<%_
const { listComponentConfig } = (bcEntityData || {listComponentConfig: {}});
_%>
<%_
const updateRelationships = relationships.filter(relationship => relationship.relationshipLeftSide && relationship.relationshipManyToMany);
const supportOwnerEntityRelationship = fields.some(field => field.options?.ownerEntityName === true) &&
        fields.some(field => field.options?.ownerEntityId === true);
_%>
<template>
  <div<% if (cypressTests) { %> data-cy="<%= entityAngularName %>RelationHeading"<% } %>>
    <%_ if (filterByTree) { _%>
    <SplitPanes class="default-theme" v-if="cardSlots?.includes('split')">
      <SplitPane size="20">
        <a-card
          title="高级搜索"
          class="bc-list-result-card"
          :body-style="{ 'padding': '12px 12px 8px 12px' }"
          :head-style="{ 'min-height': '40px', 'padding': '12px' }"
        >
          <BasicTree
            :expandedKeys="filterTreeConfig.expandedKeys"
            :autoExpandParent="filterTreeConfig.autoExpandParent"
            :selectedKeys="filterTreeConfig.selectedKeys"
            :treeData="filterTreeConfig.treeFilterData"
            @select="onSelect"
          />
        </a-card>
      </SplitPane>
      <SplitPane>
    <%_ } _%>
    <a-card
      v-if="searchFormConfig.toggleSearchStatus && !searchFormConfig.disabled"
      title="高级搜索"
      class="bc-list-search-form-card"
      :body-style="{ 'padding-top': '12px', 'padding-bottom': '8px' }"
      :head-style="{ 'min-height': '40px' }"
    >
      <template #extra>
        <a-space>
          <BasicButton type="default" @click="showSearchFormSetting" pre-icon="ant-design:setting-outlined" shape="circle" size="small"></BasicButton>
        </a-space>
      </template>
      <SearchForm :config="searchFormConfig" @formSearch="formSearch" @close="handleToggleSearch" ref="searchFormRef" />
    </a-card>
    <a-card :bordered="false" class="bc-list-result-card" :bodyStyle="{'padding-top': '1px'}">
      <template #title v-if="cardSlots?.includes('title')">
        <BasicButton type="text" pre-icon="ant-design:unordered-list-outlined" shape="default" size="large" @click="formSearch"><%= bcTitle %>列表</BasicButton>
      </template>
      <template #extra v-if="cardSlots?.includes('extra')">
        <a-space>
          <a-divider type="vertical" />
          <BasicButton
            v-if="cardExtra?.includes('import')"
            type="default"
            @click="xGrid.openImport()"
            pre-icon="ant-design:cloud-upload-outlined"
            shape="circle"
            size="small"
          ></BasicButton>
          <BasicButton
            v-if="cardExtra?.includes('export')"
            type="default"
            @click="xGrid.openExport()"
            pre-icon="ant-design:download-outlined"
            shape="circle"
            size="small"
          ></BasicButton>
          <BasicButton
            v-if="cardExtra?.includes('print')"
            type="default"
            @click="xGrid.openPrint()"
            pre-icon="ant-design:printer-outlined"
            shape="circle"
            size="small"
          ></BasicButton>
<!--          <BasicButton type="default" pre-icon="ant-design:setting-outlined" shape="circle" size="small"></Button>-->
          <%_ if (softDelete && !skipSoftDelete) { _%>
          <BasicButton type="default"  @click="showRecycleBin = !showRecycleBin" pre-icon="ant-design:rest-twotone" shape="circle" size="small"></BasicButton>
          <%_ } _%>
        </a-space>
      </template>
      <vxe-grid ref="xGrid" v-bind="gridOptions" v-on="gridEvents">
        <template #toolbar_buttons>
          <a-row :gutter="16">
            <a-col v-if="!searchFormConfig.toggleSearchStatus && !searchFormConfig.disabled">
              <a-space>
                <a-input
                  v-model:value="searchFormConfig.jhiCommonSearchKeywords"
                  placeholder="请输入关键字"
                  allow-clear
                  @change="inputSearch"
                  @pressEnter="formSearch"
                  style="width: 280px"
                  data-cy="listSearchInput"
                >
                  <template #prefix>
                    <Icon icon="ant-design:search-outlined" />
                  </template>
                  <template #addonAfter>
                    <BasicButton type="link" @click="formSearch" style="height: 30px" data-cy="listSearchButton"
                    >查询<Icon icon="ant-design:filter-outlined" @click="handleToggleSearch" data-cy="listSearchMore"></Icon>
                    </BasicButton>
                  </template>
                </a-input>
                <template v-for="button of gridOptions?.toolbarConfig?.buttons">
                  <BasicButton v-if="!button.dropdowns">{{button.name}}</BasicButton>
                  <a-dropdown v-else-if="selectedRows.length" :key="button.name" :content="button.name">
                    <template #overlay>
                      <a-menu @click="gridEvents.toolbarButtonClick?.(subButton as any)" v-for="subButton of button.dropdowns">
                        <a-menu-item :key="subButton.name + 's'">
                          <Icon :icon="subButton.icon"></Icon>
                          {{subButton.name}}
                        </a-menu-item>
                      </a-menu>
                    </template>
                    <BasicButton>
                      {{button.name}}
                      <Icon icon="ant-design:down-outlined" />
                    </BasicButton>
                  </a-dropdown>
                </template>
              </a-space>
            </a-col>
          </a-row>
        </template>
        <template #recordAction="{ row }">
          <ButtonGroup  :row="row" :buttons="rowOperations" @click="rowClick"/>
        </template>
        <template #pagerLeft>
          <a-alert type="warning" banner :message="'已选择 ' + selectedRows.length + ' 项'" style="height: 30px" />
        </template>
      </vxe-grid>
    </a-card>
    <%_ if (filterByTree) { _%>
      </SplitPane>
    </SplitPanes>
    <%_ } _%>
    <%_ if (filterByTree) { _%>
    <div v-else>
      <a-card
        v-if="searchFormConfig.toggleSearchStatus && !searchFormConfig.disabled"
        title="高级搜索"
        class="bc-list-search-form-card"
        :body-style="{ 'padding-top': '12px', 'padding-bottom': '8px' }"
        :head-style="{ 'min-height': '40px' }"
      >
        <template #extra>
          <a-space><BasicButton type="default" @click="showSearchFormSetting" pre-icon="ant-design:setting-outlined" shape="circle" size="small"></BasicButton></a-space>
        </template>
        <SearchForm :config="searchFormConfig" @formSearch="formSearch" @close="handleToggleSearch" ref="searchFormRef" />
      </a-card>
      <a-card :bordered="false" class="bc-list-result-card" :bodyStyle="{'padding': '1px 0 0 0'}">
        <template #title v-if="cardSlots?.includes('title')">
          <BasicButton type="text" pre-icon="ant-design:unordered-list-outlined" shape="default" size="large" @click="formSearch"><%= bcTitle %>列表</BasicButton>
        </template>
        <template #extra v-if="cardSlots?.includes('extra')">
          <a-space>
            <a-divider type="vertical" />
          <BasicButton
            v-if="cardExtra?.includes('import')"
            type="default"
            @click="xGrid.openImport()"
            pre-icon="ant-design:cloud-upload-outlined"
            shape="circle"
            size="small"
          ></BasicButton>
          <BasicButton
            v-if="cardExtra?.includes('export')"
            type="default"
            @click="xGrid.openExport()"
            pre-icon="ant-design:download-outlined"
            shape="circle"
            size="small"
          ></BasicButton>
          <BasicButton
            v-if="cardExtra?.includes('print')"
            type="default"
            @click="xGrid.openPrint()"
            pre-icon="ant-design:printer-outlined"
            shape="circle"
            size="small"
          ></BasicButton>
<!--          <BasicButton type="default" pre-icon="ant-design:setting-outlined" shape="circle" size="small"></BasicButton>-->
          <%_ if (softDelete && !skipSoftDelete) { _%>
          <BasicButton type="default"  @click="showRecycleBin = !showRecycleBin" pre-icon="ant-design:rest-twotone" shape="circle" size="small"></BasicButton>
          <%_ } _%>
          </a-space>
        </template>
        <vxe-grid ref="xGrid" v-bind="gridOptions" v-on="gridEvents">
          <template #toolbar_buttons>
            <a-row :gutter="16">
              <a-col v-if="!searchFormConfig.toggleSearchStatus && !searchFormConfig.disabled">
                <a-space>
                  <a-input
                    v-model:value="searchFormConfig.jhiCommonSearchKeywords"
                    placeholder="请输入关键字"
                    allow-clear
                    @change="inputSearch"
                    @pressEnter="formSearch"
                    style="width: 280px"
                    data-cy="listSearchInput"
                    >
                    <template #prefix>
                      <Icon icon="ant-design:search-outlined" />
                    </template>
                    <template #addonAfter>
                      <BasicButton type="link" @click="formSearch" style="height: 30px" data-cy="listSearchButton"
                      >查询<Icon icon="ant-design:filter-outlined" @click="handleToggleSearch" data-cy="listSearchMore"></Icon>
                      </BasicButton>
                    </template>
                  </a-input>
                  <template v-for="button of gridOptions?.toolbarConfig?.buttons">
                    <BasicButton v-if="!button.dropdowns">{{button.name}}</BasicButton>
                    <a-dropdown v-else-if="selectedRows.length" :key="button.name" :content="button.name">
                      <template #overlay>
                        <a-menu @click="gridEvents.toolbarButtonClick?.(subButton as any)" v-for="subButton of button.dropdowns">
                          <a-menu-item :key="subButton.name + 's'">
                            <Icon :icon="subButton.icon"></Icon>
                            {{subButton.name}}
                          </a-menu-item>
                        </a-menu>
                      </template>
                      <BasicButton>
                        {{button.name}}
                        <Icon icon="ant-design:down-outlined" />
                      </BasicButton>
                    </a-dropdown>
                  </template>
                </a-space>
              </a-col>
            </a-row>
          </template>
          <template #recordAction="{ row }">
            <ButtonGroup  :row="row" :buttons="rowOperations" @click="rowClick"/>
          </template>
          <template #pagerLeft>
            <a-alert type="warning" banner :message="'已选择 ' + selectedRows.length + ' 项'" style="height: 30px" />
          </template>
        </vxe-grid>
      </a-card>
    </div>
    <%_ } _%>
    <BasicModal v-bind="popupConfig.containerProps" @register="registerModal" @cancel="closeModal" v-on="popupConfig.containerEvents">
      <component
        v-if="popupConfig.componentProps.is"
        v-bind="popupConfig.componentProps"
        :is="popupConfig.componentProps.is"
        @cancel="closeModal"
        @refresh="formSearch"
        v-on="popupConfig.componentEvents"
        ref="modalComponentRef"
      />
    </BasicModal>
    <BasicDrawer v-bind="popupConfig.containerProps" @register="registerDrawer" @close="closeDrawer" v-on="popupConfig.containerEvents">
      <component
        v-if="popupConfig.componentProps.is"
        v-bind="popupConfig.componentProps"
        :is="popupConfig.componentProps.is"
        @cancel="closeDrawer"
        @refresh="formSearch"
        v-on="popupConfig.componentEvents"
        ref="drawerComponentRef"
      />
    </BasicDrawer>
  </div>
</template>

<script lang="ts" setup>
import { Modal, message } from 'ant-design-vue';
import type { VxeGridPropTypes, VxeGridInstance, VxeGridListeners, VxeGridProps } from 'vxe-table/types/grid';
import { getSearchQueryData } from '@/utils/jhipster/entity-utils';
import { transVxeSorts } from '@/utils/jhipster/sorts';
import { useDrawer } from '@/components/Drawer';
import { useModal } from '@/components/Modal';
import { ButtonGroup } from '@/components/Button';
import ServerProvider from '@/api-service/index';
import <%= entityClass %>Detail from './detail-component.vue';
import <%= entityClass %>Edit from './form-component.vue';
import <%= entityClass %>List from '../<%= entityFileName %>-list.vue';
import { useMergeGridProps } from '@/components/VxeTable/src/helper';
<%_ Object.keys(listComponentConfig.importPackages).forEach(importPackage => {
  const importComponents = listComponentConfig.importPackages[importPackage];
  let importComponentList = '';
  if (typeof importComponents === 'string') {
      importComponentList = listComponentConfig.importPackages[importPackage];
  } else {
      importComponentList = `{ ${Array.from(new Set(listComponentConfig.importPackages[importPackage])).join(', ')} }`;
  }
_%>
import <%= importComponentList %> from '<%= importPackage %>';
<%_ }); _%>

<%_
const { relationTableColumns, searchFormFields, tableImportStatements } = (bcEntityData || { relationTableColumns: [], searchFormFields: [], tableImportStatements: [] });
_%>
<%_ if (tableImportStatements && tableImportStatements.size) { _%>
<%- Array.from(tableImportStatements).join('\n') %>
<%_ } _%>
<%_ if (addCustomMethod.indexOf('listRelation') !== -1) { _%>
<%- include(`../../common/entity-custom/${entityClass}.listRelation.ejs`, {position: 'import'}); -%>
<%_ } _%>
<%_
let apiModuleName = this._.camelCase(clientRootFolder || microserviceName);
_%>

const relationships = {
  <%_ relationships.filter(relationship => relationship.relationshipManyToMany).forEach(relationship => { _%>
    '<%= relationship.otherEntity.persistClass %>.<%= relationship.otherRelationship.relationshipName %>': '<%= relationship.relationshipName %>',
  <%_ }); _%>
}

const config = {
  searchForm: (relationshipApis): any[] => {
<%_ if (fields.find(field => field.fieldIsEnum)) { _%>
  <%_ if (enableTranslation) { _%>
  const { getEnumDict } = useI18n();
  <%_ } _%>
<%_ } _%>
  return [
    <%_
      searchFormFields.forEach(column => {
  _%>
  <%- column _%>
    <%_ });_%>
  ];
},
  columns: (): VxeGridPropTypes.Columns => {
<%_ if (fields.find(field => field.fieldIsEnum)) { _%>
  <%_ if (enableTranslation) { _%>
  const { getEnumDict } = useI18n();
  <%_ } _%>
<%_ } _%>
  return [
  <%_
    relationTableColumns.forEach(column => {
  _%>
  <%- column _%>
    <%_ });_%>
  ] as VxeGridPropTypes.Columns;
},
  baseGridOptions: (): VxeGridProps => {
  return {
    rowConfig: {
      keyField: 'id',
      isHover: true,
    },
    border: true,
    showHeaderOverflow: true,
    showOverflow: true,
    keepSource: true,
    id: 'vxe_grid_<%= entityInstance %>_relation',
    printConfig: {
      columns: [
        // { field: 'name' },
      ],
    },
    filterConfig: {
      remote: true,
    },
    columnConfig: {
      resizable: true,
    },
    sortConfig: {
      trigger: 'cell',
      remote: true,
      orders: ['asc', 'desc', null],
      multiple: true,
      defaultSort: {
        field: 'id',
        order: 'desc',
      },
      showIcon: true,
    },
    pagerConfig: {
      layouts: ['Sizes', 'PrevJump', 'PrevPage', 'Number', 'NextPage', 'NextJump', 'FullJump', 'Total'] as VxeGridPropTypes.PagerConfig['layouts'],
      pageSize: 15,
      pageSizes: [5, 10, 15, 20, 30, 50],
      total: 0,
      pagerCount: 5,
      currentPage: 1,
      autoHidden: false,
      slots: {
        left: 'pagerLeft',
      },
    },
    importConfig: {},
    exportConfig: {},
    checkboxConfig: {
      // labelField: 'id',
      reserve: true,
      highlight: true,
    },
    editRules: {},
    editConfig: {
      enabled: false,
      trigger: 'click',
      mode: 'cell',
      showStatus: false,
    },
<%_ if (fieldsContainParentAndChildren) { _%>
    treeConfig: {
      childrenField: 'children',
      indent: 20,
      showLine: false,
      expandAll: false,
      accordion: false,
      trigger: 'default',
    },
<%_ } _%>
  };
},
};

// begcode-please-regenerate-this-file 如果您不希望重新生成代码时被覆盖，将please修改为don't ！！！
const props = defineProps(
  {
    query: {
      type: Object,
      default: () => ({}),
    },
    editIn: {
      type: String,
      default: '',
    },
    field: {
      type: String,
      default: '',
    },
    source: {
      type: String,
      default: '',
    },
    ownerId: {
      type: [String , Number],
      default: '',
    },
    baseData: {
      type: Object,
      default: () => ({}),
    },
    cardExtra: {
      type: Array,
      default: ['import', 'export', 'print'],
    },
    cardSlots: {
      type: Array,
      default: ['title', 'extra'],
    },
    gridOptions: {
      type: Object,
      default: () => ({}),
    },
    searchFormOptions: {
      type: Object,
      default: () => ({
        disabled: false,
      }),
    },
    gridCustomConfig: {
      type: Object,
      default: () => ({
        hideOperations: false,
        hideSlots: [],
        hideColumns: [],
      }),
    },
    updateType: {
      type: String,
      default: 'remoteApi', // 'remoteApi' | 'emitSelected'
    },
    relationData: {
      type: Array,
      default: null,
    },
    deleteRelationType: {
      type: String,
      default: 'delete', // 'delete' | 'cancel' 一对多时，使用delete，多对多时，使用cancel
    },
    parentContainer: {
      type: String,
      default: '',
    }
  }
);

const emit = defineEmits(['updateRelationData']);

const [registerModal, { closeModal, setModalProps }] = useModal();
const [registerDrawer, { closeDrawer, setDrawerProps }] = useDrawer();
const modalComponentRef = ref<any>(null);
const drawerComponentRef = ref<any>(null);
const ctx = getCurrentInstance()?.proxy;
const apiService = ctx?.$apiService as typeof ServerProvider;
const apis = {
  <%= entityInstance %>Service: apiService.<%= apiModuleName ? apiModuleName + '.' : '' %><%= entityInstance %>Service,
  find: apiService.<%= apiModuleName ? apiModuleName + '.' : '' %><%= entityInstance %>Service.<%= fieldsContainParentAndChildren ? 'tree' : 'retrieve'%>,
  <%_ if (fieldsContainParentAndChildren) { _%>
  findByParentId: apiService.<%= apiModuleName ? apiModuleName + '.' : '' %><%= entityInstance %>Service.treeByParentId,
  <%_ } _%>
  deleteById: apiService.<%= apiModuleName ? apiModuleName + '.' : '' %><%= entityInstance %>Service.delete,
  deleteByIds: apiService.<%= apiModuleName ? apiModuleName + '.' : '' %><%= entityInstance %>Service.deleteByIds,
  <%_ if (features.includes('copy')) { _%>
  copy: apiService.<%= apiModuleName ? apiModuleName + '.' : '' %><%= entityInstance %>Service.copy,
  <%_ } _%>
  import: apiService.<%= apiModuleName ? apiModuleName + '.' : '' %><%= entityInstance %>Service.importExcel,
  export: apiService.<%= apiModuleName ? apiModuleName + '.' : '' %><%= entityInstance %>Service.exportExcel,
  <%_ if (updateRelationships && updateRelationships.length) { _%>
  updateRelations: apiService.<%= apiModuleName ? apiModuleName + '.' : '' %><%= entityInstance %>Service.updateRelations,
  <%_ } _%>
  <%_ Object.keys(listComponentConfig.relationshipApis).forEach(relationshipApiName => { _%>
  <%= relationshipApiName %>: <%= listComponentConfig.relationshipApis[relationshipApiName]%>,
  <%_}); _%>
  <%_ for (relationship of relationships.filter(relationship => !relationship.otherEntity?.skipClient)) {
    const relationApiModuleName = this._.camelCase(relationship.otherEntity.clientRootFolder || relationship.otherEntity.microserviceName);
  _%>
  <%= relationship.relationshipName %>: apiService<%= relationApiModuleName ?  '.' + relationApiModuleName : ''%>.<%= relationship.otherEntity.entityInstance%>Service.<%= relationship.otherEntity.fieldsContainParentAndChildren ? 'tree' : 'retrieve'%>,
  <%_ } _%>
};
const columns = config.columns();
if (props.gridCustomConfig?.hideColumns?.length > 0) {
  const filterColumns = columns
    .filter(column => !props.gridCustomConfig.hideColumns.includes(column.field));
  columns.length = 0;
  columns.push(...filterColumns);
}
<%_ if (softDelete && !skipSoftDelete) { _%>
const showRecycleBin = ref<Boolean>(false);
<%_ } _%>
const xGrid = ref({} as VxeGridInstance);
const searchFormConfig = reactive<Record<string, any>>(
  {
    fieldList: config.searchForm(apis),
    toggleSearchStatus: false,
    useOr: false,
    disabled: false,
    allowSwitch: true,
    compact: true,
    jhiCommonSearchKeywords: '',
    ...props.searchFormOptions,
  }
);
let rowOperations = [
  {
    title: '取消关联',
    name: 'cancelRelate',
    type: 'link',
    hide: () => props.deleteRelationType !== 'cancel',
  },
  {
    title: '删除',
    name: 'delete',
    type: 'link',
    hide: () => props.deleteRelationType !== 'delete',
  },
  <%_ if (!skipWebButton.includes('listDetail')) { _%>
  {
    title: '详情',
    name: 'detail',
    containerType: 'drawer',
    type: 'link',
  },
  <%_ } _%>
<%_ if (addCustomMethod.indexOf('listRelation') !== -1) { _%>
<%- include(`../../common/entity-custom/${entityClass}.listRelation.ejs`, {position: 'rowOperations'}); -%>
<%_ } _%>
];
if (props.gridCustomConfig?.rowOperations && _isArray(props.gridCustomConfig.rowOperations)) {
  if (props.gridCustomConfig.rowOperations.length === 0) {
    rowOperations = [];
  } else {
    rowOperations = rowOperations
      .filter(item =>
        props.gridCustomConfig.rowOperations.some(rowItem =>
          _isObject(rowItem) ? item.name === rowItem['name'] : item.name === rowItem
        )
      );
  }
}
const tableRowOperations = reactive<any[]>([]);
const tableRowMoreOperations = reactive<any[]>([]);
const saveOperation = rowOperations.find(operation => operation.name === 'save');
if (rowOperations.length > 4 || (saveOperation && rowOperations.length > 3)) {
if (saveOperation) {
  tableRowOperations.push(...rowOperations?.slice(0, 3));
  tableRowMoreOperations.push(...rowOperations.slice(3));
} else {
  tableRowOperations.push(...rowOperations?.slice(0, 4));
  tableRowMoreOperations.push(...rowOperations.slice(4));
}
} else {
tableRowOperations.push(...rowOperations);
}
const selectedRows = reactive<any>([]);
const searchFormRef = ref<any>(null);
const searchValue = ref('');
<%_ if (filterByTree) { _%>
const mapOfFilter = ref({});
const filterTreeConfig = reactive({
  treeFilterData: [] as any[],
  expandedKeys: [],
  checkedKeys: [],
  selectedKeys: [],
  autoExpandParent: true,
});
  <%_ (listComponentConfig.filterByTreeGetData || []).forEach(filterGetData => { _%>
<%- filterGetData -%>
  <%_ }); _%>
<%_ } _%>
const popupConfig = reactive<any>({
  needSubmit: false,
  containerProps: {
    width: '80%',
    destroyOnClose: true,
    okText: '确定',
    cancelText: '取消',
  },
  containerEvents: {},
  componentProps: {
    containerType: 'modal',
    baseData: props.baseData,
    is: '',
    entityId: '',
  },
  componentEvents: {},
});
const gridOptions = computed(() => {
  const result: VxeGridProps = {
    ...config.baseGridOptions(),
    customConfig: {
      storage: true,
      checkMethod({ column }) {
        return !['nickname', 'role'].includes(column.field);
      },
    },
  proxyConfig: {
    enabled: true,
    autoLoad: true,
    seq: true,
    sort: true,
    filter: true,
    response: {
      result: 'records',
      total: 'total',
    },
    ajax: {
      query: async ({ filters, page, sort, sorts }) => {
        console.log('filters', filters);
        const queryData = _pickBy(props.query);
        const queryParams: any = {...queryData};
        queryParams.page = page?.currentPage > 0 ? page.currentPage - 1 : 0;
        queryParams.size = page?.pageSize;
        if (props.relationData) {
          queryParams['id.in'] = props.relationData.map(item => item.<%= primaryKey.name %>);
        }
        if (Object.values(queryData).length === 0 && (!props.relationData || props.relationData.length === 0)) {
          return new Promise<any>((resolve) => {
            resolve({records: [], size: page?.pageSize || 15, page: page.currentPage, total: 0 })
          })
        }
        const allSort = sorts || [];
        sort && allSort.push(sort)
        queryParams.sort = transVxeSorts(allSort);
        if (searchFormConfig.jhiCommonSearchKeywords) {
          queryParams['jhiCommonSearchKeywords'] = searchFormConfig.jhiCommonSearchKeywords;
        } else {
          delete queryParams['jhiCommonSearchKeywords'];
          Object.assign(queryParams, getSearchQueryData(searchFormConfig));
        }
        <%_ if (filterByTree) { _%>
        if (Object.keys(mapOfFilter.value).length) {
          queryParams.and = mapOfFilter.value;
        } else {
          delete queryParams.and;
        }
        <%_ } _%>
        return await apis.find(queryParams);
      },
      queryAll: async () => await apis.find({ size: -1 }),
      import: async ({file, options}) => {
        apis.import(file).then(() => {
          formSearch();
        });
      },
    },
  },
  toolbarConfig: {
    custom: false,
    import: false,
    print: false,
    export: false,
    slots: {
      buttons: 'toolbar_buttons',
    },
    // 表格左上角自定义按钮
    buttons: [
      {
        name: '批量操作',
        visible: true,
        circle: false,
        icon: 'vxe-icon-add',
        status: 'primary',
        dropdowns: [
          { code: 'batchDelete', name: '删除', visible: props.deleteRelationType === 'delete', circle: false, icon: 'ant-design:delete-filled', status: 'primary' },
          { code: 'batchCancelRelate', name: '取消关联', visible: props.deleteRelationType === 'cancel', circle: false, icon: 'ant-design:split-cells-outlined', status: 'primary' },
        ],
      },
    ],
    // 表格右上角自定义按钮
    tools: [
    <%_ if (skipWebButton.indexOf('listAdd') === -1) { _%>
      { code: 'add', name: '选择', visible: true, circle: false, icon: 'vxe-icon-arrow-double-left'},
      { code: 'new', name: '新建', visible: true, circle: false, icon: 'vxe-icon-add'},
    <%_ } _%>
      { code: 'custom-column', name: '列配置', visible: true, circle: false, icon: 'vxe-icon-custom-column'},
<%_ if (addCustomMethod.indexOf('listRelation') !== -1) { _%>
<%- include(`../../common/entity-custom/${entityClass}.listRelation.ejs`, {position: 'tools'}); -%>
<%_ } _%>
    ],
  },
  columns,
};
  useMergeGridProps(result, props.gridOptions);
  return result;
});


const toolbarClick = ({ code }) => {
  const $grid = xGrid.value;
  switch (code) {
    case 'batchDelete': {
      const records = $grid.getCheckboxRecords(true);
      if (records?.length > 0) {
        if (props.updateType === 'remoteApi') {
          const ids = records.map(record => record.<%= primaryKey.name %>);
          Modal.confirm({
            title: `操作提示`,
            content: `是否删除ID为【${ids.join(',')}】的${records.length}项数据？`,
            onOk() {
              apis
                .deleteByIds(ids)
                .then(() => {
                  message.success({ content: `删除成功`, duration: 1 });
                  formSearch();
                })
                .catch(err => {
                  console.log('err', err);
                  message.error({ content: `删除失败`, duration: 1 });
                });
            },
          });
        } else {
          if (xGrid.value && records?.length > 0) {
            xGrid.value.remove(records).then(() => {
              message.success({ content: `删除成功`, duration: 1 });
            });
          }
        }
      }
      break;
    }
    case 'batchCancelRelate': {
      const records = $grid.getCheckboxRecords(true);
      if (records?.length > 0) {
        if (props.updateType === 'remoteApi') {
          const ids = records.map(record => record.<%= primaryKey.name %>);
          Modal.confirm({
            title: `操作提示`,
            content: `是否取消ID为【${ids.join(',')}】的${records.length}项数据的关联？`,
            onOk() {
              <%_ if (updateRelationships && updateRelationships.length) { _%>
              if (props.source && props.field) {
                const relationshipName = relationships[`${props.source}.${props.field}`];
                apis.updateRelations([props.ownerId], relationshipName, ids, 'delete').then(result => {
                  formSearch();
                });
              }
              <%_ } else { _%>
              // todo 暂时不需要
              <%_ } _%>
            },
          });
        } else {
          if (xGrid.value && records?.length > 0) {
            xGrid.value.remove(records).then(() => {
              message.success({ content: `取消关联成功`, duration: 1 });
            });
          }
        }
      }
      break
    }
    case 'add':
    {
      popupConfig.needSubmit = true;
      popupConfig.containerProps.title = '选择';
      popupConfig.containerProps.okText = '确定';
      popupConfig.containerProps.cancelText = '取消';
      popupConfig.containerProps.showOkBtn = true;
      popupConfig.containerProps.showCancelBtn = true;
      popupConfig.componentProps.is = shallowRef(<%= entityClass %>List);
      popupConfig.componentProps.baseData = props.baseData;
      popupConfig.componentProps.query = {};
      popupConfig.componentProps.entityId = '';
      if (getData().length > 0) {
        popupConfig.componentProps.query['<%= primaryKey.name %>.notIn'] = getData().map(item => item.<%= primaryKey.name %>);
      }
      const tools: string[] = [];
      const buttons: string[] = [];
      const rowOperations = ['detail'];
      popupConfig.componentProps.gridOptions = _merge({}, { toolbarConfig: { import: false, print: false, export: false, custom: false, tools, buttons } });
      popupConfig.componentProps.cardExtra = [];
      popupConfig.componentProps.searchFormOptions = _merge({});
      popupConfig.componentProps.gridCustomConfig = _merge({}, { rowOperations });
      if (props.editIn === 'drawer') {
        popupConfig.componentProps.containerType = 'drawer';
        popupConfig.containerEvents.ok = okDrawer;
        popupConfig.containerProps.width = '40%';
        setDrawerProps({ open: true });
      } else {
        popupConfig.componentProps.containerType = 'modal';
        popupConfig.containerProps.width = '80%';
        popupConfig.containerEvents.ok = okModal;
        setModalProps({ open: true });
      }
      break;
    }
    <%_ if (skipWebButton.indexOf('listAdd') === -1) { _%>
    case 'new':
      popupConfig.needSubmit = true;
      popupConfig.containerProps.title = '新建';
      popupConfig.containerProps.okText = '保存';
      popupConfig.containerProps.cancelText = '取消';
      popupConfig.containerProps.showOkBtn = true;
      popupConfig.containerProps.showCancelBtn = true;
      popupConfig.componentProps.is = shallowRef(<%= entityClass %>Edit);
      popupConfig.componentProps.entityId = '';
      popupConfig.componentProps.baseData = props.baseData;
      popupConfig.containerEvents.ok = async () => {
        const result = await drawerComponentRef.value.submit({submitToServer: <% if (features.includes('createBySelf')) { %>true<% } else { %>false<% } %>});
          if (result) {
            // 对新增的记录进行关联关系处理
            <%_ if (updateRelationships && updateRelationships.length) { _%>
            const entityIds = [result].map(row => row.<%= primaryKey.name %>);
            const relationshipName = relationships[`${props.source}.${props.field}`];
            apis.updateRelations([props.ownerId], relationshipName, entityIds, 'add').then(result => {
              formSearch();
              if (props.editIn === 'drawer') {
                closeDrawer();
              } else {
                closeModal();
              }
            });
            <%_ } else { _%>
            if (props.editIn === 'drawer') {
              closeDrawer();
            } else {
              closeModal();
            }
            formSearch();
            <%_ } _%>
          } else {
            // 此时result = false;
            console.log('保存失败。');
          }
        };
      popupConfig.componentProps.containerType = props.editIn === 'drawer' ? 'drawer' : 'modal';
      popupConfig.containerProps.width = props.editIn === 'drawer' ? '40%' : '80%';
      if (props.editIn === 'drawer') {
        setDrawerProps({ open: true });
      } else {
        setModalProps({ open: true });
      }
      break;
    <%_ } _%>
    case 'custom-column':
      xGrid.value.openCustom();
      break;
<%_ if (addCustomMethod.indexOf('listRelation') !== -1) { _%>
<%- include(`../../common/entity-custom/${entityClass}.listRelation.ejs`, {position: 'toolbarToolClick'}); -%>
<%_ } _%>
    default:
        console.log('事件未定义', code);
  }
};

const gridEvents = reactive<VxeGridListeners>({
  checkboxAll: () => {
    const $grid = xGrid.value
    selectedRows.length = 0;
    selectedRows.push(...$grid.getCheckboxRecords());
  },
  checkboxChange: () => {
    const $grid = xGrid.value;
    selectedRows.length = 0;
    selectedRows.push(...$grid.getCheckboxRecords());
  },
  radioChange() {
    const $grid = xGrid.value;
    selectedRows.length = 0;
    selectedRows.push($grid.getRadioRecord());
  },
  // 表格左上角按钮事件
  toolbarButtonClick: toolbarClick,
  // 表格右上角自定义按钮事件
  toolbarToolClick: toolbarClick,
});
const okModal = async () => {
  if (modalComponentRef.value) {
    const selectRows = modalComponentRef.value.getSelectRows();
    if (props.updateType === 'remoteApi') {
      // 对selectRows进行处理。
        <%_ if (updateRelationships?.length) { _%>
      const entityIds = selectRows.map(row => row.<%= primaryKey.name %>);
      const relationshipName = relationships[`${props.source}.${props.field}`];
      apis.updateRelations([props.ownerId], relationshipName, entityIds, 'add').then(result => {
        formSearch();
        closeModal();
      });
        <%_ } else if (supportOwnerEntityRelationship && features.includes('copy')) { _%>
      const newRows = selectRows.map(row => Object.assign(row, props.baseData));
      for (const row of newRows) {
        await apis.copy(row);
      }
      formSearch();
      closeModal();
        <%_ } else { _%>
      if (xGrid.value && selectRows?.length > 0) {
        xGrid.value.insert(selectRows).then(() => {
          emit('updateRelationData', getData());
          message.success({
            content: `关联成功`,
            duration: 1,
          });
        });
      }
        <%_ } _%>
    } else {
      if (xGrid.value && selectRows?.length > 0) {
        xGrid.value.insert(selectRows).then(() => {
          emit('updateRelationData', getData());
          message.success({
            content: `关联成功`,
            duration: 1,
          });
        });
      }
      closeModal();
    }
  }
};
const okDrawer = async () => {
  if (drawerComponentRef.value) {
    const selectRows = drawerComponentRef.value.getSelectRows();
    if (props.updateType === 'remoteApi') {
      // 对selectRows进行处理。
        <%_ if (updateRelationships && updateRelationships.length) { _%>
      const entityIds = selectRows.map(row => row.<%= primaryKey.name %>);
      const relationshipName = relationships[`${props.source}.${props.field}`];
      apis.updateRelations([props.ownerId], relationshipName, entityIds, 'add').then(result => {
        formSearch();
        closeDrawer();
      });
        <%_ } else if (supportOwnerEntityRelationship && features.includes('copy')) { _%>
      const newRows = selectRows.map(row => Object.assign(row, props.baseData));
      for (const row of newRows) {
        await apis.copy(row);
      }
      closeDrawer();
      formSearch();
        <%_ } else { _%>
      if (xGrid.value && selectRows?.length > 0) {
        xGrid.value.insert(selectRows).then(() => {
          emit('updateRelationData', getData());
          message.success({
            content: `关联成功`,
            duration: 1,
          });
        });
      }
        <%_ } _%>
    } else {
      if (xGrid.value && selectRows?.length > 0) {
        xGrid.value.insert(selectRows).then(() => {
          emit('updateRelationData', getData());
          message.success({
            content: `关联成功`,
            duration: 1,
          });
        });
      }
      closeDrawer();
    }
  }
};
const formSearch = () => {
  xGrid.value.commitProxy('reload');
};
const inputSearch = _debounce(formSearch, 700);

const handleToggleSearch = () => {
  searchFormConfig.toggleSearchStatus = !searchFormConfig.toggleSearchStatus;
};


const showSearchFormSetting = () => {
  if (searchFormRef.value) {
    searchFormRef.value.showSettingModal();
  }
};
<%_ if (filterByTree) { _%>

const onSelect = (selectedKeys, info) => {
  const filterData = info.node.dataRef;
  mapOfFilter.value = {};
  if (selectedKeys && selectedKeys.length > 0) {
    if (filterData.type === 'filterItem') {
      mapOfFilter.value[info.node.dataRef.filterName] = info.node.dataRef.filterValue;
      filterTreeConfig.selectedKeys = selectedKeys;
    }
  }
  formSearch();
};
<%_ } _%>

const rowClick = ({name, data}) => {
  const row = data;
  const operation = tableRowOperations.find(operation => operation.name === name);
  if (operation?.click) {
    operation.click(row);
  } else {
    switch (name) {
      case 'detail':
        popupConfig.componentProps.is = shallowRef(<%= entityClass %>Detail);
        popupConfig.componentProps.entityId = row.<%= primaryKey.name %>;
        popupConfig.containerProps.title = '详情';
        popupConfig.containerProps.showOkBtn = false;
        popupConfig.containerProps.showCancelBtn = true;
        popupConfig.containerProps.cancelText = '关闭';
        if (operation?.containerType === 'drawer') {
          popupConfig.componentProps.containerType = 'drawer';
          popupConfig.containerProps.width = '40%';
          setDrawerProps({ open: true });
        } else {
          popupConfig.componentProps.containerType = 'modal';
          popupConfig.containerProps.width = '80%';
          setModalProps({ open: true });
        }
        break;
      case 'cancelRelate':
        Modal.confirm({
          title: `操作提示`,
          content: `是否取消ID为${row.<%= primaryKey.name %>}的关联？`,
          onOk() {
            if (operation.click) {
              operation.click(row);
            } else {
              if (props.updateType === 'remoteApi') {
                <%_ if (updateRelationships && updateRelationships.length) { _%>
                if (props.source && props.field) {
                  const relationshipName = relationships[`${props.source}.${props.field}`];
                  apis.updateRelations([props.ownerId], relationshipName, [row.<%= primaryKey.name %>], 'delete').then(result => {
                    formSearch();
                  });
                }
                <%_ } else { _%>
                // todo 暂时不需要
                <%_ } _%>
              } else {
                if (xGrid.value) {
                  xGrid.value.remove([row]).then(() => {
                    message.success({
                      content: `取消成功`,
                      duration: 1,
                    });
                  });
                }
              }
            }
          },
        });
        break;
      case 'delete':
        Modal.confirm({
          title: `操作提示`,
          content: `是否删除ID为${row.<%= primaryKey.name %>}的数据？`,
          onOk() {
            if (operation.click) {
              operation.click(row);
            } else {
              if (props.updateType === 'remoteApi') {
                apis.deleteById(row.<%= primaryKey.name %>).then(result => {
                  message.success({
                    content: `删除成功`,
                    duration: 1,
                  });
                  formSearch();
                });
              } else {
                if (xGrid.value) {
                  xGrid.value.remove([row]).then(() => {
                    message.success({
                      content: `删除成功`,
                      duration: 1,
                    });
                  });
                }
              }
            }
          },
        });
        break;
      <%_ if (addCustomMethod.indexOf('listRelation') !== -1) { _%>
      <%- include(`../../common/entity-custom/${entityClass}.listRelation.ejs`, {position: 'rowClickHandler'}); -%>
      <%_ } _%>
      default:
        console.log('error', `${name}未定义`);
    }
  }
};

<%_ if (addCustomMethod.indexOf('listRelation') !== -1) { _%>
<%- include(`../../common/entity-custom/${entityClass}.listRelation.ejs`, {position: 'method'}); -%>
<%_ } _%>

const getSelectRows = () => {
  return toRaw(selectedRows);
};
const getData = () => {
  if (xGrid.value) {
    const data = xGrid.value.getTableData();
    return data.fullData || [];
  } else {
    return [];
  }
};

const validate = async () => {
  const result = await xGrid.value.validate(true);
  if (!result) {
    return getData();
  } else {
    return false;
  }
};

watchEffect(() => {
  if (props.relationData && props.relationData.length > 0 || props.query && Object.keys(props.query).length > 0) {
    nextTick(() => {
      formSearch();
    });
  }
});

defineExpose({
  getSelectRows,
  getData,
  validate,
})
</script>
<style lang="less" scoped>
  :deep(.ant-card-bordered.bc-list-result-card) {
    border: none;
  }
</style>
