liyu-pc-base 1.0.486 → 1.0.490
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{FieldRender-BK1b61Fg.js → FieldRender-BwKmAXkb.js} +1 -1
- package/dist/{FieldRender-BK1b61Fg.js.map → FieldRender-BwKmAXkb.js.map} +1 -1
- package/dist/{FieldRender2-CNdvHlXJ.js → FieldRender2-BpVSM5cl.js} +2 -2
- package/dist/{FieldRender2-CNdvHlXJ.js.map → FieldRender2-BpVSM5cl.js.map} +1 -1
- package/dist/{FormRender3-BveAS0Un.js → FormRender3-DK0ZPf_t.js} +1 -1
- package/dist/{FormRender3-BveAS0Un.js.map → FormRender3-DK0ZPf_t.js.map} +1 -1
- package/dist/{RemoteSelectPro-C-LgAnnI.js → RemoteSelectPro-Q4BcXw3X.js} +1 -1
- package/dist/{RemoteSelectPro-C-LgAnnI.js.map → RemoteSelectPro-Q4BcXw3X.js.map} +1 -1
- package/dist/{SearchRender-02V6hXM3.js → SearchRender-DONZ9JQn.js} +1 -1
- package/dist/{SearchRender-02V6hXM3.js.map → SearchRender-DONZ9JQn.js.map} +1 -1
- package/dist/components/index.js +8914 -8301
- package/dist/components/index.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/liyu-pc-base.css +1 -1
- package/dist/{tableModal-xUayfRER.js → tableModal-BG9p7q0l.js} +1 -1
- package/dist/{tableModal-xUayfRER.js.map → tableModal-BG9p7q0l.js.map} +1 -1
- package/dist/{tablePro-DHw9O3mT.js → tablePro-mmuwTNO0.js} +1399 -966
- package/dist/tablePro-mmuwTNO0.js.map +1 -0
- package/package.json +1 -1
- package/dist/tablePro-DHw9O3mT.js.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"tablePro-DHw9O3mT.js","names":[],"sources":["../src/components/FormRender/SmallTableSerarchField.vue","../src/components/FormRender/SmallTableSerarchField.vue","../src/api/view-model.ts","../src/utils/dom.ts","../src/utils/hooks/useFullscreen.ts","../src/components/tablePro/utils.ts","../src/components/tablePro/searchSummary.vue","../src/components/tablePro/searchSummary.vue","../src/components/tablePro/tableConfig/searchConfig.vue","../src/components/tablePro/tableConfig/searchConfig.vue","../src/components/tablePro/SearchForm.vue","../src/components/tablePro/SearchForm.vue","../src/components/tablePro/search.vue","../src/components/tablePro/search.vue","../src/components/tablePro/SearchFormGroup.vue","../src/components/tablePro/SearchFormGroup.vue","../src/components/tablePro/TableFilterDropdown.vue","../src/components/tablePro/TableFilterDropdown.vue","../src/components/tablePro/tableConfig/columnsConfig.vue","../src/components/tablePro/tableConfig/columnsConfig.vue","../src/components/tablePro/tableConfig/pivotConfig.vue","../src/components/tablePro/tableConfig/pivotConfig.vue","../src/components/tablePro/hooks/view.ts","../src/components/tablePro/tableConfig/viewsConfig.vue","../src/components/tablePro/tableConfig/viewsConfig.vue","../src/components/tablePro/tableConfig/index.vue","../src/components/tablePro/tableConfig/index.vue","../src/components/tablePro/head_btn_confirm.ts","../src/components/tablePro/head_btn_custom_component.ts","../src/components/tablePro/head_btn_form.ts","../src/components/tablePro/headBtnChildren.vue","../src/components/tablePro/headBtnChildren.vue","../src/components/tablePro/headBtn.vue","../src/components/tablePro/headBtn.vue","../src/components/tablePro/refresh-type-modal/index.vue","../src/components/tablePro/refresh-type-modal/index.vue","../src/components/tablePro/ConditionGroupSelecter.vue","../src/components/tablePro/ConditionGroupSelecter.vue","../src/components/tablePro/ConditionGroupView.vue","../src/components/tablePro/ConditionGroupView.vue","../src/components/tablePro/tableHeader.vue","../src/components/tablePro/tableHeader.vue","../src/components/tablePro/TableSummary.vue","../src/components/tablePro/TableSummary.vue","../src/components/tablePro/TableContextMenu.vue","../src/components/tablePro/TableContextMenu.vue","../src/components/tablePro/tablePro.vue","../src/components/tablePro/tablePro.vue"],"sourcesContent":["<template>\n <template\n v-if=\"field.type !== 'divider' && (field?.is_search_show !== false || field_render_show)\"\n >\n <slot />\n <div\n v-if=\"field.type === 'kong'\"\n style=\"height: 62px; width: 200px\"\n ></div>\n <!-- 展示内容-->\n <div v-if=\"field.type === 'tag'\">\n <a-tag\n :color=\"field.color ? field.color(field, model) : 'green'\"\n :style=\"field.style\"\n v-if=\"(field.content && field.content(field, model)) || model\"\n @click=\"field.cb ? field.cb(field, model) : ''\"\n >\n <span v-if=\"field.content\">\n {{ field.content(field, model) }}\n </span>\n <span v-else>{{ model }}</span>\n </a-tag>\n </div>\n <!-- 表单占位组件-->\n <!-- 默认 【表单空位 高62px; 名称空位 高30px;】 如遇个别特殊表单,根据实际情况自行调节 高度-->\n <!-- height 属性必填-->\n <div\n v-if=\"field.type === 'kong_title'\"\n :style=\"'height: ' + field.height + 'px'\"\n ></div>\n <div\n v-if=\"field.type === 'title'\"\n style=\"height: 30px; position: relative\"\n >\n <span\n style=\"\n position: absolute;\n bottom: 0;\n padding: 0;\n margin: 0;\n font-weight: bolder;\n font-size: 17px;\n \"\n >\n {{ field.name }}\n </span>\n </div>\n <a-rate\n v-if=\"field.type === 'rate'\"\n v-model:value=\"model\"\n :disabled=\"field.disabled\"\n allow-half\n :style=\"`width: ${field_width}px`\"\n />\n <a-input\n v-if=\"field.type === 'input'\"\n v-model:value=\"model\"\n :allow-clear=\"field.allowClear == undefined ? true : field.allowClear\"\n :autocomplete=\"field.autocomplete == undefined ? 'off' : field.autocomplete\"\n :default-value=\"field.defaultValue\"\n :disabled=\"field.disabled\"\n :maxlength=\"field.maxlength\"\n :placeholder=\"field.placeholder ? field.placeholder : $t('请输入') + field.label\"\n :type=\"field.inputType ? field.inputType : 'text'\"\n size=\"small\"\n :style=\"`width: ${field_width}px`\"\n >\n <template\n v-if=\"field?.prefix || field?.prefixIcon\"\n #prefix\n >\n <span v-if=\"field?.prefix\">{{ field.prefix }}</span>\n <component\n v-if=\"field?.prefixIcon\"\n :is=\"field?.prefixIcon\"\n />\n </template>\n <template\n v-if=\"field?.suffix || field?.suffixIcon\"\n #suffix\n >\n <span v-if=\"field?.suffix\">{{ field.suffix }}</span>\n <component\n v-if=\"field?.suffixIcon\"\n :is=\"field?.suffixIcon\"\n />\n </template>\n <template\n v-if=\"field?.addonBefore || field?.addonBeforeIcon\"\n #addonBefore\n >\n <span v-if=\"field?.addonBefore\">{{ field.addonBefore }}</span>\n <component\n v-if=\"field?.addonBeforeIcon\"\n :is=\"field?.addonBeforeIcon\"\n />\n </template>\n <template\n v-if=\"field?.addonAfter || field?.addonAfterIcon\"\n #addonAfter\n >\n <span v-if=\"field?.addonAfter\">{{ field.addonAfter }}</span>\n <component\n v-if=\"field?.addonAfterIcon\"\n :is=\"field?.addonAfterIcon\"\n />\n </template>\n </a-input>\n\n <a-input-number\n v-if=\"field.type === 'money'\"\n size=\"small\"\n v-model:value=\"model\"\n :autocomplete=\"field.autocomplete == undefined ? 'off' : field.autocomplete\"\n :disabled=\"field.disabled\"\n :default-value=\"field.defaultValue\"\n :min=\"field.min\"\n :max=\"field.max\"\n :formatter=\"value => `${value}`.replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',')\"\n :precision=\"field.precision\"\n :step=\"field.step\"\n :placeholder=\"\n field.placeholder_i18n == undefined ? field.placeholder : t(field.placeholder_i18n)\n \"\n :style=\"`width: ${field_width}px`\"\n />\n <a-input-number\n v-if=\"field.type === 'number'\"\n v-model:value=\"model\"\n :autocomplete=\"field.autocomplete == undefined ? 'off' : field.autocomplete\"\n :default-value=\"field.defaultValue\"\n :disabled=\"field.disabled\"\n :formatter=\"field.formatter\"\n :max=\"field.max\"\n :min=\"field.min\"\n :placeholder=\"field.placeholder ? field.placeholder : '请输入' + field.label\"\n :precision=\"field.precision\"\n :step=\"field.step\"\n size=\"small\"\n :style=\"`width: ${field_width}px`\"\n >\n <template\n v-if=\"field?.prefix || field?.prefixIcon\"\n #prefix\n >\n <span v-if=\"field?.prefix\">{{ field.prefix }}</span>\n <component\n v-if=\"field?.prefixIcon\"\n :is=\"field?.prefixIcon\"\n />\n </template>\n <template\n v-if=\"field?.suffix || field?.suffixIcon\"\n #suffix\n >\n <span v-if=\"field?.suffix\">{{ field.suffix }}</span>\n <component\n v-if=\"field?.suffixIcon\"\n :is=\"field?.suffixIcon\"\n />\n </template>\n <template\n v-if=\"field?.addonBefore || field?.addonBeforeIcon\"\n #addonBefore\n >\n <span v-if=\"field?.addonBefore\">{{ field.addonBefore }}</span>\n <component\n v-if=\"field?.addonBeforeIcon\"\n :is=\"field?.addonBeforeIcon\"\n />\n </template>\n <template\n v-if=\"field?.addonAfter || field?.addonAfterIcon\"\n #addonAfter\n >\n <span v-if=\"field?.addonAfter\">{{ field.addonAfter }}</span>\n <component\n v-if=\"field?.addonAfterIcon\"\n :is=\"field?.addonAfterIcon\"\n />\n </template>\n </a-input-number>\n\n <template v-if=\"field.type === 'select'\">\n <a-select\n v-if=\"field.mode === 'default'\"\n v-model:value=\"model\"\n :allow-clear=\"field.allowClear\"\n :autocomplete=\"field.autocomplete == undefined ? 'off' : field.autocomplete\"\n :default-value=\"field.defaultValue\"\n :disabled=\"field.disabled\"\n :dropdownMatchSelectWidth=\"false\"\n :maxTagCount=\"field.maxTagCount ? field.maxTagCount : 'responsive'\"\n :placeholder=\"field.placeholder ? field.placeholder : $t('请选择') + field.label\"\n :show-search=\"!!field.show_search\"\n size=\"small\"\n :style=\"`width: ${field_width}px`\"\n >\n <a-select-option\n v-for=\"option in options\"\n :key=\"option[field.valueKey ? field.valueKey : 'value']\"\n :value=\"option[field.valueKey ? field.valueKey : 'value']\"\n >\n {{ option[field.labelKey ? field.labelKey : 'label'] }}\n </a-select-option>\n </a-select>\n <a-select\n v-else\n v-model:value=\"model\"\n :allow-clear=\"field.allowClear\"\n :default-value=\"field.defaultValue\"\n :disabled=\"field.disabled\"\n :dropdownMatchSelectWidth=\"false\"\n :maxTagCount=\"field.maxTagCount ? field.maxTagCount : 'responsive'\"\n :mode=\"field.mode\"\n :placeholder=\"field.placeholder ? field.placeholder : $t('请选择') + field.label\"\n :show-search=\"!!field.show_search\"\n size=\"small\"\n :style=\"`width: ${field_width}px`\"\n >\n <a-select-option\n v-for=\"(option, index) in options\"\n :key=\"index\"\n :value=\"option[field.valueKey ? field.valueKey : 'value']\"\n >\n {{ option[field.labelKey ? field.labelKey : 'label'] }}\n </a-select-option>\n </a-select>\n </template>\n <template v-if=\"field.type === 'groupselect'\">\n <a-select\n v-if=\"field.mode === 'default'\"\n v-model:value=\"model\"\n :allow-clear=\"field.allowClear\"\n :autocomplete=\"field.autocomplete == undefined ? 'off' : field.autocomplete\"\n :default-value=\"field.defaultValue\"\n :disabled=\"field.disabled\"\n :dropdownMatchSelectWidth=\"false\"\n :getPopupContainer=\"field.getPopupContainer == undefined ? null : field.getPopupContainer\"\n :labelInValue=\"field.labelInValue === true\"\n :maxTagCount=\"field.maxTagCount ? field.maxTagCount : 'responsive'\"\n :options=\"options\"\n :placeholder=\"field.placeholder ? field.placeholder : $t('请选择') + field.label\"\n :show-search=\"!!field.show_search\"\n size=\"small\"\n :style=\"`width: ${field_width}px`\"\n ></a-select>\n <a-select\n v-else\n v-model:value=\"model\"\n :allow-clear=\"field.allowClear\"\n :default-value=\"field.defaultValue\"\n :disabled=\"field.disabled\"\n :dropdownMatchSelectWidth=\"false\"\n :getPopupContainer=\"field.getPopupContainer == undefined ? null : field.getPopupContainer\"\n :labelInValue=\"field.labelInValue === true\"\n :maxTagCount=\"field.maxTagCount ? field.maxTagCount : 'responsive'\"\n :mode=\"field.mode\"\n :options=\"options\"\n :placeholder=\"field.placeholder ? field.placeholder : $t('请选择') + field.label\"\n :show-search=\"!!field.show_search\"\n size=\"small\"\n :style=\"`width: ${field_width}px`\"\n ></a-select>\n </template>\n\n <a-cascader\n v-if=\"field.type === 'cascader'\"\n v-model:value=\"model\"\n :allow-clear=\"field.allowClear\"\n :default-value=\"field.defaultValue\"\n :disabled=\"field.disabled\"\n :multiple=\"field.multiple\"\n :show-search=\"field.show_search\"\n :changeOnSelect=\"field.changeOnSelect ? field.changeOnSelect : false\"\n :options=\"field.getOptionsData ? field.getOptionsData(options, model) : options\"\n :placeholder=\"field.placeholder ? field.placeholder : $t('请选择') + field.label\"\n size=\"small\"\n :style=\"`width: ${field_width}px`\"\n />\n\n <remote-cascader\n v-if=\"field.type === 'remotecascader'\"\n v-model:value=\"model\"\n v-model:label=\"labelModel\"\n :field=\"field\"\n :formModel=\"formModel\"\n :get-data=\"field.getData\"\n :label-key=\"field.labelKey\"\n :label-key-list=\"field.labelKeyList\"\n :label-space=\"field.labelSpace\"\n :search_config=\"field.search_config\"\n :value-key=\"field.valueKey\"\n :style=\"`width: ${field_width}px`\"\n />\n <remote-cascader-pro\n v-if=\"field.type === 'remotecascaderpro'\"\n v-model:label=\"labelModel\"\n v-model:value=\"model\"\n :allow-clear=\"field.allowClear\"\n :default-value=\"field.defaultValue\"\n :disabled=\"field.disabled\"\n :field=\"field\"\n :formModel=\"formModel\"\n :outModel=\"outModel\"\n :get-data=\"field.getData\"\n :multiple=\"field.multiple\"\n :maxTagCount=\"field.maxTagCount ? field.maxTagCount : 'responsive'\"\n :show_search=\"field.show_search\"\n :label-key-type=\"field.labelKeyType\"\n :label-key-list=\"field.labelKeyList\"\n :label-space=\"field.labelSpace\"\n :label-key=\"field.labelKey\"\n :value-key=\"field.valueKey\"\n :init_model=\"field.init_model\"\n :init_watch=\"field.init_watch\"\n :is_form_design=\"is_form_design\"\n :placeholder=\"\n field.placeholder_i18n == undefined\n ? field.placeholder\n ? field.placeholder\n : t('请选择') + field.label\n : t(field.placeholder_i18n)\n \"\n :style=\"`width: ${field_width}px`\"\n />\n\n <month-picker\n v-if=\"field.type === 'monthpicker'\"\n v-model:value=\"model\"\n :allow-clear=\"field.allowClear\"\n :autocomplete=\"field.autocomplete == undefined ? 'off' : field.autocomplete\"\n :default-value=\"field.defaultValue\"\n :disabled=\"field.disabled\"\n :placeholder=\"field.placeholder ? field.placeholder : $t('请选择') + field.label\"\n size=\"small\"\n :is_range=\"field.is_range\"\n :value_has_time=\"field.value_has_time\"\n :start_offset_day=\"field.start_offset_day\"\n :end_offset_day=\"field.end_offset_day\"\n :fix_day=\"field.fix_day\"\n :style=\"`width: ${field_width}px`\"\n />\n <a-date-picker\n v-if=\"field.type === 'datepicker'\"\n v-model:value=\"model\"\n :allow-clear=\"field.allowClear\"\n :autocomplete=\"field.autocomplete == undefined ? 'off' : field.autocomplete\"\n :default-value=\"field.defaultValue\"\n :disabled=\"field.disabled\"\n :format=\"field.format\"\n :picker=\"field.picker\"\n :placeholder=\"field.placeholder ? field.placeholder : $t('请选择') + field.label\"\n :show-time=\"field.showTime\"\n :value-format=\"field.valueFormat\"\n size=\"small\"\n :style=\"`width: ${field_width}px`\"\n />\n\n <a-range-picker\n v-if=\"field.type === 'rangepicker'\"\n v-model:value=\"model\"\n :allow-clear=\"field.allowClear\"\n :default-value=\"field.defaultValue || []\"\n :disabled=\"field.disabled\"\n :format=\"field.format\"\n :placeholder=\"\n field.placeholder && isArray(field.placeholder) && field.placeholder.length > 0\n ? field.placeholder\n : [$t('开始时间'), $t('结束时间')]\n \"\n :show-time=\"field.showTime\"\n :value-format=\"field.valueFormat\"\n :picker=\"field.picker ? field.picker : 'date'\"\n size=\"small\"\n :style=\"`width: ${field_width}px`\"\n />\n\n <month-range-picker\n v-if=\"field.type === 'monthrangepicker'\"\n v-model:value=\"model\"\n :allow-clear=\"field.allowClear\"\n :default-value=\"field.defaultValue || []\"\n :disabled=\"field.disabled\"\n :placeholder=\"field.placeholder\"\n size=\"small\"\n :is_range=\"field.is_range\"\n :value_has_time=\"field.value_has_time\"\n :start_offset_day=\"field.start_offset_day\"\n :end_offset_day=\"field.end_offset_day\"\n :fix_day=\"field.fix_day\"\n :style=\"`width: ${field_width}px`\"\n />\n\n <a-time-picker\n v-if=\"field.type === 'timepicker'\"\n v-model:value=\"model\"\n :allow-clear=\"field.allowClear\"\n :default-value=\"field.defaultValue\"\n :disabled=\"field.disabled\"\n :format=\"field.format ? field.format : 'HH:mm'\"\n :placeholder=\"field.placeholder ? field.placeholder : $t('请选择') + field.label\"\n :value-format=\"field.valueFormat ? field.valueFormat : 'HH:mm'\"\n size=\"small\"\n :style=\"`width: ${field_width}px`\"\n />\n <a-time-range-picker\n v-if=\"field.type === 'timerangepicker'\"\n v-model:value=\"model\"\n :allow-clear=\"field.allowClear\"\n :default-value=\"field.defaultValue\"\n :disabled=\"field.disabled\"\n :format=\"field.format ? field.format : 'HH:mm'\"\n :placeholder=\"\n field.placeholder && isArray(field.placeholder) && field.placeholder.length > 0\n ? field.placeholder\n : [$t('开始时间'), $t('结束时间')]\n \"\n :value-format=\"field.valueFormat ? field.valueFormat : 'HH:mm'\"\n size=\"small\"\n :style=\"`width: ${field_width}px`\"\n />\n <a-radio-group\n v-if=\"field.type === 'radio'\"\n v-model:value=\"model\"\n :default-value=\"field.defaultValue\"\n :disabled=\"field.disabled\"\n size=\"small\"\n :style=\"`width: ${field_width}px`\"\n >\n <a-radio\n v-for=\"option in options\"\n :key=\"option[field.valueKey ? field.valueKey : 'value']\"\n :disabled=\"option.disabled\"\n :value=\"option[field.valueKey ? field.valueKey : 'value']\"\n >\n {{ option[field.labelKey ? field.labelKey : 'label'] }}\n </a-radio>\n </a-radio-group>\n\n <a-checkbox-group\n v-if=\"field.type === 'checkbox'\"\n v-model:value=\"model\"\n :default-value=\"field.defaultValue\"\n :disabled=\"field.disabled\"\n size=\"small\"\n :style=\"`width: ${field_width}px`\"\n >\n <a-checkbox\n v-for=\"option in options\"\n :key=\"option[field.valueKey ? field.valueKey : 'value']\"\n :disabled=\"option.disabled\"\n :value=\"option[field.valueKey ? field.valueKey : 'value']\"\n >\n {{ option[field.labelKey ? field.labelKey : 'label'] }}\n </a-checkbox>\n </a-checkbox-group>\n\n <a-tree-select\n v-if=\"field.type === 'treeselect'\"\n v-model:value=\"model\"\n :allow-clear=\"field.allowClear\"\n :default-value=\"field.defaultValue\"\n :disabled=\"field.disabled\"\n :dropdownMatchSelectWidth=\"false\"\n :placeholder=\"field.placeholder ? field.placeholder : $t('请选择') + field.label\"\n :multiple=\"field.multiple\"\n :tree-checkable=\"field.treeCheckable\"\n :tree-data=\"options\"\n :tree-label-prop=\"field.labelKey\"\n :tree-node-filter-prop=\"field.valueKey\"\n size=\"small\"\n :style=\"`width: ${field_width}px`\"\n />\n <remote-filter-select\n v-if=\"field.type === 'remotefilterselect'\"\n v-model:label=\"labelModel\"\n v-model:value=\"model\"\n :field=\"field\"\n :formModel=\"formModel\"\n :get-data=\"field.getData\"\n :init_model=\"field.init_model\"\n :label-key=\"field.labelKey\"\n :label-key-list=\"field.labelKeyList\"\n :label-space=\"field.labelSpace\"\n :search_config=\"field.search_config\"\n :value-key=\"field.valueKey\"\n :style=\"`width: ${field_width}px`\"\n />\n <remote-select\n v-if=\"field.type === 'remoteselect'\"\n v-model:label=\"labelModel\"\n v-model:value=\"model\"\n :field=\"field\"\n :formModel=\"formModel\"\n :get-data=\"field.getData\"\n :init_model=\"field.init_model\"\n :label-key=\"field.labelKey\"\n :label-key-list=\"field.labelKeyList\"\n :label-space=\"field.labelSpace\"\n :search_config=\"field.search_config\"\n :value-key=\"field.valueKey\"\n :style=\"`width: ${field_width}px`\"\n />\n <remote-select-pro\n v-if=\"field.type === 'remoteselectpro'\"\n v-model:label=\"labelModel\"\n v-model:value=\"model\"\n :field=\"field\"\n :formModel=\"formModel\"\n :outModel=\"outModel\"\n :get-data=\"field.getData\"\n :init_model=\"field.init_model\"\n :init_watch=\"field.init_watch\"\n :label-key=\"field.labelKey\"\n :label-key-type=\"field.labelKeyType\"\n :label-key-list=\"field.labelKeyList\"\n :label-space=\"field.labelSpace\"\n :search_config=\"field.search_config\"\n :value-key=\"field.valueKey\"\n :is_input=\"field.is_input\"\n :is_form_design=\"is_form_design\"\n :placeholder=\"\n field.placeholder_i18n == undefined\n ? field.placeholder\n ? field.placeholder\n : $t('请选择') + field.label\n : t(field.placeholder_i18n)\n \"\n :style=\"`width: ${field_width}px`\"\n />\n <remote-complete\n v-if=\"field.type === 'remotecomplete'\"\n v-model:value=\"model\"\n :field=\"field\"\n :formModel=\"formModel\"\n :outModel=\"outModel\"\n :get-data=\"field.getData\"\n :init_model=\"field.init_model\"\n :init_watch=\"field.init_watch\"\n :label-key=\"field.labelKey\"\n :label-key-type=\"field.labelKeyType\"\n :label-key-list=\"field.labelKeyList\"\n :label-space=\"field.labelSpace\"\n :search_config=\"field.search_config\"\n :value-key=\"field.valueKey\"\n :maxlength=\"field.maxlength\"\n :is_input=\"field.is_input\"\n :is_form_design=\"is_form_design\"\n :placeholder=\"\n field.placeholder_i18n == undefined\n ? field.placeholder\n ? field.placeholder\n : $t('请选择') + field.label\n : t(field.placeholder_i18n)\n \"\n :style=\"`width: ${field_width}px`\"\n />\n <remote-tree-select\n v-if=\"field.type === 'remotetreeselect'\"\n v-model:label=\"labelModel\"\n v-model:value=\"model\"\n :allow-clear=\"field.allowClear\"\n :default-value=\"field.defaultValue\"\n :disabled=\"field.disabled\"\n :field=\"field\"\n :formModel=\"formModel\"\n :get-data=\"field.getData\"\n :label-key=\"field.labelKey\"\n :search_config=\"field.search_config\"\n :value-key=\"field.valueKey\"\n :style=\"`width: ${field_width}px`\"\n />\n <remote-tree-select-pro\n v-if=\"field.type === 'remotetreeselectpro'\"\n v-model:label=\"labelModel\"\n v-model:value=\"model\"\n :allow-clear=\"field.allowClear\"\n :default-value=\"field.defaultValue\"\n :disabled=\"field.disabled\"\n :field=\"field\"\n :formModel=\"formModel\"\n :outModel=\"outModel\"\n :get-data=\"field.getData\"\n :multiple=\"field.multiple\"\n :search_config=\"field.search_config\"\n :label-key-type=\"field.labelKeyType\"\n :label-key-list=\"field.labelKeyList\"\n :label-space=\"field.labelSpace\"\n :label-key=\"field.labelKey\"\n :value-key=\"field.valueKey\"\n :init_model=\"field.init_model\"\n :init_watch=\"field.init_watch\"\n :is_form_design=\"is_form_design\"\n :placeholder=\"\n field.placeholder_i18n == undefined\n ? field.placeholder\n ? field.placeholder\n : $t('请选择') + field.label\n : t(field.placeholder_i18n)\n \"\n :style=\"`width: ${field_width}px`\"\n />\n <remote-modal\n v-if=\"field.type === 'remotemodal'\"\n v-model:label=\"labelModel\"\n v-model:value=\"model\"\n :columns=\"field.columns\"\n :field=\"field\"\n :field_status=\"field.field_status\"\n :get-data=\"field.getData\"\n :init_model=\"field.init_model\"\n :modalType=\"field.modalType\"\n :search_config=\"field.search_config\"\n :watch=\"field.watch\"\n :style=\"`width: ${field_width}px`\"\n />\n <remote-table\n v-if=\"field.type === 'remotetable'\"\n v-model:value=\"model\"\n :columns=\"field.columns\"\n :formModel=\"formModel\"\n :field=\"field\"\n :field_status=\"field.field_status\"\n :get-data=\"field.getData\"\n :init_model=\"field.init_model\"\n :modalType=\"field.modalType\"\n :search_config=\"field.search_config\"\n :watch=\"field.watch\"\n :style=\"`width: ${field_width}px`\"\n />\n\n <remote-text\n v-if=\"field.type === 'remotetext'\"\n v-model:value=\"model\"\n :columns=\"field.columns\"\n :formModel=\"formModel\"\n :field=\"field\"\n :get-data=\"field.getData\"\n :init_model=\"field.init_model\"\n :modalType=\"field.modalType\"\n :search_config=\"field.search_config\"\n :watch=\"field.watch\"\n />\n\n <a-rate\n v-if=\"field.type === 'rate'\"\n v-model:value=\"model\"\n :count=\"field.count ? field.count : 5\"\n :allow-half=\"field.allowHalf\"\n :style=\"`width: ${field_width}px`\"\n />\n <a-radio-group\n v-if=\"field.type === 'radio-color'\"\n v-model:value=\"model\"\n :default-value=\"field.defaultValue\"\n :disabled=\"field.disabled\"\n size=\"small\"\n :style=\"`width: ${field_width}px`\"\n >\n <a-radio\n v-for=\"option in options\"\n :key=\"option[field.valueKey ? field.valueKey : 'value']\"\n :disabled=\"option.disabled\"\n :value=\"option[field.valueKey ? field.valueKey : 'value']\"\n >\n <div\n :style=\"{\n width: '20px',\n height: '20px',\n backgroundColor: option[field.valueKey ? field.valueKey : 'value'],\n }\"\n ></div>\n </a-radio>\n </a-radio-group>\n </template>\n\n <a-divider\n v-if=\"field.type === 'divider'\"\n :orientation=\"field.orientation\"\n >\n {{ field.label }}\n </a-divider>\n</template>\n<script lang=\"ts\">\nimport RemoteSelect from 'liyu-pc-base/components/FormRender/RemoteSelect/RemoteSelect.vue';\nimport RemoteCascader from 'liyu-pc-base/components/FormRender/RemoteCascader/RemoteCascader.vue';\nimport RemoteModal from 'liyu-pc-base/components/FormRender/RemoteModal/RemoteModal.vue';\nimport RemoteTreeSelect from 'liyu-pc-base/components/FormRender/RemoteTreeSelect/RemoteTreeSelect.vue';\nimport RemoteTable from 'liyu-pc-base/components/FormRender/RemoteTable/RemoteTable.vue';\nimport { defineComponent, watch, onMounted, ref } from 'vue';\nimport RemoteFilterSelect from 'liyu-pc-base/components/FormRender/RemoteFilterSelect/RemoteFilterSelect.vue';\nimport AttributeNomTable from 'liyu-pc-base/components/FormRender/AttributeNomTable/index.vue';\nimport AttributeTable from 'liyu-pc-base/components/FormRender/AttributeTable/index.vue';\nimport JsonStr from 'liyu-pc-base/components/FormRender/JsonStr/index.vue';\nimport JsonObj from 'liyu-pc-base/components/FormRender/JsonObj/index.vue';\nimport RemoteText from 'liyu-pc-base/components/FormRender/RemoteText/RemoteText.vue';\nimport RemoteTablePro from 'liyu-pc-base/components/FormRender/RemoteTablePro/RemoteTablePro.vue';\nimport { debounce, isArray, isEqual } from 'lodash-es';\nimport moment from 'moment';\nimport { isEmpty, isNotEmpty } from 'liyu-pc-base/utils/function';\nimport { PlusOutlined } from '@ant-design/icons-vue';\nimport RemoteSelectPro from 'liyu-pc-base/components/FormRender/RemoteSelectPro/RemoteSelectPro.vue';\nimport RemoteComplete from 'liyu-pc-base/components/FormRender/RemoteComplete/RemoteComplete.vue';\nimport RemoteTreeSelectPro from 'liyu-pc-base/components/FormRender/RemoteTreeSelectPro/RemoteTreeSelectPro.vue';\nimport RemoteCascaderPro from 'liyu-pc-base/components/FormRender/RemoteCascaderPro/RemoteCascaderPro.vue';\nimport Upload from 'liyu-pc-base/components/FormRender/Upload/upload.vue';\nimport RichTextEditor from 'liyu-pc-base/components/FormRender/RichTextEditor/index.vue';\nimport { useI18n } from 'vue-i18n';\nimport IconSelect from 'liyu-pc-base/components/FormRender/iconSelect/index.vue';\nimport MonthPicker from 'liyu-pc-base/components/FormRender/MonthPicker/index.vue';\nimport MonthRangePicker from 'liyu-pc-base/components/FormRender/MonthRangePicker/index.vue';\nimport CodeEditor from 'liyu-pc-base/components/code/CodeEditor.vue';\nimport TinymceEditor from 'liyu-pc-base/components/tinymce/TinymceEditor.vue';\n\nconst isValidDate = (dateString, format = 'YYYY-MM-DD') => {\n const date = moment(dateString, format, true);\n return date.isValid();\n};\nconst isValidDateTime = (dateString, format = 'YYYY-MM-DD HH:mm:ss') => {\n const date = moment(dateString, format, true);\n return date.isValid();\n};\nconst isValidTime = (dateString, format = 'HH:mm:ss') => {\n const date = moment(dateString, format, true);\n return date.isValid();\n};\nexport default defineComponent({\n name: 'FieldRender2',\n methods: { isArray },\n props: {\n field: {\n type: Object,\n required: true,\n },\n value: {\n required: true,\n },\n label: {\n required: false,\n },\n options: {\n type: Array,\n default: () => [],\n },\n validateInfos: {\n type: Object,\n default: () => {},\n },\n formModel: {\n type: Object,\n default: () => {},\n },\n outModel: {\n type: Object,\n default: () => {},\n },\n field_render_show: {\n type: Boolean,\n default: true,\n },\n is_show_label: {\n type: Boolean,\n default: true,\n },\n isUseConditions: {\n type: Boolean,\n default: true,\n },\n is_show_field: {\n type: Boolean,\n default: true,\n },\n is_edit: {\n type: Boolean,\n default: true,\n },\n conditionsVisibleNum: {\n type: Number,\n default: 0,\n },\n is_form_design: {\n type: Boolean,\n default: false,\n },\n field_width: {\n type: Number,\n default: 150,\n },\n },\n emits: [\n 'add',\n 'update:value',\n 'update:label',\n 'update_model',\n 'update:is_show_field',\n 'update:is_edit',\n 'update_name2',\n ],\n setup(props, { emit }) {\n const newModel = ref({ ...props.formModel });\n const rangeDate = (v: any) => {\n if (typeof v == 'string' && v.indexOf(',') >= 0) {\n return v.split(',');\n }\n return v;\n };\n const convertValueByClassName = (value, class_name) => {\n //class_name 'int','float',str','bool','date','datetime','time'\n let new_value;\n if (class_name == 'int') {\n if (isNotEmpty(value) && value instanceof Array) {\n new_value = [];\n value.forEach(item => {\n if (isNotEmpty(item) && typeof item === 'string') {\n new_value.push(Number(item));\n } else {\n new_value.push(item);\n }\n });\n } else if (isNotEmpty(value) && typeof value === 'string') {\n new_value = Number(value);\n } else {\n new_value = value;\n }\n } else if (class_name == 'str') {\n if (isNotEmpty(value) && value instanceof Array) {\n new_value = [];\n value.forEach(item => {\n if (isNotEmpty(item) && typeof item === 'number') {\n new_value.push(item.toString());\n } else {\n new_value.push(item);\n }\n });\n } else if (isNotEmpty(value) && typeof value === 'number') {\n new_value = value.toString();\n } else {\n new_value = value;\n }\n } else if (class_name == 'date') {\n if (isNotEmpty(value) && value instanceof Array) {\n new_value = [];\n value.forEach(item => {\n if (isValidDate(item) && typeof item === 'string') {\n new_value.push(moment(item, 'YYYY-MM-DD'));\n } else {\n new_value.push(item);\n }\n });\n } else if (isValidDate(value) && typeof value === 'string') {\n new_value = value.toString();\n } else {\n new_value = value;\n }\n } else if (class_name == 'datetime') {\n if (isNotEmpty(value) && value instanceof Array) {\n new_value = [];\n value.forEach(item => {\n if (isValidDateTime(item) && typeof item === 'string') {\n new_value.push(moment(item, 'YYYY-MM-DD HH:mm:ss'));\n } else {\n new_value.push(item);\n }\n });\n } else if (isValidDateTime(value) && typeof value === 'string') {\n new_value = moment(value, 'YYYY-MM-DD HH:mm:ss');\n } else {\n new_value = value;\n }\n } else if (class_name == 'time') {\n if (isNotEmpty(value) && value instanceof Array) {\n new_value = [];\n value.forEach(item => {\n if (isValidTime(item) && typeof item === 'string') {\n new_value.push(moment(item, 'HH:mm:ss'));\n } else {\n new_value.push(item);\n }\n });\n } else if (isValidTime(value) && typeof value === 'string') {\n new_value = moment(value, 'HH:mm:ss');\n } else {\n new_value = value;\n }\n } else if (class_name == 'float') {\n if (isNotEmpty(value) && value instanceof Array) {\n new_value = [];\n value.forEach(item => {\n if (isNotEmpty(item) && typeof item === 'string') {\n new_value.push(Number(item));\n } else {\n new_value.push(item);\n }\n });\n } else if (isNotEmpty(value) && typeof value === 'string') {\n new_value = Number(value);\n } else {\n new_value = value;\n }\n } else if (class_name == 'bool') {\n if (isNotEmpty(value) && value instanceof Array) {\n new_value = [];\n value.forEach(item => {\n if (isNotEmpty(item) && typeof item === 'string') {\n new_value.push(Boolean(item));\n } else {\n new_value.push(item);\n }\n });\n } else if (isNotEmpty(value) && typeof value === 'string') {\n new_value = Boolean(value);\n } else {\n new_value = value;\n }\n }\n return new_value;\n };\n const is_show_field = ref(props.is_show_field);\n const is_edit = ref(false);\n const handleToggleEdit = () => {\n emit('update:is_edit', is_edit.value);\n };\n const handleAdd = () => {\n emit('add');\n };\n const check_visible_field_fun = debounce(() => {\n const old_is_show_field = is_show_field.value;\n const condition_result_list: any = [];\n for (const i in props.field?.conditions) {\n const group_list = props.field?.conditions[i];\n const group_results = [];\n for (const j in group_list) {\n const item = group_list[j];\n const value = props.formModel[item.watchKey];\n let new_value;\n if (item.class_name) {\n new_value = convertValueByClassName(item.value, item.class_name);\n } else {\n new_value = item.value;\n }\n let first, second;\n if (new_value instanceof Array) {\n [first, second] = new_value;\n }\n if (item.operator == 'lt') {\n if (typeof first === 'number') {\n if (isEmpty(value)) {\n group_results.push(false);\n } else if (value < first) {\n group_results.push(true);\n } else {\n group_results.push(false);\n }\n } else if (isValidDate(first)) {\n if (isEmpty(value)) {\n group_results.push(false);\n } else if (moment(value).isBefore(moment(first))) {\n group_results.push(true);\n } else {\n group_results.push(false);\n }\n }\n } else if (item.operator == 'lte') {\n if (typeof first === 'number') {\n if (isEmpty(value)) {\n group_results.push(false);\n } else if (value <= first) {\n group_results.push(true);\n } else {\n group_results.push(false);\n }\n } else if (isValidDate(first)) {\n if (isEmpty(value)) {\n group_results.push(false);\n } else if (\n moment(value).isBefore(moment(first)) ||\n moment(value).isSame(moment(first))\n ) {\n group_results.push(true);\n } else {\n group_results.push(false);\n }\n }\n } else if (item.operator == 'gt') {\n if (typeof first === 'number') {\n if (isEmpty(value)) {\n group_results.push(false);\n } else if (value > first) {\n group_results.push(true);\n } else {\n group_results.push(false);\n }\n } else if (isValidDate(first)) {\n if (isEmpty(value)) {\n group_results.push(false);\n } else if (moment(value).isAfter(moment(first))) {\n group_results.push(true);\n } else {\n group_results.push(false);\n }\n }\n } else if (item.operator == 'gte') {\n if (typeof first === 'number') {\n if (isEmpty(value)) {\n group_results.push(false);\n } else if (value >= first) {\n group_results.push(true);\n } else {\n group_results.push(false);\n }\n } else if (isValidDate(first)) {\n if (isEmpty(value)) {\n group_results.push(false);\n } else if (\n moment(value).isAfter(moment(first)) ||\n moment(value).isSame(moment(first))\n ) {\n group_results.push(true);\n } else {\n group_results.push(false);\n }\n }\n } else if (item.operator == 'between') {\n if (typeof first === 'number' && typeof second === 'number' && first && second) {\n if (isEmpty(value)) {\n group_results.push(false);\n } else if (value >= first && value <= second) {\n group_results.push(true);\n } else {\n group_results.push(false);\n }\n } else if (isValidDate(first)) {\n if (isEmpty(value)) {\n group_results.push(false);\n } else if (\n (moment(value).isAfter(moment(first)) || moment(value).isSame(moment(first))) &&\n (moment(value).isBefore(moment(second)) || moment(value).isSame(moment(second)))\n ) {\n group_results.push(true);\n } else {\n group_results.push(false);\n }\n }\n } else if (item.operator == 'notbetween') {\n if (typeof first === 'number' && typeof second === 'number' && first && second) {\n if (isEmpty(value)) {\n group_results.push(false);\n } else if (value < first || value > second) {\n group_results.push(true);\n } else {\n group_results.push(false);\n }\n } else if (isValidDate(first)) {\n if (isEmpty(value)) {\n group_results.push(false);\n } else if (\n moment(value).isBefore(moment(first)) ||\n moment(value).isAfter(moment(second))\n ) {\n group_results.push(true);\n } else {\n group_results.push(false);\n }\n }\n } else if (item.operator == 'in') {\n if (value instanceof Array) {\n const f_list = new_value.filter(x => {\n return value.includes(x);\n });\n if (f_list.length > 0) {\n group_results.push(true);\n } else {\n group_results.push(false);\n }\n } else if (typeof value == 'string' || typeof value == 'number' || isEmpty(value)) {\n // 数字 字符串 空\n const f = new_value.find(x => {\n return value == x;\n });\n if (f) {\n group_results.push(true);\n } else {\n group_results.push(false);\n }\n }\n } else if (item.operator == 'eq') {\n if (value === first) {\n group_results.push(true);\n } else {\n group_results.push(false);\n }\n } else if (item.operator == 'contains') {\n if (value.toString().indexOf(first) > -1) {\n group_results.push(true);\n } else {\n group_results.push(false);\n }\n } else if (item.operator == 'startswith') {\n if (value.toString().startsWith(first)) {\n group_results.push(true);\n } else {\n group_results.push(false);\n }\n } else if (item.operator == 'notin') {\n if (value instanceof Array) {\n const f_list = new_value.filter(x => {\n return value.includes(x);\n });\n if (f_list.length > 0) {\n group_results.push(true);\n } else {\n group_results.push(false);\n }\n } else if (typeof value == 'string' || typeof value == 'number' || isEmpty(value)) {\n // 数字 字符串 空\n const f = new_value.find(x => {\n return value == x;\n });\n if (!f) {\n group_results.push(true);\n } else {\n group_results.push(false);\n }\n }\n } else if (item.operator == 'notcontains') {\n if (value.toString().indexOf(first) == -1) {\n group_results.push(true);\n } else {\n group_results.push(false);\n }\n } else if (item.operator == '_eq') {\n //todo\n } else if (item.operator == 'json_list_not_blank_not_null') {\n // 非空\n if (value) {\n group_results.push(true);\n } else {\n group_results.push(false);\n }\n } else if (item.operator == 'json_list_is_blank_is_null') {\n //为空\n if (!value) {\n group_results.push(true);\n } else {\n group_results.push(false);\n }\n } else if (item.operator == 'not_eq') {\n //为空\n if (!value) {\n group_results.push(true);\n } else {\n group_results.push(false);\n }\n } else if (item.operator == 'not_blank_not_null') {\n // 非空\n if (value) {\n group_results.push(true);\n } else {\n group_results.push(false);\n }\n }\n }\n condition_result_list.push(group_results);\n }\n const con_list = [];\n condition_result_list.forEach(item => {\n const find_false_list = item.filter(x => x === false);\n if (find_false_list && find_false_list.length > 0) {\n con_list.push(false);\n } else {\n con_list.push(true);\n }\n });\n\n const find_true_list = con_list.filter(x => x === true);\n if (find_true_list && find_true_list.length > 0) {\n is_show_field.value = true;\n emit('update:is_show_field', is_show_field.value);\n } else {\n is_show_field.value = false;\n emit('update:is_show_field', is_show_field.value);\n }\n if (is_show_field.value !== old_is_show_field) {\n if (is_show_field.value) {\n newModel.value[props.field.name] = null;\n emit('update_model', {\n add_key: props.field.name,\n value: null,\n });\n } else {\n delete newModel.value[props.field.name];\n emit('update_model', {\n remove_key: props.field.name,\n });\n }\n }\n }, 300);\n const model = ref<any>('');\n const labelModel = ref(props.label);\n watch(\n () => model.value,\n (newValue, oldValue) => {\n if (isEqual(newValue, oldValue)) {\n return;\n }\n emit('update:value', newValue);\n if (props.field.name2) {\n let label: any;\n if (props.field.type === 'radio') {\n const obj = props.options.find(\n (item: any) =>\n item[props.field.valueKey ? props.field.valueKey : 'value'] == newValue,\n );\n label = obj?.[props.field.labelKey ? props.field.labelKey : 'label'];\n } else if (props.field.type === 'checkbox' && newValue && newValue.length >= 0) {\n const list = [];\n props.options.forEach((item: any) => {\n newValue.forEach((item1: any) => {\n if (item1 == item?.[props.field.valueKey ? props.field.valueKey : 'value']) {\n list.push(item?.[props.field.labelKey ? props.field.labelKey : 'label']);\n }\n });\n });\n label = list.toString();\n } else if (props.field.type === 'select') {\n if (isArray(newValue)) {\n const list = [];\n props.options.forEach((item: any) => {\n newValue.forEach((item1: any) => {\n if (item1 == item?.[props.field.valueKey ? props.field.valueKey : 'value']) {\n list.push(item?.[props.field.labelKey ? props.field.labelKey : 'label']);\n }\n });\n });\n label = list.toString();\n } else {\n const obj = props.options.find(\n (item: any) =>\n item[props.field.valueKey ? props.field.valueKey : 'value'] == newValue,\n );\n label = obj?.[props.field.labelKey ? props.field.labelKey : 'label'];\n }\n }\n emit('update_name2', {\n key: props.field.name2,\n value: label,\n });\n }\n },\n { deep: true },\n );\n watch(\n () => props.value,\n newValue => {\n let value = newValue;\n if (props.field.type === 'rangepicker' && value) {\n value = rangeDate(value);\n } else if (props.field.type === 'input' && value) {\n value = value.toString().replace(/(^\\s*)|(\\s*$)/g, '');\n }\n if (is_show_field.value) {\n //当该表单项显示时,才做向上的数据绑定,避免把undefined向上传递,影响rules字段的有效过滤\n model.value = value;\n }\n },\n { immediate: true },\n );\n watch(\n () => labelModel.value,\n newValue => {\n emit('update:label', newValue);\n if ('name2' in props.field) {\n emit('update_name2', { key: props.field.name2, value: newValue.toString() });\n }\n },\n { deep: true },\n );\n watch(\n () => props.label,\n newValue => {\n labelModel.value = newValue;\n },\n );\n watch(\n () => props.formModel,\n newValue => {\n newModel.value = { ...newValue };\n },\n { deep: true },\n );\n watch(\n () => newModel.value,\n (newValue, oldValue) => {\n if (props.field?.conditions) {\n props.field?.conditions.forEach(condition_list => {\n condition_list.forEach(item => {\n if (oldValue[item.watchKey] != newValue[item.watchKey]) {\n check_visible_field_fun();\n }\n });\n });\n }\n },\n { deep: true },\n );\n watch(\n () => [props.conditionsVisibleNum, props.isUseConditions],\n () => {\n if (props.field?.conditions) {\n if (props.isUseConditions) {\n check_visible_field_fun();\n } else {\n is_show_field.value = true;\n emit('update:is_show_field', is_show_field.value);\n }\n } else {\n is_show_field.value = true;\n emit('update:is_show_field', is_show_field.value);\n }\n },\n );\n onMounted(() => {\n if (props.field?.conditions instanceof Array && props.field?.conditions.length > 0) {\n check_visible_field_fun();\n } else {\n is_show_field.value = true;\n emit('update:is_show_field', is_show_field.value);\n }\n if (!is_show_field.value) {\n // 表单项所见即所得,如果有隐藏的字段,那么model的key也要清除\n delete newModel.value[props.field.name];\n emit('update_model', {\n remove_key: props.field.name,\n });\n }\n });\n const { t } = useI18n();\n return {\n t,\n is_show_field,\n is_edit,\n handleToggleEdit,\n rangeDate,\n handleAdd,\n model,\n labelModel,\n };\n },\n components: {\n IconSelect,\n RichTextEditor,\n Upload,\n RemoteCascaderPro,\n RemoteTreeSelectPro,\n RemoteSelectPro,\n RemoteComplete,\n AttributeTable,\n AttributeNomTable,\n RemoteFilterSelect,\n RemoteModal,\n RemoteSelect,\n RemoteCascader,\n RemoteTreeSelect,\n RemoteTable,\n JsonStr,\n JsonObj,\n RemoteText,\n RemoteTablePro,\n PlusOutlined,\n MonthPicker,\n MonthRangePicker,\n CodeEditor,\n TinymceEditor,\n },\n});\n</script>\n\n<style scoped>\n.ant-calendar-picker {\n width: 100% !important;\n}\n</style>\n","<template>\n <template\n v-if=\"field.type !== 'divider' && (field?.is_search_show !== false || field_render_show)\"\n >\n <slot />\n <div\n v-if=\"field.type === 'kong'\"\n style=\"height: 62px; width: 200px\"\n ></div>\n <!-- 展示内容-->\n <div v-if=\"field.type === 'tag'\">\n <a-tag\n :color=\"field.color ? field.color(field, model) : 'green'\"\n :style=\"field.style\"\n v-if=\"(field.content && field.content(field, model)) || model\"\n @click=\"field.cb ? field.cb(field, model) : ''\"\n >\n <span v-if=\"field.content\">\n {{ field.content(field, model) }}\n </span>\n <span v-else>{{ model }}</span>\n </a-tag>\n </div>\n <!-- 表单占位组件-->\n <!-- 默认 【表单空位 高62px; 名称空位 高30px;】 如遇个别特殊表单,根据实际情况自行调节 高度-->\n <!-- height 属性必填-->\n <div\n v-if=\"field.type === 'kong_title'\"\n :style=\"'height: ' + field.height + 'px'\"\n ></div>\n <div\n v-if=\"field.type === 'title'\"\n style=\"height: 30px; position: relative\"\n >\n <span\n style=\"\n position: absolute;\n bottom: 0;\n padding: 0;\n margin: 0;\n font-weight: bolder;\n font-size: 17px;\n \"\n >\n {{ field.name }}\n </span>\n </div>\n <a-rate\n v-if=\"field.type === 'rate'\"\n v-model:value=\"model\"\n :disabled=\"field.disabled\"\n allow-half\n :style=\"`width: ${field_width}px`\"\n />\n <a-input\n v-if=\"field.type === 'input'\"\n v-model:value=\"model\"\n :allow-clear=\"field.allowClear == undefined ? true : field.allowClear\"\n :autocomplete=\"field.autocomplete == undefined ? 'off' : field.autocomplete\"\n :default-value=\"field.defaultValue\"\n :disabled=\"field.disabled\"\n :maxlength=\"field.maxlength\"\n :placeholder=\"field.placeholder ? field.placeholder : $t('请输入') + field.label\"\n :type=\"field.inputType ? field.inputType : 'text'\"\n size=\"small\"\n :style=\"`width: ${field_width}px`\"\n >\n <template\n v-if=\"field?.prefix || field?.prefixIcon\"\n #prefix\n >\n <span v-if=\"field?.prefix\">{{ field.prefix }}</span>\n <component\n v-if=\"field?.prefixIcon\"\n :is=\"field?.prefixIcon\"\n />\n </template>\n <template\n v-if=\"field?.suffix || field?.suffixIcon\"\n #suffix\n >\n <span v-if=\"field?.suffix\">{{ field.suffix }}</span>\n <component\n v-if=\"field?.suffixIcon\"\n :is=\"field?.suffixIcon\"\n />\n </template>\n <template\n v-if=\"field?.addonBefore || field?.addonBeforeIcon\"\n #addonBefore\n >\n <span v-if=\"field?.addonBefore\">{{ field.addonBefore }}</span>\n <component\n v-if=\"field?.addonBeforeIcon\"\n :is=\"field?.addonBeforeIcon\"\n />\n </template>\n <template\n v-if=\"field?.addonAfter || field?.addonAfterIcon\"\n #addonAfter\n >\n <span v-if=\"field?.addonAfter\">{{ field.addonAfter }}</span>\n <component\n v-if=\"field?.addonAfterIcon\"\n :is=\"field?.addonAfterIcon\"\n />\n </template>\n </a-input>\n\n <a-input-number\n v-if=\"field.type === 'money'\"\n size=\"small\"\n v-model:value=\"model\"\n :autocomplete=\"field.autocomplete == undefined ? 'off' : field.autocomplete\"\n :disabled=\"field.disabled\"\n :default-value=\"field.defaultValue\"\n :min=\"field.min\"\n :max=\"field.max\"\n :formatter=\"value => `${value}`.replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',')\"\n :precision=\"field.precision\"\n :step=\"field.step\"\n :placeholder=\"\n field.placeholder_i18n == undefined ? field.placeholder : t(field.placeholder_i18n)\n \"\n :style=\"`width: ${field_width}px`\"\n />\n <a-input-number\n v-if=\"field.type === 'number'\"\n v-model:value=\"model\"\n :autocomplete=\"field.autocomplete == undefined ? 'off' : field.autocomplete\"\n :default-value=\"field.defaultValue\"\n :disabled=\"field.disabled\"\n :formatter=\"field.formatter\"\n :max=\"field.max\"\n :min=\"field.min\"\n :placeholder=\"field.placeholder ? field.placeholder : '请输入' + field.label\"\n :precision=\"field.precision\"\n :step=\"field.step\"\n size=\"small\"\n :style=\"`width: ${field_width}px`\"\n >\n <template\n v-if=\"field?.prefix || field?.prefixIcon\"\n #prefix\n >\n <span v-if=\"field?.prefix\">{{ field.prefix }}</span>\n <component\n v-if=\"field?.prefixIcon\"\n :is=\"field?.prefixIcon\"\n />\n </template>\n <template\n v-if=\"field?.suffix || field?.suffixIcon\"\n #suffix\n >\n <span v-if=\"field?.suffix\">{{ field.suffix }}</span>\n <component\n v-if=\"field?.suffixIcon\"\n :is=\"field?.suffixIcon\"\n />\n </template>\n <template\n v-if=\"field?.addonBefore || field?.addonBeforeIcon\"\n #addonBefore\n >\n <span v-if=\"field?.addonBefore\">{{ field.addonBefore }}</span>\n <component\n v-if=\"field?.addonBeforeIcon\"\n :is=\"field?.addonBeforeIcon\"\n />\n </template>\n <template\n v-if=\"field?.addonAfter || field?.addonAfterIcon\"\n #addonAfter\n >\n <span v-if=\"field?.addonAfter\">{{ field.addonAfter }}</span>\n <component\n v-if=\"field?.addonAfterIcon\"\n :is=\"field?.addonAfterIcon\"\n />\n </template>\n </a-input-number>\n\n <template v-if=\"field.type === 'select'\">\n <a-select\n v-if=\"field.mode === 'default'\"\n v-model:value=\"model\"\n :allow-clear=\"field.allowClear\"\n :autocomplete=\"field.autocomplete == undefined ? 'off' : field.autocomplete\"\n :default-value=\"field.defaultValue\"\n :disabled=\"field.disabled\"\n :dropdownMatchSelectWidth=\"false\"\n :maxTagCount=\"field.maxTagCount ? field.maxTagCount : 'responsive'\"\n :placeholder=\"field.placeholder ? field.placeholder : $t('请选择') + field.label\"\n :show-search=\"!!field.show_search\"\n size=\"small\"\n :style=\"`width: ${field_width}px`\"\n >\n <a-select-option\n v-for=\"option in options\"\n :key=\"option[field.valueKey ? field.valueKey : 'value']\"\n :value=\"option[field.valueKey ? field.valueKey : 'value']\"\n >\n {{ option[field.labelKey ? field.labelKey : 'label'] }}\n </a-select-option>\n </a-select>\n <a-select\n v-else\n v-model:value=\"model\"\n :allow-clear=\"field.allowClear\"\n :default-value=\"field.defaultValue\"\n :disabled=\"field.disabled\"\n :dropdownMatchSelectWidth=\"false\"\n :maxTagCount=\"field.maxTagCount ? field.maxTagCount : 'responsive'\"\n :mode=\"field.mode\"\n :placeholder=\"field.placeholder ? field.placeholder : $t('请选择') + field.label\"\n :show-search=\"!!field.show_search\"\n size=\"small\"\n :style=\"`width: ${field_width}px`\"\n >\n <a-select-option\n v-for=\"(option, index) in options\"\n :key=\"index\"\n :value=\"option[field.valueKey ? field.valueKey : 'value']\"\n >\n {{ option[field.labelKey ? field.labelKey : 'label'] }}\n </a-select-option>\n </a-select>\n </template>\n <template v-if=\"field.type === 'groupselect'\">\n <a-select\n v-if=\"field.mode === 'default'\"\n v-model:value=\"model\"\n :allow-clear=\"field.allowClear\"\n :autocomplete=\"field.autocomplete == undefined ? 'off' : field.autocomplete\"\n :default-value=\"field.defaultValue\"\n :disabled=\"field.disabled\"\n :dropdownMatchSelectWidth=\"false\"\n :getPopupContainer=\"field.getPopupContainer == undefined ? null : field.getPopupContainer\"\n :labelInValue=\"field.labelInValue === true\"\n :maxTagCount=\"field.maxTagCount ? field.maxTagCount : 'responsive'\"\n :options=\"options\"\n :placeholder=\"field.placeholder ? field.placeholder : $t('请选择') + field.label\"\n :show-search=\"!!field.show_search\"\n size=\"small\"\n :style=\"`width: ${field_width}px`\"\n ></a-select>\n <a-select\n v-else\n v-model:value=\"model\"\n :allow-clear=\"field.allowClear\"\n :default-value=\"field.defaultValue\"\n :disabled=\"field.disabled\"\n :dropdownMatchSelectWidth=\"false\"\n :getPopupContainer=\"field.getPopupContainer == undefined ? null : field.getPopupContainer\"\n :labelInValue=\"field.labelInValue === true\"\n :maxTagCount=\"field.maxTagCount ? field.maxTagCount : 'responsive'\"\n :mode=\"field.mode\"\n :options=\"options\"\n :placeholder=\"field.placeholder ? field.placeholder : $t('请选择') + field.label\"\n :show-search=\"!!field.show_search\"\n size=\"small\"\n :style=\"`width: ${field_width}px`\"\n ></a-select>\n </template>\n\n <a-cascader\n v-if=\"field.type === 'cascader'\"\n v-model:value=\"model\"\n :allow-clear=\"field.allowClear\"\n :default-value=\"field.defaultValue\"\n :disabled=\"field.disabled\"\n :multiple=\"field.multiple\"\n :show-search=\"field.show_search\"\n :changeOnSelect=\"field.changeOnSelect ? field.changeOnSelect : false\"\n :options=\"field.getOptionsData ? field.getOptionsData(options, model) : options\"\n :placeholder=\"field.placeholder ? field.placeholder : $t('请选择') + field.label\"\n size=\"small\"\n :style=\"`width: ${field_width}px`\"\n />\n\n <remote-cascader\n v-if=\"field.type === 'remotecascader'\"\n v-model:value=\"model\"\n v-model:label=\"labelModel\"\n :field=\"field\"\n :formModel=\"formModel\"\n :get-data=\"field.getData\"\n :label-key=\"field.labelKey\"\n :label-key-list=\"field.labelKeyList\"\n :label-space=\"field.labelSpace\"\n :search_config=\"field.search_config\"\n :value-key=\"field.valueKey\"\n :style=\"`width: ${field_width}px`\"\n />\n <remote-cascader-pro\n v-if=\"field.type === 'remotecascaderpro'\"\n v-model:label=\"labelModel\"\n v-model:value=\"model\"\n :allow-clear=\"field.allowClear\"\n :default-value=\"field.defaultValue\"\n :disabled=\"field.disabled\"\n :field=\"field\"\n :formModel=\"formModel\"\n :outModel=\"outModel\"\n :get-data=\"field.getData\"\n :multiple=\"field.multiple\"\n :maxTagCount=\"field.maxTagCount ? field.maxTagCount : 'responsive'\"\n :show_search=\"field.show_search\"\n :label-key-type=\"field.labelKeyType\"\n :label-key-list=\"field.labelKeyList\"\n :label-space=\"field.labelSpace\"\n :label-key=\"field.labelKey\"\n :value-key=\"field.valueKey\"\n :init_model=\"field.init_model\"\n :init_watch=\"field.init_watch\"\n :is_form_design=\"is_form_design\"\n :placeholder=\"\n field.placeholder_i18n == undefined\n ? field.placeholder\n ? field.placeholder\n : t('请选择') + field.label\n : t(field.placeholder_i18n)\n \"\n :style=\"`width: ${field_width}px`\"\n />\n\n <month-picker\n v-if=\"field.type === 'monthpicker'\"\n v-model:value=\"model\"\n :allow-clear=\"field.allowClear\"\n :autocomplete=\"field.autocomplete == undefined ? 'off' : field.autocomplete\"\n :default-value=\"field.defaultValue\"\n :disabled=\"field.disabled\"\n :placeholder=\"field.placeholder ? field.placeholder : $t('请选择') + field.label\"\n size=\"small\"\n :is_range=\"field.is_range\"\n :value_has_time=\"field.value_has_time\"\n :start_offset_day=\"field.start_offset_day\"\n :end_offset_day=\"field.end_offset_day\"\n :fix_day=\"field.fix_day\"\n :style=\"`width: ${field_width}px`\"\n />\n <a-date-picker\n v-if=\"field.type === 'datepicker'\"\n v-model:value=\"model\"\n :allow-clear=\"field.allowClear\"\n :autocomplete=\"field.autocomplete == undefined ? 'off' : field.autocomplete\"\n :default-value=\"field.defaultValue\"\n :disabled=\"field.disabled\"\n :format=\"field.format\"\n :picker=\"field.picker\"\n :placeholder=\"field.placeholder ? field.placeholder : $t('请选择') + field.label\"\n :show-time=\"field.showTime\"\n :value-format=\"field.valueFormat\"\n size=\"small\"\n :style=\"`width: ${field_width}px`\"\n />\n\n <a-range-picker\n v-if=\"field.type === 'rangepicker'\"\n v-model:value=\"model\"\n :allow-clear=\"field.allowClear\"\n :default-value=\"field.defaultValue || []\"\n :disabled=\"field.disabled\"\n :format=\"field.format\"\n :placeholder=\"\n field.placeholder && isArray(field.placeholder) && field.placeholder.length > 0\n ? field.placeholder\n : [$t('开始时间'), $t('结束时间')]\n \"\n :show-time=\"field.showTime\"\n :value-format=\"field.valueFormat\"\n :picker=\"field.picker ? field.picker : 'date'\"\n size=\"small\"\n :style=\"`width: ${field_width}px`\"\n />\n\n <month-range-picker\n v-if=\"field.type === 'monthrangepicker'\"\n v-model:value=\"model\"\n :allow-clear=\"field.allowClear\"\n :default-value=\"field.defaultValue || []\"\n :disabled=\"field.disabled\"\n :placeholder=\"field.placeholder\"\n size=\"small\"\n :is_range=\"field.is_range\"\n :value_has_time=\"field.value_has_time\"\n :start_offset_day=\"field.start_offset_day\"\n :end_offset_day=\"field.end_offset_day\"\n :fix_day=\"field.fix_day\"\n :style=\"`width: ${field_width}px`\"\n />\n\n <a-time-picker\n v-if=\"field.type === 'timepicker'\"\n v-model:value=\"model\"\n :allow-clear=\"field.allowClear\"\n :default-value=\"field.defaultValue\"\n :disabled=\"field.disabled\"\n :format=\"field.format ? field.format : 'HH:mm'\"\n :placeholder=\"field.placeholder ? field.placeholder : $t('请选择') + field.label\"\n :value-format=\"field.valueFormat ? field.valueFormat : 'HH:mm'\"\n size=\"small\"\n :style=\"`width: ${field_width}px`\"\n />\n <a-time-range-picker\n v-if=\"field.type === 'timerangepicker'\"\n v-model:value=\"model\"\n :allow-clear=\"field.allowClear\"\n :default-value=\"field.defaultValue\"\n :disabled=\"field.disabled\"\n :format=\"field.format ? field.format : 'HH:mm'\"\n :placeholder=\"\n field.placeholder && isArray(field.placeholder) && field.placeholder.length > 0\n ? field.placeholder\n : [$t('开始时间'), $t('结束时间')]\n \"\n :value-format=\"field.valueFormat ? field.valueFormat : 'HH:mm'\"\n size=\"small\"\n :style=\"`width: ${field_width}px`\"\n />\n <a-radio-group\n v-if=\"field.type === 'radio'\"\n v-model:value=\"model\"\n :default-value=\"field.defaultValue\"\n :disabled=\"field.disabled\"\n size=\"small\"\n :style=\"`width: ${field_width}px`\"\n >\n <a-radio\n v-for=\"option in options\"\n :key=\"option[field.valueKey ? field.valueKey : 'value']\"\n :disabled=\"option.disabled\"\n :value=\"option[field.valueKey ? field.valueKey : 'value']\"\n >\n {{ option[field.labelKey ? field.labelKey : 'label'] }}\n </a-radio>\n </a-radio-group>\n\n <a-checkbox-group\n v-if=\"field.type === 'checkbox'\"\n v-model:value=\"model\"\n :default-value=\"field.defaultValue\"\n :disabled=\"field.disabled\"\n size=\"small\"\n :style=\"`width: ${field_width}px`\"\n >\n <a-checkbox\n v-for=\"option in options\"\n :key=\"option[field.valueKey ? field.valueKey : 'value']\"\n :disabled=\"option.disabled\"\n :value=\"option[field.valueKey ? field.valueKey : 'value']\"\n >\n {{ option[field.labelKey ? field.labelKey : 'label'] }}\n </a-checkbox>\n </a-checkbox-group>\n\n <a-tree-select\n v-if=\"field.type === 'treeselect'\"\n v-model:value=\"model\"\n :allow-clear=\"field.allowClear\"\n :default-value=\"field.defaultValue\"\n :disabled=\"field.disabled\"\n :dropdownMatchSelectWidth=\"false\"\n :placeholder=\"field.placeholder ? field.placeholder : $t('请选择') + field.label\"\n :multiple=\"field.multiple\"\n :tree-checkable=\"field.treeCheckable\"\n :tree-data=\"options\"\n :tree-label-prop=\"field.labelKey\"\n :tree-node-filter-prop=\"field.valueKey\"\n size=\"small\"\n :style=\"`width: ${field_width}px`\"\n />\n <remote-filter-select\n v-if=\"field.type === 'remotefilterselect'\"\n v-model:label=\"labelModel\"\n v-model:value=\"model\"\n :field=\"field\"\n :formModel=\"formModel\"\n :get-data=\"field.getData\"\n :init_model=\"field.init_model\"\n :label-key=\"field.labelKey\"\n :label-key-list=\"field.labelKeyList\"\n :label-space=\"field.labelSpace\"\n :search_config=\"field.search_config\"\n :value-key=\"field.valueKey\"\n :style=\"`width: ${field_width}px`\"\n />\n <remote-select\n v-if=\"field.type === 'remoteselect'\"\n v-model:label=\"labelModel\"\n v-model:value=\"model\"\n :field=\"field\"\n :formModel=\"formModel\"\n :get-data=\"field.getData\"\n :init_model=\"field.init_model\"\n :label-key=\"field.labelKey\"\n :label-key-list=\"field.labelKeyList\"\n :label-space=\"field.labelSpace\"\n :search_config=\"field.search_config\"\n :value-key=\"field.valueKey\"\n :style=\"`width: ${field_width}px`\"\n />\n <remote-select-pro\n v-if=\"field.type === 'remoteselectpro'\"\n v-model:label=\"labelModel\"\n v-model:value=\"model\"\n :field=\"field\"\n :formModel=\"formModel\"\n :outModel=\"outModel\"\n :get-data=\"field.getData\"\n :init_model=\"field.init_model\"\n :init_watch=\"field.init_watch\"\n :label-key=\"field.labelKey\"\n :label-key-type=\"field.labelKeyType\"\n :label-key-list=\"field.labelKeyList\"\n :label-space=\"field.labelSpace\"\n :search_config=\"field.search_config\"\n :value-key=\"field.valueKey\"\n :is_input=\"field.is_input\"\n :is_form_design=\"is_form_design\"\n :placeholder=\"\n field.placeholder_i18n == undefined\n ? field.placeholder\n ? field.placeholder\n : $t('请选择') + field.label\n : t(field.placeholder_i18n)\n \"\n :style=\"`width: ${field_width}px`\"\n />\n <remote-complete\n v-if=\"field.type === 'remotecomplete'\"\n v-model:value=\"model\"\n :field=\"field\"\n :formModel=\"formModel\"\n :outModel=\"outModel\"\n :get-data=\"field.getData\"\n :init_model=\"field.init_model\"\n :init_watch=\"field.init_watch\"\n :label-key=\"field.labelKey\"\n :label-key-type=\"field.labelKeyType\"\n :label-key-list=\"field.labelKeyList\"\n :label-space=\"field.labelSpace\"\n :search_config=\"field.search_config\"\n :value-key=\"field.valueKey\"\n :maxlength=\"field.maxlength\"\n :is_input=\"field.is_input\"\n :is_form_design=\"is_form_design\"\n :placeholder=\"\n field.placeholder_i18n == undefined\n ? field.placeholder\n ? field.placeholder\n : $t('请选择') + field.label\n : t(field.placeholder_i18n)\n \"\n :style=\"`width: ${field_width}px`\"\n />\n <remote-tree-select\n v-if=\"field.type === 'remotetreeselect'\"\n v-model:label=\"labelModel\"\n v-model:value=\"model\"\n :allow-clear=\"field.allowClear\"\n :default-value=\"field.defaultValue\"\n :disabled=\"field.disabled\"\n :field=\"field\"\n :formModel=\"formModel\"\n :get-data=\"field.getData\"\n :label-key=\"field.labelKey\"\n :search_config=\"field.search_config\"\n :value-key=\"field.valueKey\"\n :style=\"`width: ${field_width}px`\"\n />\n <remote-tree-select-pro\n v-if=\"field.type === 'remotetreeselectpro'\"\n v-model:label=\"labelModel\"\n v-model:value=\"model\"\n :allow-clear=\"field.allowClear\"\n :default-value=\"field.defaultValue\"\n :disabled=\"field.disabled\"\n :field=\"field\"\n :formModel=\"formModel\"\n :outModel=\"outModel\"\n :get-data=\"field.getData\"\n :multiple=\"field.multiple\"\n :search_config=\"field.search_config\"\n :label-key-type=\"field.labelKeyType\"\n :label-key-list=\"field.labelKeyList\"\n :label-space=\"field.labelSpace\"\n :label-key=\"field.labelKey\"\n :value-key=\"field.valueKey\"\n :init_model=\"field.init_model\"\n :init_watch=\"field.init_watch\"\n :is_form_design=\"is_form_design\"\n :placeholder=\"\n field.placeholder_i18n == undefined\n ? field.placeholder\n ? field.placeholder\n : $t('请选择') + field.label\n : t(field.placeholder_i18n)\n \"\n :style=\"`width: ${field_width}px`\"\n />\n <remote-modal\n v-if=\"field.type === 'remotemodal'\"\n v-model:label=\"labelModel\"\n v-model:value=\"model\"\n :columns=\"field.columns\"\n :field=\"field\"\n :field_status=\"field.field_status\"\n :get-data=\"field.getData\"\n :init_model=\"field.init_model\"\n :modalType=\"field.modalType\"\n :search_config=\"field.search_config\"\n :watch=\"field.watch\"\n :style=\"`width: ${field_width}px`\"\n />\n <remote-table\n v-if=\"field.type === 'remotetable'\"\n v-model:value=\"model\"\n :columns=\"field.columns\"\n :formModel=\"formModel\"\n :field=\"field\"\n :field_status=\"field.field_status\"\n :get-data=\"field.getData\"\n :init_model=\"field.init_model\"\n :modalType=\"field.modalType\"\n :search_config=\"field.search_config\"\n :watch=\"field.watch\"\n :style=\"`width: ${field_width}px`\"\n />\n\n <remote-text\n v-if=\"field.type === 'remotetext'\"\n v-model:value=\"model\"\n :columns=\"field.columns\"\n :formModel=\"formModel\"\n :field=\"field\"\n :get-data=\"field.getData\"\n :init_model=\"field.init_model\"\n :modalType=\"field.modalType\"\n :search_config=\"field.search_config\"\n :watch=\"field.watch\"\n />\n\n <a-rate\n v-if=\"field.type === 'rate'\"\n v-model:value=\"model\"\n :count=\"field.count ? field.count : 5\"\n :allow-half=\"field.allowHalf\"\n :style=\"`width: ${field_width}px`\"\n />\n <a-radio-group\n v-if=\"field.type === 'radio-color'\"\n v-model:value=\"model\"\n :default-value=\"field.defaultValue\"\n :disabled=\"field.disabled\"\n size=\"small\"\n :style=\"`width: ${field_width}px`\"\n >\n <a-radio\n v-for=\"option in options\"\n :key=\"option[field.valueKey ? field.valueKey : 'value']\"\n :disabled=\"option.disabled\"\n :value=\"option[field.valueKey ? field.valueKey : 'value']\"\n >\n <div\n :style=\"{\n width: '20px',\n height: '20px',\n backgroundColor: option[field.valueKey ? field.valueKey : 'value'],\n }\"\n ></div>\n </a-radio>\n </a-radio-group>\n </template>\n\n <a-divider\n v-if=\"field.type === 'divider'\"\n :orientation=\"field.orientation\"\n >\n {{ field.label }}\n </a-divider>\n</template>\n<script lang=\"ts\">\nimport RemoteSelect from 'liyu-pc-base/components/FormRender/RemoteSelect/RemoteSelect.vue';\nimport RemoteCascader from 'liyu-pc-base/components/FormRender/RemoteCascader/RemoteCascader.vue';\nimport RemoteModal from 'liyu-pc-base/components/FormRender/RemoteModal/RemoteModal.vue';\nimport RemoteTreeSelect from 'liyu-pc-base/components/FormRender/RemoteTreeSelect/RemoteTreeSelect.vue';\nimport RemoteTable from 'liyu-pc-base/components/FormRender/RemoteTable/RemoteTable.vue';\nimport { defineComponent, watch, onMounted, ref } from 'vue';\nimport RemoteFilterSelect from 'liyu-pc-base/components/FormRender/RemoteFilterSelect/RemoteFilterSelect.vue';\nimport AttributeNomTable from 'liyu-pc-base/components/FormRender/AttributeNomTable/index.vue';\nimport AttributeTable from 'liyu-pc-base/components/FormRender/AttributeTable/index.vue';\nimport JsonStr from 'liyu-pc-base/components/FormRender/JsonStr/index.vue';\nimport JsonObj from 'liyu-pc-base/components/FormRender/JsonObj/index.vue';\nimport RemoteText from 'liyu-pc-base/components/FormRender/RemoteText/RemoteText.vue';\nimport RemoteTablePro from 'liyu-pc-base/components/FormRender/RemoteTablePro/RemoteTablePro.vue';\nimport { debounce, isArray, isEqual } from 'lodash-es';\nimport moment from 'moment';\nimport { isEmpty, isNotEmpty } from 'liyu-pc-base/utils/function';\nimport { PlusOutlined } from '@ant-design/icons-vue';\nimport RemoteSelectPro from 'liyu-pc-base/components/FormRender/RemoteSelectPro/RemoteSelectPro.vue';\nimport RemoteComplete from 'liyu-pc-base/components/FormRender/RemoteComplete/RemoteComplete.vue';\nimport RemoteTreeSelectPro from 'liyu-pc-base/components/FormRender/RemoteTreeSelectPro/RemoteTreeSelectPro.vue';\nimport RemoteCascaderPro from 'liyu-pc-base/components/FormRender/RemoteCascaderPro/RemoteCascaderPro.vue';\nimport Upload from 'liyu-pc-base/components/FormRender/Upload/upload.vue';\nimport RichTextEditor from 'liyu-pc-base/components/FormRender/RichTextEditor/index.vue';\nimport { useI18n } from 'vue-i18n';\nimport IconSelect from 'liyu-pc-base/components/FormRender/iconSelect/index.vue';\nimport MonthPicker from 'liyu-pc-base/components/FormRender/MonthPicker/index.vue';\nimport MonthRangePicker from 'liyu-pc-base/components/FormRender/MonthRangePicker/index.vue';\nimport CodeEditor from 'liyu-pc-base/components/code/CodeEditor.vue';\nimport TinymceEditor from 'liyu-pc-base/components/tinymce/TinymceEditor.vue';\n\nconst isValidDate = (dateString, format = 'YYYY-MM-DD') => {\n const date = moment(dateString, format, true);\n return date.isValid();\n};\nconst isValidDateTime = (dateString, format = 'YYYY-MM-DD HH:mm:ss') => {\n const date = moment(dateString, format, true);\n return date.isValid();\n};\nconst isValidTime = (dateString, format = 'HH:mm:ss') => {\n const date = moment(dateString, format, true);\n return date.isValid();\n};\nexport default defineComponent({\n name: 'FieldRender2',\n methods: { isArray },\n props: {\n field: {\n type: Object,\n required: true,\n },\n value: {\n required: true,\n },\n label: {\n required: false,\n },\n options: {\n type: Array,\n default: () => [],\n },\n validateInfos: {\n type: Object,\n default: () => {},\n },\n formModel: {\n type: Object,\n default: () => {},\n },\n outModel: {\n type: Object,\n default: () => {},\n },\n field_render_show: {\n type: Boolean,\n default: true,\n },\n is_show_label: {\n type: Boolean,\n default: true,\n },\n isUseConditions: {\n type: Boolean,\n default: true,\n },\n is_show_field: {\n type: Boolean,\n default: true,\n },\n is_edit: {\n type: Boolean,\n default: true,\n },\n conditionsVisibleNum: {\n type: Number,\n default: 0,\n },\n is_form_design: {\n type: Boolean,\n default: false,\n },\n field_width: {\n type: Number,\n default: 150,\n },\n },\n emits: [\n 'add',\n 'update:value',\n 'update:label',\n 'update_model',\n 'update:is_show_field',\n 'update:is_edit',\n 'update_name2',\n ],\n setup(props, { emit }) {\n const newModel = ref({ ...props.formModel });\n const rangeDate = (v: any) => {\n if (typeof v == 'string' && v.indexOf(',') >= 0) {\n return v.split(',');\n }\n return v;\n };\n const convertValueByClassName = (value, class_name) => {\n //class_name 'int','float',str','bool','date','datetime','time'\n let new_value;\n if (class_name == 'int') {\n if (isNotEmpty(value) && value instanceof Array) {\n new_value = [];\n value.forEach(item => {\n if (isNotEmpty(item) && typeof item === 'string') {\n new_value.push(Number(item));\n } else {\n new_value.push(item);\n }\n });\n } else if (isNotEmpty(value) && typeof value === 'string') {\n new_value = Number(value);\n } else {\n new_value = value;\n }\n } else if (class_name == 'str') {\n if (isNotEmpty(value) && value instanceof Array) {\n new_value = [];\n value.forEach(item => {\n if (isNotEmpty(item) && typeof item === 'number') {\n new_value.push(item.toString());\n } else {\n new_value.push(item);\n }\n });\n } else if (isNotEmpty(value) && typeof value === 'number') {\n new_value = value.toString();\n } else {\n new_value = value;\n }\n } else if (class_name == 'date') {\n if (isNotEmpty(value) && value instanceof Array) {\n new_value = [];\n value.forEach(item => {\n if (isValidDate(item) && typeof item === 'string') {\n new_value.push(moment(item, 'YYYY-MM-DD'));\n } else {\n new_value.push(item);\n }\n });\n } else if (isValidDate(value) && typeof value === 'string') {\n new_value = value.toString();\n } else {\n new_value = value;\n }\n } else if (class_name == 'datetime') {\n if (isNotEmpty(value) && value instanceof Array) {\n new_value = [];\n value.forEach(item => {\n if (isValidDateTime(item) && typeof item === 'string') {\n new_value.push(moment(item, 'YYYY-MM-DD HH:mm:ss'));\n } else {\n new_value.push(item);\n }\n });\n } else if (isValidDateTime(value) && typeof value === 'string') {\n new_value = moment(value, 'YYYY-MM-DD HH:mm:ss');\n } else {\n new_value = value;\n }\n } else if (class_name == 'time') {\n if (isNotEmpty(value) && value instanceof Array) {\n new_value = [];\n value.forEach(item => {\n if (isValidTime(item) && typeof item === 'string') {\n new_value.push(moment(item, 'HH:mm:ss'));\n } else {\n new_value.push(item);\n }\n });\n } else if (isValidTime(value) && typeof value === 'string') {\n new_value = moment(value, 'HH:mm:ss');\n } else {\n new_value = value;\n }\n } else if (class_name == 'float') {\n if (isNotEmpty(value) && value instanceof Array) {\n new_value = [];\n value.forEach(item => {\n if (isNotEmpty(item) && typeof item === 'string') {\n new_value.push(Number(item));\n } else {\n new_value.push(item);\n }\n });\n } else if (isNotEmpty(value) && typeof value === 'string') {\n new_value = Number(value);\n } else {\n new_value = value;\n }\n } else if (class_name == 'bool') {\n if (isNotEmpty(value) && value instanceof Array) {\n new_value = [];\n value.forEach(item => {\n if (isNotEmpty(item) && typeof item === 'string') {\n new_value.push(Boolean(item));\n } else {\n new_value.push(item);\n }\n });\n } else if (isNotEmpty(value) && typeof value === 'string') {\n new_value = Boolean(value);\n } else {\n new_value = value;\n }\n }\n return new_value;\n };\n const is_show_field = ref(props.is_show_field);\n const is_edit = ref(false);\n const handleToggleEdit = () => {\n emit('update:is_edit', is_edit.value);\n };\n const handleAdd = () => {\n emit('add');\n };\n const check_visible_field_fun = debounce(() => {\n const old_is_show_field = is_show_field.value;\n const condition_result_list: any = [];\n for (const i in props.field?.conditions) {\n const group_list = props.field?.conditions[i];\n const group_results = [];\n for (const j in group_list) {\n const item = group_list[j];\n const value = props.formModel[item.watchKey];\n let new_value;\n if (item.class_name) {\n new_value = convertValueByClassName(item.value, item.class_name);\n } else {\n new_value = item.value;\n }\n let first, second;\n if (new_value instanceof Array) {\n [first, second] = new_value;\n }\n if (item.operator == 'lt') {\n if (typeof first === 'number') {\n if (isEmpty(value)) {\n group_results.push(false);\n } else if (value < first) {\n group_results.push(true);\n } else {\n group_results.push(false);\n }\n } else if (isValidDate(first)) {\n if (isEmpty(value)) {\n group_results.push(false);\n } else if (moment(value).isBefore(moment(first))) {\n group_results.push(true);\n } else {\n group_results.push(false);\n }\n }\n } else if (item.operator == 'lte') {\n if (typeof first === 'number') {\n if (isEmpty(value)) {\n group_results.push(false);\n } else if (value <= first) {\n group_results.push(true);\n } else {\n group_results.push(false);\n }\n } else if (isValidDate(first)) {\n if (isEmpty(value)) {\n group_results.push(false);\n } else if (\n moment(value).isBefore(moment(first)) ||\n moment(value).isSame(moment(first))\n ) {\n group_results.push(true);\n } else {\n group_results.push(false);\n }\n }\n } else if (item.operator == 'gt') {\n if (typeof first === 'number') {\n if (isEmpty(value)) {\n group_results.push(false);\n } else if (value > first) {\n group_results.push(true);\n } else {\n group_results.push(false);\n }\n } else if (isValidDate(first)) {\n if (isEmpty(value)) {\n group_results.push(false);\n } else if (moment(value).isAfter(moment(first))) {\n group_results.push(true);\n } else {\n group_results.push(false);\n }\n }\n } else if (item.operator == 'gte') {\n if (typeof first === 'number') {\n if (isEmpty(value)) {\n group_results.push(false);\n } else if (value >= first) {\n group_results.push(true);\n } else {\n group_results.push(false);\n }\n } else if (isValidDate(first)) {\n if (isEmpty(value)) {\n group_results.push(false);\n } else if (\n moment(value).isAfter(moment(first)) ||\n moment(value).isSame(moment(first))\n ) {\n group_results.push(true);\n } else {\n group_results.push(false);\n }\n }\n } else if (item.operator == 'between') {\n if (typeof first === 'number' && typeof second === 'number' && first && second) {\n if (isEmpty(value)) {\n group_results.push(false);\n } else if (value >= first && value <= second) {\n group_results.push(true);\n } else {\n group_results.push(false);\n }\n } else if (isValidDate(first)) {\n if (isEmpty(value)) {\n group_results.push(false);\n } else if (\n (moment(value).isAfter(moment(first)) || moment(value).isSame(moment(first))) &&\n (moment(value).isBefore(moment(second)) || moment(value).isSame(moment(second)))\n ) {\n group_results.push(true);\n } else {\n group_results.push(false);\n }\n }\n } else if (item.operator == 'notbetween') {\n if (typeof first === 'number' && typeof second === 'number' && first && second) {\n if (isEmpty(value)) {\n group_results.push(false);\n } else if (value < first || value > second) {\n group_results.push(true);\n } else {\n group_results.push(false);\n }\n } else if (isValidDate(first)) {\n if (isEmpty(value)) {\n group_results.push(false);\n } else if (\n moment(value).isBefore(moment(first)) ||\n moment(value).isAfter(moment(second))\n ) {\n group_results.push(true);\n } else {\n group_results.push(false);\n }\n }\n } else if (item.operator == 'in') {\n if (value instanceof Array) {\n const f_list = new_value.filter(x => {\n return value.includes(x);\n });\n if (f_list.length > 0) {\n group_results.push(true);\n } else {\n group_results.push(false);\n }\n } else if (typeof value == 'string' || typeof value == 'number' || isEmpty(value)) {\n // 数字 字符串 空\n const f = new_value.find(x => {\n return value == x;\n });\n if (f) {\n group_results.push(true);\n } else {\n group_results.push(false);\n }\n }\n } else if (item.operator == 'eq') {\n if (value === first) {\n group_results.push(true);\n } else {\n group_results.push(false);\n }\n } else if (item.operator == 'contains') {\n if (value.toString().indexOf(first) > -1) {\n group_results.push(true);\n } else {\n group_results.push(false);\n }\n } else if (item.operator == 'startswith') {\n if (value.toString().startsWith(first)) {\n group_results.push(true);\n } else {\n group_results.push(false);\n }\n } else if (item.operator == 'notin') {\n if (value instanceof Array) {\n const f_list = new_value.filter(x => {\n return value.includes(x);\n });\n if (f_list.length > 0) {\n group_results.push(true);\n } else {\n group_results.push(false);\n }\n } else if (typeof value == 'string' || typeof value == 'number' || isEmpty(value)) {\n // 数字 字符串 空\n const f = new_value.find(x => {\n return value == x;\n });\n if (!f) {\n group_results.push(true);\n } else {\n group_results.push(false);\n }\n }\n } else if (item.operator == 'notcontains') {\n if (value.toString().indexOf(first) == -1) {\n group_results.push(true);\n } else {\n group_results.push(false);\n }\n } else if (item.operator == '_eq') {\n //todo\n } else if (item.operator == 'json_list_not_blank_not_null') {\n // 非空\n if (value) {\n group_results.push(true);\n } else {\n group_results.push(false);\n }\n } else if (item.operator == 'json_list_is_blank_is_null') {\n //为空\n if (!value) {\n group_results.push(true);\n } else {\n group_results.push(false);\n }\n } else if (item.operator == 'not_eq') {\n //为空\n if (!value) {\n group_results.push(true);\n } else {\n group_results.push(false);\n }\n } else if (item.operator == 'not_blank_not_null') {\n // 非空\n if (value) {\n group_results.push(true);\n } else {\n group_results.push(false);\n }\n }\n }\n condition_result_list.push(group_results);\n }\n const con_list = [];\n condition_result_list.forEach(item => {\n const find_false_list = item.filter(x => x === false);\n if (find_false_list && find_false_list.length > 0) {\n con_list.push(false);\n } else {\n con_list.push(true);\n }\n });\n\n const find_true_list = con_list.filter(x => x === true);\n if (find_true_list && find_true_list.length > 0) {\n is_show_field.value = true;\n emit('update:is_show_field', is_show_field.value);\n } else {\n is_show_field.value = false;\n emit('update:is_show_field', is_show_field.value);\n }\n if (is_show_field.value !== old_is_show_field) {\n if (is_show_field.value) {\n newModel.value[props.field.name] = null;\n emit('update_model', {\n add_key: props.field.name,\n value: null,\n });\n } else {\n delete newModel.value[props.field.name];\n emit('update_model', {\n remove_key: props.field.name,\n });\n }\n }\n }, 300);\n const model = ref<any>('');\n const labelModel = ref(props.label);\n watch(\n () => model.value,\n (newValue, oldValue) => {\n if (isEqual(newValue, oldValue)) {\n return;\n }\n emit('update:value', newValue);\n if (props.field.name2) {\n let label: any;\n if (props.field.type === 'radio') {\n const obj = props.options.find(\n (item: any) =>\n item[props.field.valueKey ? props.field.valueKey : 'value'] == newValue,\n );\n label = obj?.[props.field.labelKey ? props.field.labelKey : 'label'];\n } else if (props.field.type === 'checkbox' && newValue && newValue.length >= 0) {\n const list = [];\n props.options.forEach((item: any) => {\n newValue.forEach((item1: any) => {\n if (item1 == item?.[props.field.valueKey ? props.field.valueKey : 'value']) {\n list.push(item?.[props.field.labelKey ? props.field.labelKey : 'label']);\n }\n });\n });\n label = list.toString();\n } else if (props.field.type === 'select') {\n if (isArray(newValue)) {\n const list = [];\n props.options.forEach((item: any) => {\n newValue.forEach((item1: any) => {\n if (item1 == item?.[props.field.valueKey ? props.field.valueKey : 'value']) {\n list.push(item?.[props.field.labelKey ? props.field.labelKey : 'label']);\n }\n });\n });\n label = list.toString();\n } else {\n const obj = props.options.find(\n (item: any) =>\n item[props.field.valueKey ? props.field.valueKey : 'value'] == newValue,\n );\n label = obj?.[props.field.labelKey ? props.field.labelKey : 'label'];\n }\n }\n emit('update_name2', {\n key: props.field.name2,\n value: label,\n });\n }\n },\n { deep: true },\n );\n watch(\n () => props.value,\n newValue => {\n let value = newValue;\n if (props.field.type === 'rangepicker' && value) {\n value = rangeDate(value);\n } else if (props.field.type === 'input' && value) {\n value = value.toString().replace(/(^\\s*)|(\\s*$)/g, '');\n }\n if (is_show_field.value) {\n //当该表单项显示时,才做向上的数据绑定,避免把undefined向上传递,影响rules字段的有效过滤\n model.value = value;\n }\n },\n { immediate: true },\n );\n watch(\n () => labelModel.value,\n newValue => {\n emit('update:label', newValue);\n if ('name2' in props.field) {\n emit('update_name2', { key: props.field.name2, value: newValue.toString() });\n }\n },\n { deep: true },\n );\n watch(\n () => props.label,\n newValue => {\n labelModel.value = newValue;\n },\n );\n watch(\n () => props.formModel,\n newValue => {\n newModel.value = { ...newValue };\n },\n { deep: true },\n );\n watch(\n () => newModel.value,\n (newValue, oldValue) => {\n if (props.field?.conditions) {\n props.field?.conditions.forEach(condition_list => {\n condition_list.forEach(item => {\n if (oldValue[item.watchKey] != newValue[item.watchKey]) {\n check_visible_field_fun();\n }\n });\n });\n }\n },\n { deep: true },\n );\n watch(\n () => [props.conditionsVisibleNum, props.isUseConditions],\n () => {\n if (props.field?.conditions) {\n if (props.isUseConditions) {\n check_visible_field_fun();\n } else {\n is_show_field.value = true;\n emit('update:is_show_field', is_show_field.value);\n }\n } else {\n is_show_field.value = true;\n emit('update:is_show_field', is_show_field.value);\n }\n },\n );\n onMounted(() => {\n if (props.field?.conditions instanceof Array && props.field?.conditions.length > 0) {\n check_visible_field_fun();\n } else {\n is_show_field.value = true;\n emit('update:is_show_field', is_show_field.value);\n }\n if (!is_show_field.value) {\n // 表单项所见即所得,如果有隐藏的字段,那么model的key也要清除\n delete newModel.value[props.field.name];\n emit('update_model', {\n remove_key: props.field.name,\n });\n }\n });\n const { t } = useI18n();\n return {\n t,\n is_show_field,\n is_edit,\n handleToggleEdit,\n rangeDate,\n handleAdd,\n model,\n labelModel,\n };\n },\n components: {\n IconSelect,\n RichTextEditor,\n Upload,\n RemoteCascaderPro,\n RemoteTreeSelectPro,\n RemoteSelectPro,\n RemoteComplete,\n AttributeTable,\n AttributeNomTable,\n RemoteFilterSelect,\n RemoteModal,\n RemoteSelect,\n RemoteCascader,\n RemoteTreeSelect,\n RemoteTable,\n JsonStr,\n JsonObj,\n RemoteText,\n RemoteTablePro,\n PlusOutlined,\n MonthPicker,\n MonthRangePicker,\n CodeEditor,\n TinymceEditor,\n },\n});\n</script>\n\n<style scoped>\n.ant-calendar-picker {\n width: 100% !important;\n}\n</style>\n","import { useRequest } from 'liyu-pc-base/init-plugin';\nimport type { PageResult } from 'liyu-pc-base/api/typing';\n\nexport async function create_view_settings(params: Record<string, any>) {\n return useRequest().post('/view/create_view_settings', params);\n}\n\nexport async function update_view_settings(params: Record<string, any>) {\n return useRequest().post('/view/update_view_settings', params);\n}\n\nexport async function refresh_view_settings_cache(params: Record<string, any>) {\n return useRequest().post('/view/refresh_view_settings_cache', params);\n}\n\nexport async function set_view_settings_default(params: Record<string, any>) {\n return useRequest().post('/view/set_view_settings_default', params);\n}\n\nexport async function delete_view_settings(params: Record<string, any>) {\n return useRequest().post('/view/delete_view_settings', params);\n}\n\nexport async function recover_view_settings(params: Record<string, any>) {\n return useRequest().post('/view/recover_view_settings', params);\n}\n\nexport async function get_view_settings(params: Record<string, any>) {\n return useRequest().post('/view/get_view_settings', params);\n}\n\nexport async function create_user_view(params: Record<string, any>) {\n return useRequest().post('/view/create_user_view', params);\n}\n\nexport async function update_user_view(params: Record<string, any>) {\n return useRequest().post('/view/update_user_view', params);\n}\n\nexport async function delete_user_view(params: Record<string, any>) {\n return useRequest().post('/view/delete_user_view', params);\n}\n\nexport async function recover_user_view(params: Record<string, any>) {\n return useRequest().post('/view/recover_user_view', params);\n}\n\nexport async function get_user_view(params: Record<string, any>) {\n return useRequest().post('/view/get_user_view', params);\n}\n\nexport async function get_view_settings_for_user(params: Record<string, any>) {\n return useRequest().post('/view/get_view_settings_for_user', params);\n}\n\nexport async function change_view_settings_sort(params: Record<string, any>) {\n return useRequest().post('/view/change_view_settings_sort', params);\n}\n\nexport async function query_view_settings_list(params?: {\n [key: string]: any;\n}): Promise<PageResult> {\n return useRequest().post('/view/query_view_settings_list', params);\n}\n\nexport async function query_user_view_list(params?: { [key: string]: any }): Promise<PageResult> {\n return useRequest().post('/view/query_user_view_list', params);\n}\n","import type { Ref, ComponentPublicInstance } from 'vue';\n\nexport type BasicTarget<T = HTMLElement> = (() => T | null) | T | null | Ref<T | null | undefined>;\n\nexport type TargetElement = ComponentPublicInstance | HTMLElement | Element | Document | Window;\n\nexport function getTargetElement(\n target?: BasicTarget<TargetElement>,\n defaultElement?: TargetElement,\n): TargetElement | undefined | null {\n if (!target) {\n return defaultElement;\n }\n\n let targetElement: TargetElement | undefined | null;\n\n if (typeof target === 'function') {\n targetElement = target();\n } else if ('value' in target) {\n targetElement = (target.value as ComponentPublicInstance)?.$el;\n } else {\n targetElement = target;\n }\n\n return targetElement;\n}\n","import type { Ref, ComponentPublicInstance } from 'vue';\nimport { ref, onUnmounted } from 'vue';\nimport { getTargetElement } from 'liyu-pc-base/utils/dom';\nimport { default as screenfull } from 'screenfull';\n\nexport interface Options {\n onExitFull?: () => void;\n onFull?: () => void;\n}\n\nexport type UseFullscreen = readonly [\n Ref<ComponentPublicInstance | null>,\n Ref<boolean>,\n {\n setFull: () => void;\n exitFull: () => void;\n toggleFull: () => void;\n },\n];\n\nexport const useFullscreen = (options?: Options): UseFullscreen => {\n const { onExitFull, onFull } = options || {};\n const elRef = ref<ComponentPublicInstance | null>(null);\n const onExitFullRef = ref(onExitFull);\n const onFullRef = ref(onFull);\n\n const state = ref(false);\n\n const onChange = () => {\n if (screenfull.isEnabled) {\n const { isFullscreen } = screenfull;\n if (isFullscreen) {\n onFullRef.value && onFullRef.value();\n } else {\n screenfull.off('change', onChange);\n onExitFullRef.value && onExitFullRef.value();\n }\n state.value = isFullscreen;\n }\n };\n\n const setFull = () => {\n const el = getTargetElement(elRef);\n if (!el) {\n return;\n }\n if (screenfull.isEnabled) {\n screenfull.request(el as HTMLElement);\n screenfull.on('change', onChange);\n }\n };\n\n const exitFull = () => {\n if (!state.value) {\n return;\n }\n if (screenfull.isEnabled) {\n screenfull.exit();\n }\n };\n\n const toggleFull = () => {\n if (state.value) {\n exitFull();\n } else {\n setFull();\n }\n };\n\n onUnmounted(() => {\n if (screenfull.isEnabled) {\n screenfull.off('change', onChange);\n }\n });\n\n return [\n elRef,\n state,\n {\n setFull,\n exitFull,\n toggleFull,\n },\n ] as const;\n};\n\n// examples\n/*\nconst [elRef, screenState, { setFull, exitFull, toggleFull } ] = useFullscreen({\n onExitFull: () => {\n console.log('exitFull callback');\n },\n onFull: () => {\n console.log('inFull callback');\n }\n});\n\n<template>\n <div ref=\"elRef\">\n <p>123</p>\n <p>current fullscreen state: {{ screenState }}</p>\n <a-button @click=\"toggleFull\">Toggle</a-button>\n <a-button v-if=\"!screenState\" @click=\"setFull\">fullScreen</a-button>\n <a-button v-else @click=\"exitFull\">exitFullScreen</a-button>\n </div>\n</template>\n*/\n","import { isEmpty, isNotEmpty } from 'liyu-pc-base/utils/function';\nimport { getApiData } from 'liyu-pc-base/api/api-model';\nimport { ConditionOperatorMap } from 'liyu-pc-base/api/typing';\nimport { inject } from 'vue';\nimport type { TableProState } from './typing';\nimport { get_view_settings_for_user } from 'liyu-pc-base/api/view-model';\nimport { useUserStore, useEnv } from 'liyu-pc-base/init-plugin';\nexport function removeNestedDuplicates(nodes, seenIds = new Set(), parentPath = []) {\n const result = [];\n\n nodes.forEach((node, index) => {\n const currentPath = [...parentPath, index]; // 记录当前节点的路径\n const nodeId = node.name;\n\n if (!seenIds.has(nodeId)) {\n seenIds.add(nodeId);\n const newNode = { ...node };\n\n if (newNode.children && Array.isArray(newNode.children)) {\n newNode.children = removeNestedDuplicates(newNode.children, seenIds, currentPath);\n }\n\n result.push(newNode);\n } else {\n // 如果需要处理子对象(即使父对象被忽略了),则递归调用\n if (node.children && Array.isArray(node.children)) {\n // 注意:这里我们不将子对象添加到结果数组中,只是处理它们以避免丢失新的 id\n removeNestedDuplicates(node.children, seenIds, currentPath);\n }\n }\n });\n\n return result;\n}\nexport const operator_type_map = ConditionOperatorMap;\n\nexport const options_for_date_eq = [\n { value: '上月', label: '上月' },\n { value: '本月', label: '本月' },\n { value: '今日', label: '今日' },\n { value: '昨日', label: '昨日' },\n { value: '期初', label: '期初' },\n];\n\nconst operator_params_count = {\n between: 2,\n gt: 1,\n lt: 1,\n gte: 1,\n lte: 1,\n in: 0,\n eq: 1,\n _eq: 1,\n contains: 1,\n icontains: 1,\n startswith: 1,\n notbetween: 2,\n notin: 0,\n notcontains: 1,\n not_eq: 1,\n not_blank_not_null: 1,\n json_list_not_blank_not_null: 1,\n json_list_is_blank_is_null: 1,\n is_or_not_blank_or_null: 1,\n is_or_not_null: 1,\n};\n\nexport const getParamsCount = (operator, configItem) => {\n return operator_params_count[operator];\n};\n\nexport const filterConditions = conditions => {\n if (!conditions) {\n return [];\n }\n const res = conditions.filter(item => {\n return (\n item.value instanceof Array &&\n item.value.length > 0 &&\n !item.value.some(item => isEmpty(item))\n );\n });\n return res;\n};\n\nconst processColumnDataSource = (res_data: any, name_map: object) => {\n res_data.forEach((item: any) => {\n name_map[item.name] = item.verbose_name;\n if (item.children) {\n processColumnDataSource(item.children, name_map);\n }\n });\n};\n\nexport const getColumnNameList = async (modelType: string): Promise<any[]> => {\n if (!modelType) {\n return [];\n }\n const url = modelType.split('-')[0] + '/obtain_' + modelType.split('-')[1] + '_column_data';\n const res = await getApiData({}, url, false, { skip_error: true });\n const name_map = {};\n let res_data = removeNestedDuplicates(res || []);\n processColumnDataSource(res_data, name_map);\n if (!('id' in name_map)) {\n name_map['id'] = 'ID';\n }\n return Object.keys(name_map).map((item: any) => ({\n value: item,\n label: name_map[item],\n }));\n};\n\nexport const tableProStateSymbol = Symbol('tableProState');\n\nexport const useTableProState = (): TableProState => {\n const state = inject<TableProState>(tableProStateSymbol);\n return state;\n};\nexport const fetchViewsData = async (view_key, getQueryParamsFunc, count_url, config) => {\n const userStore = useUserStore();\n const userid = userStore.userid;\n const env = useEnv();\n const res = await get_view_settings_for_user({\n user_id: userid,\n view_project__flag: env.VITE_APP_VIEW_PROJECT_FLAG,\n view_menu__flag: view_key,\n sort_fields: ['sort', 'create_time'],\n is_cache: false,\n });\n\n const getGroupDataList = async viewData => {\n let selectedConditionGroup = null;\n if (viewData.groupConditionFieldName && config.condition_group_config_list?.length > 0) {\n selectedConditionGroup = config.condition_group_config_list.find(\n item => item.field_name === viewData.groupConditionFieldName,\n );\n } else {\n selectedConditionGroup = null;\n }\n if (!selectedConditionGroup) {\n return [];\n }\n if (!config.query_group_url) {\n return [];\n }\n\n const params = getQueryParamsFunc({ type: 'group', viewData });\n params['group_condition'] = {\n field_name: selectedConditionGroup.field_name,\n display_name: selectedConditionGroup.display_name,\n order_name: selectedConditionGroup.order_name || [],\n };\n const res = await getApiData(params, config.query_group_url || '', false, {\n api_log: `tablePro ${config.key} ${config.title}`,\n });\n return res || [];\n };\n\n let list: any = [];\n if (res.system_user_datas) list = list.concat(res.system_user_datas);\n if (res.system_public_datas) list = list.concat(res.system_public_datas);\n if (res.public_datas) list = list.concat(res.public_datas);\n if (res.user_datas) list = list.concat(res.user_datas);\n\n return Promise.all(\n list.map(async (item: any) => {\n let data = item.data;\n if (typeof data === 'string') {\n try {\n data = JSON.parse(data);\n } catch (e) {}\n }\n if (count_url) {\n const groupDataList = await getGroupDataList(data);\n const params = getQueryParamsFunc({ type: 'count', viewData: data, groupDataList });\n const num = await getApiData(params, count_url || '', false, {\n api_log: `tablePro ${config.key} ${config.title}`,\n });\n item.num = num;\n }\n return { ...item, data };\n }),\n );\n};\n\nexport const getCurrentGroupConditionValue = (conditionGroupDataList, groupConditionValue) => {\n if (!conditionGroupDataList) {\n return null;\n }\n const findItem = conditionGroupDataList.find(\n item => item.group_info.value === groupConditionValue,\n );\n return findItem?.group_info || conditionGroupDataList[0]?.group_info;\n};\n\n/**\n * 将 RemoteSelectPro 字段的 value 数组转换为可读 label 字符串\n * 参考 src/components/FormRender/RemoteSelectPro/RemoteSelectPro.vue 的查询逻辑\n * 内置全局缓存:按\"单条记录 + valueKey\"独立缓存\n * - 缓存 key 形如 `${postUrl}::${valueKey}::${id}`,valueKey 不同 → 不同缓存\n * - 命中后不再请求;支持跨调用复用\n * - 即便某次请求只查 ids=[1,2,3],下次请求 ids=[2,3,4] 也只会再请求 4\n * - 带 TTL 过期;其他参数(labelKey/labelKeyList 等)不在 key 中,\n * 若需要按字段组合切换建议主动调用 clearRemoteSelectProCache(postUrl)\n *\n * 函数只接收解构后的原始参数,不再依赖某个特定的 configItem 对象,便于在其它场景下复用:\n * - 入参全部独立命名,未提供的字段走默认值\n * - value 仅作为入参传入,内部统一处理 Array / 单值 / 空值场景\n * - 接口请求参数与 RemoteSelectPro 保持完全一致\n *\n * @param value value 数组(RemoteSelectPro 选中项的 id 集合)\n * @param params.RemoteSelectPro 字段配置(任一字段可省略,使用默认值)\n * - postUrl: 查询接口,必填\n * - valueKey: id 字段,默认 'id'\n * - labelKey: 单 label 字段,默认 'name'\n * - labelKeyList: 多 label 字段数组,默认 []\n * - labelKeyType: labelKeyList 类型,默认 0\n * - labelSpace: 多 label 拼接分隔符,默认 '-'\n * - queryType: 'simple' 走简单查询,其它走高级 conditions\n * @param params.cacheTTL 缓存有效期(毫秒),默认 5 分钟;传 0 表示不缓存\n * @returns label 用逗号拼接的字符串\n */\n\n// 单条记录级缓存:key = `${postUrl}::${valueKey}::${id}` -> { record, timestamp }\n// 使用 (globalThis as any) 挂载,保证整个应用单例\nconst _GLOBAL_CACHE_KEY = '__liyu_pc_base_remote_select_pro_cache__';\ntype RemoteSelectProCacheEntry = { record: any; timestamp: number };\ntype RemoteSelectProCacheStore = Record<string, RemoteSelectProCacheEntry>;\nconst remoteSelectProCache: RemoteSelectProCacheStore =\n ((globalThis as any)[_GLOBAL_CACHE_KEY] =\n (globalThis as any)[_GLOBAL_CACHE_KEY] || {}) as RemoteSelectProCacheStore;\n\n/**\n * 构造单条记录缓存 key:postUrl + valueKey + id\n */\nconst buildRecordCacheKey = (postUrl: string, valueKey: string, id: any): string => {\n const idStr = id === null || id === undefined ? '' : String(id);\n return `${postUrl}::${valueKey}::${idStr}`;\n};\n\n/**\n * 读取单条缓存;过期则删除并返回 null\n */\nconst getRecordCache = (\n postUrl: string,\n valueKey: string,\n id: any,\n cacheTTL: number,\n): any | null => {\n const key = buildRecordCacheKey(postUrl, valueKey, id);\n const entry = remoteSelectProCache[key];\n if (!entry) return null;\n if (Date.now() - entry.timestamp > cacheTTL) {\n delete remoteSelectProCache[key];\n return null;\n }\n return entry.record;\n};\n\n/**\n * 写入单条缓存\n */\nconst setRecordCache = (postUrl: string, valueKey: string, id: any, record: any): void => {\n const key = buildRecordCacheKey(postUrl, valueKey, id);\n remoteSelectProCache[key] = { record, timestamp: Date.now() };\n};\n\n/**\n * 主动清空缓存\n * @param postUrl 指定 postUrl 则只清空该接口的缓存,传空则清空全部\n */\nexport const clearRemoteSelectProCache = (postUrl?: string): void => {\n if (!postUrl) {\n for (const k of Object.keys(remoteSelectProCache)) {\n delete remoteSelectProCache[k];\n }\n return;\n }\n const prefix = `${postUrl}::`;\n for (const k of Object.keys(remoteSelectProCache)) {\n if (k.startsWith(prefix)) {\n delete remoteSelectProCache[k];\n }\n }\n};\n\nexport const transferRemoteSelectProValue = async (\n value: any,\n params: {\n postUrl?: string;\n valueKey?: string;\n labelKey?: string;\n labelKeyList?: string[];\n labelKeyType?: number;\n labelSpace?: string;\n queryType?: string;\n cacheTTL?: number;\n } = {},\n): Promise<string> => {\n const cacheTTL = params.cacheTTL ?? 5 * 60 * 1000; // 默认 5 分钟\n const postUrl = params.postUrl;\n // 提取 value 数组中的 id\n let ids: any[] = [];\n if (value instanceof Array) {\n ids = value.filter((item: any) => isNotEmpty(item));\n } else if (isNotEmpty(value)) {\n ids = [value];\n }\n if (ids.length === 0) {\n return '';\n }\n if (!postUrl) {\n return ids.join(',');\n }\n const valueKey = params.valueKey || 'id';\n const labelKey = params.labelKey || 'name';\n const labelKeyList: string[] = params.labelKeyList || [];\n const labelKeyType = params.labelKeyType ?? 0;\n const labelSpace = params.labelSpace || '-';\n const queryType = params.queryType;\n // 组装 column_fields 和 sort_fields,参考 RemoteSelectPro 中的 getColumnFields / get_sort_fields\n const columnFields: string[] = [valueKey];\n if (labelKeyList.length > 0 && labelKeyType !== 1) {\n columnFields.push(...labelKeyList);\n } else {\n columnFields.push(labelKey);\n }\n const uniqueFields = [...new Set(columnFields)];\n const sortFields =\n labelKeyList.length > 0 && labelKeyType !== 1 ? labelKeyList : [labelKey];\n\n /**\n * 查询一组 ids,返回 id -> record 映射\n * 内部会先从全局缓存批量取,未命中的再发起一次接口请求\n */\n const fetchRecordsByIds = async (\n targetIds: any[],\n ): Promise<Record<string, any>> => {\n const idMap: Record<string, any> = {};\n if (targetIds.length === 0) return idMap;\n let missingIds: any[] = targetIds;\n if (cacheTTL > 0) {\n const cachedList: any[] = [];\n const missed: any[] = [];\n targetIds.forEach((id: any) => {\n const cached = getRecordCache(postUrl, valueKey, id, cacheTTL);\n if (cached !== null) {\n cachedList.push(cached);\n } else {\n missed.push(id);\n }\n });\n missingIds = missed;\n cachedList.forEach((rec: any) => {\n idMap[String(rec[valueKey])] = rec;\n });\n if (missingIds.length === 0) return idMap;\n }\n let res: any;\n if (queryType === 'simple') {\n res = await getApiData(\n {\n current: 1,\n pageSize: missingIds.length,\n is_pagination: true,\n request_source: 'strict',\n is_active: true,\n column_fields: uniqueFields,\n sort_fields: sortFields,\n [valueKey]: missingIds.join(','),\n },\n postUrl,\n false,\n { skip_error: true },\n );\n } else {\n res = await getApiData(\n {\n current: 1,\n pageSize: missingIds.length,\n is_pagination: true,\n request_source: 'strict',\n is_active: true,\n column_fields: uniqueFields,\n sort_fields: sortFields,\n conditions: [\n [\n {\n class_name: 'int',\n operator: 'in',\n value: missingIds,\n format: 'remote',\n field_name: valueKey,\n },\n ],\n ],\n },\n postUrl,\n false,\n { skip_error: true },\n );\n }\n const dataList: any[] = res?.data || [];\n dataList.forEach((rec: any) => {\n const recId = rec?.[valueKey];\n if (recId === null || recId === undefined) return;\n idMap[String(recId)] = rec;\n if (cacheTTL > 0) {\n setRecordCache(postUrl, valueKey, recId, rec);\n }\n });\n return idMap;\n };\n\n let idMap: Record<string, any> = {};\n try {\n idMap = await fetchRecordsByIds(ids);\n } catch (e) {\n // 查询失败时回退为原始 value\n return ids.join(',');\n }\n // 按原 ids 顺序匹配,组装 label(与 RemoteSelectPro 中 datasource 的逻辑保持一致)\n const labelList: any[] = [];\n ids.forEach((id: any) => {\n const foundItem: any = idMap[String(id)];\n if (foundItem) {\n if (labelKeyList.length > 0 && labelKeyType !== 1) {\n const labels: any[] = [];\n for (const key of labelKeyList) {\n labels.push(foundItem[key]);\n }\n labelList.push(labels.join(labelSpace));\n } else {\n labelList.push(foundItem[labelKey]);\n }\n } else {\n labelList.push(id);\n }\n });\n return labelList.join(',');\n};\n","<template>\n <span class=\"search-summary\">\n <a-tag\n v-for=\"item in dataSource\"\n :key=\"item.field_name\"\n color=\"green\"\n closable\n @close=\"handleClose(item.field_name)\"\n >\n {{ item.summary }}\n </a-tag>\n <a-button\n size=\"small\"\n type=\"text\"\n @click=\"handleRefresh\"\n v-if=\"showRefresh\"\n >\n <RedoOutlined />\n </a-button>\n </span>\n</template>\n\n<script setup lang=\"ts\">\nimport { isEmpty } from 'liyu-pc-base/utils/function';\nimport moment from 'moment';\nimport { onMounted, ref, watch } from 'vue';\nimport { useI18n } from 'vue-i18n';\nimport { SearchConditionItem, SearchConfig, SearchType } from './typing';\nimport { operator_type_map, transferRemoteSelectProValue } from './utils';\ninterface Props {\n searchConfig: SearchConfig[];\n searchConditions: SearchConditionItem[];\n eventBus: any;\n searchType: SearchType;\n showRefresh: boolean;\n}\nconst props = withDefaults(defineProps<Props>(), {\n searchType: 'advanced',\n showRefresh: true,\n});\nconst emit = defineEmits(['update:searchConditions']);\n\nconst { t } = useI18n();\nconst dataSource = ref<any[]>([]);\nconst transferValue = async (configItem, operator, value) => {\n const str_list: any = [];\n let transfer_value;\n if (operator === 'is_or_not_blank_or_null' || operator === 'is_or_not_null') {\n if (value === 'yes') {\n return t('is_or_not_blank_or_null.yes');\n } else {\n return t('is_or_not_blank_or_null.no');\n }\n } else if (operator === '_eq') {\n if (['上月', '本月', '今日', '昨日', '期初'].includes(value[0])) {\n return t(value[0]);\n }\n } else if (configItem.options instanceof Array) {\n if (value instanceof Array) {\n value.forEach(item => {\n configItem.options.forEach(i => {\n if (item == i.value) {\n str_list.push(i.label || i.name);\n }\n });\n });\n if (props.searchType === 'advanced') {\n return `${operator_type_map[operator]} ${str_list.join(',')}`;\n } else {\n return str_list.join(',');\n }\n } else {\n configItem.options.forEach(i => {\n if (value == i.value) {\n transfer_value = i.label;\n }\n });\n if (props.searchType === 'advanced') {\n return `${operator_type_map[operator]} ${transfer_value}`;\n } else {\n return transfer_value;\n }\n }\n } else if (configItem.type == 'monthpicker' && configItem.dateFormat) {\n if (value instanceof Array) {\n const str_list = [];\n value.forEach(i => {\n if (i) {\n str_list.push(moment(i).format(configItem.dateFormat));\n } else {\n str_list.push(i);\n }\n });\n transfer_value = str_list.join(',');\n } else {\n transfer_value = moment(value).format(configItem.dateFormat);\n }\n if (props.searchType === 'advanced') {\n return `${operator_type_map[operator]} ${transfer_value}`;\n } else {\n return transfer_value;\n }\n } else if (configItem.type === 'remoteselectpro') {\n const transfer_value = await transferRemoteSelectProValue(value, {\n postUrl: configItem.postUrl,\n valueKey: configItem.valueKey,\n labelKey: configItem.labelKey,\n labelKeyList: configItem.labelKeyList,\n labelKeyType: configItem.labelKeyType,\n labelSpace: configItem.labelSpace,\n queryType: configItem.queryType,\n });\n if (props.searchType === 'advanced') {\n return `${operator_type_map[operator]} ${transfer_value}`;\n } else {\n return transfer_value;\n }\n } else {\n if (value instanceof Array) {\n value = value.map(item => {\n if (item instanceof Boolean) {\n return item ? '是' : '否';\n } else {\n return item;\n }\n });\n value = value.join(',');\n } else {\n if (value instanceof Boolean) {\n value = value ? '是' : '否';\n }\n }\n if (props.searchType === 'advanced') {\n return `${operator_type_map[operator]} ${value}`;\n } else {\n return value;\n }\n }\n};\nconst getDataSource = async () => {\n const searchConditionsMap = {};\n for (const condition of props.searchConditions) {\n searchConditionsMap[condition.field_name] = {\n value: condition.value,\n operator: condition.operator,\n };\n }\n let tmpValue: any = props.searchConfig?.map(async configItem => {\n const data = searchConditionsMap[configItem.field_name] || {\n operator: configItem.default_operator || 'eq',\n value: null,\n };\n let summary = null;\n if (\n data.value instanceof Array &&\n data.value.length > 0 &&\n !data.value.some(item => isEmpty(item))\n ) {\n const transfer_value = await transferValue(configItem, data.operator, data.value);\n summary = `${configItem.label}: ${transfer_value}`;\n }\n return {\n field_name: configItem.field_name,\n summary,\n };\n });\n tmpValue = await Promise.all(tmpValue);\n dataSource.value = tmpValue.filter(item => item.summary);\n};\nconst handleClose = (fieldName: string) => {\n emit(\n 'update:searchConditions',\n props.searchConditions.filter(item => item.field_name !== fieldName),\n );\n props.eventBus.emit('refresh');\n};\nconst handleRefresh = () => {\n props.eventBus.emit('refresh');\n};\nonMounted(() => {\n getDataSource();\n});\nwatch(() => props.searchConditions, getDataSource);\nwatch(() => props.searchConfig, getDataSource);\nwatch(() => props.searchType, getDataSource);\n</script>\n<style lang=\"less\" scoped>\n.search-summary {\n display: inline-block;\n padding: 4px 2px;\n}\n</style>\n","<template>\n <span class=\"search-summary\">\n <a-tag\n v-for=\"item in dataSource\"\n :key=\"item.field_name\"\n color=\"green\"\n closable\n @close=\"handleClose(item.field_name)\"\n >\n {{ item.summary }}\n </a-tag>\n <a-button\n size=\"small\"\n type=\"text\"\n @click=\"handleRefresh\"\n v-if=\"showRefresh\"\n >\n <RedoOutlined />\n </a-button>\n </span>\n</template>\n\n<script setup lang=\"ts\">\nimport { isEmpty } from 'liyu-pc-base/utils/function';\nimport moment from 'moment';\nimport { onMounted, ref, watch } from 'vue';\nimport { useI18n } from 'vue-i18n';\nimport { SearchConditionItem, SearchConfig, SearchType } from './typing';\nimport { operator_type_map, transferRemoteSelectProValue } from './utils';\ninterface Props {\n searchConfig: SearchConfig[];\n searchConditions: SearchConditionItem[];\n eventBus: any;\n searchType: SearchType;\n showRefresh: boolean;\n}\nconst props = withDefaults(defineProps<Props>(), {\n searchType: 'advanced',\n showRefresh: true,\n});\nconst emit = defineEmits(['update:searchConditions']);\n\nconst { t } = useI18n();\nconst dataSource = ref<any[]>([]);\nconst transferValue = async (configItem, operator, value) => {\n const str_list: any = [];\n let transfer_value;\n if (operator === 'is_or_not_blank_or_null' || operator === 'is_or_not_null') {\n if (value === 'yes') {\n return t('is_or_not_blank_or_null.yes');\n } else {\n return t('is_or_not_blank_or_null.no');\n }\n } else if (operator === '_eq') {\n if (['上月', '本月', '今日', '昨日', '期初'].includes(value[0])) {\n return t(value[0]);\n }\n } else if (configItem.options instanceof Array) {\n if (value instanceof Array) {\n value.forEach(item => {\n configItem.options.forEach(i => {\n if (item == i.value) {\n str_list.push(i.label || i.name);\n }\n });\n });\n if (props.searchType === 'advanced') {\n return `${operator_type_map[operator]} ${str_list.join(',')}`;\n } else {\n return str_list.join(',');\n }\n } else {\n configItem.options.forEach(i => {\n if (value == i.value) {\n transfer_value = i.label;\n }\n });\n if (props.searchType === 'advanced') {\n return `${operator_type_map[operator]} ${transfer_value}`;\n } else {\n return transfer_value;\n }\n }\n } else if (configItem.type == 'monthpicker' && configItem.dateFormat) {\n if (value instanceof Array) {\n const str_list = [];\n value.forEach(i => {\n if (i) {\n str_list.push(moment(i).format(configItem.dateFormat));\n } else {\n str_list.push(i);\n }\n });\n transfer_value = str_list.join(',');\n } else {\n transfer_value = moment(value).format(configItem.dateFormat);\n }\n if (props.searchType === 'advanced') {\n return `${operator_type_map[operator]} ${transfer_value}`;\n } else {\n return transfer_value;\n }\n } else if (configItem.type === 'remoteselectpro') {\n const transfer_value = await transferRemoteSelectProValue(value, {\n postUrl: configItem.postUrl,\n valueKey: configItem.valueKey,\n labelKey: configItem.labelKey,\n labelKeyList: configItem.labelKeyList,\n labelKeyType: configItem.labelKeyType,\n labelSpace: configItem.labelSpace,\n queryType: configItem.queryType,\n });\n if (props.searchType === 'advanced') {\n return `${operator_type_map[operator]} ${transfer_value}`;\n } else {\n return transfer_value;\n }\n } else {\n if (value instanceof Array) {\n value = value.map(item => {\n if (item instanceof Boolean) {\n return item ? '是' : '否';\n } else {\n return item;\n }\n });\n value = value.join(',');\n } else {\n if (value instanceof Boolean) {\n value = value ? '是' : '否';\n }\n }\n if (props.searchType === 'advanced') {\n return `${operator_type_map[operator]} ${value}`;\n } else {\n return value;\n }\n }\n};\nconst getDataSource = async () => {\n const searchConditionsMap = {};\n for (const condition of props.searchConditions) {\n searchConditionsMap[condition.field_name] = {\n value: condition.value,\n operator: condition.operator,\n };\n }\n let tmpValue: any = props.searchConfig?.map(async configItem => {\n const data = searchConditionsMap[configItem.field_name] || {\n operator: configItem.default_operator || 'eq',\n value: null,\n };\n let summary = null;\n if (\n data.value instanceof Array &&\n data.value.length > 0 &&\n !data.value.some(item => isEmpty(item))\n ) {\n const transfer_value = await transferValue(configItem, data.operator, data.value);\n summary = `${configItem.label}: ${transfer_value}`;\n }\n return {\n field_name: configItem.field_name,\n summary,\n };\n });\n tmpValue = await Promise.all(tmpValue);\n dataSource.value = tmpValue.filter(item => item.summary);\n};\nconst handleClose = (fieldName: string) => {\n emit(\n 'update:searchConditions',\n props.searchConditions.filter(item => item.field_name !== fieldName),\n );\n props.eventBus.emit('refresh');\n};\nconst handleRefresh = () => {\n props.eventBus.emit('refresh');\n};\nonMounted(() => {\n getDataSource();\n});\nwatch(() => props.searchConditions, getDataSource);\nwatch(() => props.searchConfig, getDataSource);\nwatch(() => props.searchType, getDataSource);\n</script>\n<style lang=\"less\" scoped>\n.search-summary {\n display: inline-block;\n padding: 4px 2px;\n}\n</style>\n","<template>\n <a-modal\n :title=\"$t('设置搜索字段')\"\n v-model:open=\"visible\"\n width=\"1000px\"\n @ok=\"handleOk\"\n @cancel=\"handleCancel\"\n >\n <div class=\"search-config-container\">\n <div class=\"table-wrapper left-table\">\n <div class=\"table-title\">\n {{ $t('所有字段') }}\n <a-input\n v-model:value=\"leftSearch\"\n size=\"small\"\n :placeholder=\"$t('搜索标签/字段名')\"\n style=\"margin-top: 8px\"\n allow-clear\n />\n </div>\n <s-table\n :columns=\"leftColumns\"\n :data-source=\"filteredLeftData\"\n :pagination=\"false\"\n :row-selection=\"leftRowSelection\"\n v-model:selectedRowKeys=\"leftSelectedRowKeys\"\n row-key=\"field_name\"\n size=\"small\"\n :row-class-name=\"record => (record.is_selected ? 'row-selected' : '')\"\n expand-row-by-click\n >\n <template #bodyCell=\"{ column, record }\">\n <template v-if=\"column.dataIndex === 'label'\">\n <span\n :style=\"{\n color: record.is_selected ? '#ccc' : 'inherit',\n }\"\n >\n {{ record.label }}\n </span>\n </template>\n </template>\n </s-table>\n </div>\n\n <div class=\"middle-btns\">\n <a-button\n type=\"primary\"\n shape=\"circle\"\n :disabled=\"leftSelectedRowKeys.length === 0\"\n @click=\"moveToRight\"\n >\n <template #icon><RightOutlined /></template>\n </a-button>\n <a-button\n type=\"primary\"\n shape=\"circle\"\n :disabled=\"rightSelectedRowKeys.length === 0\"\n @click=\"moveToLeft\"\n >\n <template #icon><LeftOutlined /></template>\n </a-button>\n </div>\n\n <div class=\"table-wrapper right-table\">\n <div class=\"table-title\">\n {{ $t('已选字段') }}\n <a-input\n v-model:value=\"rightSearch\"\n size=\"small\"\n :placeholder=\"$t('搜索标签/字段名')\"\n style=\"margin-top: 8px\"\n allow-clear\n />\n </div>\n <s-table\n :columns=\"rightColumns\"\n :data-source=\"filteredRightData\"\n :pagination=\"false\"\n :row-selection=\"rightRowSelection\"\n v-model:selectedRowKeys=\"rightSelectedRowKeys\"\n row-key=\"field_name\"\n size=\"small\"\n @row-drag-end=\"onRowDragEnd\"\n />\n </div>\n </div>\n </a-modal>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, computed, watch, PropType } from 'vue';\nimport { useI18n } from 'vue-i18n';\nimport { RightOutlined, LeftOutlined } from '@ant-design/icons-vue';\nimport { SearchConfig, ViewSearchItem } from '../typing';\nimport { cloneDeep } from 'lodash';\n\nconst props = defineProps({\n open: {\n type: Boolean,\n default: false,\n },\n searchConfig: {\n type: Array as PropType<SearchConfig[]>,\n default: () => [],\n },\n viewSearchConfig: {\n type: Object as PropType<Record<string, ViewSearchItem>>,\n default: () => ({}),\n },\n});\n\nconst emit = defineEmits(['update:open', 'change']);\n\nconst { t } = useI18n();\n\nconst visible = ref(false);\nconst leftSearch = ref('');\nconst rightSearch = ref('');\nconst leftSelectedRowKeys = ref<string[]>([]);\nconst rightSelectedRowKeys = ref<string[]>([]);\nconst rightData = ref<SearchConfig[]>([]);\n\nconst leftColumns = [\n {\n title: t('字段名称'),\n dataIndex: 'label',\n key: 'label',\n width: 250,\n ellipsis: true,\n },\n];\n\nconst rightColumns = computed(() => {\n const columns: any = [\n {\n title: t('字段名称'),\n dataIndex: 'label',\n key: 'label',\n rowDrag: true,\n width: 150,\n ellipsis: true,\n },\n ];\n if (filteredRightData.value.length > 0) {\n if (filteredRightData.value.some(item => item.group_name)) {\n columns.push({\n title: t('分组'),\n dataIndex: 'group_name',\n key: 'group_name',\n width: 150,\n ellipsis: true,\n });\n }\n }\n return columns;\n});\n\nwatch(\n () => props.open,\n val => {\n visible.value = val;\n if (val) {\n leftSearch.value = '';\n rightSearch.value = '';\n initData();\n }\n },\n);\n\nwatch(visible, val => {\n emit('update:open', val);\n});\n\nconst initData = () => {\n // 根据 viewSearchConfig 和 searchConfig 初始化右侧数据\n const configMap = new Map();\n props.searchConfig.forEach(item => {\n configMap.set(item.field_name, item);\n });\n\n const selectedFields: SearchConfig[] = [];\n\n if (props.viewSearchConfig && Object.keys(props.viewSearchConfig).length > 0) {\n // 先处理 viewSearchConfig 中已有的配置\n Object.keys(props.viewSearchConfig).forEach(fieldName => {\n const viewItem = props.viewSearchConfig[fieldName];\n if (viewItem.checked && configMap.has(fieldName)) {\n selectedFields.push({\n ...configMap.get(fieldName),\n order: viewItem.order ?? 0,\n });\n }\n });\n // 排序\n selectedFields.sort((a, b) => (a.order ?? 0) - (b.order ?? 0));\n } else {\n // 当 viewSearchConfig 为空时,所有 item.checked !== false 的字段都是选中字段\n props.searchConfig.forEach((item, index) => {\n if (item.checked !== false) {\n selectedFields.push({\n ...item,\n order: index + 1,\n });\n }\n });\n }\n\n rightData.value = cloneDeep(selectedFields);\n\n leftSelectedRowKeys.value = [];\n rightSelectedRowKeys.value = [];\n};\n\nconst leftData = computed(() => {\n const selectedKeys = new Set(rightData.value.map(item => item.field_name));\n const groups: Record<string, any[]> = {};\n const noGroup: any[] = [];\n\n props.searchConfig.forEach(item => {\n const itemData = {\n ...item,\n is_selected: selectedKeys.has(item.field_name),\n };\n if (item.group_name) {\n if (!groups[item.group_name]) {\n groups[item.group_name] = [];\n }\n groups[item.group_name].push(itemData);\n } else {\n noGroup.push(itemData);\n }\n });\n\n const result: any[] = [];\n Object.keys(groups).forEach(groupName => {\n result.push({\n field_name: `group_${groupName}`,\n label: groupName,\n is_group: true,\n children: groups[groupName],\n });\n });\n\n return [...result, ...noGroup];\n});\n\nconst filteredLeftData = computed(() => {\n if (!leftSearch.value) return leftData.value;\n const search = leftSearch.value.toLowerCase();\n\n const filterNode = (nodes: any[]) => {\n return nodes.reduce((acc: any[], node: any) => {\n const matchSelf =\n node.label?.toLowerCase().includes(search) ||\n node.field_name?.toLowerCase().includes(search);\n\n if (node.children) {\n const filteredChildren = filterNode(node.children);\n if (filteredChildren.length > 0) {\n acc.push({ ...node, children: filteredChildren });\n } else if (matchSelf) {\n acc.push({ ...node, children: [] });\n }\n } else if (matchSelf) {\n acc.push(node);\n }\n return acc;\n }, []);\n };\n\n return filterNode(leftData.value);\n});\n\nconst filteredRightData = computed(() => {\n if (!rightSearch.value) return rightData.value;\n const search = rightSearch.value.toLowerCase();\n return rightData.value.filter(\n item =>\n item.label?.toLowerCase().includes(search) || item.field_name?.toLowerCase().includes(search),\n );\n});\n\nconst leftRowSelection = {\n onChange: (selectedRowKeys: string[]) => {\n leftSelectedRowKeys.value = selectedRowKeys;\n },\n getCheckboxProps: (record: any) => ({\n disabled: record.is_group || record.is_selected,\n }),\n};\n\nconst rightRowSelection = {\n onChange: (selectedRowKeys: string[]) => {\n rightSelectedRowKeys.value = selectedRowKeys;\n },\n};\n\nconst moveToRight = () => {\n const selectedKeys = new Set(leftSelectedRowKeys.value);\n const toMove: SearchConfig[] = [];\n\n // 遍历所有 searchConfig,按原始顺序找到匹配项\n props.searchConfig.forEach(item => {\n if (selectedKeys.has(item.field_name)) {\n toMove.push(item);\n }\n });\n\n if (toMove.length > 0) {\n rightData.value = [...rightData.value, ...cloneDeep(toMove)];\n }\n leftSelectedRowKeys.value = [];\n};\n\nconst moveToLeft = () => {\n rightData.value = rightData.value.filter(\n item => !rightSelectedRowKeys.value.includes(item.field_name),\n );\n rightSelectedRowKeys.value = [];\n};\n\nconst onRowDragEnd = ({ oldIndex, newIndex }) => {\n const target = rightData.value.splice(oldIndex, 1)[0];\n rightData.value.splice(newIndex, 0, target);\n};\n\nconst handleOk = () => {\n const result: Record<string, ViewSearchItem> = {};\n\n // 处理所有字段,默认为未选中\n props.searchConfig.forEach(item => {\n result[item.field_name] = {\n checked: false,\n order: 0,\n };\n });\n\n // 更新已选中的字段\n rightData.value.forEach((item, index) => {\n result[item.field_name] = {\n checked: true,\n order: index + 1,\n };\n });\n\n emit('change', result);\n visible.value = false;\n};\n\nconst handleCancel = () => {\n visible.value = false;\n};\n</script>\n\n<style lang=\"less\" scoped>\n.search-config-container {\n display: flex;\n align-items: center;\n gap: 16px;\n height: 70vh;\n .table-wrapper {\n width: 450px;\n border: 1px solid #f0f0f0;\n border-radius: 4px;\n height: 100%;\n display: flex;\n flex-direction: column;\n overflow: auto;\n\n .table-title {\n padding: 8px 12px;\n background: #fafafa;\n border-bottom: 1px solid #f0f0f0;\n font-weight: bold;\n }\n }\n\n .middle-btns {\n display: flex;\n flex-direction: column;\n gap: 16px;\n }\n}\n</style>\n","<template>\n <a-modal\n :title=\"$t('设置搜索字段')\"\n v-model:open=\"visible\"\n width=\"1000px\"\n @ok=\"handleOk\"\n @cancel=\"handleCancel\"\n >\n <div class=\"search-config-container\">\n <div class=\"table-wrapper left-table\">\n <div class=\"table-title\">\n {{ $t('所有字段') }}\n <a-input\n v-model:value=\"leftSearch\"\n size=\"small\"\n :placeholder=\"$t('搜索标签/字段名')\"\n style=\"margin-top: 8px\"\n allow-clear\n />\n </div>\n <s-table\n :columns=\"leftColumns\"\n :data-source=\"filteredLeftData\"\n :pagination=\"false\"\n :row-selection=\"leftRowSelection\"\n v-model:selectedRowKeys=\"leftSelectedRowKeys\"\n row-key=\"field_name\"\n size=\"small\"\n :row-class-name=\"record => (record.is_selected ? 'row-selected' : '')\"\n expand-row-by-click\n >\n <template #bodyCell=\"{ column, record }\">\n <template v-if=\"column.dataIndex === 'label'\">\n <span\n :style=\"{\n color: record.is_selected ? '#ccc' : 'inherit',\n }\"\n >\n {{ record.label }}\n </span>\n </template>\n </template>\n </s-table>\n </div>\n\n <div class=\"middle-btns\">\n <a-button\n type=\"primary\"\n shape=\"circle\"\n :disabled=\"leftSelectedRowKeys.length === 0\"\n @click=\"moveToRight\"\n >\n <template #icon><RightOutlined /></template>\n </a-button>\n <a-button\n type=\"primary\"\n shape=\"circle\"\n :disabled=\"rightSelectedRowKeys.length === 0\"\n @click=\"moveToLeft\"\n >\n <template #icon><LeftOutlined /></template>\n </a-button>\n </div>\n\n <div class=\"table-wrapper right-table\">\n <div class=\"table-title\">\n {{ $t('已选字段') }}\n <a-input\n v-model:value=\"rightSearch\"\n size=\"small\"\n :placeholder=\"$t('搜索标签/字段名')\"\n style=\"margin-top: 8px\"\n allow-clear\n />\n </div>\n <s-table\n :columns=\"rightColumns\"\n :data-source=\"filteredRightData\"\n :pagination=\"false\"\n :row-selection=\"rightRowSelection\"\n v-model:selectedRowKeys=\"rightSelectedRowKeys\"\n row-key=\"field_name\"\n size=\"small\"\n @row-drag-end=\"onRowDragEnd\"\n />\n </div>\n </div>\n </a-modal>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, computed, watch, PropType } from 'vue';\nimport { useI18n } from 'vue-i18n';\nimport { RightOutlined, LeftOutlined } from '@ant-design/icons-vue';\nimport { SearchConfig, ViewSearchItem } from '../typing';\nimport { cloneDeep } from 'lodash';\n\nconst props = defineProps({\n open: {\n type: Boolean,\n default: false,\n },\n searchConfig: {\n type: Array as PropType<SearchConfig[]>,\n default: () => [],\n },\n viewSearchConfig: {\n type: Object as PropType<Record<string, ViewSearchItem>>,\n default: () => ({}),\n },\n});\n\nconst emit = defineEmits(['update:open', 'change']);\n\nconst { t } = useI18n();\n\nconst visible = ref(false);\nconst leftSearch = ref('');\nconst rightSearch = ref('');\nconst leftSelectedRowKeys = ref<string[]>([]);\nconst rightSelectedRowKeys = ref<string[]>([]);\nconst rightData = ref<SearchConfig[]>([]);\n\nconst leftColumns = [\n {\n title: t('字段名称'),\n dataIndex: 'label',\n key: 'label',\n width: 250,\n ellipsis: true,\n },\n];\n\nconst rightColumns = computed(() => {\n const columns: any = [\n {\n title: t('字段名称'),\n dataIndex: 'label',\n key: 'label',\n rowDrag: true,\n width: 150,\n ellipsis: true,\n },\n ];\n if (filteredRightData.value.length > 0) {\n if (filteredRightData.value.some(item => item.group_name)) {\n columns.push({\n title: t('分组'),\n dataIndex: 'group_name',\n key: 'group_name',\n width: 150,\n ellipsis: true,\n });\n }\n }\n return columns;\n});\n\nwatch(\n () => props.open,\n val => {\n visible.value = val;\n if (val) {\n leftSearch.value = '';\n rightSearch.value = '';\n initData();\n }\n },\n);\n\nwatch(visible, val => {\n emit('update:open', val);\n});\n\nconst initData = () => {\n // 根据 viewSearchConfig 和 searchConfig 初始化右侧数据\n const configMap = new Map();\n props.searchConfig.forEach(item => {\n configMap.set(item.field_name, item);\n });\n\n const selectedFields: SearchConfig[] = [];\n\n if (props.viewSearchConfig && Object.keys(props.viewSearchConfig).length > 0) {\n // 先处理 viewSearchConfig 中已有的配置\n Object.keys(props.viewSearchConfig).forEach(fieldName => {\n const viewItem = props.viewSearchConfig[fieldName];\n if (viewItem.checked && configMap.has(fieldName)) {\n selectedFields.push({\n ...configMap.get(fieldName),\n order: viewItem.order ?? 0,\n });\n }\n });\n // 排序\n selectedFields.sort((a, b) => (a.order ?? 0) - (b.order ?? 0));\n } else {\n // 当 viewSearchConfig 为空时,所有 item.checked !== false 的字段都是选中字段\n props.searchConfig.forEach((item, index) => {\n if (item.checked !== false) {\n selectedFields.push({\n ...item,\n order: index + 1,\n });\n }\n });\n }\n\n rightData.value = cloneDeep(selectedFields);\n\n leftSelectedRowKeys.value = [];\n rightSelectedRowKeys.value = [];\n};\n\nconst leftData = computed(() => {\n const selectedKeys = new Set(rightData.value.map(item => item.field_name));\n const groups: Record<string, any[]> = {};\n const noGroup: any[] = [];\n\n props.searchConfig.forEach(item => {\n const itemData = {\n ...item,\n is_selected: selectedKeys.has(item.field_name),\n };\n if (item.group_name) {\n if (!groups[item.group_name]) {\n groups[item.group_name] = [];\n }\n groups[item.group_name].push(itemData);\n } else {\n noGroup.push(itemData);\n }\n });\n\n const result: any[] = [];\n Object.keys(groups).forEach(groupName => {\n result.push({\n field_name: `group_${groupName}`,\n label: groupName,\n is_group: true,\n children: groups[groupName],\n });\n });\n\n return [...result, ...noGroup];\n});\n\nconst filteredLeftData = computed(() => {\n if (!leftSearch.value) return leftData.value;\n const search = leftSearch.value.toLowerCase();\n\n const filterNode = (nodes: any[]) => {\n return nodes.reduce((acc: any[], node: any) => {\n const matchSelf =\n node.label?.toLowerCase().includes(search) ||\n node.field_name?.toLowerCase().includes(search);\n\n if (node.children) {\n const filteredChildren = filterNode(node.children);\n if (filteredChildren.length > 0) {\n acc.push({ ...node, children: filteredChildren });\n } else if (matchSelf) {\n acc.push({ ...node, children: [] });\n }\n } else if (matchSelf) {\n acc.push(node);\n }\n return acc;\n }, []);\n };\n\n return filterNode(leftData.value);\n});\n\nconst filteredRightData = computed(() => {\n if (!rightSearch.value) return rightData.value;\n const search = rightSearch.value.toLowerCase();\n return rightData.value.filter(\n item =>\n item.label?.toLowerCase().includes(search) || item.field_name?.toLowerCase().includes(search),\n );\n});\n\nconst leftRowSelection = {\n onChange: (selectedRowKeys: string[]) => {\n leftSelectedRowKeys.value = selectedRowKeys;\n },\n getCheckboxProps: (record: any) => ({\n disabled: record.is_group || record.is_selected,\n }),\n};\n\nconst rightRowSelection = {\n onChange: (selectedRowKeys: string[]) => {\n rightSelectedRowKeys.value = selectedRowKeys;\n },\n};\n\nconst moveToRight = () => {\n const selectedKeys = new Set(leftSelectedRowKeys.value);\n const toMove: SearchConfig[] = [];\n\n // 遍历所有 searchConfig,按原始顺序找到匹配项\n props.searchConfig.forEach(item => {\n if (selectedKeys.has(item.field_name)) {\n toMove.push(item);\n }\n });\n\n if (toMove.length > 0) {\n rightData.value = [...rightData.value, ...cloneDeep(toMove)];\n }\n leftSelectedRowKeys.value = [];\n};\n\nconst moveToLeft = () => {\n rightData.value = rightData.value.filter(\n item => !rightSelectedRowKeys.value.includes(item.field_name),\n );\n rightSelectedRowKeys.value = [];\n};\n\nconst onRowDragEnd = ({ oldIndex, newIndex }) => {\n const target = rightData.value.splice(oldIndex, 1)[0];\n rightData.value.splice(newIndex, 0, target);\n};\n\nconst handleOk = () => {\n const result: Record<string, ViewSearchItem> = {};\n\n // 处理所有字段,默认为未选中\n props.searchConfig.forEach(item => {\n result[item.field_name] = {\n checked: false,\n order: 0,\n };\n });\n\n // 更新已选中的字段\n rightData.value.forEach((item, index) => {\n result[item.field_name] = {\n checked: true,\n order: index + 1,\n };\n });\n\n emit('change', result);\n visible.value = false;\n};\n\nconst handleCancel = () => {\n visible.value = false;\n};\n</script>\n\n<style lang=\"less\" scoped>\n.search-config-container {\n display: flex;\n align-items: center;\n gap: 16px;\n height: 70vh;\n .table-wrapper {\n width: 450px;\n border: 1px solid #f0f0f0;\n border-radius: 4px;\n height: 100%;\n display: flex;\n flex-direction: column;\n overflow: auto;\n\n .table-title {\n padding: 8px 12px;\n background: #fafafa;\n border-bottom: 1px solid #f0f0f0;\n font-weight: bold;\n }\n }\n\n .middle-btns {\n display: flex;\n flex-direction: column;\n gap: 16px;\n }\n}\n</style>\n","<template>\n <a-form\n :layout=\"searchColumnCount > 0 ? 'horizontal' : 'inline'\"\n :class=\"{ 'search-form-grid-inner': searchColumnCount > 0 }\"\n >\n <template\n v-for=\"condition in dataSource\"\n :key=\"condition.field_name\"\n >\n <div\n v-if=\"condition.is_group\"\n class=\"search-field-group-title\"\n >\n {{ condition.label }}\n </div>\n <a-form-item v-else>\n <template #label>\n <span\n :title=\"condition.label\"\n class=\"search-item-label-text\"\n >\n {{ condition.label }}\n </span>\n </template>\n <a-input-group\n compact\n size=\"small\"\n >\n <a-select\n v-if=\"condition.operator_list.length > 0 && searchType === 'advanced'\"\n style=\"width: 100px\"\n :dropdownMatchSelectWidth=\"false\"\n :value=\"condition.operator\"\n @change=\"onChange(condition.field_name, 'operator', $event)\"\n size=\"small\"\n >\n <a-select-option\n v-for=\"item in condition.operator_list\"\n :value=\"item\"\n :key=\"item\"\n >\n <a-tooltip :title=\"operator_type_map[item]\">\n {{ operator_type_map[item] }}\n </a-tooltip>\n </a-select-option>\n </a-select>\n <template\n v-if=\"['is_or_not_blank_or_null', 'is_or_not_null'].includes(condition.operator)\"\n >\n <SmallTableSerarchField\n :is_show_label=\"false\"\n :label=\"condition.field_name\"\n :value=\"getValue(condition)\"\n :field=\"{\n ...condition,\n type: 'select',\n mode: 'default',\n format: 'choices',\n class_name: 'str',\n placeholder: $t('请选择是否为空'),\n }\"\n :formModel=\"formModel\"\n :options=\"is_or_not_blank_or_null_options\"\n :validateInfos=\"validateInfos\"\n @update:value=\"onChange(condition.field_name, 'value', $event)\"\n :field_width=\"condition.field_width\"\n />\n </template>\n <template\n v-else-if=\"condition.operator === 'between' || condition.operator === 'notbetween'\"\n >\n <template v-if=\"condition.type === 'datepicker'\">\n <SmallTableSerarchField\n :is_show_label=\"false\"\n :label=\"condition.field_name\"\n :value=\"getValue(condition)\"\n :field=\"{ ...condition, type: 'rangepicker', format: condition.dateFormat }\"\n :formModel=\"formModel\"\n :validateInfos=\"validateInfos\"\n :field_width=\"condition.field_width * 2\"\n @update:value=\"onChange(condition.field_name, 'value', $event)\"\n />\n </template>\n <template v-else-if=\"condition.type === 'monthpicker'\">\n <SmallTableSerarchField\n :is_show_label=\"false\"\n :label=\"condition.field_name\"\n :value=\"getValue(condition)\"\n :field=\"{\n ...condition,\n type: 'monthrangepicker',\n }\"\n :formModel=\"formModel\"\n :validateInfos=\"validateInfos\"\n :field_width=\"condition.field_width * 2\"\n @update:value=\"onChange(condition.field_name, 'value', $event)\"\n />\n </template>\n <template v-else>\n <SmallTableSerarchField\n :is_show_label=\"false\"\n :label=\"condition.field_name\"\n :value=\"condition.value?.[0]\"\n :field=\"condition\"\n :formModel=\"formModel\"\n :options=\"condition.options\"\n :validateInfos=\"validateInfos\"\n :field_width=\"condition.field_width\"\n @update:value=\"onChange(condition.field_name, 'value', $event, 0)\"\n />\n <span class=\"range\">~</span>\n <SmallTableSerarchField\n :is_show_label=\"false\"\n :label=\"condition.field_name\"\n :value=\"condition.value?.[1]\"\n :field=\"condition\"\n :formModel=\"formModel\"\n :options=\"condition.options\"\n :validateInfos=\"validateInfos\"\n :field_width=\"condition.field_width\"\n @update:value=\"onChange(condition.field_name, 'value', $event, 1)\"\n />\n </template>\n </template>\n <template v-else-if=\"condition.operator === '_eq'\">\n <SmallTableSerarchField\n :is_show_label=\"false\"\n :label=\"condition.field_name\"\n :value=\"getValue(condition)\"\n :field=\"{\n ...condition,\n type: 'select',\n mode: 'default',\n format: 'choices',\n class_name: 'str',\n placeholder: '',\n }\"\n :formModel=\"formModel\"\n :options=\"options_for_date_eq\"\n :validateInfos=\"validateInfos\"\n :field_width=\"condition.field_width\"\n @update:value=\"onChange(condition.field_name, 'value', $event)\"\n />\n </template>\n <template v-else-if=\"condition.type === 'datepicker' || condition.type === 'monthpicker'\">\n <SmallTableSerarchField\n :is_show_label=\"false\"\n :label=\"condition.field_name\"\n :value=\"getValue(condition)\"\n :field=\"{ ...condition, format: condition.dateFormat }\"\n :formModel=\"formModel\"\n :options=\"condition.options\"\n :validateInfos=\"validateInfos\"\n :field_width=\"condition.field_width\"\n @update:value=\"onChange(condition.field_name, 'value', $event)\"\n />\n </template>\n <template v-else>\n <SmallTableSerarchField\n :is_show_label=\"false\"\n :label=\"condition.field_name\"\n :value=\"getValue(condition)\"\n :field=\"{ ...condition, name: condition?.field_name }\"\n :formModel=\"formModel\"\n :options=\"condition.options\"\n :validateInfos=\"validateInfos\"\n :field_width=\"condition.field_width\"\n @update:value=\"onChange(condition.field_name, 'value', $event)\"\n />\n </template>\n </a-input-group>\n </a-form-item>\n </template>\n <div\n class=\"btn-content\"\n v-if=\"showQueryBtn && !autoRefreshOnSearchChange\"\n >\n <a-button\n size=\"small\"\n type=\"primary\"\n @click=\"handleRefresh\"\n >\n 查询\n </a-button>\n </div>\n </a-form>\n</template>\n\n<script setup lang=\"ts\">\nimport { cloneDeep, debounce } from 'lodash';\nimport { computed, PropType, ref } from 'vue';\nimport { useI18n } from 'vue-i18n';\nimport { SearchConditionItem, SearchConfig, SearchType, ViewSearchItem } from './typing';\nimport SmallTableSerarchField from 'liyu-pc-base/components/FormRender/SmallTableSerarchField.vue';\nimport { getParamsCount, operator_type_map, options_for_date_eq } from './utils';\nimport { isEmpty, isNotEmpty } from 'liyu-pc-base/utils/function';\n\ndefineOptions({\n name: 'SearchForm',\n});\n\nconst props = defineProps({\n searchConfig: {\n type: Array as PropType<SearchConfig[]>,\n required: true,\n },\n searchConditions: {\n type: Array as PropType<SearchConditionItem[]>,\n required: true,\n },\n viewSearchConfig: {\n type: Object as PropType<Record<string, ViewSearchItem>>,\n default: () => ({}),\n },\n searchType: {\n type: String as () => SearchType,\n default: 'advanced',\n },\n searchColumnCount: {\n type: Number,\n default: 0,\n },\n autoRefreshOnSearchChange: {\n type: Boolean,\n default: false,\n },\n eventBus: {\n type: Object as any,\n required: false,\n },\n showQueryBtn: {\n type: Boolean,\n default: false,\n },\n disabledShowSearchGroupName: {\n type: Boolean,\n default: false, // 是否显示搜索分组名称,默认不显示\n },\n});\n\nconst emit = defineEmits(['update:searchConditions', 'change']);\n\nconst { t } = useI18n();\nconst formModel = ref<Record<string, any>>({});\nconst validateInfos = ref({});\n\nconst is_or_not_blank_or_null_options = ref([\n { value: 'yes', label: t('is_or_not_blank_or_null.yes') },\n { value: 'no', label: t('is_or_not_blank_or_null.no') },\n]);\n\nconst dataSource = computed(() => {\n const searchConditionsMap: Record<string, any> = {};\n for (const condition of props.searchConditions) {\n searchConditionsMap[condition.field_name] = {\n value: condition.value,\n operator: condition.operator,\n };\n }\n\n const flatData = props.searchConfig\n ?.filter(item => {\n if (props.viewSearchConfig[item.field_name]) {\n return props.viewSearchConfig[item.field_name].checked !== false;\n } else {\n return item.checked !== false;\n }\n })\n ?.map(configItem => {\n const data = searchConditionsMap[configItem.field_name] || {\n operator: configItem.default_operator || 'eq',\n value: undefined,\n };\n let formValue = data.value;\n if (isNotEmpty(data.value)) {\n const paramsCount = getParamsCount(data.operator, configItem);\n if (paramsCount === 1 && formValue instanceof Array) {\n formValue = formValue[0];\n }\n }\n formModel.value[configItem.field_name] = formValue;\n return {\n ...configItem,\n value: data.value,\n operator: data.operator,\n model: 'default',\n _order: props.viewSearchConfig[configItem.field_name]?.order || 0,\n field_width: configItem.field_width || 165,\n };\n })\n .sort((a, b) => a._order - b._order);\n\n const groups: Record<string, any[]> = {};\n const orderList: any[] = [];\n\n flatData.forEach(item => {\n if (item.group_name) {\n if (!groups[item.group_name]) {\n groups[item.group_name] = [];\n orderList.push({\n field_name: `group_${item.group_name}`,\n label: item.group_name,\n is_group: true,\n _group_key: item.group_name,\n });\n }\n groups[item.group_name].push(item);\n } else {\n orderList.push(item);\n }\n });\n\n const finalResult: any[] = [];\n orderList.forEach(item => {\n if (item.is_group) {\n if (!props.disabledShowSearchGroupName) {\n finalResult.push(item);\n }\n finalResult.push(...groups[item._group_key]);\n } else {\n finalResult.push(item);\n }\n });\n\n return finalResult;\n});\n\nconst getValue = (configItemAndValue: any) => {\n const value_count = getParamsCount(configItemAndValue.operator, configItemAndValue);\n let value = configItemAndValue.value;\n if (value_count == 1) {\n if (value instanceof Array) {\n return value[0] || undefined;\n } else {\n return value || undefined;\n }\n } else if (value_count == 2) {\n if (value instanceof Array) {\n const [first, seconds] = value;\n return [first, seconds];\n } else if (value) {\n const first = value;\n return [first, null];\n } else {\n return [null, null];\n }\n } else {\n return value;\n }\n};\n\nconst delayRefresh = debounce(() => {\n props.eventBus.emit('refresh');\n}, 500);\n\nconst onChange = (\n field_name: string,\n type: 'value' | 'operator',\n newValue: any,\n array_index: number | undefined = undefined,\n) => {\n const conditions = cloneDeep(props.searchConditions);\n const configItem = props.searchConfig.find(item => item.field_name === field_name);\n let value: any;\n let operator: string;\n let condition: any = conditions.find(item => item.field_name === field_name);\n if (type === 'value') {\n if (condition) {\n operator = condition.operator;\n } else {\n operator = configItem?.default_operator || 'eq';\n }\n if (array_index !== undefined) {\n const value_count = getParamsCount(newValue, configItem);\n if (condition) {\n value = condition.value;\n if (isEmpty(value) || !(value instanceof Array)) {\n value = [];\n for (let i = 0; i < value_count; i++) {\n value.push(null);\n }\n }\n value[array_index] = newValue;\n } else {\n value = [];\n for (let i = 0; i < value_count; i++) {\n value.push(null);\n }\n value[array_index] = newValue;\n }\n } else {\n if (isNotEmpty(newValue) && !(newValue instanceof Array)) {\n newValue = [newValue];\n }\n value = newValue;\n }\n } else if (type === 'operator') {\n operator = newValue;\n const value_count = getParamsCount(newValue, configItem);\n if (value_count) {\n value = [];\n for (let i = 0; i < value_count; i++) {\n value.push(null);\n }\n } else {\n value = undefined;\n }\n }\n if (condition) {\n condition.operator = operator!;\n condition.value = value;\n } else {\n let format = 'input';\n let class_name = 'str';\n if (configItem) {\n format = configItem.format || 'input';\n class_name = configItem.class_name || 'str';\n }\n condition = {\n field_name: field_name,\n value,\n operator: operator!,\n format,\n class_name,\n };\n conditions.push(condition);\n }\n emit('update:searchConditions', conditions);\n emit('change', conditions);\n if (props.autoRefreshOnSearchChange) {\n delayRefresh();\n }\n};\n\nconst handleRefresh = () => {\n props.eventBus.emit('refresh');\n};\n</script>\n\n<style lang=\"less\" scoped>\n.search-field-group-title {\n font-weight: bold;\n padding: 8px 4px 4px 4px;\n margin-bottom: 4px;\n border-bottom: 1px solid #f0f0f0;\n color: var(--primary-color, #1890ff);\n display: flex;\n align-items: center;\n width: 100%;\n flex-basis: 100%;\n &:not(:first-child) {\n margin-top: 8px;\n }\n}\n.search-form-grid-inner {\n display: grid;\n grid-template-columns: repeat(var(--column-count), max-content 1fr);\n gap: 2px 8px;\n align-items: center;\n .search-field-group-title {\n grid-column: span calc(var(--column-count) * 2);\n &:not(:first-child) {\n margin-top: 8px;\n }\n }\n :deep(.ant-form-item) {\n display: contents;\n margin-right: 0;\n margin-bottom: 2px;\n .ant-form-item-row,\n .ant-form-item-label,\n .ant-form-item-control,\n .ant-form-item-control-input,\n .ant-form-item-control-input-content {\n display: contents;\n }\n }\n :deep(.ant-form-item-label) {\n justify-self: end;\n display: flex !important;\n align-items: center;\n max-width: 150px;\n .search-item-label-text {\n text-overflow: ellipsis;\n overflow: hidden;\n white-space: nowrap;\n padding-right: 8px;\n text-align: right;\n }\n }\n :deep(.ant-input-group) {\n display: flex !important;\n width: 100%;\n }\n .btn-content {\n grid-column: span calc(var(--column-count) * 2);\n }\n}\n.btn-content {\n padding: 4px;\n margin-left: auto;\n}\n.range {\n padding: 0 4px;\n}\n:deep(.ant-select-selection-placeholder) {\n overflow: hidden;\n width: 100%;\n}\n</style>\n","<template>\n <a-form\n :layout=\"searchColumnCount > 0 ? 'horizontal' : 'inline'\"\n :class=\"{ 'search-form-grid-inner': searchColumnCount > 0 }\"\n >\n <template\n v-for=\"condition in dataSource\"\n :key=\"condition.field_name\"\n >\n <div\n v-if=\"condition.is_group\"\n class=\"search-field-group-title\"\n >\n {{ condition.label }}\n </div>\n <a-form-item v-else>\n <template #label>\n <span\n :title=\"condition.label\"\n class=\"search-item-label-text\"\n >\n {{ condition.label }}\n </span>\n </template>\n <a-input-group\n compact\n size=\"small\"\n >\n <a-select\n v-if=\"condition.operator_list.length > 0 && searchType === 'advanced'\"\n style=\"width: 100px\"\n :dropdownMatchSelectWidth=\"false\"\n :value=\"condition.operator\"\n @change=\"onChange(condition.field_name, 'operator', $event)\"\n size=\"small\"\n >\n <a-select-option\n v-for=\"item in condition.operator_list\"\n :value=\"item\"\n :key=\"item\"\n >\n <a-tooltip :title=\"operator_type_map[item]\">\n {{ operator_type_map[item] }}\n </a-tooltip>\n </a-select-option>\n </a-select>\n <template\n v-if=\"['is_or_not_blank_or_null', 'is_or_not_null'].includes(condition.operator)\"\n >\n <SmallTableSerarchField\n :is_show_label=\"false\"\n :label=\"condition.field_name\"\n :value=\"getValue(condition)\"\n :field=\"{\n ...condition,\n type: 'select',\n mode: 'default',\n format: 'choices',\n class_name: 'str',\n placeholder: $t('请选择是否为空'),\n }\"\n :formModel=\"formModel\"\n :options=\"is_or_not_blank_or_null_options\"\n :validateInfos=\"validateInfos\"\n @update:value=\"onChange(condition.field_name, 'value', $event)\"\n :field_width=\"condition.field_width\"\n />\n </template>\n <template\n v-else-if=\"condition.operator === 'between' || condition.operator === 'notbetween'\"\n >\n <template v-if=\"condition.type === 'datepicker'\">\n <SmallTableSerarchField\n :is_show_label=\"false\"\n :label=\"condition.field_name\"\n :value=\"getValue(condition)\"\n :field=\"{ ...condition, type: 'rangepicker', format: condition.dateFormat }\"\n :formModel=\"formModel\"\n :validateInfos=\"validateInfos\"\n :field_width=\"condition.field_width * 2\"\n @update:value=\"onChange(condition.field_name, 'value', $event)\"\n />\n </template>\n <template v-else-if=\"condition.type === 'monthpicker'\">\n <SmallTableSerarchField\n :is_show_label=\"false\"\n :label=\"condition.field_name\"\n :value=\"getValue(condition)\"\n :field=\"{\n ...condition,\n type: 'monthrangepicker',\n }\"\n :formModel=\"formModel\"\n :validateInfos=\"validateInfos\"\n :field_width=\"condition.field_width * 2\"\n @update:value=\"onChange(condition.field_name, 'value', $event)\"\n />\n </template>\n <template v-else>\n <SmallTableSerarchField\n :is_show_label=\"false\"\n :label=\"condition.field_name\"\n :value=\"condition.value?.[0]\"\n :field=\"condition\"\n :formModel=\"formModel\"\n :options=\"condition.options\"\n :validateInfos=\"validateInfos\"\n :field_width=\"condition.field_width\"\n @update:value=\"onChange(condition.field_name, 'value', $event, 0)\"\n />\n <span class=\"range\">~</span>\n <SmallTableSerarchField\n :is_show_label=\"false\"\n :label=\"condition.field_name\"\n :value=\"condition.value?.[1]\"\n :field=\"condition\"\n :formModel=\"formModel\"\n :options=\"condition.options\"\n :validateInfos=\"validateInfos\"\n :field_width=\"condition.field_width\"\n @update:value=\"onChange(condition.field_name, 'value', $event, 1)\"\n />\n </template>\n </template>\n <template v-else-if=\"condition.operator === '_eq'\">\n <SmallTableSerarchField\n :is_show_label=\"false\"\n :label=\"condition.field_name\"\n :value=\"getValue(condition)\"\n :field=\"{\n ...condition,\n type: 'select',\n mode: 'default',\n format: 'choices',\n class_name: 'str',\n placeholder: '',\n }\"\n :formModel=\"formModel\"\n :options=\"options_for_date_eq\"\n :validateInfos=\"validateInfos\"\n :field_width=\"condition.field_width\"\n @update:value=\"onChange(condition.field_name, 'value', $event)\"\n />\n </template>\n <template v-else-if=\"condition.type === 'datepicker' || condition.type === 'monthpicker'\">\n <SmallTableSerarchField\n :is_show_label=\"false\"\n :label=\"condition.field_name\"\n :value=\"getValue(condition)\"\n :field=\"{ ...condition, format: condition.dateFormat }\"\n :formModel=\"formModel\"\n :options=\"condition.options\"\n :validateInfos=\"validateInfos\"\n :field_width=\"condition.field_width\"\n @update:value=\"onChange(condition.field_name, 'value', $event)\"\n />\n </template>\n <template v-else>\n <SmallTableSerarchField\n :is_show_label=\"false\"\n :label=\"condition.field_name\"\n :value=\"getValue(condition)\"\n :field=\"{ ...condition, name: condition?.field_name }\"\n :formModel=\"formModel\"\n :options=\"condition.options\"\n :validateInfos=\"validateInfos\"\n :field_width=\"condition.field_width\"\n @update:value=\"onChange(condition.field_name, 'value', $event)\"\n />\n </template>\n </a-input-group>\n </a-form-item>\n </template>\n <div\n class=\"btn-content\"\n v-if=\"showQueryBtn && !autoRefreshOnSearchChange\"\n >\n <a-button\n size=\"small\"\n type=\"primary\"\n @click=\"handleRefresh\"\n >\n 查询\n </a-button>\n </div>\n </a-form>\n</template>\n\n<script setup lang=\"ts\">\nimport { cloneDeep, debounce } from 'lodash';\nimport { computed, PropType, ref } from 'vue';\nimport { useI18n } from 'vue-i18n';\nimport { SearchConditionItem, SearchConfig, SearchType, ViewSearchItem } from './typing';\nimport SmallTableSerarchField from 'liyu-pc-base/components/FormRender/SmallTableSerarchField.vue';\nimport { getParamsCount, operator_type_map, options_for_date_eq } from './utils';\nimport { isEmpty, isNotEmpty } from 'liyu-pc-base/utils/function';\n\ndefineOptions({\n name: 'SearchForm',\n});\n\nconst props = defineProps({\n searchConfig: {\n type: Array as PropType<SearchConfig[]>,\n required: true,\n },\n searchConditions: {\n type: Array as PropType<SearchConditionItem[]>,\n required: true,\n },\n viewSearchConfig: {\n type: Object as PropType<Record<string, ViewSearchItem>>,\n default: () => ({}),\n },\n searchType: {\n type: String as () => SearchType,\n default: 'advanced',\n },\n searchColumnCount: {\n type: Number,\n default: 0,\n },\n autoRefreshOnSearchChange: {\n type: Boolean,\n default: false,\n },\n eventBus: {\n type: Object as any,\n required: false,\n },\n showQueryBtn: {\n type: Boolean,\n default: false,\n },\n disabledShowSearchGroupName: {\n type: Boolean,\n default: false, // 是否显示搜索分组名称,默认不显示\n },\n});\n\nconst emit = defineEmits(['update:searchConditions', 'change']);\n\nconst { t } = useI18n();\nconst formModel = ref<Record<string, any>>({});\nconst validateInfos = ref({});\n\nconst is_or_not_blank_or_null_options = ref([\n { value: 'yes', label: t('is_or_not_blank_or_null.yes') },\n { value: 'no', label: t('is_or_not_blank_or_null.no') },\n]);\n\nconst dataSource = computed(() => {\n const searchConditionsMap: Record<string, any> = {};\n for (const condition of props.searchConditions) {\n searchConditionsMap[condition.field_name] = {\n value: condition.value,\n operator: condition.operator,\n };\n }\n\n const flatData = props.searchConfig\n ?.filter(item => {\n if (props.viewSearchConfig[item.field_name]) {\n return props.viewSearchConfig[item.field_name].checked !== false;\n } else {\n return item.checked !== false;\n }\n })\n ?.map(configItem => {\n const data = searchConditionsMap[configItem.field_name] || {\n operator: configItem.default_operator || 'eq',\n value: undefined,\n };\n let formValue = data.value;\n if (isNotEmpty(data.value)) {\n const paramsCount = getParamsCount(data.operator, configItem);\n if (paramsCount === 1 && formValue instanceof Array) {\n formValue = formValue[0];\n }\n }\n formModel.value[configItem.field_name] = formValue;\n return {\n ...configItem,\n value: data.value,\n operator: data.operator,\n model: 'default',\n _order: props.viewSearchConfig[configItem.field_name]?.order || 0,\n field_width: configItem.field_width || 165,\n };\n })\n .sort((a, b) => a._order - b._order);\n\n const groups: Record<string, any[]> = {};\n const orderList: any[] = [];\n\n flatData.forEach(item => {\n if (item.group_name) {\n if (!groups[item.group_name]) {\n groups[item.group_name] = [];\n orderList.push({\n field_name: `group_${item.group_name}`,\n label: item.group_name,\n is_group: true,\n _group_key: item.group_name,\n });\n }\n groups[item.group_name].push(item);\n } else {\n orderList.push(item);\n }\n });\n\n const finalResult: any[] = [];\n orderList.forEach(item => {\n if (item.is_group) {\n if (!props.disabledShowSearchGroupName) {\n finalResult.push(item);\n }\n finalResult.push(...groups[item._group_key]);\n } else {\n finalResult.push(item);\n }\n });\n\n return finalResult;\n});\n\nconst getValue = (configItemAndValue: any) => {\n const value_count = getParamsCount(configItemAndValue.operator, configItemAndValue);\n let value = configItemAndValue.value;\n if (value_count == 1) {\n if (value instanceof Array) {\n return value[0] || undefined;\n } else {\n return value || undefined;\n }\n } else if (value_count == 2) {\n if (value instanceof Array) {\n const [first, seconds] = value;\n return [first, seconds];\n } else if (value) {\n const first = value;\n return [first, null];\n } else {\n return [null, null];\n }\n } else {\n return value;\n }\n};\n\nconst delayRefresh = debounce(() => {\n props.eventBus.emit('refresh');\n}, 500);\n\nconst onChange = (\n field_name: string,\n type: 'value' | 'operator',\n newValue: any,\n array_index: number | undefined = undefined,\n) => {\n const conditions = cloneDeep(props.searchConditions);\n const configItem = props.searchConfig.find(item => item.field_name === field_name);\n let value: any;\n let operator: string;\n let condition: any = conditions.find(item => item.field_name === field_name);\n if (type === 'value') {\n if (condition) {\n operator = condition.operator;\n } else {\n operator = configItem?.default_operator || 'eq';\n }\n if (array_index !== undefined) {\n const value_count = getParamsCount(newValue, configItem);\n if (condition) {\n value = condition.value;\n if (isEmpty(value) || !(value instanceof Array)) {\n value = [];\n for (let i = 0; i < value_count; i++) {\n value.push(null);\n }\n }\n value[array_index] = newValue;\n } else {\n value = [];\n for (let i = 0; i < value_count; i++) {\n value.push(null);\n }\n value[array_index] = newValue;\n }\n } else {\n if (isNotEmpty(newValue) && !(newValue instanceof Array)) {\n newValue = [newValue];\n }\n value = newValue;\n }\n } else if (type === 'operator') {\n operator = newValue;\n const value_count = getParamsCount(newValue, configItem);\n if (value_count) {\n value = [];\n for (let i = 0; i < value_count; i++) {\n value.push(null);\n }\n } else {\n value = undefined;\n }\n }\n if (condition) {\n condition.operator = operator!;\n condition.value = value;\n } else {\n let format = 'input';\n let class_name = 'str';\n if (configItem) {\n format = configItem.format || 'input';\n class_name = configItem.class_name || 'str';\n }\n condition = {\n field_name: field_name,\n value,\n operator: operator!,\n format,\n class_name,\n };\n conditions.push(condition);\n }\n emit('update:searchConditions', conditions);\n emit('change', conditions);\n if (props.autoRefreshOnSearchChange) {\n delayRefresh();\n }\n};\n\nconst handleRefresh = () => {\n props.eventBus.emit('refresh');\n};\n</script>\n\n<style lang=\"less\" scoped>\n.search-field-group-title {\n font-weight: bold;\n padding: 8px 4px 4px 4px;\n margin-bottom: 4px;\n border-bottom: 1px solid #f0f0f0;\n color: var(--primary-color, #1890ff);\n display: flex;\n align-items: center;\n width: 100%;\n flex-basis: 100%;\n &:not(:first-child) {\n margin-top: 8px;\n }\n}\n.search-form-grid-inner {\n display: grid;\n grid-template-columns: repeat(var(--column-count), max-content 1fr);\n gap: 2px 8px;\n align-items: center;\n .search-field-group-title {\n grid-column: span calc(var(--column-count) * 2);\n &:not(:first-child) {\n margin-top: 8px;\n }\n }\n :deep(.ant-form-item) {\n display: contents;\n margin-right: 0;\n margin-bottom: 2px;\n .ant-form-item-row,\n .ant-form-item-label,\n .ant-form-item-control,\n .ant-form-item-control-input,\n .ant-form-item-control-input-content {\n display: contents;\n }\n }\n :deep(.ant-form-item-label) {\n justify-self: end;\n display: flex !important;\n align-items: center;\n max-width: 150px;\n .search-item-label-text {\n text-overflow: ellipsis;\n overflow: hidden;\n white-space: nowrap;\n padding-right: 8px;\n text-align: right;\n }\n }\n :deep(.ant-input-group) {\n display: flex !important;\n width: 100%;\n }\n .btn-content {\n grid-column: span calc(var(--column-count) * 2);\n }\n}\n.btn-content {\n padding: 4px;\n margin-left: auto;\n}\n.range {\n padding: 0 4px;\n}\n:deep(.ant-select-selection-placeholder) {\n overflow: hidden;\n width: 100%;\n}\n</style>\n","<template>\n <span\n class=\"search-switch\"\n v-if=\"search_display_type !== 'show_no_hide'\"\n >\n <a-button\n v-if=\"!isShowForm\"\n type=\"link\"\n size=\"small\"\n @click=\"isShowForm = true\"\n >\n <span class=\"expand-btn\">{{ $t('展开') }}</span>\n </a-button>\n <div v-else>\n <a-button\n type=\"link\"\n size=\"small\"\n @click=\"isShowForm = false\"\n >\n {{ $t('隐藏') }}\n </a-button>\n <a-button\n type=\"text\"\n size=\"small\"\n @click=\"searchConfigVisible = true\"\n v-if=\"config?.sys_btn?.search_field_config !== false\"\n >\n <a-tooltip :title=\"$t('设置搜索字段')\">\n <SettingOutlined />\n </a-tooltip>\n </a-button>\n </div>\n </span>\n <search-config-modal\n v-model:open=\"searchConfigVisible\"\n :search-config=\"searchConfig\"\n :view-search-config=\"viewSearchConfig\"\n @change=\"handleSearchConfigChange\"\n />\n <search-summary\n v-if=\"!isShowForm\"\n :search-conditions=\"searchConditions\"\n :search-config=\"searchConfig\"\n :event-bus=\"eventBus\"\n :searchType=\"searchType\"\n @update:searchConditions=\"handleUpdateSearchConditions\"\n />\n <div\n v-if=\"isShowForm\"\n class=\"search-form-wraper\"\n :style=\"{\n '--column-count': searchColumnCount || 0,\n }\"\n >\n <SearchForm\n :searchConfig=\"searchConfig\"\n :searchConditions=\"searchConditions\"\n :viewSearchConfig=\"viewSearchConfig\"\n :searchType=\"searchType\"\n :searchColumnCount=\"searchColumnCount\"\n :autoRefreshOnSearchChange=\"autoRefreshOnSearchChange\"\n :eventBus=\"eventBus\"\n :showQueryBtn=\"!searchColumnCount\"\n :disabledShowSearchGroupName=\"disabledShowSearchGroupName\"\n @update:searchConditions=\"handleUpdateSearchConditions\"\n @change=\"handleSearchChange\"\n />\n </div>\n <div\n class=\"bottom-content\"\n v-if=\"searchColumnCount && isShowForm && !autoRefreshOnSearchChange\"\n >\n <a-button\n size=\"small\"\n type=\"primary\"\n @click=\"handleRefresh\"\n >\n 查询\n </a-button>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, onMounted, PropType, ref } from 'vue';\nimport { useI18n } from 'vue-i18n';\nimport searchSummary from './searchSummary.vue';\nimport SearchConfigModal from './tableConfig/searchConfig.vue';\nimport SearchForm from './SearchForm.vue';\nimport {\n SearchConditionItem,\n SearchConfig,\n SearchDisplayType,\n SearchType,\n ViewSearchItem,\n} from './typing';\nimport { useTableProState } from './utils';\n\ndefineOptions({\n name: 'Search',\n});\n\nconst props = defineProps({\n searchConfig: {\n type: Array as PropType<SearchConfig[]>,\n required: true,\n },\n searchConditions: {\n type: Array as PropType<SearchConditionItem[]>,\n required: true,\n },\n eventBus: {\n type: Object as any,\n required: false,\n },\n searchType: {\n type: String as () => SearchType,\n default: 'advanced',\n },\n searchDisplayType: {\n type: String as () => SearchDisplayType,\n default: 'hide',\n },\n searchColumnCount: {\n type: Number,\n default: 0,\n },\n viewSearchConfig: {\n type: Object as PropType<Record<string, ViewSearchItem>>,\n default: () => ({}),\n },\n autoRefreshOnSearchChange: {\n type: Boolean,\n default: false,\n },\n disabledShowSearchGroupName: {\n type: Boolean,\n default: false, // 是否显示搜索分组名称,默认不显示\n },\n});\n\nconst emit = defineEmits(['update:searchConditions', 'viewSearchConfigChange', 'change']);\n\nconst { t } = useI18n();\nconst isShowForm = ref(false);\nconst searchConfigVisible = ref(false);\nconst { config } = useTableProState();\n\nconst handleUpdateSearchConditions = (newConditions: Condition[]) => {\n emit('update:searchConditions', newConditions);\n};\n\nconst handleSearchChange = () => {\n emit('change');\n};\n\nconst handleRefresh = () => {\n props.eventBus.emit('refresh');\n};\n\nconst handleSearchConfigChange = (data: any) => {\n emit('viewSearchConfigChange', data);\n};\n\nconst search_display_type = computed(() => {\n return props.searchDisplayType || 'hide';\n});\n\nonMounted(() => {\n if (['show', 'show_no_hide'].includes(search_display_type.value)) {\n isShowForm.value = true;\n }\n});\n</script>\n\n<style lang=\"less\" scoped>\n.search-form-wraper {\n padding-left: 2px;\n padding-right: 2px;\n max-height: 300px;\n overflow-y: auto;\n}\n.search-switch {\n display: inline-block;\n line-height: 32px;\n height: 32px;\n}\n.bottom-content {\n display: flex;\n justify-content: flex-end;\n padding: 8px 26px 8px 8px;\n}\n</style>\n","<template>\n <span\n class=\"search-switch\"\n v-if=\"search_display_type !== 'show_no_hide'\"\n >\n <a-button\n v-if=\"!isShowForm\"\n type=\"link\"\n size=\"small\"\n @click=\"isShowForm = true\"\n >\n <span class=\"expand-btn\">{{ $t('展开') }}</span>\n </a-button>\n <div v-else>\n <a-button\n type=\"link\"\n size=\"small\"\n @click=\"isShowForm = false\"\n >\n {{ $t('隐藏') }}\n </a-button>\n <a-button\n type=\"text\"\n size=\"small\"\n @click=\"searchConfigVisible = true\"\n v-if=\"config?.sys_btn?.search_field_config !== false\"\n >\n <a-tooltip :title=\"$t('设置搜索字段')\">\n <SettingOutlined />\n </a-tooltip>\n </a-button>\n </div>\n </span>\n <search-config-modal\n v-model:open=\"searchConfigVisible\"\n :search-config=\"searchConfig\"\n :view-search-config=\"viewSearchConfig\"\n @change=\"handleSearchConfigChange\"\n />\n <search-summary\n v-if=\"!isShowForm\"\n :search-conditions=\"searchConditions\"\n :search-config=\"searchConfig\"\n :event-bus=\"eventBus\"\n :searchType=\"searchType\"\n @update:searchConditions=\"handleUpdateSearchConditions\"\n />\n <div\n v-if=\"isShowForm\"\n class=\"search-form-wraper\"\n :style=\"{\n '--column-count': searchColumnCount || 0,\n }\"\n >\n <SearchForm\n :searchConfig=\"searchConfig\"\n :searchConditions=\"searchConditions\"\n :viewSearchConfig=\"viewSearchConfig\"\n :searchType=\"searchType\"\n :searchColumnCount=\"searchColumnCount\"\n :autoRefreshOnSearchChange=\"autoRefreshOnSearchChange\"\n :eventBus=\"eventBus\"\n :showQueryBtn=\"!searchColumnCount\"\n :disabledShowSearchGroupName=\"disabledShowSearchGroupName\"\n @update:searchConditions=\"handleUpdateSearchConditions\"\n @change=\"handleSearchChange\"\n />\n </div>\n <div\n class=\"bottom-content\"\n v-if=\"searchColumnCount && isShowForm && !autoRefreshOnSearchChange\"\n >\n <a-button\n size=\"small\"\n type=\"primary\"\n @click=\"handleRefresh\"\n >\n 查询\n </a-button>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, onMounted, PropType, ref } from 'vue';\nimport { useI18n } from 'vue-i18n';\nimport searchSummary from './searchSummary.vue';\nimport SearchConfigModal from './tableConfig/searchConfig.vue';\nimport SearchForm from './SearchForm.vue';\nimport {\n SearchConditionItem,\n SearchConfig,\n SearchDisplayType,\n SearchType,\n ViewSearchItem,\n} from './typing';\nimport { useTableProState } from './utils';\n\ndefineOptions({\n name: 'Search',\n});\n\nconst props = defineProps({\n searchConfig: {\n type: Array as PropType<SearchConfig[]>,\n required: true,\n },\n searchConditions: {\n type: Array as PropType<SearchConditionItem[]>,\n required: true,\n },\n eventBus: {\n type: Object as any,\n required: false,\n },\n searchType: {\n type: String as () => SearchType,\n default: 'advanced',\n },\n searchDisplayType: {\n type: String as () => SearchDisplayType,\n default: 'hide',\n },\n searchColumnCount: {\n type: Number,\n default: 0,\n },\n viewSearchConfig: {\n type: Object as PropType<Record<string, ViewSearchItem>>,\n default: () => ({}),\n },\n autoRefreshOnSearchChange: {\n type: Boolean,\n default: false,\n },\n disabledShowSearchGroupName: {\n type: Boolean,\n default: false, // 是否显示搜索分组名称,默认不显示\n },\n});\n\nconst emit = defineEmits(['update:searchConditions', 'viewSearchConfigChange', 'change']);\n\nconst { t } = useI18n();\nconst isShowForm = ref(false);\nconst searchConfigVisible = ref(false);\nconst { config } = useTableProState();\n\nconst handleUpdateSearchConditions = (newConditions: Condition[]) => {\n emit('update:searchConditions', newConditions);\n};\n\nconst handleSearchChange = () => {\n emit('change');\n};\n\nconst handleRefresh = () => {\n props.eventBus.emit('refresh');\n};\n\nconst handleSearchConfigChange = (data: any) => {\n emit('viewSearchConfigChange', data);\n};\n\nconst search_display_type = computed(() => {\n return props.searchDisplayType || 'hide';\n});\n\nonMounted(() => {\n if (['show', 'show_no_hide'].includes(search_display_type.value)) {\n isShowForm.value = true;\n }\n});\n</script>\n\n<style lang=\"less\" scoped>\n.search-form-wraper {\n padding-left: 2px;\n padding-right: 2px;\n max-height: 300px;\n overflow-y: auto;\n}\n.search-switch {\n display: inline-block;\n line-height: 32px;\n height: 32px;\n}\n.bottom-content {\n display: flex;\n justify-content: flex-end;\n padding: 8px 26px 8px 8px;\n}\n</style>\n","<template>\n <span\n class=\"search-switch\"\n v-if=\"search_display_type !== 'show_no_hide'\"\n >\n <a-button\n v-if=\"!isShowForm\"\n type=\"link\"\n size=\"small\"\n @click=\"isShowForm = true\"\n >\n <span class=\"expand-btn\">{{ $t('展开') }}</span>\n </a-button>\n <a-button\n v-else\n type=\"link\"\n size=\"small\"\n @click=\"isShowForm = false\"\n >\n {{ $t('隐藏') }}\n </a-button>\n </span>\n <!-- 多分组模式:搜索摘要 -->\n <template v-if=\"!isShowForm\">\n <template\n v-for=\"(group, index) in searchGroups\"\n :key=\"group.id\"\n >\n <span\n class=\"group-or-separator\"\n v-if=\"index > 0\"\n >\n OR\n </span>\n <search-summary\n :search-conditions=\"group.conditions\"\n :search-config=\"searchConfig\"\n :event-bus=\"eventBus\"\n :searchType=\"searchType\"\n :showRefresh=\"index === searchGroups.length - 1\"\n @update:searchConditions=\"conditions => handleGroupSummaryUpdate(group.id, conditions)\"\n />\n </template>\n </template>\n <!-- 多分组模式:搜索表单 -->\n <div\n v-if=\"isShowForm\"\n class=\"search-groups-container\"\n >\n <div\n v-for=\"(group, index) in searchGroups\"\n :key=\"group.id\"\n class=\"search-group-item\"\n >\n <div class=\"search-group-header\">\n <span class=\"search-group-header-title\">{{ $t('分组') + ' ' + (index + 1) }}</span>\n <div class=\"search-group-actions\">\n <a-button\n type=\"text\"\n size=\"small\"\n @click=\"searchConfigVisibleMap[group.id] = true\"\n v-if=\"config?.sys_btn?.search_field_config !== false\"\n >\n <a-tooltip :title=\"$t('设置搜索字段')\">\n <SettingOutlined />\n </a-tooltip>\n </a-button>\n <a-button\n type=\"text\"\n size=\"small\"\n danger\n @click=\"handleRemoveGroup(group.id)\"\n v-if=\"searchGroups.length > 1\"\n >\n <a-tooltip :title=\"$t('删除分组')\">\n <DeleteOutlined />\n </a-tooltip>\n </a-button>\n </div>\n </div>\n <div\n class=\"search-form-wraper\"\n :style=\"{\n '--column-count': searchColumnCount || 0,\n }\"\n >\n <SearchForm\n :searchConfig=\"searchConfig\"\n :searchConditions=\"group.conditions\"\n :viewSearchConfig=\"group.viewSearchConfig\"\n :searchType=\"searchType\"\n :searchColumnCount=\"searchColumnCount\"\n :autoRefreshOnSearchChange=\"autoRefreshOnSearchChange\"\n :eventBus=\"eventBus\"\n :disabledShowSearchGroupName=\"disabledShowSearchGroupName\"\n @update:searchConditions=\"conditions => handleGroupConditionsUpdate(group.id, conditions)\"\n @change=\"handleGroupSearchChange\"\n />\n </div>\n <search-config-modal\n v-model:open=\"searchConfigVisibleMap[group.id]\"\n :search-config=\"searchConfig\"\n :view-search-config=\"group.viewSearchConfig\"\n @change=\"config => handleGroupViewSearchConfigChange(group.id, config)\"\n />\n </div>\n <a-button\n class=\"add-group-btn\"\n size=\"small\"\n type=\"dashed\"\n @click=\"handleAddGroup\"\n >\n <PlusOutlined />\n {{ $t('添加分组') }}\n </a-button>\n </div>\n <div\n class=\"bottom-content\"\n v-if=\"isShowForm && !autoRefreshOnSearchChange\"\n >\n <a-button\n size=\"small\"\n type=\"primary\"\n @click=\"handleRefresh\"\n >\n 查询\n </a-button>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, onMounted, PropType, ref } from 'vue';\nimport { useI18n } from 'vue-i18n';\nimport searchSummary from './searchSummary.vue';\nimport SearchConfigModal from './tableConfig/searchConfig.vue';\nimport SearchForm from './SearchForm.vue';\nimport { SearchConfig, SearchGroupItem, SearchType, ViewSearchItem } from './typing';\nimport { useTableProState } from './utils';\nimport { genID } from 'liyu-pc-base/utils/function.js';\n\ndefineOptions({\n name: 'SearchFormGroup',\n});\n\nconst props = defineProps({\n searchConfig: {\n type: Array as PropType<SearchConfig[]>,\n required: true,\n },\n searchGroups: {\n type: Array as PropType<SearchGroupItem[]>,\n required: true,\n },\n eventBus: {\n type: Object as any,\n required: false,\n },\n searchType: {\n type: String as () => SearchType,\n default: 'advanced',\n },\n searchDisplayType: {\n type: String,\n default: 'hide',\n },\n searchColumnCount: {\n type: Number,\n default: 0,\n },\n autoRefreshOnSearchChange: {\n type: Boolean,\n default: false,\n },\n disabledShowSearchGroupName: {\n type: Boolean,\n default: false, // 是否显示搜索分组名称,默认不显示\n },\n});\n\nconst emit = defineEmits(['update:searchGroups', 'change']);\n\nconst { t } = useI18n();\nconst isShowForm = ref(false);\nconst searchConfigVisibleMap = ref<Record<string, boolean>>({});\nconst { config } = useTableProState();\n\nconst handleRefresh = () => {\n props.eventBus.emit('refresh');\n};\n\nconst handleAddGroup = () => {\n const newGroups = [\n ...props.searchGroups,\n {\n id: genID(),\n conditions: [],\n viewSearchConfig: {},\n },\n ];\n emit('update:searchGroups', newGroups);\n emit('change');\n};\n\nconst handleRemoveGroup = (groupId: string) => {\n const newGroups = props.searchGroups.filter(g => g.id !== groupId);\n emit('update:searchGroups', newGroups);\n emit('change');\n if (props.autoRefreshOnSearchChange) {\n handleRefresh();\n }\n};\n\nconst handleGroupConditionsUpdate = (groupId: string, conditions: any[]) => {\n const newGroups = props.searchGroups.map(g => (g.id === groupId ? { ...g, conditions } : g));\n emit('update:searchGroups', newGroups);\n};\n\nconst handleGroupViewSearchConfigChange = (\n groupId: string,\n viewSearchConfig: Record<string, ViewSearchItem>,\n) => {\n const newGroups = props.searchGroups.map(g =>\n g.id === groupId ? { ...g, viewSearchConfig } : g,\n );\n emit('update:searchGroups', newGroups);\n emit('change');\n};\n\nconst handleGroupSearchChange = () => {\n emit('change');\n};\n\nconst handleGroupSummaryUpdate = (groupId: string, conditions: any[]) => {\n const newGroups = props.searchGroups.map(g => (g.id === groupId ? { ...g, conditions } : g));\n emit('update:searchGroups', newGroups);\n handleRefresh();\n};\n\nconst search_display_type = computed(() => {\n return props.searchDisplayType || 'hide';\n});\n\nonMounted(() => {\n if (['show', 'show_no_hide'].includes(search_display_type.value)) {\n isShowForm.value = true;\n }\n});\n</script>\n\n<style lang=\"less\" scoped>\n.search-switch {\n display: inline-block;\n line-height: 32px;\n height: 32px;\n}\n.search-groups-container {\n max-height: 300px;\n overflow-y: auto;\n padding: 4px 0;\n}\n.search-group-item {\n border: 1px solid #f0f0f0;\n border-radius: 4px;\n padding: 8px;\n margin-bottom: 8px;\n background: #fafafa;\n}\n.search-group-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 8px;\n padding-bottom: 4px;\n border-bottom: 1px dashed #e0e0e0;\n}\n.search-group-header-title {\n font-weight: bold;\n color: var(--primary-color, #1890ff);\n font-size: 13px;\n}\n.search-group-actions {\n display: flex;\n gap: 4px;\n}\n.search-form-wraper {\n padding-left: 2px;\n padding-right: 2px;\n}\n.add-group-btn {\n margin: 4px 0 8px 8px;\n}\n.bottom-content {\n display: flex;\n justify-content: flex-end;\n padding: 8px 26px 8px 8px;\n}\n.group-or-separator {\n display: inline-block;\n padding: 0 8px;\n color: #999;\n font-size: 12px;\n font-weight: bold;\n line-height: 32px;\n}\n</style>\n","<template>\n <span\n class=\"search-switch\"\n v-if=\"search_display_type !== 'show_no_hide'\"\n >\n <a-button\n v-if=\"!isShowForm\"\n type=\"link\"\n size=\"small\"\n @click=\"isShowForm = true\"\n >\n <span class=\"expand-btn\">{{ $t('展开') }}</span>\n </a-button>\n <a-button\n v-else\n type=\"link\"\n size=\"small\"\n @click=\"isShowForm = false\"\n >\n {{ $t('隐藏') }}\n </a-button>\n </span>\n <!-- 多分组模式:搜索摘要 -->\n <template v-if=\"!isShowForm\">\n <template\n v-for=\"(group, index) in searchGroups\"\n :key=\"group.id\"\n >\n <span\n class=\"group-or-separator\"\n v-if=\"index > 0\"\n >\n OR\n </span>\n <search-summary\n :search-conditions=\"group.conditions\"\n :search-config=\"searchConfig\"\n :event-bus=\"eventBus\"\n :searchType=\"searchType\"\n :showRefresh=\"index === searchGroups.length - 1\"\n @update:searchConditions=\"conditions => handleGroupSummaryUpdate(group.id, conditions)\"\n />\n </template>\n </template>\n <!-- 多分组模式:搜索表单 -->\n <div\n v-if=\"isShowForm\"\n class=\"search-groups-container\"\n >\n <div\n v-for=\"(group, index) in searchGroups\"\n :key=\"group.id\"\n class=\"search-group-item\"\n >\n <div class=\"search-group-header\">\n <span class=\"search-group-header-title\">{{ $t('分组') + ' ' + (index + 1) }}</span>\n <div class=\"search-group-actions\">\n <a-button\n type=\"text\"\n size=\"small\"\n @click=\"searchConfigVisibleMap[group.id] = true\"\n v-if=\"config?.sys_btn?.search_field_config !== false\"\n >\n <a-tooltip :title=\"$t('设置搜索字段')\">\n <SettingOutlined />\n </a-tooltip>\n </a-button>\n <a-button\n type=\"text\"\n size=\"small\"\n danger\n @click=\"handleRemoveGroup(group.id)\"\n v-if=\"searchGroups.length > 1\"\n >\n <a-tooltip :title=\"$t('删除分组')\">\n <DeleteOutlined />\n </a-tooltip>\n </a-button>\n </div>\n </div>\n <div\n class=\"search-form-wraper\"\n :style=\"{\n '--column-count': searchColumnCount || 0,\n }\"\n >\n <SearchForm\n :searchConfig=\"searchConfig\"\n :searchConditions=\"group.conditions\"\n :viewSearchConfig=\"group.viewSearchConfig\"\n :searchType=\"searchType\"\n :searchColumnCount=\"searchColumnCount\"\n :autoRefreshOnSearchChange=\"autoRefreshOnSearchChange\"\n :eventBus=\"eventBus\"\n :disabledShowSearchGroupName=\"disabledShowSearchGroupName\"\n @update:searchConditions=\"conditions => handleGroupConditionsUpdate(group.id, conditions)\"\n @change=\"handleGroupSearchChange\"\n />\n </div>\n <search-config-modal\n v-model:open=\"searchConfigVisibleMap[group.id]\"\n :search-config=\"searchConfig\"\n :view-search-config=\"group.viewSearchConfig\"\n @change=\"config => handleGroupViewSearchConfigChange(group.id, config)\"\n />\n </div>\n <a-button\n class=\"add-group-btn\"\n size=\"small\"\n type=\"dashed\"\n @click=\"handleAddGroup\"\n >\n <PlusOutlined />\n {{ $t('添加分组') }}\n </a-button>\n </div>\n <div\n class=\"bottom-content\"\n v-if=\"isShowForm && !autoRefreshOnSearchChange\"\n >\n <a-button\n size=\"small\"\n type=\"primary\"\n @click=\"handleRefresh\"\n >\n 查询\n </a-button>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, onMounted, PropType, ref } from 'vue';\nimport { useI18n } from 'vue-i18n';\nimport searchSummary from './searchSummary.vue';\nimport SearchConfigModal from './tableConfig/searchConfig.vue';\nimport SearchForm from './SearchForm.vue';\nimport { SearchConfig, SearchGroupItem, SearchType, ViewSearchItem } from './typing';\nimport { useTableProState } from './utils';\nimport { genID } from 'liyu-pc-base/utils/function.js';\n\ndefineOptions({\n name: 'SearchFormGroup',\n});\n\nconst props = defineProps({\n searchConfig: {\n type: Array as PropType<SearchConfig[]>,\n required: true,\n },\n searchGroups: {\n type: Array as PropType<SearchGroupItem[]>,\n required: true,\n },\n eventBus: {\n type: Object as any,\n required: false,\n },\n searchType: {\n type: String as () => SearchType,\n default: 'advanced',\n },\n searchDisplayType: {\n type: String,\n default: 'hide',\n },\n searchColumnCount: {\n type: Number,\n default: 0,\n },\n autoRefreshOnSearchChange: {\n type: Boolean,\n default: false,\n },\n disabledShowSearchGroupName: {\n type: Boolean,\n default: false, // 是否显示搜索分组名称,默认不显示\n },\n});\n\nconst emit = defineEmits(['update:searchGroups', 'change']);\n\nconst { t } = useI18n();\nconst isShowForm = ref(false);\nconst searchConfigVisibleMap = ref<Record<string, boolean>>({});\nconst { config } = useTableProState();\n\nconst handleRefresh = () => {\n props.eventBus.emit('refresh');\n};\n\nconst handleAddGroup = () => {\n const newGroups = [\n ...props.searchGroups,\n {\n id: genID(),\n conditions: [],\n viewSearchConfig: {},\n },\n ];\n emit('update:searchGroups', newGroups);\n emit('change');\n};\n\nconst handleRemoveGroup = (groupId: string) => {\n const newGroups = props.searchGroups.filter(g => g.id !== groupId);\n emit('update:searchGroups', newGroups);\n emit('change');\n if (props.autoRefreshOnSearchChange) {\n handleRefresh();\n }\n};\n\nconst handleGroupConditionsUpdate = (groupId: string, conditions: any[]) => {\n const newGroups = props.searchGroups.map(g => (g.id === groupId ? { ...g, conditions } : g));\n emit('update:searchGroups', newGroups);\n};\n\nconst handleGroupViewSearchConfigChange = (\n groupId: string,\n viewSearchConfig: Record<string, ViewSearchItem>,\n) => {\n const newGroups = props.searchGroups.map(g =>\n g.id === groupId ? { ...g, viewSearchConfig } : g,\n );\n emit('update:searchGroups', newGroups);\n emit('change');\n};\n\nconst handleGroupSearchChange = () => {\n emit('change');\n};\n\nconst handleGroupSummaryUpdate = (groupId: string, conditions: any[]) => {\n const newGroups = props.searchGroups.map(g => (g.id === groupId ? { ...g, conditions } : g));\n emit('update:searchGroups', newGroups);\n handleRefresh();\n};\n\nconst search_display_type = computed(() => {\n return props.searchDisplayType || 'hide';\n});\n\nonMounted(() => {\n if (['show', 'show_no_hide'].includes(search_display_type.value)) {\n isShowForm.value = true;\n }\n});\n</script>\n\n<style lang=\"less\" scoped>\n.search-switch {\n display: inline-block;\n line-height: 32px;\n height: 32px;\n}\n.search-groups-container {\n max-height: 300px;\n overflow-y: auto;\n padding: 4px 0;\n}\n.search-group-item {\n border: 1px solid #f0f0f0;\n border-radius: 4px;\n padding: 8px;\n margin-bottom: 8px;\n background: #fafafa;\n}\n.search-group-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 8px;\n padding-bottom: 4px;\n border-bottom: 1px dashed #e0e0e0;\n}\n.search-group-header-title {\n font-weight: bold;\n color: var(--primary-color, #1890ff);\n font-size: 13px;\n}\n.search-group-actions {\n display: flex;\n gap: 4px;\n}\n.search-form-wraper {\n padding-left: 2px;\n padding-right: 2px;\n}\n.add-group-btn {\n margin: 4px 0 8px 8px;\n}\n.bottom-content {\n display: flex;\n justify-content: flex-end;\n padding: 8px 26px 8px 8px;\n}\n.group-or-separator {\n display: inline-block;\n padding: 0 8px;\n color: #999;\n font-size: 12px;\n font-weight: bold;\n line-height: 32px;\n}\n</style>\n","<template>\n <div style=\"padding: 8px\">\n <a-input-group\n compact\n size=\"small\"\n style=\"margin-bottom: 8px; display: flex\"\n >\n <a-select\n v-if=\"condition.operator_list?.length > 0 && searchType === 'advanced'\"\n :dropdownMatchSelectWidth=\"false\"\n :value=\"condition.operator\"\n @change=\"onChange('operator', $event)\"\n size=\"small\"\n >\n <a-select-option\n v-for=\"item in condition.operator_list\"\n :value=\"item\"\n :key=\"item\"\n >\n {{ operator_type_map[item] }}\n </a-select-option>\n </a-select>\n <template v-if=\"['is_or_not_blank_or_null', 'is_or_not_null'].includes(condition.operator)\">\n <SmallTableSerarchField\n :is_show_label=\"false\"\n :label=\"column.dataIndex\"\n :value=\"fieldValue\"\n :field=\"{\n ...condition,\n type: 'select',\n mode: 'default',\n format: 'choices',\n class_name: 'str',\n placeholder: '',\n }\"\n :formModel=\"formModel\"\n :options=\"is_or_not_blank_or_null_options\"\n :validateInfos=\"validateInfos\"\n @update:value=\"onChange('value', $event)\"\n :field_width=\"condition.field_width || 155\"\n />\n </template>\n <template v-else-if=\"['between', 'notbetween'].includes(condition.operator)\">\n <template v-if=\"condition.type === 'datepicker'\">\n <SmallTableSerarchField\n :is_show_label=\"false\"\n :label=\"column.dataIndex\"\n :value=\"fieldValue\"\n :field=\"{\n ...condition,\n type: 'rangepicker',\n format: condition.dateFormat,\n }\"\n :formModel=\"formModel\"\n :validateInfos=\"validateInfos\"\n :field_width=\"condition.field_width ? condition.field_width * 2 : 320\"\n @update:value=\"onChange('value', $event)\"\n />\n </template>\n <template v-else-if=\"condition.type === 'monthpicker'\">\n <SmallTableSerarchField\n :is_show_label=\"false\"\n :label=\"column.dataIndex\"\n :value=\"fieldValue\"\n :field=\"{\n ...condition,\n type: 'monthrangepicker',\n }\"\n :formModel=\"formModel\"\n :validateInfos=\"validateInfos\"\n :field_width=\"condition.field_width ? condition.field_width * 2 : 320\"\n @update:value=\"onChange('value', $event)\"\n />\n </template>\n <template v-else>\n <SmallTableSerarchField\n :is_show_label=\"false\"\n :label=\"column.dataIndex\"\n :value=\"fieldValue?.[0]\"\n :field=\"condition\"\n :formModel=\"formModel\"\n :options=\"condition.options\"\n :validateInfos=\"validateInfos\"\n :field_width=\"condition.field_width || 155\"\n @update:value=\"onChange('value', $event, 0)\"\n />\n <span\n class=\"range\"\n style=\"padding: 0 4px; line-height: 24px\"\n >\n ~\n </span>\n <SmallTableSerarchField\n :is_show_label=\"false\"\n :label=\"column.dataIndex\"\n :value=\"fieldValue?.[1]\"\n :field=\"condition\"\n :formModel=\"formModel\"\n :options=\"condition.options\"\n :validateInfos=\"validateInfos\"\n :field_width=\"condition.field_width || 155\"\n @update:value=\"onChange('value', $event, 1)\"\n />\n </template>\n </template>\n <template v-else-if=\"condition.operator === '_eq'\">\n <SmallTableSerarchField\n :is_show_label=\"false\"\n :label=\"column.dataIndex\"\n :value=\"fieldValue\"\n :field=\"{\n ...condition,\n type: 'select',\n mode: 'default',\n format: 'choices',\n class_name: 'str',\n placeholder: '',\n }\"\n :formModel=\"formModel\"\n :options=\"options_for_date_eq\"\n :validateInfos=\"validateInfos\"\n :field_width=\"condition.field_width || 155\"\n @update:value=\"onChange('value', $event)\"\n />\n </template>\n <template v-else-if=\"condition.type === 'datepicker' || condition.type === 'monthpicker'\">\n <SmallTableSerarchField\n :is_show_label=\"false\"\n :label=\"column.dataIndex\"\n :value=\"fieldValue\"\n :field=\"{ ...condition, format: condition.dateFormat }\"\n :formModel=\"formModel\"\n :options=\"condition.options\"\n :validateInfos=\"validateInfos\"\n :field_width=\"condition.field_width || 155\"\n @update:value=\"onChange('value', $event)\"\n />\n </template>\n <template v-else>\n <SmallTableSerarchField\n :is_show_label=\"false\"\n :label=\"column.dataIndex\"\n :value=\"fieldValue\"\n :field=\"{\n ...condition,\n name: column.dataIndex,\n }\"\n :formModel=\"formModel\"\n :options=\"condition.options\"\n :validateInfos=\"validateInfos\"\n :field_width=\"condition.field_width || 155\"\n @update:value=\"onChange('value', $event)\"\n />\n </template>\n </a-input-group>\n <div style=\"display: flex; justify-content: flex-end\">\n <a-button\n type=\"primary\"\n size=\"small\"\n style=\"width: 70px; margin-right: 8px\"\n @click=\"handleSearch\"\n >\n 查询\n </a-button>\n <a-button\n size=\"small\"\n style=\"width: 70px\"\n @click=\"handleReset\"\n >\n 重置\n </a-button>\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, PropType, ref } from 'vue';\nimport { useI18n } from 'vue-i18n';\nimport SmallTableSerarchField from 'liyu-pc-base/components/FormRender/SmallTableSerarchField.vue';\nimport { getParamsCount, operator_type_map, options_for_date_eq } from './utils';\nimport { Column, SearchConditionItem, SearchConfig, SearchType } from './typing';\nimport { isArray } from 'lodash';\nimport { ConditionOperator } from 'liyu-pc-base/api/typing';\n\nconst props = defineProps({\n column: {\n type: Object as PropType<Column>,\n required: true,\n },\n searchConfig: {\n type: Array as PropType<SearchConfig[]>,\n required: true,\n },\n searchConditions: {\n type: Array as PropType<SearchConditionItem[]>,\n required: true,\n },\n searchType: {\n type: String as PropType<SearchType>,\n default: 'advanced',\n },\n confirm: {\n type: Function as PropType<() => void>,\n required: true,\n },\n clearFilters: {\n type: Function as PropType<() => void>,\n required: true,\n },\n});\n\nconst emit = defineEmits(['search', 'reset', 'update:searchConditions']);\n\nconst { t } = useI18n();\nconst formModel = ref<Record<string, any>>({});\nconst validateInfos = ref({});\n\nconst is_or_not_blank_or_null_options = ref([\n { value: 'yes', label: t('is_or_not_blank_or_null.yes') },\n { value: 'no', label: t('is_or_not_blank_or_null.no') },\n]);\n\nconst condition = computed<any>(() => {\n const dataIndex = props.column.dataIndex;\n const currentCondition = props.searchConditions.find(item => item.field_name === dataIndex);\n const configItem = props.searchConfig?.find(item => item.field_name === dataIndex);\n if (currentCondition) {\n return {\n ...configItem,\n ...currentCondition,\n };\n }\n return {\n ...configItem,\n operator: configItem?.default_operator || 'eq',\n value: undefined,\n };\n});\n\nconst fieldValue = computed(() => {\n const dataIndex = props.column.dataIndex;\n const configItem = props.searchConfig?.find(item => item.field_name === dataIndex);\n if (!configItem) return undefined;\n const value_count = getParamsCount(condition.value.operator, configItem);\n let value = condition.value.value;\n if (value_count == 1) {\n if (value instanceof Array) {\n return value[0] || undefined;\n } else {\n return value || undefined;\n }\n } else if (value_count == 2) {\n if (value instanceof Array) {\n return [value[0], value[1]];\n } else if (value) {\n return [value, null];\n } else {\n return [null, null];\n }\n } else {\n return value;\n }\n});\n\nconst onChange = (type: 'value' | 'operator', newValue: any, array_index?: number) => {\n const field_name = props.column.dataIndex!;\n const conditions = [...props.searchConditions];\n const configItem = props.searchConfig.find(item => item.field_name === field_name);\n if (!configItem) return;\n let value: any;\n let operator: ConditionOperator;\n let currentCondition = conditions.find(item => item.field_name === field_name);\n\n if (type === 'value') {\n operator = currentCondition\n ? currentCondition.operator\n : (configItem?.default_operator as ConditionOperator) || 'eq';\n if (array_index !== undefined) {\n const value_count = getParamsCount(operator, configItem);\n value = currentCondition?.value;\n if (!value || !isArray(value)) {\n value = new Array(value_count).fill(null);\n } else {\n value = [...value];\n }\n value[array_index] = newValue;\n } else {\n value = isArray(newValue)\n ? newValue\n : newValue !== undefined && newValue !== null\n ? [newValue]\n : [];\n }\n } else {\n operator = newValue as ConditionOperator;\n const value_count = getParamsCount(newValue, configItem);\n value = value_count ? new Array(value_count).fill(null) : undefined;\n }\n\n if (currentCondition) {\n currentCondition.operator = operator;\n currentCondition.value = value;\n } else {\n conditions.push({\n field_name,\n value,\n operator: operator,\n format: configItem?.format || 'input',\n class_name: configItem?.class_name || 'str',\n });\n }\n\n formModel.value[field_name] = isArray(value) ? value[0] : value;\n emit('update:searchConditions', conditions);\n};\n\nconst handleSearch = () => {\n const dataIndex = props.column.dataIndex!;\n const activeCondition = props.searchConditions.find(item => item.field_name === dataIndex);\n let searchVal = '';\n if (activeCondition) {\n searchVal = isArray(activeCondition.value) ? activeCondition.value[0] : activeCondition.value;\n }\n emit('search', { confirm: props.confirm, dataIndex, value: searchVal });\n};\n\nconst handleReset = () => {\n emit('reset', { clearFilters: props.clearFilters, dataIndex: props.column.dataIndex });\n};\n</script>\n","<template>\n <div style=\"padding: 8px\">\n <a-input-group\n compact\n size=\"small\"\n style=\"margin-bottom: 8px; display: flex\"\n >\n <a-select\n v-if=\"condition.operator_list?.length > 0 && searchType === 'advanced'\"\n :dropdownMatchSelectWidth=\"false\"\n :value=\"condition.operator\"\n @change=\"onChange('operator', $event)\"\n size=\"small\"\n >\n <a-select-option\n v-for=\"item in condition.operator_list\"\n :value=\"item\"\n :key=\"item\"\n >\n {{ operator_type_map[item] }}\n </a-select-option>\n </a-select>\n <template v-if=\"['is_or_not_blank_or_null', 'is_or_not_null'].includes(condition.operator)\">\n <SmallTableSerarchField\n :is_show_label=\"false\"\n :label=\"column.dataIndex\"\n :value=\"fieldValue\"\n :field=\"{\n ...condition,\n type: 'select',\n mode: 'default',\n format: 'choices',\n class_name: 'str',\n placeholder: '',\n }\"\n :formModel=\"formModel\"\n :options=\"is_or_not_blank_or_null_options\"\n :validateInfos=\"validateInfos\"\n @update:value=\"onChange('value', $event)\"\n :field_width=\"condition.field_width || 155\"\n />\n </template>\n <template v-else-if=\"['between', 'notbetween'].includes(condition.operator)\">\n <template v-if=\"condition.type === 'datepicker'\">\n <SmallTableSerarchField\n :is_show_label=\"false\"\n :label=\"column.dataIndex\"\n :value=\"fieldValue\"\n :field=\"{\n ...condition,\n type: 'rangepicker',\n format: condition.dateFormat,\n }\"\n :formModel=\"formModel\"\n :validateInfos=\"validateInfos\"\n :field_width=\"condition.field_width ? condition.field_width * 2 : 320\"\n @update:value=\"onChange('value', $event)\"\n />\n </template>\n <template v-else-if=\"condition.type === 'monthpicker'\">\n <SmallTableSerarchField\n :is_show_label=\"false\"\n :label=\"column.dataIndex\"\n :value=\"fieldValue\"\n :field=\"{\n ...condition,\n type: 'monthrangepicker',\n }\"\n :formModel=\"formModel\"\n :validateInfos=\"validateInfos\"\n :field_width=\"condition.field_width ? condition.field_width * 2 : 320\"\n @update:value=\"onChange('value', $event)\"\n />\n </template>\n <template v-else>\n <SmallTableSerarchField\n :is_show_label=\"false\"\n :label=\"column.dataIndex\"\n :value=\"fieldValue?.[0]\"\n :field=\"condition\"\n :formModel=\"formModel\"\n :options=\"condition.options\"\n :validateInfos=\"validateInfos\"\n :field_width=\"condition.field_width || 155\"\n @update:value=\"onChange('value', $event, 0)\"\n />\n <span\n class=\"range\"\n style=\"padding: 0 4px; line-height: 24px\"\n >\n ~\n </span>\n <SmallTableSerarchField\n :is_show_label=\"false\"\n :label=\"column.dataIndex\"\n :value=\"fieldValue?.[1]\"\n :field=\"condition\"\n :formModel=\"formModel\"\n :options=\"condition.options\"\n :validateInfos=\"validateInfos\"\n :field_width=\"condition.field_width || 155\"\n @update:value=\"onChange('value', $event, 1)\"\n />\n </template>\n </template>\n <template v-else-if=\"condition.operator === '_eq'\">\n <SmallTableSerarchField\n :is_show_label=\"false\"\n :label=\"column.dataIndex\"\n :value=\"fieldValue\"\n :field=\"{\n ...condition,\n type: 'select',\n mode: 'default',\n format: 'choices',\n class_name: 'str',\n placeholder: '',\n }\"\n :formModel=\"formModel\"\n :options=\"options_for_date_eq\"\n :validateInfos=\"validateInfos\"\n :field_width=\"condition.field_width || 155\"\n @update:value=\"onChange('value', $event)\"\n />\n </template>\n <template v-else-if=\"condition.type === 'datepicker' || condition.type === 'monthpicker'\">\n <SmallTableSerarchField\n :is_show_label=\"false\"\n :label=\"column.dataIndex\"\n :value=\"fieldValue\"\n :field=\"{ ...condition, format: condition.dateFormat }\"\n :formModel=\"formModel\"\n :options=\"condition.options\"\n :validateInfos=\"validateInfos\"\n :field_width=\"condition.field_width || 155\"\n @update:value=\"onChange('value', $event)\"\n />\n </template>\n <template v-else>\n <SmallTableSerarchField\n :is_show_label=\"false\"\n :label=\"column.dataIndex\"\n :value=\"fieldValue\"\n :field=\"{\n ...condition,\n name: column.dataIndex,\n }\"\n :formModel=\"formModel\"\n :options=\"condition.options\"\n :validateInfos=\"validateInfos\"\n :field_width=\"condition.field_width || 155\"\n @update:value=\"onChange('value', $event)\"\n />\n </template>\n </a-input-group>\n <div style=\"display: flex; justify-content: flex-end\">\n <a-button\n type=\"primary\"\n size=\"small\"\n style=\"width: 70px; margin-right: 8px\"\n @click=\"handleSearch\"\n >\n 查询\n </a-button>\n <a-button\n size=\"small\"\n style=\"width: 70px\"\n @click=\"handleReset\"\n >\n 重置\n </a-button>\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, PropType, ref } from 'vue';\nimport { useI18n } from 'vue-i18n';\nimport SmallTableSerarchField from 'liyu-pc-base/components/FormRender/SmallTableSerarchField.vue';\nimport { getParamsCount, operator_type_map, options_for_date_eq } from './utils';\nimport { Column, SearchConditionItem, SearchConfig, SearchType } from './typing';\nimport { isArray } from 'lodash';\nimport { ConditionOperator } from 'liyu-pc-base/api/typing';\n\nconst props = defineProps({\n column: {\n type: Object as PropType<Column>,\n required: true,\n },\n searchConfig: {\n type: Array as PropType<SearchConfig[]>,\n required: true,\n },\n searchConditions: {\n type: Array as PropType<SearchConditionItem[]>,\n required: true,\n },\n searchType: {\n type: String as PropType<SearchType>,\n default: 'advanced',\n },\n confirm: {\n type: Function as PropType<() => void>,\n required: true,\n },\n clearFilters: {\n type: Function as PropType<() => void>,\n required: true,\n },\n});\n\nconst emit = defineEmits(['search', 'reset', 'update:searchConditions']);\n\nconst { t } = useI18n();\nconst formModel = ref<Record<string, any>>({});\nconst validateInfos = ref({});\n\nconst is_or_not_blank_or_null_options = ref([\n { value: 'yes', label: t('is_or_not_blank_or_null.yes') },\n { value: 'no', label: t('is_or_not_blank_or_null.no') },\n]);\n\nconst condition = computed<any>(() => {\n const dataIndex = props.column.dataIndex;\n const currentCondition = props.searchConditions.find(item => item.field_name === dataIndex);\n const configItem = props.searchConfig?.find(item => item.field_name === dataIndex);\n if (currentCondition) {\n return {\n ...configItem,\n ...currentCondition,\n };\n }\n return {\n ...configItem,\n operator: configItem?.default_operator || 'eq',\n value: undefined,\n };\n});\n\nconst fieldValue = computed(() => {\n const dataIndex = props.column.dataIndex;\n const configItem = props.searchConfig?.find(item => item.field_name === dataIndex);\n if (!configItem) return undefined;\n const value_count = getParamsCount(condition.value.operator, configItem);\n let value = condition.value.value;\n if (value_count == 1) {\n if (value instanceof Array) {\n return value[0] || undefined;\n } else {\n return value || undefined;\n }\n } else if (value_count == 2) {\n if (value instanceof Array) {\n return [value[0], value[1]];\n } else if (value) {\n return [value, null];\n } else {\n return [null, null];\n }\n } else {\n return value;\n }\n});\n\nconst onChange = (type: 'value' | 'operator', newValue: any, array_index?: number) => {\n const field_name = props.column.dataIndex!;\n const conditions = [...props.searchConditions];\n const configItem = props.searchConfig.find(item => item.field_name === field_name);\n if (!configItem) return;\n let value: any;\n let operator: ConditionOperator;\n let currentCondition = conditions.find(item => item.field_name === field_name);\n\n if (type === 'value') {\n operator = currentCondition\n ? currentCondition.operator\n : (configItem?.default_operator as ConditionOperator) || 'eq';\n if (array_index !== undefined) {\n const value_count = getParamsCount(operator, configItem);\n value = currentCondition?.value;\n if (!value || !isArray(value)) {\n value = new Array(value_count).fill(null);\n } else {\n value = [...value];\n }\n value[array_index] = newValue;\n } else {\n value = isArray(newValue)\n ? newValue\n : newValue !== undefined && newValue !== null\n ? [newValue]\n : [];\n }\n } else {\n operator = newValue as ConditionOperator;\n const value_count = getParamsCount(newValue, configItem);\n value = value_count ? new Array(value_count).fill(null) : undefined;\n }\n\n if (currentCondition) {\n currentCondition.operator = operator;\n currentCondition.value = value;\n } else {\n conditions.push({\n field_name,\n value,\n operator: operator,\n format: configItem?.format || 'input',\n class_name: configItem?.class_name || 'str',\n });\n }\n\n formModel.value[field_name] = isArray(value) ? value[0] : value;\n emit('update:searchConditions', conditions);\n};\n\nconst handleSearch = () => {\n const dataIndex = props.column.dataIndex!;\n const activeCondition = props.searchConditions.find(item => item.field_name === dataIndex);\n let searchVal = '';\n if (activeCondition) {\n searchVal = isArray(activeCondition.value) ? activeCondition.value[0] : activeCondition.value;\n }\n emit('search', { confirm: props.confirm, dataIndex, value: searchVal });\n};\n\nconst handleReset = () => {\n emit('reset', { clearFilters: props.clearFilters, dataIndex: props.column.dataIndex });\n};\n</script>\n","<template>\n <div class=\"columns-config-wrapper\">\n <a-input\n v-model:value=\"searchText\"\n :placeholder=\"$t('搜索列名/字段名')\"\n allow-clear\n style=\"margin-bottom: 8px\"\n />\n <s-table\n :columns=\"columnsConfig\"\n :rowHeight=\"30\"\n :data-source=\"filteredDataSource\"\n :row-selection=\"rowSelection\"\n v-model:selectedRowKeys=\"selectedRowKeys\"\n expand-row-by-click\n @row-drag-end=\"onRowDragEnd\"\n :row-key=\"'key'\"\n :pagination=\"false\"\n >\n <template #bodyCell=\"{ column, index, text, record }\">\n <template v-if=\"column.dataIndex == 'fixed'\">\n <a-radio-group\n v-if=\"!record?.is_children\"\n v-model:value=\"record.fixed\"\n size=\"small\"\n @change=\"change_fixed\"\n >\n <a-radio-button value=\"left\">{{ $t('左') }}</a-radio-button>\n <a-radio-button :value=\"undefined\">{{ $t('不固定') }}</a-radio-button>\n <a-radio-button value=\"right\">{{ $t('右') }}</a-radio-button>\n </a-radio-group>\n </template>\n <template v-if=\"column.dataIndex == 'autoHeight'\">\n <a-switch\n v-if=\"!(record.children && record.children.length > 0)\"\n v-model:checked=\"record.autoHeight\"\n :checked-value=\"true\"\n :un-checked-value=\"false\"\n :checked-children=\"$t('自动')\"\n :un-checked-children=\"$t('固定')\"\n @change=\"change_autoHeight\"\n />\n </template>\n <template v-if=\"column.dataIndex == 'autoWidth'\">\n <a-switch\n v-if=\"!(record.children && record.children.length > 0) && record?.resizable\"\n v-model:checked=\"record.autoWidth\"\n :checked-value=\"true\"\n :un-checked-value=\"false\"\n :checked-children=\"$t('自动')\"\n :un-checked-children=\"$t('固定')\"\n @click=\"change_autoWidth\"\n />\n </template>\n <template v-if=\"column.dataIndex == 'ellipsis'\">\n <a-switch\n v-if=\"!(record.children && record.children.length > 0) && record?.resizable\"\n v-model:checked=\"record.ellipsis\"\n :checked-value=\"true\"\n :un-checked-value=\"false\"\n :checked-children=\"$t('开启')\"\n :un-checked-children=\"$t('关闭')\"\n @click=\"change_ellipsis(record)\"\n />\n </template>\n </template>\n </s-table>\n </div>\n</template>\n\n<script lang=\"ts\">\nimport { computed, defineComponent, ref } from 'vue';\nimport { useI18n } from 'vue-i18n';\nimport { Column } from '../typing';\n\nexport default defineComponent({\n name: 'ColumnsConfig',\n props: {\n columns: {\n type: Array as () => Array<Column>,\n default: () => [],\n },\n },\n emits: ['change'],\n setup(props, { emit }) {\n const { t } = useI18n();\n const searchText = ref('');\n\n const columnsConfig = ref([\n {\n title: t('列名称'),\n dataIndex: 'title',\n key: 'title',\n rowDrag: true,\n width: 270,\n },\n {\n title: t('冻结列'),\n dataIndex: 'fixed',\n key: 'fixed',\n width: 200,\n },\n {\n title: t('行高'),\n dataIndex: 'autoHeight',\n width: 100,\n key: 'autoHeight',\n },\n {\n title: t('列宽'),\n dataIndex: 'autoWidth',\n width: 100,\n key: 'autoWidth',\n },\n {\n title: t('超宽省略'),\n dataIndex: 'ellipsis',\n width: 100,\n key: 'ellipsis',\n },\n ]);\n\n const dataSource = computed(() => {\n return props.columns.filter(item => item.key !== 'index' && item.key !== 'action');\n });\n\n const filteredDataSource = computed(() => {\n if (!searchText.value) return dataSource.value;\n const search = searchText.value.toLowerCase();\n\n const filterNode = (nodes: any[]) => {\n return nodes.reduce((acc: any[], node: any) => {\n const matchSelf =\n node.title?.toLowerCase().includes(search) ||\n node.dataIndex?.toLowerCase().includes(search) ||\n node.key?.toLowerCase().includes(search);\n\n if (node.children && node.children.length > 0) {\n const filteredChildren = filterNode(node.children);\n if (filteredChildren.length > 0) {\n acc.push({ ...node, children: filteredChildren });\n } else if (matchSelf) {\n acc.push({ ...node, children: [] });\n }\n } else if (matchSelf) {\n acc.push(node);\n }\n return acc;\n }, []);\n };\n\n return filterNode(dataSource.value);\n });\n\n const getAllKeysChecked = (children: any) => {\n let allChildrenChecked = true;\n children.forEach((item: any) => {\n if (item.children && item.children.length > 0) {\n allChildrenChecked = allChildrenChecked && getAllKeysChecked(item.children);\n } else {\n allChildrenChecked = allChildrenChecked && item?.checked !== false;\n }\n });\n return allChildrenChecked;\n };\n\n const add_selectedRowKeys = (record: any) => {\n let list = [];\n record.children.forEach((item: any) => {\n if (item.children && item.children.length > 0) {\n const allChildrenChecked = getAllKeysChecked(item.children);\n if (allChildrenChecked) {\n list.push(item.key);\n }\n list = list.concat(add_selectedRowKeys(item));\n } else {\n if (item?.checked !== false) {\n list.push(item.key);\n }\n }\n });\n return list;\n };\n\n const selectedRowKeys = computed(() => {\n if (props.columns) {\n let list = [];\n props.columns.forEach((item: any) => {\n if (item.children && item.children.length > 0) {\n const allChildrenChecked = getAllKeysChecked(item.children);\n if (allChildrenChecked) {\n list.push(item.key);\n }\n list = list.concat(add_selectedRowKeys(item));\n } else {\n if (item?.checked) {\n list.push(item.key);\n }\n }\n });\n return list;\n } else {\n return [];\n }\n });\n\n const rowSelection = ref({\n checkStrictly: false,\n hideSelectAll: true,\n onSelect: (record: any, selected: boolean) => {\n const change_selecte_children_props = (children: any) => {\n children.forEach((item: any) => {\n if (item.children && item.children.length > 0) {\n change_selecte_children_props(item.children);\n }\n item.checked = selected;\n });\n };\n\n const change_selecte_props = (obj: any, key: any, is_checked: any) => {\n obj.children.forEach((item: any) => {\n if (item.key == key) {\n if (is_checked && item.children && item.children.length > 0) {\n change_selecte_children_props(item.children);\n }\n if (selected) {\n item.checked = true;\n obj.checked = true;\n if (obj.is_children) {\n change_selecte_dataSource(obj.key, false);\n }\n } else {\n item.checked = false;\n }\n }\n if (item.children && item.children.length > 0) {\n change_selecte_props(item, key, is_checked);\n }\n });\n };\n\n const change_selecte_dataSource = (key: any, is_checked: any) => {\n dataSource.value.forEach((item: any) => {\n if (item.key == key) {\n if (item.children && item.children.length > 0) {\n change_selecte_children_props(item.children);\n }\n item.checked = selected;\n }\n if (item.children && item.children.length > 0) {\n change_selecte_props(item, key, is_checked);\n }\n });\n };\n\n change_selecte_dataSource(record.key, true);\n emit('change', dataSource.value);\n },\n });\n\n const findParent = (data: any[], childKey: any) => {\n let foundParentKey: any;\n const searchParent = (id: any, keys: any[], childKeys: any) => {\n for (const key of keys) {\n if (key.key === childKeys) {\n foundParentKey = id;\n return foundParentKey;\n } else if (key.children && key.children.length > 0) {\n foundParentKey = searchParent(key.key, key.children, childKeys);\n if (foundParentKey !== undefined) return foundParentKey;\n }\n }\n return undefined;\n };\n return searchParent(null, data, childKey);\n };\n\n const onRowDragEnd = ({ record, preTargetInfo, nextTargetInfo }) => {\n return new Promise((reslove, reject) => {\n // 获取当前拖拽节点的父节点ID\n const currentParentId = findParent(dataSource.value, record.key);\n\n if (preTargetInfo) {\n // 如果拖拽到某个节点之后,检查该目标节点的父节点是否与当前节点相同\n const targetParentId = findParent(dataSource.value, preTargetInfo.record.key);\n if (currentParentId === targetParentId) {\n reslove(true);\n } else {\n reject();\n }\n } else if (nextTargetInfo) {\n // 如果拖拽到某个节点之前,检查该目标节点的父节点是否与当前节点相同\n const targetParentId = findParent(dataSource.value, nextTargetInfo.record.key);\n if (currentParentId === targetParentId) {\n reslove(true);\n } else {\n reject();\n }\n } else {\n reject();\n }\n }).then(() => {\n setTimeout(() => {\n emit('change', dataSource.value);\n }, 200);\n });\n };\n\n const change_fixed = () => emit('change', dataSource.value);\n const change_autoHeight = () => emit('change', dataSource.value);\n const change_autoWidth = () => emit('change', dataSource.value);\n\n const recursion_change_ellipsis = (obj: any, record: any) => {\n obj.children.forEach((item: any) => {\n if (item.key == record.key) {\n item.ellipsis = record.ellipsis;\n }\n if (item.children && item.children.length > 0) {\n recursion_change_ellipsis(item, record);\n }\n });\n };\n\n const change_ellipsis = (record: any) => {\n const list = dataSource.value;\n list.forEach((item: any) => {\n if (item.key == record.key) {\n item.ellipsis = record.ellipsis;\n }\n if (item.children && item.children.length > 0) {\n recursion_change_ellipsis(item, record);\n }\n });\n emit('change', list);\n };\n\n return {\n searchText,\n columnsConfig,\n dataSource,\n filteredDataSource,\n rowSelection,\n selectedRowKeys,\n onRowDragEnd,\n change_fixed,\n change_autoHeight,\n change_autoWidth,\n change_ellipsis,\n };\n },\n});\n</script>\n\n<style lang=\"less\" scoped>\n.columns-config-wrapper {\n padding: 8px 0;\n}\n</style>\n","<template>\n <div class=\"columns-config-wrapper\">\n <a-input\n v-model:value=\"searchText\"\n :placeholder=\"$t('搜索列名/字段名')\"\n allow-clear\n style=\"margin-bottom: 8px\"\n />\n <s-table\n :columns=\"columnsConfig\"\n :rowHeight=\"30\"\n :data-source=\"filteredDataSource\"\n :row-selection=\"rowSelection\"\n v-model:selectedRowKeys=\"selectedRowKeys\"\n expand-row-by-click\n @row-drag-end=\"onRowDragEnd\"\n :row-key=\"'key'\"\n :pagination=\"false\"\n >\n <template #bodyCell=\"{ column, index, text, record }\">\n <template v-if=\"column.dataIndex == 'fixed'\">\n <a-radio-group\n v-if=\"!record?.is_children\"\n v-model:value=\"record.fixed\"\n size=\"small\"\n @change=\"change_fixed\"\n >\n <a-radio-button value=\"left\">{{ $t('左') }}</a-radio-button>\n <a-radio-button :value=\"undefined\">{{ $t('不固定') }}</a-radio-button>\n <a-radio-button value=\"right\">{{ $t('右') }}</a-radio-button>\n </a-radio-group>\n </template>\n <template v-if=\"column.dataIndex == 'autoHeight'\">\n <a-switch\n v-if=\"!(record.children && record.children.length > 0)\"\n v-model:checked=\"record.autoHeight\"\n :checked-value=\"true\"\n :un-checked-value=\"false\"\n :checked-children=\"$t('自动')\"\n :un-checked-children=\"$t('固定')\"\n @change=\"change_autoHeight\"\n />\n </template>\n <template v-if=\"column.dataIndex == 'autoWidth'\">\n <a-switch\n v-if=\"!(record.children && record.children.length > 0) && record?.resizable\"\n v-model:checked=\"record.autoWidth\"\n :checked-value=\"true\"\n :un-checked-value=\"false\"\n :checked-children=\"$t('自动')\"\n :un-checked-children=\"$t('固定')\"\n @click=\"change_autoWidth\"\n />\n </template>\n <template v-if=\"column.dataIndex == 'ellipsis'\">\n <a-switch\n v-if=\"!(record.children && record.children.length > 0) && record?.resizable\"\n v-model:checked=\"record.ellipsis\"\n :checked-value=\"true\"\n :un-checked-value=\"false\"\n :checked-children=\"$t('开启')\"\n :un-checked-children=\"$t('关闭')\"\n @click=\"change_ellipsis(record)\"\n />\n </template>\n </template>\n </s-table>\n </div>\n</template>\n\n<script lang=\"ts\">\nimport { computed, defineComponent, ref } from 'vue';\nimport { useI18n } from 'vue-i18n';\nimport { Column } from '../typing';\n\nexport default defineComponent({\n name: 'ColumnsConfig',\n props: {\n columns: {\n type: Array as () => Array<Column>,\n default: () => [],\n },\n },\n emits: ['change'],\n setup(props, { emit }) {\n const { t } = useI18n();\n const searchText = ref('');\n\n const columnsConfig = ref([\n {\n title: t('列名称'),\n dataIndex: 'title',\n key: 'title',\n rowDrag: true,\n width: 270,\n },\n {\n title: t('冻结列'),\n dataIndex: 'fixed',\n key: 'fixed',\n width: 200,\n },\n {\n title: t('行高'),\n dataIndex: 'autoHeight',\n width: 100,\n key: 'autoHeight',\n },\n {\n title: t('列宽'),\n dataIndex: 'autoWidth',\n width: 100,\n key: 'autoWidth',\n },\n {\n title: t('超宽省略'),\n dataIndex: 'ellipsis',\n width: 100,\n key: 'ellipsis',\n },\n ]);\n\n const dataSource = computed(() => {\n return props.columns.filter(item => item.key !== 'index' && item.key !== 'action');\n });\n\n const filteredDataSource = computed(() => {\n if (!searchText.value) return dataSource.value;\n const search = searchText.value.toLowerCase();\n\n const filterNode = (nodes: any[]) => {\n return nodes.reduce((acc: any[], node: any) => {\n const matchSelf =\n node.title?.toLowerCase().includes(search) ||\n node.dataIndex?.toLowerCase().includes(search) ||\n node.key?.toLowerCase().includes(search);\n\n if (node.children && node.children.length > 0) {\n const filteredChildren = filterNode(node.children);\n if (filteredChildren.length > 0) {\n acc.push({ ...node, children: filteredChildren });\n } else if (matchSelf) {\n acc.push({ ...node, children: [] });\n }\n } else if (matchSelf) {\n acc.push(node);\n }\n return acc;\n }, []);\n };\n\n return filterNode(dataSource.value);\n });\n\n const getAllKeysChecked = (children: any) => {\n let allChildrenChecked = true;\n children.forEach((item: any) => {\n if (item.children && item.children.length > 0) {\n allChildrenChecked = allChildrenChecked && getAllKeysChecked(item.children);\n } else {\n allChildrenChecked = allChildrenChecked && item?.checked !== false;\n }\n });\n return allChildrenChecked;\n };\n\n const add_selectedRowKeys = (record: any) => {\n let list = [];\n record.children.forEach((item: any) => {\n if (item.children && item.children.length > 0) {\n const allChildrenChecked = getAllKeysChecked(item.children);\n if (allChildrenChecked) {\n list.push(item.key);\n }\n list = list.concat(add_selectedRowKeys(item));\n } else {\n if (item?.checked !== false) {\n list.push(item.key);\n }\n }\n });\n return list;\n };\n\n const selectedRowKeys = computed(() => {\n if (props.columns) {\n let list = [];\n props.columns.forEach((item: any) => {\n if (item.children && item.children.length > 0) {\n const allChildrenChecked = getAllKeysChecked(item.children);\n if (allChildrenChecked) {\n list.push(item.key);\n }\n list = list.concat(add_selectedRowKeys(item));\n } else {\n if (item?.checked) {\n list.push(item.key);\n }\n }\n });\n return list;\n } else {\n return [];\n }\n });\n\n const rowSelection = ref({\n checkStrictly: false,\n hideSelectAll: true,\n onSelect: (record: any, selected: boolean) => {\n const change_selecte_children_props = (children: any) => {\n children.forEach((item: any) => {\n if (item.children && item.children.length > 0) {\n change_selecte_children_props(item.children);\n }\n item.checked = selected;\n });\n };\n\n const change_selecte_props = (obj: any, key: any, is_checked: any) => {\n obj.children.forEach((item: any) => {\n if (item.key == key) {\n if (is_checked && item.children && item.children.length > 0) {\n change_selecte_children_props(item.children);\n }\n if (selected) {\n item.checked = true;\n obj.checked = true;\n if (obj.is_children) {\n change_selecte_dataSource(obj.key, false);\n }\n } else {\n item.checked = false;\n }\n }\n if (item.children && item.children.length > 0) {\n change_selecte_props(item, key, is_checked);\n }\n });\n };\n\n const change_selecte_dataSource = (key: any, is_checked: any) => {\n dataSource.value.forEach((item: any) => {\n if (item.key == key) {\n if (item.children && item.children.length > 0) {\n change_selecte_children_props(item.children);\n }\n item.checked = selected;\n }\n if (item.children && item.children.length > 0) {\n change_selecte_props(item, key, is_checked);\n }\n });\n };\n\n change_selecte_dataSource(record.key, true);\n emit('change', dataSource.value);\n },\n });\n\n const findParent = (data: any[], childKey: any) => {\n let foundParentKey: any;\n const searchParent = (id: any, keys: any[], childKeys: any) => {\n for (const key of keys) {\n if (key.key === childKeys) {\n foundParentKey = id;\n return foundParentKey;\n } else if (key.children && key.children.length > 0) {\n foundParentKey = searchParent(key.key, key.children, childKeys);\n if (foundParentKey !== undefined) return foundParentKey;\n }\n }\n return undefined;\n };\n return searchParent(null, data, childKey);\n };\n\n const onRowDragEnd = ({ record, preTargetInfo, nextTargetInfo }) => {\n return new Promise((reslove, reject) => {\n // 获取当前拖拽节点的父节点ID\n const currentParentId = findParent(dataSource.value, record.key);\n\n if (preTargetInfo) {\n // 如果拖拽到某个节点之后,检查该目标节点的父节点是否与当前节点相同\n const targetParentId = findParent(dataSource.value, preTargetInfo.record.key);\n if (currentParentId === targetParentId) {\n reslove(true);\n } else {\n reject();\n }\n } else if (nextTargetInfo) {\n // 如果拖拽到某个节点之前,检查该目标节点的父节点是否与当前节点相同\n const targetParentId = findParent(dataSource.value, nextTargetInfo.record.key);\n if (currentParentId === targetParentId) {\n reslove(true);\n } else {\n reject();\n }\n } else {\n reject();\n }\n }).then(() => {\n setTimeout(() => {\n emit('change', dataSource.value);\n }, 200);\n });\n };\n\n const change_fixed = () => emit('change', dataSource.value);\n const change_autoHeight = () => emit('change', dataSource.value);\n const change_autoWidth = () => emit('change', dataSource.value);\n\n const recursion_change_ellipsis = (obj: any, record: any) => {\n obj.children.forEach((item: any) => {\n if (item.key == record.key) {\n item.ellipsis = record.ellipsis;\n }\n if (item.children && item.children.length > 0) {\n recursion_change_ellipsis(item, record);\n }\n });\n };\n\n const change_ellipsis = (record: any) => {\n const list = dataSource.value;\n list.forEach((item: any) => {\n if (item.key == record.key) {\n item.ellipsis = record.ellipsis;\n }\n if (item.children && item.children.length > 0) {\n recursion_change_ellipsis(item, record);\n }\n });\n emit('change', list);\n };\n\n return {\n searchText,\n columnsConfig,\n dataSource,\n filteredDataSource,\n rowSelection,\n selectedRowKeys,\n onRowDragEnd,\n change_fixed,\n change_autoHeight,\n change_autoWidth,\n change_ellipsis,\n };\n },\n});\n</script>\n\n<style lang=\"less\" scoped>\n.columns-config-wrapper {\n padding: 8px 0;\n}\n</style>\n","<template>\n <div class=\"pivot-config-wrapper\">\n <div class=\"pivot-config-main\">\n <!-- 字段列表区域 -->\n <div class=\"pivot-field-list\">\n <div class=\"pivot-section-title\">{{ $t('字段列表') }}</div>\n <a-input\n v-model:value=\"searchText\"\n :placeholder=\"$t('搜索字段')\"\n allow-clear\n size=\"small\"\n style=\"margin-bottom: 8px\"\n />\n <div class=\"pivot-field-pool\">\n <div\n v-for=\"field in availableFields\"\n :key=\"field.field\"\n class=\"pivot-field-item\"\n draggable=\"true\"\n @dragstart=\"onDragStart($event, field, 'pool')\"\n @dragend=\"onDragEnd\"\n @dblclick=\"addToValues(field)\"\n >\n <span class=\"pivot-field-icon\">\n <database-outlined />\n </span>\n <span class=\"pivot-field-label\">{{ field.label }}</span>\n <span\n v-if=\"isFieldInRowOrCol(field.field)\"\n class=\"pivot-field-tag\"\n >{{ getFieldLocation(field.field) }}</span>\n </div>\n <div\n v-if=\"availableFields.length === 0\"\n class=\"pivot-field-empty\"\n >\n {{ $t('未找到匹配字段') }}\n </div>\n </div>\n </div>\n\n <!-- 拖放区域 -->\n <div class=\"pivot-drop-zones\">\n <!-- 列区域 -->\n <div\n class=\"pivot-drop-zone\"\n :class=\"{ 'drag-over': dragOverZone === 'columns' }\"\n @dragover.prevent=\"onDragOver('columns')\"\n @dragleave=\"onDragLeave\"\n @drop=\"onDrop('columns')\"\n >\n <div class=\"pivot-zone-header\">\n <span class=\"pivot-zone-title\">\n <swap-outlined />\n {{ $t('列') }}\n </span>\n <a-tooltip :title=\"$t('拖拽字段到此处作为列维度')\">\n <info-circle-outlined class=\"pivot-zone-tip\" />\n </a-tooltip>\n </div>\n <div class=\"pivot-zone-items\">\n <div\n v-for=\"(item, index) in localConfig.columns\"\n :key=\"item.field\"\n class=\"pivot-zone-item\"\n :class=\"{ 'drag-before': dragOverZone === 'columns' && dragInsertIndex === index, 'drag-after': dragOverZone === 'columns' && dragInsertIndex === index + 1 }\"\n draggable=\"true\"\n @dragstart=\"onDragStart($event, item, 'columns')\"\n @dragend=\"onDragEnd\"\n @dragover.prevent.stop=\"onItemDragOver('columns', index, $event, 'horizontal')\"\n >\n <span class=\"pivot-zone-item-label\">{{ item.label }}</span>\n <close-outlined\n class=\"pivot-zone-item-remove\"\n @click=\"removeField('columns', index)\"\n />\n </div>\n <div\n v-if=\"localConfig.columns.length === 0\"\n class=\"pivot-zone-placeholder\"\n >\n {{ $t('拖拽字段到此处') }}\n </div>\n </div>\n </div>\n\n <!-- 行区域 -->\n <div\n class=\"pivot-drop-zone\"\n :class=\"{ 'drag-over': dragOverZone === 'rows' }\"\n @dragover.prevent=\"onDragOver('rows')\"\n @dragleave=\"onDragLeave\"\n @drop=\"onDrop('rows')\"\n >\n <div class=\"pivot-zone-header\">\n <span class=\"pivot-zone-title\">\n <bars-outlined />\n {{ $t('行') }}\n </span>\n <a-tooltip :title=\"$t('拖拽字段到此处作为行维度')\">\n <info-circle-outlined class=\"pivot-zone-tip\" />\n </a-tooltip>\n </div>\n <div class=\"pivot-zone-items\">\n <div\n v-for=\"(item, index) in localConfig.rows\"\n :key=\"item.field\"\n class=\"pivot-zone-item\"\n :class=\"{ 'drag-before': dragOverZone === 'rows' && dragInsertIndex === index, 'drag-after': dragOverZone === 'rows' && dragInsertIndex === index + 1 }\"\n draggable=\"true\"\n @dragstart=\"onDragStart($event, item, 'rows')\"\n @dragend=\"onDragEnd\"\n @dragover.prevent.stop=\"onItemDragOver('rows', index, $event, 'horizontal')\"\n >\n <span class=\"pivot-zone-item-label\">{{ item.label }}</span>\n <close-outlined\n class=\"pivot-zone-item-remove\"\n @click=\"removeField('rows', index)\"\n />\n </div>\n <div\n v-if=\"localConfig.rows.length === 0\"\n class=\"pivot-zone-placeholder\"\n >\n {{ $t('拖拽字段到此处') }}\n </div>\n </div>\n </div>\n\n <!-- 值区域 -->\n <div\n class=\"pivot-drop-zone pivot-drop-zone-values\"\n :class=\"{ 'drag-over': dragOverZone === 'values' }\"\n @dragover.prevent=\"onDragOver('values')\"\n @dragleave=\"onDragLeave\"\n @drop=\"onDrop('values')\"\n >\n <div class=\"pivot-zone-header\">\n <span class=\"pivot-zone-title\">\n <calculator-outlined />\n {{ $t('值') }}\n </span>\n <a-tooltip :title=\"$t('拖拽字段到此处作为值,双击字段可快速添加')\">\n <info-circle-outlined class=\"pivot-zone-tip\" />\n </a-tooltip>\n </div>\n <div class=\"pivot-zone-items\">\n <div\n v-for=\"(item, index) in localConfig.values\"\n :key=\"item.id\"\n class=\"pivot-zone-item pivot-value-item\"\n :class=\"{ 'drag-before': dragOverZone === 'values' && dragInsertIndex === index, 'drag-after': dragOverZone === 'values' && dragInsertIndex === index + 1 }\"\n draggable=\"true\"\n @dragstart=\"onDragStart($event, item, 'values')\"\n @dragend=\"onDragEnd\"\n @dragover.prevent.stop=\"onItemDragOver('values', index, $event, 'vertical')\"\n >\n <span class=\"pivot-zone-item-label\">{{ item.label }}</span>\n <a-select\n v-model:value=\"item.aggregationType\"\n size=\"small\"\n style=\"width: 90px\"\n :options=\"aggregationOptions\"\n @change=\"onValueConfigChange\"\n @click.stop\n />\n <a-input\n v-model:value=\"item.title\"\n size=\"small\"\n style=\"width: 100px\"\n :placeholder=\"$t('显示名称')\"\n @change=\"onValueConfigChange\"\n @click.stop\n />\n <close-outlined\n class=\"pivot-zone-item-remove\"\n @click=\"removeField('values', index)\"\n />\n </div>\n <div\n v-if=\"localConfig.values.length === 0\"\n class=\"pivot-zone-placeholder\"\n >\n {{ $t('拖拽字段到此处') }}\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- 选项区域 -->\n <div class=\"pivot-options\">\n <a-form layout=\"inline\" size=\"small\">\n <a-form-item :label=\"$t('指标显示位置')\">\n <a-radio-group v-model:value=\"localConfig.indicatorsAsCol\" @change=\"onConfigChange\">\n <a-radio-button :value=\"true\">{{ $t('列上') }}</a-radio-button>\n <a-radio-button :value=\"false\">{{ $t('行上') }}</a-radio-button>\n </a-radio-group>\n </a-form-item>\n <a-form-item :label=\"$t('行维度结构')\">\n <a-radio-group\n v-model:value=\"localConfig.rowHierarchyType\"\n @change=\"onConfigChange\"\n >\n <a-radio-button value=\"grid\">{{ $t('扁平') }}</a-radio-button>\n <a-radio-button value=\"tree\">{{ $t('树形') }}</a-radio-button>\n <a-radio-button value=\"grid-tree\">{{ $t('网格树形') }}</a-radio-button>\n </a-radio-group>\n </a-form-item>\n </a-form>\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport {\n DatabaseOutlined,\n SwapOutlined,\n BarsOutlined,\n CalculatorOutlined,\n CloseOutlined,\n InfoCircleOutlined,\n} from '@ant-design/icons-vue';\nimport { cloneDeep } from 'lodash';\nimport { computed, ref, watch } from 'vue';\nimport { Column, PivotConfig, PivotFieldConfig, PivotValueField } from '../typing';\n\nconst props = defineProps<{\n columns: Column[];\n modelValue?: PivotConfig;\n}>();\n\nconst emit = defineEmits<{\n (e: 'update:modelValue', value: PivotConfig): void;\n (e: 'change', value: PivotConfig): void;\n}>();\n\nconst searchText = ref('');\nconst dragData = ref<{\n field: PivotFieldConfig | PivotValueField;\n source: 'pool' | 'columns' | 'rows' | 'values';\n} | null>(null);\nconst dragOverZone = ref<string>('');\nconst dragInsertIndex = ref<number>(-1); // 拖拽插入位置索引\n\nconst defaultConfig: PivotConfig = {\n rows: [],\n columns: [],\n values: [],\n indicatorsAsCol: true,\n rowHierarchyType: 'grid',\n};\n\nconst localConfig = ref<PivotConfig>(cloneDeep(props.modelValue || defaultConfig));\n\n// 确保每个 value field 都有唯一 id(兼容旧数据)\nconst ensureValueIds = (config: PivotConfig) => {\n config.values.forEach((v) => {\n if (!v.id) {\n v.id = `${v.field}_${Date.now()}_${Math.random().toString(36).slice(2, 6)}`;\n }\n });\n};\nensureValueIds(localConfig.value);\n\nwatch(\n () => props.modelValue,\n (val) => {\n if (val) {\n localConfig.value = cloneDeep(val);\n ensureValueIds(localConfig.value);\n }\n },\n { deep: true },\n);\n\n// 所有可用字段列表\nconst allFields = computed<PivotFieldConfig[]>(() => {\n const getLeaves = (cols: Column[]): Column[] => {\n const list: Column[] = [];\n cols.forEach((col) => {\n if (col.children && col.children.length > 0) {\n list.push(...getLeaves(col.children));\n } else {\n list.push(col);\n }\n });\n return list;\n };\n const leaves = getLeaves(props.columns || []);\n return leaves\n .filter((col) => col.dataIndex && col.dataIndex !== 'index' && col.dataIndex !== 'action')\n .map((col) => ({\n field: col.dataIndex!,\n label: col.title || col.dataIndex!,\n }));\n});\n\n// 过滤后的可用字段(始终显示全部字段,不因已在行/列/值中而隐藏)\nconst availableFields = computed(() => {\n if (!searchText.value) return allFields.value;\n const search = searchText.value.toLowerCase();\n return allFields.value.filter(\n (f) =>\n f.label.toLowerCase().includes(search) || f.field.toLowerCase().includes(search),\n );\n});\n\n// 检查字段是否已在行或列中\nconst isFieldInRowOrCol = (field: string) => {\n return (\n localConfig.value.rows.some((r) => r.field === field) ||\n localConfig.value.columns.some((c) => c.field === field)\n );\n};\n\n// 获取字段所在位置标签\nconst getFieldLocation = (field: string) => {\n if (localConfig.value.rows.some((r) => r.field === field)) return '行';\n if (localConfig.value.columns.some((c) => c.field === field)) return '列';\n return '';\n};\n\nconst aggregationOptions = [\n { label: '求和', value: 'SUM' },\n { label: '计数', value: 'COUNT' },\n { label: '平均值', value: 'AVG' },\n { label: '最小值', value: 'MIN' },\n { label: '最大值', value: 'MAX' },\n { label: '无', value: 'NONE' },\n];\n\n// 拖拽相关\nconst onDragStart = (\n event: DragEvent,\n field: PivotFieldConfig | PivotValueField,\n source: 'pool' | 'columns' | 'rows' | 'values',\n) => {\n dragData.value = { field, source };\n if (event.dataTransfer) {\n event.dataTransfer.effectAllowed = 'move';\n event.dataTransfer.setData('text/plain', field.field);\n }\n};\n\nconst onDragEnd = () => {\n dragData.value = null;\n dragOverZone.value = '';\n dragInsertIndex.value = -1;\n};\n\nconst onDragOver = (zone: string) => {\n dragOverZone.value = zone;\n};\n\n// 拖拽到某个 item 上方时,根据鼠标位置计算插入点(前/后)\nconst onItemDragOver = (\n zone: 'columns' | 'rows' | 'values',\n index: number,\n event: DragEvent,\n direction: 'horizontal' | 'vertical',\n) => {\n dragOverZone.value = zone;\n if (!event.currentTarget) return;\n const rect = (event.currentTarget as HTMLElement).getBoundingClientRect();\n if (direction === 'horizontal') {\n const midpoint = rect.left + rect.width / 2;\n if (event.clientX < midpoint) {\n dragInsertIndex.value = index;\n } else {\n dragInsertIndex.value = index + 1;\n }\n } else {\n const midpoint = rect.top + rect.height / 2;\n if (event.clientY < midpoint) {\n dragInsertIndex.value = index;\n } else {\n dragInsertIndex.value = index + 1;\n }\n }\n};\n\nconst onDragLeave = () => {\n // 只在离开整个区域时清除\n};\n\n// 获取区域列表的引用\nconst getZoneList = (zone: 'columns' | 'rows' | 'values') => {\n return localConfig.value[zone];\n};\n\n// 在区域列表中查找已拖拽项的索引\nconst findItemIndexInZone = (\n zone: 'columns' | 'rows' | 'values',\n field: PivotFieldConfig | PivotValueField,\n): number => {\n const list = getZoneList(zone);\n if (zone === 'values') {\n return list.findIndex((f) => (f as PivotValueField).id === (field as PivotValueField).id);\n }\n return list.findIndex((f) => f.field === field.field);\n};\n\nconst onDrop = (zone: 'columns' | 'rows' | 'values') => {\n if (!dragData.value) return;\n const { field, source } = dragData.value;\n\n // 同区域内拖拽 → 调整顺序\n if (source === zone) {\n const list = getZoneList(zone);\n const fromIndex = findItemIndexInZone(zone, field);\n if (fromIndex === -1) {\n dragOverZone.value = '';\n dragInsertIndex.value = -1;\n return;\n }\n // 计算目标插入位置\n let toIndex = dragInsertIndex.value;\n if (toIndex < 0) toIndex = list.length;\n // 从原位置移除后,如果目标位置在原位置之后,索引需减1\n if (toIndex > fromIndex) toIndex -= 1;\n if (toIndex >= list.length) toIndex = list.length - 1;\n if (toIndex < 0) toIndex = 0;\n // 取出并重新插入\n const [item] = list.splice(fromIndex, 1);\n list.splice(toIndex, 0, item);\n dragOverZone.value = '';\n dragInsertIndex.value = -1;\n onConfigChange();\n return;\n }\n\n // 跨区域拖拽\n // 从源区域移除(pool 不需要移除)\n if (source === 'columns') {\n localConfig.value.columns = localConfig.value.columns.filter(\n (f) => f.field !== field.field,\n );\n } else if (source === 'rows') {\n localConfig.value.rows = localConfig.value.rows.filter(\n (f) => f.field !== field.field,\n );\n } else if (source === 'values') {\n const valueField = field as PivotValueField;\n localConfig.value.values = localConfig.value.values.filter(\n (f) => f.id !== valueField.id,\n );\n }\n\n // 添加到目标区域(支持插入到指定位置)\n const insertIndex = dragInsertIndex.value >= 0 ? dragInsertIndex.value : getZoneList(zone).length;\n\n if (zone === 'values') {\n const valueField: PivotValueField = {\n id: `${field.field}_${Date.now()}_${Math.random().toString(36).slice(2, 6)}`,\n field: field.field,\n label: field.label,\n aggregationType: 'SUM',\n title: field.label,\n };\n localConfig.value.values.splice(insertIndex, 0, valueField);\n } else if (zone === 'columns') {\n // 行/列互斥\n localConfig.value.rows = localConfig.value.rows.filter(\n (f) => f.field !== field.field,\n );\n const baseField: PivotFieldConfig = {\n field: field.field,\n label: field.label,\n };\n localConfig.value.columns.splice(insertIndex, 0, baseField);\n } else if (zone === 'rows') {\n // 行/列互斥\n localConfig.value.columns = localConfig.value.columns.filter(\n (f) => f.field !== field.field,\n );\n const baseField: PivotFieldConfig = {\n field: field.field,\n label: field.label,\n };\n localConfig.value.rows.splice(insertIndex, 0, baseField);\n }\n\n dragOverZone.value = '';\n dragInsertIndex.value = -1;\n onConfigChange();\n};\n\n// 双击字段快速添加到值区域(允许重复添加,不限制是否已在行/列中)\nconst addToValues = (field: PivotFieldConfig) => {\n const valueField: PivotValueField = {\n id: `${field.field}_${Date.now()}_${Math.random().toString(36).slice(2, 6)}`,\n field: field.field,\n label: field.label,\n aggregationType: 'SUM',\n title: field.label,\n };\n localConfig.value.values.push(valueField);\n onConfigChange();\n};\n\n// 移除字段\nconst removeField = (zone: 'columns' | 'rows' | 'values', index: number) => {\n if (zone === 'columns') {\n localConfig.value.columns.splice(index, 1);\n } else if (zone === 'rows') {\n localConfig.value.rows.splice(index, 1);\n } else if (zone === 'values') {\n localConfig.value.values.splice(index, 1);\n }\n onConfigChange();\n};\n\nconst onValueConfigChange = () => {\n onConfigChange();\n};\n\nconst onConfigChange = () => {\n const config = cloneDeep(localConfig.value);\n emit('update:modelValue', config);\n emit('change', config);\n};\n</script>\n\n<style lang=\"less\" scoped>\n.pivot-config-wrapper {\n display: flex;\n flex-direction: column;\n gap: 12px;\n height: 500px;\n}\n\n.pivot-config-main {\n display: flex;\n gap: 16px;\n flex: 1;\n min-height: 0;\n}\n\n.pivot-field-list {\n width: 220px;\n flex-shrink: 0;\n border: 1px solid #f0f0f0;\n border-radius: 6px;\n padding: 8px;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n\n .pivot-section-title {\n font-weight: 600;\n margin-bottom: 8px;\n font-size: 13px;\n color: #333;\n }\n\n .pivot-field-pool {\n flex: 1;\n overflow-y: auto;\n min-height: 0;\n }\n\n .pivot-field-item {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 8px;\n margin-bottom: 4px;\n border: 1px solid #f0f0f0;\n border-radius: 4px;\n cursor: grab;\n font-size: 13px;\n transition: all 0.2s;\n user-select: none;\n\n &:hover {\n border-color: #1890ff;\n background: #f0f7ff;\n }\n\n &:active {\n cursor: grabbing;\n }\n\n .pivot-field-icon {\n color: #1890ff;\n font-size: 12px;\n }\n\n .pivot-field-label {\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .pivot-field-tag {\n flex-shrink: 0;\n font-size: 10px;\n color: #fff;\n background: #1890ff;\n border-radius: 8px;\n padding: 1px 6px;\n line-height: 16px;\n }\n }\n\n .pivot-field-empty {\n text-align: center;\n color: #999;\n font-size: 12px;\n padding: 20px 0;\n }\n}\n\n.pivot-drop-zones {\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: 12px;\n min-width: 0;\n overflow-y: auto;\n}\n\n.pivot-drop-zone {\n border: 2px dashed #d9d9d9;\n border-radius: 6px;\n padding: 8px;\n transition: all 0.2s;\n min-height: 80px;\n flex-shrink: 0;\n\n &.drag-over {\n border-color: #1890ff;\n background: #f0f7ff;\n }\n\n .pivot-zone-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 6px;\n\n .pivot-zone-title {\n font-weight: 600;\n font-size: 13px;\n color: #333;\n display: flex;\n align-items: center;\n gap: 4px;\n }\n\n .pivot-zone-tip {\n color: #999;\n font-size: 12px;\n cursor: help;\n }\n }\n\n .pivot-zone-items {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n min-height: 32px;\n }\n\n .pivot-zone-placeholder {\n color: #bbb;\n font-size: 12px;\n padding: 4px 8px;\n width: 100%;\n text-align: center;\n }\n}\n\n.pivot-zone-item {\n display: flex;\n align-items: center;\n gap: 4px;\n padding: 4px 8px;\n background: #fafafa;\n border: 1px solid #d9d9d9;\n border-radius: 4px;\n font-size: 12px;\n cursor: grab;\n user-select: none;\n transition: all 0.2s;\n max-width: 100%;\n box-sizing: border-box;\n position: relative;\n\n &:hover {\n border-color: #1890ff;\n background: #f0f7ff;\n }\n\n &:active {\n cursor: grabbing;\n }\n\n // 拖拽插入位置指示线(行/列区域:左右指示)\n &.drag-before {\n box-shadow: -2px 0 0 0 #1890ff;\n }\n\n &.drag-after {\n box-shadow: 2px 0 0 0 #1890ff;\n }\n\n .pivot-zone-item-label {\n flex: 0 1 auto;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .pivot-zone-item-remove {\n color: #999;\n cursor: pointer;\n font-size: 10px;\n margin-left: 2px;\n flex-shrink: 0;\n\n &:hover {\n color: #ff4d4f;\n }\n }\n}\n\n.pivot-value-item {\n background: #fff7e6;\n border-color: #ffd591;\n flex-wrap: wrap;\n width: 100%;\n max-width: 100%;\n\n &:hover {\n border-color: #fa8c16;\n background: #fff7e6;\n }\n\n // 值区域:上下指示\n &.drag-before {\n box-shadow: 0 -2px 0 0 #1890ff;\n }\n\n &.drag-after {\n box-shadow: 0 2px 0 0 #1890ff;\n }\n\n .pivot-zone-item-label {\n flex-shrink: 0;\n }\n\n :deep(.ant-select) {\n flex: 1 1 auto;\n min-width: 70px;\n }\n\n :deep(.ant-input) {\n flex: 1 1 auto;\n min-width: 70px;\n }\n}\n\n.pivot-drop-zone-values {\n /* 值区域根据内容自动扩展,不再用 flex: 1 限制高度 */\n min-height: 80px;\n}\n\n.pivot-options {\n flex-shrink: 0;\n padding: 8px 0;\n border-top: 1px solid #f0f0f0;\n}\n</style>\n","<template>\n <div class=\"pivot-config-wrapper\">\n <div class=\"pivot-config-main\">\n <!-- 字段列表区域 -->\n <div class=\"pivot-field-list\">\n <div class=\"pivot-section-title\">{{ $t('字段列表') }}</div>\n <a-input\n v-model:value=\"searchText\"\n :placeholder=\"$t('搜索字段')\"\n allow-clear\n size=\"small\"\n style=\"margin-bottom: 8px\"\n />\n <div class=\"pivot-field-pool\">\n <div\n v-for=\"field in availableFields\"\n :key=\"field.field\"\n class=\"pivot-field-item\"\n draggable=\"true\"\n @dragstart=\"onDragStart($event, field, 'pool')\"\n @dragend=\"onDragEnd\"\n @dblclick=\"addToValues(field)\"\n >\n <span class=\"pivot-field-icon\">\n <database-outlined />\n </span>\n <span class=\"pivot-field-label\">{{ field.label }}</span>\n <span\n v-if=\"isFieldInRowOrCol(field.field)\"\n class=\"pivot-field-tag\"\n >{{ getFieldLocation(field.field) }}</span>\n </div>\n <div\n v-if=\"availableFields.length === 0\"\n class=\"pivot-field-empty\"\n >\n {{ $t('未找到匹配字段') }}\n </div>\n </div>\n </div>\n\n <!-- 拖放区域 -->\n <div class=\"pivot-drop-zones\">\n <!-- 列区域 -->\n <div\n class=\"pivot-drop-zone\"\n :class=\"{ 'drag-over': dragOverZone === 'columns' }\"\n @dragover.prevent=\"onDragOver('columns')\"\n @dragleave=\"onDragLeave\"\n @drop=\"onDrop('columns')\"\n >\n <div class=\"pivot-zone-header\">\n <span class=\"pivot-zone-title\">\n <swap-outlined />\n {{ $t('列') }}\n </span>\n <a-tooltip :title=\"$t('拖拽字段到此处作为列维度')\">\n <info-circle-outlined class=\"pivot-zone-tip\" />\n </a-tooltip>\n </div>\n <div class=\"pivot-zone-items\">\n <div\n v-for=\"(item, index) in localConfig.columns\"\n :key=\"item.field\"\n class=\"pivot-zone-item\"\n :class=\"{ 'drag-before': dragOverZone === 'columns' && dragInsertIndex === index, 'drag-after': dragOverZone === 'columns' && dragInsertIndex === index + 1 }\"\n draggable=\"true\"\n @dragstart=\"onDragStart($event, item, 'columns')\"\n @dragend=\"onDragEnd\"\n @dragover.prevent.stop=\"onItemDragOver('columns', index, $event, 'horizontal')\"\n >\n <span class=\"pivot-zone-item-label\">{{ item.label }}</span>\n <close-outlined\n class=\"pivot-zone-item-remove\"\n @click=\"removeField('columns', index)\"\n />\n </div>\n <div\n v-if=\"localConfig.columns.length === 0\"\n class=\"pivot-zone-placeholder\"\n >\n {{ $t('拖拽字段到此处') }}\n </div>\n </div>\n </div>\n\n <!-- 行区域 -->\n <div\n class=\"pivot-drop-zone\"\n :class=\"{ 'drag-over': dragOverZone === 'rows' }\"\n @dragover.prevent=\"onDragOver('rows')\"\n @dragleave=\"onDragLeave\"\n @drop=\"onDrop('rows')\"\n >\n <div class=\"pivot-zone-header\">\n <span class=\"pivot-zone-title\">\n <bars-outlined />\n {{ $t('行') }}\n </span>\n <a-tooltip :title=\"$t('拖拽字段到此处作为行维度')\">\n <info-circle-outlined class=\"pivot-zone-tip\" />\n </a-tooltip>\n </div>\n <div class=\"pivot-zone-items\">\n <div\n v-for=\"(item, index) in localConfig.rows\"\n :key=\"item.field\"\n class=\"pivot-zone-item\"\n :class=\"{ 'drag-before': dragOverZone === 'rows' && dragInsertIndex === index, 'drag-after': dragOverZone === 'rows' && dragInsertIndex === index + 1 }\"\n draggable=\"true\"\n @dragstart=\"onDragStart($event, item, 'rows')\"\n @dragend=\"onDragEnd\"\n @dragover.prevent.stop=\"onItemDragOver('rows', index, $event, 'horizontal')\"\n >\n <span class=\"pivot-zone-item-label\">{{ item.label }}</span>\n <close-outlined\n class=\"pivot-zone-item-remove\"\n @click=\"removeField('rows', index)\"\n />\n </div>\n <div\n v-if=\"localConfig.rows.length === 0\"\n class=\"pivot-zone-placeholder\"\n >\n {{ $t('拖拽字段到此处') }}\n </div>\n </div>\n </div>\n\n <!-- 值区域 -->\n <div\n class=\"pivot-drop-zone pivot-drop-zone-values\"\n :class=\"{ 'drag-over': dragOverZone === 'values' }\"\n @dragover.prevent=\"onDragOver('values')\"\n @dragleave=\"onDragLeave\"\n @drop=\"onDrop('values')\"\n >\n <div class=\"pivot-zone-header\">\n <span class=\"pivot-zone-title\">\n <calculator-outlined />\n {{ $t('值') }}\n </span>\n <a-tooltip :title=\"$t('拖拽字段到此处作为值,双击字段可快速添加')\">\n <info-circle-outlined class=\"pivot-zone-tip\" />\n </a-tooltip>\n </div>\n <div class=\"pivot-zone-items\">\n <div\n v-for=\"(item, index) in localConfig.values\"\n :key=\"item.id\"\n class=\"pivot-zone-item pivot-value-item\"\n :class=\"{ 'drag-before': dragOverZone === 'values' && dragInsertIndex === index, 'drag-after': dragOverZone === 'values' && dragInsertIndex === index + 1 }\"\n draggable=\"true\"\n @dragstart=\"onDragStart($event, item, 'values')\"\n @dragend=\"onDragEnd\"\n @dragover.prevent.stop=\"onItemDragOver('values', index, $event, 'vertical')\"\n >\n <span class=\"pivot-zone-item-label\">{{ item.label }}</span>\n <a-select\n v-model:value=\"item.aggregationType\"\n size=\"small\"\n style=\"width: 90px\"\n :options=\"aggregationOptions\"\n @change=\"onValueConfigChange\"\n @click.stop\n />\n <a-input\n v-model:value=\"item.title\"\n size=\"small\"\n style=\"width: 100px\"\n :placeholder=\"$t('显示名称')\"\n @change=\"onValueConfigChange\"\n @click.stop\n />\n <close-outlined\n class=\"pivot-zone-item-remove\"\n @click=\"removeField('values', index)\"\n />\n </div>\n <div\n v-if=\"localConfig.values.length === 0\"\n class=\"pivot-zone-placeholder\"\n >\n {{ $t('拖拽字段到此处') }}\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- 选项区域 -->\n <div class=\"pivot-options\">\n <a-form layout=\"inline\" size=\"small\">\n <a-form-item :label=\"$t('指标显示位置')\">\n <a-radio-group v-model:value=\"localConfig.indicatorsAsCol\" @change=\"onConfigChange\">\n <a-radio-button :value=\"true\">{{ $t('列上') }}</a-radio-button>\n <a-radio-button :value=\"false\">{{ $t('行上') }}</a-radio-button>\n </a-radio-group>\n </a-form-item>\n <a-form-item :label=\"$t('行维度结构')\">\n <a-radio-group\n v-model:value=\"localConfig.rowHierarchyType\"\n @change=\"onConfigChange\"\n >\n <a-radio-button value=\"grid\">{{ $t('扁平') }}</a-radio-button>\n <a-radio-button value=\"tree\">{{ $t('树形') }}</a-radio-button>\n <a-radio-button value=\"grid-tree\">{{ $t('网格树形') }}</a-radio-button>\n </a-radio-group>\n </a-form-item>\n </a-form>\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport {\n DatabaseOutlined,\n SwapOutlined,\n BarsOutlined,\n CalculatorOutlined,\n CloseOutlined,\n InfoCircleOutlined,\n} from '@ant-design/icons-vue';\nimport { cloneDeep } from 'lodash';\nimport { computed, ref, watch } from 'vue';\nimport { Column, PivotConfig, PivotFieldConfig, PivotValueField } from '../typing';\n\nconst props = defineProps<{\n columns: Column[];\n modelValue?: PivotConfig;\n}>();\n\nconst emit = defineEmits<{\n (e: 'update:modelValue', value: PivotConfig): void;\n (e: 'change', value: PivotConfig): void;\n}>();\n\nconst searchText = ref('');\nconst dragData = ref<{\n field: PivotFieldConfig | PivotValueField;\n source: 'pool' | 'columns' | 'rows' | 'values';\n} | null>(null);\nconst dragOverZone = ref<string>('');\nconst dragInsertIndex = ref<number>(-1); // 拖拽插入位置索引\n\nconst defaultConfig: PivotConfig = {\n rows: [],\n columns: [],\n values: [],\n indicatorsAsCol: true,\n rowHierarchyType: 'grid',\n};\n\nconst localConfig = ref<PivotConfig>(cloneDeep(props.modelValue || defaultConfig));\n\n// 确保每个 value field 都有唯一 id(兼容旧数据)\nconst ensureValueIds = (config: PivotConfig) => {\n config.values.forEach((v) => {\n if (!v.id) {\n v.id = `${v.field}_${Date.now()}_${Math.random().toString(36).slice(2, 6)}`;\n }\n });\n};\nensureValueIds(localConfig.value);\n\nwatch(\n () => props.modelValue,\n (val) => {\n if (val) {\n localConfig.value = cloneDeep(val);\n ensureValueIds(localConfig.value);\n }\n },\n { deep: true },\n);\n\n// 所有可用字段列表\nconst allFields = computed<PivotFieldConfig[]>(() => {\n const getLeaves = (cols: Column[]): Column[] => {\n const list: Column[] = [];\n cols.forEach((col) => {\n if (col.children && col.children.length > 0) {\n list.push(...getLeaves(col.children));\n } else {\n list.push(col);\n }\n });\n return list;\n };\n const leaves = getLeaves(props.columns || []);\n return leaves\n .filter((col) => col.dataIndex && col.dataIndex !== 'index' && col.dataIndex !== 'action')\n .map((col) => ({\n field: col.dataIndex!,\n label: col.title || col.dataIndex!,\n }));\n});\n\n// 过滤后的可用字段(始终显示全部字段,不因已在行/列/值中而隐藏)\nconst availableFields = computed(() => {\n if (!searchText.value) return allFields.value;\n const search = searchText.value.toLowerCase();\n return allFields.value.filter(\n (f) =>\n f.label.toLowerCase().includes(search) || f.field.toLowerCase().includes(search),\n );\n});\n\n// 检查字段是否已在行或列中\nconst isFieldInRowOrCol = (field: string) => {\n return (\n localConfig.value.rows.some((r) => r.field === field) ||\n localConfig.value.columns.some((c) => c.field === field)\n );\n};\n\n// 获取字段所在位置标签\nconst getFieldLocation = (field: string) => {\n if (localConfig.value.rows.some((r) => r.field === field)) return '行';\n if (localConfig.value.columns.some((c) => c.field === field)) return '列';\n return '';\n};\n\nconst aggregationOptions = [\n { label: '求和', value: 'SUM' },\n { label: '计数', value: 'COUNT' },\n { label: '平均值', value: 'AVG' },\n { label: '最小值', value: 'MIN' },\n { label: '最大值', value: 'MAX' },\n { label: '无', value: 'NONE' },\n];\n\n// 拖拽相关\nconst onDragStart = (\n event: DragEvent,\n field: PivotFieldConfig | PivotValueField,\n source: 'pool' | 'columns' | 'rows' | 'values',\n) => {\n dragData.value = { field, source };\n if (event.dataTransfer) {\n event.dataTransfer.effectAllowed = 'move';\n event.dataTransfer.setData('text/plain', field.field);\n }\n};\n\nconst onDragEnd = () => {\n dragData.value = null;\n dragOverZone.value = '';\n dragInsertIndex.value = -1;\n};\n\nconst onDragOver = (zone: string) => {\n dragOverZone.value = zone;\n};\n\n// 拖拽到某个 item 上方时,根据鼠标位置计算插入点(前/后)\nconst onItemDragOver = (\n zone: 'columns' | 'rows' | 'values',\n index: number,\n event: DragEvent,\n direction: 'horizontal' | 'vertical',\n) => {\n dragOverZone.value = zone;\n if (!event.currentTarget) return;\n const rect = (event.currentTarget as HTMLElement).getBoundingClientRect();\n if (direction === 'horizontal') {\n const midpoint = rect.left + rect.width / 2;\n if (event.clientX < midpoint) {\n dragInsertIndex.value = index;\n } else {\n dragInsertIndex.value = index + 1;\n }\n } else {\n const midpoint = rect.top + rect.height / 2;\n if (event.clientY < midpoint) {\n dragInsertIndex.value = index;\n } else {\n dragInsertIndex.value = index + 1;\n }\n }\n};\n\nconst onDragLeave = () => {\n // 只在离开整个区域时清除\n};\n\n// 获取区域列表的引用\nconst getZoneList = (zone: 'columns' | 'rows' | 'values') => {\n return localConfig.value[zone];\n};\n\n// 在区域列表中查找已拖拽项的索引\nconst findItemIndexInZone = (\n zone: 'columns' | 'rows' | 'values',\n field: PivotFieldConfig | PivotValueField,\n): number => {\n const list = getZoneList(zone);\n if (zone === 'values') {\n return list.findIndex((f) => (f as PivotValueField).id === (field as PivotValueField).id);\n }\n return list.findIndex((f) => f.field === field.field);\n};\n\nconst onDrop = (zone: 'columns' | 'rows' | 'values') => {\n if (!dragData.value) return;\n const { field, source } = dragData.value;\n\n // 同区域内拖拽 → 调整顺序\n if (source === zone) {\n const list = getZoneList(zone);\n const fromIndex = findItemIndexInZone(zone, field);\n if (fromIndex === -1) {\n dragOverZone.value = '';\n dragInsertIndex.value = -1;\n return;\n }\n // 计算目标插入位置\n let toIndex = dragInsertIndex.value;\n if (toIndex < 0) toIndex = list.length;\n // 从原位置移除后,如果目标位置在原位置之后,索引需减1\n if (toIndex > fromIndex) toIndex -= 1;\n if (toIndex >= list.length) toIndex = list.length - 1;\n if (toIndex < 0) toIndex = 0;\n // 取出并重新插入\n const [item] = list.splice(fromIndex, 1);\n list.splice(toIndex, 0, item);\n dragOverZone.value = '';\n dragInsertIndex.value = -1;\n onConfigChange();\n return;\n }\n\n // 跨区域拖拽\n // 从源区域移除(pool 不需要移除)\n if (source === 'columns') {\n localConfig.value.columns = localConfig.value.columns.filter(\n (f) => f.field !== field.field,\n );\n } else if (source === 'rows') {\n localConfig.value.rows = localConfig.value.rows.filter(\n (f) => f.field !== field.field,\n );\n } else if (source === 'values') {\n const valueField = field as PivotValueField;\n localConfig.value.values = localConfig.value.values.filter(\n (f) => f.id !== valueField.id,\n );\n }\n\n // 添加到目标区域(支持插入到指定位置)\n const insertIndex = dragInsertIndex.value >= 0 ? dragInsertIndex.value : getZoneList(zone).length;\n\n if (zone === 'values') {\n const valueField: PivotValueField = {\n id: `${field.field}_${Date.now()}_${Math.random().toString(36).slice(2, 6)}`,\n field: field.field,\n label: field.label,\n aggregationType: 'SUM',\n title: field.label,\n };\n localConfig.value.values.splice(insertIndex, 0, valueField);\n } else if (zone === 'columns') {\n // 行/列互斥\n localConfig.value.rows = localConfig.value.rows.filter(\n (f) => f.field !== field.field,\n );\n const baseField: PivotFieldConfig = {\n field: field.field,\n label: field.label,\n };\n localConfig.value.columns.splice(insertIndex, 0, baseField);\n } else if (zone === 'rows') {\n // 行/列互斥\n localConfig.value.columns = localConfig.value.columns.filter(\n (f) => f.field !== field.field,\n );\n const baseField: PivotFieldConfig = {\n field: field.field,\n label: field.label,\n };\n localConfig.value.rows.splice(insertIndex, 0, baseField);\n }\n\n dragOverZone.value = '';\n dragInsertIndex.value = -1;\n onConfigChange();\n};\n\n// 双击字段快速添加到值区域(允许重复添加,不限制是否已在行/列中)\nconst addToValues = (field: PivotFieldConfig) => {\n const valueField: PivotValueField = {\n id: `${field.field}_${Date.now()}_${Math.random().toString(36).slice(2, 6)}`,\n field: field.field,\n label: field.label,\n aggregationType: 'SUM',\n title: field.label,\n };\n localConfig.value.values.push(valueField);\n onConfigChange();\n};\n\n// 移除字段\nconst removeField = (zone: 'columns' | 'rows' | 'values', index: number) => {\n if (zone === 'columns') {\n localConfig.value.columns.splice(index, 1);\n } else if (zone === 'rows') {\n localConfig.value.rows.splice(index, 1);\n } else if (zone === 'values') {\n localConfig.value.values.splice(index, 1);\n }\n onConfigChange();\n};\n\nconst onValueConfigChange = () => {\n onConfigChange();\n};\n\nconst onConfigChange = () => {\n const config = cloneDeep(localConfig.value);\n emit('update:modelValue', config);\n emit('change', config);\n};\n</script>\n\n<style lang=\"less\" scoped>\n.pivot-config-wrapper {\n display: flex;\n flex-direction: column;\n gap: 12px;\n height: 500px;\n}\n\n.pivot-config-main {\n display: flex;\n gap: 16px;\n flex: 1;\n min-height: 0;\n}\n\n.pivot-field-list {\n width: 220px;\n flex-shrink: 0;\n border: 1px solid #f0f0f0;\n border-radius: 6px;\n padding: 8px;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n\n .pivot-section-title {\n font-weight: 600;\n margin-bottom: 8px;\n font-size: 13px;\n color: #333;\n }\n\n .pivot-field-pool {\n flex: 1;\n overflow-y: auto;\n min-height: 0;\n }\n\n .pivot-field-item {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 8px;\n margin-bottom: 4px;\n border: 1px solid #f0f0f0;\n border-radius: 4px;\n cursor: grab;\n font-size: 13px;\n transition: all 0.2s;\n user-select: none;\n\n &:hover {\n border-color: #1890ff;\n background: #f0f7ff;\n }\n\n &:active {\n cursor: grabbing;\n }\n\n .pivot-field-icon {\n color: #1890ff;\n font-size: 12px;\n }\n\n .pivot-field-label {\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .pivot-field-tag {\n flex-shrink: 0;\n font-size: 10px;\n color: #fff;\n background: #1890ff;\n border-radius: 8px;\n padding: 1px 6px;\n line-height: 16px;\n }\n }\n\n .pivot-field-empty {\n text-align: center;\n color: #999;\n font-size: 12px;\n padding: 20px 0;\n }\n}\n\n.pivot-drop-zones {\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: 12px;\n min-width: 0;\n overflow-y: auto;\n}\n\n.pivot-drop-zone {\n border: 2px dashed #d9d9d9;\n border-radius: 6px;\n padding: 8px;\n transition: all 0.2s;\n min-height: 80px;\n flex-shrink: 0;\n\n &.drag-over {\n border-color: #1890ff;\n background: #f0f7ff;\n }\n\n .pivot-zone-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 6px;\n\n .pivot-zone-title {\n font-weight: 600;\n font-size: 13px;\n color: #333;\n display: flex;\n align-items: center;\n gap: 4px;\n }\n\n .pivot-zone-tip {\n color: #999;\n font-size: 12px;\n cursor: help;\n }\n }\n\n .pivot-zone-items {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n min-height: 32px;\n }\n\n .pivot-zone-placeholder {\n color: #bbb;\n font-size: 12px;\n padding: 4px 8px;\n width: 100%;\n text-align: center;\n }\n}\n\n.pivot-zone-item {\n display: flex;\n align-items: center;\n gap: 4px;\n padding: 4px 8px;\n background: #fafafa;\n border: 1px solid #d9d9d9;\n border-radius: 4px;\n font-size: 12px;\n cursor: grab;\n user-select: none;\n transition: all 0.2s;\n max-width: 100%;\n box-sizing: border-box;\n position: relative;\n\n &:hover {\n border-color: #1890ff;\n background: #f0f7ff;\n }\n\n &:active {\n cursor: grabbing;\n }\n\n // 拖拽插入位置指示线(行/列区域:左右指示)\n &.drag-before {\n box-shadow: -2px 0 0 0 #1890ff;\n }\n\n &.drag-after {\n box-shadow: 2px 0 0 0 #1890ff;\n }\n\n .pivot-zone-item-label {\n flex: 0 1 auto;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .pivot-zone-item-remove {\n color: #999;\n cursor: pointer;\n font-size: 10px;\n margin-left: 2px;\n flex-shrink: 0;\n\n &:hover {\n color: #ff4d4f;\n }\n }\n}\n\n.pivot-value-item {\n background: #fff7e6;\n border-color: #ffd591;\n flex-wrap: wrap;\n width: 100%;\n max-width: 100%;\n\n &:hover {\n border-color: #fa8c16;\n background: #fff7e6;\n }\n\n // 值区域:上下指示\n &.drag-before {\n box-shadow: 0 -2px 0 0 #1890ff;\n }\n\n &.drag-after {\n box-shadow: 0 2px 0 0 #1890ff;\n }\n\n .pivot-zone-item-label {\n flex-shrink: 0;\n }\n\n :deep(.ant-select) {\n flex: 1 1 auto;\n min-width: 70px;\n }\n\n :deep(.ant-input) {\n flex: 1 1 auto;\n min-width: 70px;\n }\n}\n\n.pivot-drop-zone-values {\n /* 值区域根据内容自动扩展,不再用 flex: 1 限制高度 */\n min-height: 80px;\n}\n\n.pivot-options {\n flex-shrink: 0;\n padding: 8px 0;\n border-top: 1px solid #f0f0f0;\n}\n</style>\n","import { ExclamationCircleOutlined } from '@ant-design/icons-vue';\nimport { message, Modal } from 'ant-design-vue';\nimport { h, reactive, Ref } from 'vue';\nimport { create_view_settings, update_view_settings } from 'liyu-pc-base/api/view-model';\nimport modalBox from 'liyu-pc-base/components/form-modal/modal-tools';\nexport interface ViewHook {\n saveView: () => void;\n addView: (view_type: string | null) => void;\n}\nexport interface ViewHookProps {\n currentView: Ref<any>;\n getViewData: () => any;\n isViewChange: Ref<boolean>;\n userid: number;\n view_project__flag: string;\n view_menu__flag: string;\n view_menu__name: string;\n fetchViews: () => void;\n is_auth: boolean;\n t: (key: string) => string;\n}\n\nexport const useView = (props: ViewHookProps): ViewHook => {\n const {\n currentView,\n getViewData,\n isViewChange,\n userid,\n view_project__flag,\n view_menu__flag,\n view_menu__name,\n fetchViews,\n is_auth,\n t,\n } = props;\n const saveView = () => {\n Modal.confirm({\n title: () => '确定覆盖视图吗?',\n content: '当前视图原有的数据会被覆盖',\n icon: () => h(ExclamationCircleOutlined),\n okText: '确定',\n async onOk() {\n currentView.value.data = getViewData();\n await update_view_settings({\n view_settings_id: currentView.value.id,\n data: currentView.value.data,\n });\n isViewChange.value = false;\n message.success('修改成功');\n },\n onCancel() {},\n });\n };\n const addView = (view_type: string | null) => {\n const tempModal = reactive({\n open: true,\n loading: false,\n title: t('新建视图'),\n form: {\n settings: { labelAlign: 'right', layout: 'vertical', col: [] },\n fields: [\n {\n type: 'input',\n name: 'name',\n label: t('视图名称'),\n disabled: false,\n allowClear: true,\n inputType: 'text',\n defaultValue: '',\n placeholder: t('请输入视图名称'),\n },\n ],\n rules: reactive({\n name: [{ required: true, message: t('请输入视图名称') }],\n }),\n model: reactive({ name: '', is_system: [false], view_type: 'personal' }),\n },\n options: {\n view_type: [\n { name: t('个人视图(仅自己可见)'), value: 'personal' },\n { name: t('公共视图(项目成员均可见)'), value: 'public' },\n ],\n is_system: [{ name: t('设为系统视图'), value: true }],\n },\n ok: async (data: any) => {\n const type = view_type || data.view_type || 'personal';\n const res = await create_view_settings({\n user_id: type === 'personal' ? userid : null,\n name: data.name,\n view_project__flag: view_project__flag,\n view_menu__flag: view_menu__flag,\n view_menu__name: view_menu__name,\n is_system: data.is_system && data.is_system[0],\n data: getViewData(),\n });\n await fetchViews();\n currentView.value = res;\n message.success(t('创建成功'));\n isViewChange.value = false;\n },\n });\n if (!view_type) {\n tempModal.form.fields.push({\n type: 'radio',\n name: 'view_type',\n label: t('视图可见范围'),\n disabled: false,\n allowClear: true,\n labelKey: 'name',\n valueKey: 'value',\n defaultValue: '',\n placeholder: '',\n } as any);\n }\n if (is_auth) {\n tempModal.form.fields.push({\n type: 'checkbox',\n name: 'is_system',\n label: '',\n disabled: false,\n allowClear: true,\n labelKey: 'name',\n valueKey: 'value',\n defaultValue: [false],\n } as any);\n }\n modalBox(tempModal);\n };\n return {\n saveView,\n addView,\n };\n};\n","<template>\n <div class=\"view-manage-container\">\n <div class=\"view-section\">\n <div class=\"section-header\">\n <span class=\"title\">{{ $t('个人视图') }}</span>\n <div class=\"header-actions\">\n <a-button\n type=\"link\"\n size=\"small\"\n @click=\"handleManageView('personal')\"\n >\n <template #icon><setting-outlined /></template>\n </a-button>\n <a-button\n type=\"link\"\n size=\"small\"\n @click=\"addView('personal')\"\n >\n <template #icon><plus-outlined /></template>\n </a-button>\n </div>\n </div>\n <s-table\n :selectedRowKeys=\"selectedRowKeys\"\n :columns=\"viewTableColumns\"\n :dataSource=\"personData\"\n :pagination=\"false\"\n size=\"small\"\n :showHeader=\"false\"\n row-key=\"id\"\n :range-selection=\"false\"\n >\n <template #bodyCell=\"{ column, record }\">\n <template v-if=\"column.dataIndex === 'name'\">\n <div class=\"view-item-row\">\n <span\n class=\"view-name\"\n @click=\"handleApplyView(record)\"\n >\n {{ record.name }}\n <a-tag\n v-if=\"record.is_default\"\n color=\"blue\"\n size=\"small\"\n style=\"margin-left: 4px\"\n >\n {{ $t('默认') }}\n </a-tag>\n <a-tag\n v-if=\"record.is_system\"\n color=\"orange\"\n size=\"small\"\n style=\"margin-left: 4px\"\n >\n {{ $t('系统') }}\n </a-tag>\n </span>\n <div\n class=\"view-actions\"\n v-if=\"!record.is_system || is_auth\"\n >\n <a-tooltip :title=\"$t('设为默认')\">\n <a-button\n type=\"text\"\n size=\"small\"\n @click=\"handleSetDefault(record)\"\n >\n <template #icon>\n <star-filled\n v-if=\"record.is_default\"\n style=\"color: #fadb14\"\n />\n <star-outlined v-else />\n </template>\n </a-button>\n </a-tooltip>\n <a-button\n type=\"text\"\n size=\"small\"\n @click=\"handleEditView(record)\"\n >\n <template #icon><edit-outlined /></template>\n </a-button>\n <a-button\n type=\"text\"\n size=\"small\"\n danger\n @click=\"handleDeleteView(record)\"\n >\n <template #icon><delete-outlined /></template>\n </a-button>\n </div>\n <span\n class=\"view-num\"\n style=\"float: right\"\n :style=\"\n currentView?.id === record.id ? { color: '#1890ff', fontWeight: 'bold' } : {}\n \"\n v-if=\"record.num\"\n :title=\"record.num\"\n >\n {{ record.num > 99 ? '99+' : record.num }}\n </span>\n </div>\n </template>\n </template>\n </s-table>\n </div>\n <div class=\"view-section\">\n <div class=\"section-header\">\n <span class=\"title\">{{ $t('公共视图') }}</span>\n <div class=\"header-actions\">\n <a-button\n type=\"link\"\n size=\"small\"\n @click=\"handleManageView('public')\"\n >\n <template #icon><setting-outlined /></template>\n </a-button>\n <a-button\n type=\"link\"\n size=\"small\"\n @click=\"addView('public')\"\n >\n <template #icon><plus-outlined /></template>\n </a-button>\n </div>\n </div>\n <s-table\n :selectedRowKeys=\"selectedRowKeys\"\n :columns=\"viewTableColumns\"\n :dataSource=\"publicData\"\n :pagination=\"false\"\n size=\"small\"\n :showHeader=\"false\"\n row-key=\"id\"\n :range-selection=\"false\"\n >\n <template #bodyCell=\"{ column, record }\">\n <template v-if=\"column.dataIndex === 'name'\">\n <div class=\"view-item-row\">\n <span\n class=\"view-name\"\n @click=\"handleApplyView(record)\"\n >\n {{ record.name }}\n <a-tag\n v-if=\"record.is_default\"\n color=\"blue\"\n size=\"small\"\n style=\"margin-left: 4px\"\n >\n {{ $t('默认') }}\n </a-tag>\n <a-tag\n v-if=\"record.is_system\"\n color=\"orange\"\n size=\"small\"\n style=\"margin-left: 4px\"\n >\n {{ $t('系统') }}\n </a-tag>\n </span>\n <div\n class=\"view-actions\"\n v-if=\"!record.is_system || is_auth\"\n >\n <a-tooltip :title=\"$t('设为默认')\">\n <a-button\n type=\"text\"\n size=\"small\"\n @click=\"handleSetDefault(record)\"\n >\n <template #icon>\n <star-filled\n v-if=\"record.is_default\"\n style=\"color: #fadb14\"\n />\n <star-outlined v-else />\n </template>\n </a-button>\n </a-tooltip>\n <a-button\n type=\"text\"\n size=\"small\"\n @click=\"handleEditView(record)\"\n >\n <template #icon><edit-outlined /></template>\n </a-button>\n <a-button\n type=\"text\"\n size=\"small\"\n danger\n @click=\"handleDeleteView(record)\"\n >\n <template #icon><delete-outlined /></template>\n </a-button>\n </div>\n <span\n class=\"view-num\"\n style=\"float: right\"\n :style=\"\n currentView?.id === record.id ? { color: '#1890ff', fontWeight: 'bold' } : {}\n \"\n v-if=\"record.num\"\n :title=\"record.num\"\n >\n {{ record.num > 99 ? '99+' : record.num }}\n </span>\n </div>\n </template>\n </template>\n </s-table>\n </div>\n </div>\n</template>\n\n<script lang=\"ts\">\nimport { computed, defineComponent, ref, onMounted, reactive, createVNode } from 'vue';\nimport {\n SettingOutlined,\n PlusOutlined,\n DeleteOutlined,\n EditOutlined,\n StarOutlined,\n StarFilled,\n ExclamationCircleOutlined,\n} from '@ant-design/icons-vue';\nimport { useI18n } from 'vue-i18n';\nimport { useUserStore, useEnv } from 'liyu-pc-base/init-plugin';\nimport {\n delete_view_settings,\n update_view_settings,\n set_view_settings_default,\n refresh_view_settings_cache,\n change_view_settings_sort,\n} from 'liyu-pc-base/api/view-model';\nimport { message, Modal } from 'ant-design-vue';\nimport modalBox from 'liyu-pc-base/components/form-modal/modal-tools';\nimport { useTableProState } from '../utils';\nimport { Column } from '../typing';\nimport { useView } from '../hooks/view';\n\nexport default defineComponent({\n name: 'ViewsConfig',\n components: {\n SettingOutlined,\n PlusOutlined,\n DeleteOutlined,\n EditOutlined,\n StarOutlined,\n StarFilled,\n },\n props: {\n columns: {\n type: Array as () => Array<Column>,\n default: () => [],\n },\n view_key: {\n type: String,\n default: '',\n },\n view_flag_name: {\n type: String,\n default: '',\n },\n is_view: {\n type: Boolean,\n default: false,\n },\n },\n setup(props) {\n const { t } = useI18n();\n const userStore = useUserStore();\n const env = useEnv();\n const current_org = userStore.currentOrg;\n const userid = userStore.userid;\n const VIEW_SYSTEM_EDIT = 'view_system_edit';\n const is_auth = ref(userStore.CHECK_AUTH(VIEW_SYSTEM_EDIT));\n\n const { setViewData, getViewData, viewDataList, fetchViews, currentView, isViewChange } =\n useTableProState();\n\n const viewTableColumns = [{ dataIndex: 'name', key: 'name' }];\n const selectedRowKeys = computed(() => {\n return [currentView.value?.id];\n });\n\n const personData = computed(() => {\n const list = viewDataList.value\n .filter((item: any) => !!item.user_id && item.is_system)\n .sort((a, b) => (a.sort == b.sort ? a.id - b.id : a.sort - b.sort));\n const list1 = viewDataList.value\n .filter((item: any) => !!item.user_id && !item.is_system)\n .sort((a, b) => (a.sort == b.sort ? a.id - b.id : a.sort - b.sort));\n return list.concat(list1);\n });\n\n const publicData = computed(() => {\n const list = viewDataList.value\n .filter((item: any) => !item.user_id && item.is_system)\n .sort((a, b) => (a.sort == b.sort ? a.id - b.id : a.sort - b.sort));\n const list1 = viewDataList.value\n .filter((item: any) => !item.user_id && !item.is_system)\n .sort((a, b) => (a.sort == b.sort ? a.id - b.id : a.sort - b.sort));\n return list.concat(list1);\n });\n\n const handleApplyView = (view: any) => {\n if (currentView.value?.id === view.id) {\n currentView.value = { id: 'no-view' };\n setViewData(null);\n message.warning(t('视图已取消'));\n } else {\n currentView.value = view;\n setViewData(view.data);\n message.success(t('已应用视图:') + view.name);\n }\n };\n\n const handleSetDefault = async (view: any) => {\n try {\n await set_view_settings_default({\n org_id: current_org.id,\n view_settings_id: view.id,\n });\n await refresh_view_settings_cache({\n org_id: current_org.id,\n view_settings_id: view.id,\n });\n message.success(t('设置默认成功'));\n fetchViews();\n } catch (e) {\n message.error(t('设置默认失败'));\n }\n };\n\n const handleDeleteView = (view: any) => {\n Modal.confirm({\n title: t('确认删除视图?'),\n content: t('视图删除后不可恢复,是否确认删除?'),\n icon: createVNode(ExclamationCircleOutlined),\n onOk: async () => {\n await delete_view_settings({\n org_id: current_org.id,\n view_settings_id: view.id,\n });\n message.success(t('删除成功'));\n fetchViews();\n },\n });\n };\n\n const handleEditView = (record: any) => {\n const tempModal = reactive({\n open: true,\n loading: false,\n title: t('编辑视图'),\n form: {\n settings: { labelAlign: 'right', layout: 'vertical', col: [] },\n fields: [\n {\n type: 'input',\n name: 'name',\n label: t('视图名称'),\n disabled: false,\n allowClear: true,\n inputType: 'text',\n defaultValue: record.name,\n placeholder: t('请输入视图名称'),\n },\n ],\n rules: reactive({\n name: [{ required: true, message: t('请输入视图名称') }],\n }),\n model: reactive({\n name: record.name,\n is_system: [record.is_system || false],\n }),\n },\n options: {\n is_system: [{ name: t('设为系统视图'), value: true }],\n },\n ok: async (data: any) => {\n await update_view_settings({\n org_id: current_org.id,\n view_settings_id: record.id,\n name: data.name,\n is_system: data.is_system && data.is_system[0],\n });\n message.success(t('修改成功'));\n fetchViews();\n },\n });\n\n if (is_auth.value) {\n tempModal.form.fields.push({\n type: 'checkbox',\n name: 'is_system',\n label: '',\n disabled: false,\n allowClear: true,\n labelKey: 'name',\n valueKey: 'value',\n defaultValue: [false],\n } as any);\n }\n modalBox(tempModal);\n };\n const { addView } = useView({\n currentView,\n getViewData,\n isViewChange,\n userid,\n view_project__flag: env.VITE_APP_VIEW_PROJECT_FLAG,\n view_menu__flag: props.view_key,\n view_menu__name: props.view_flag_name,\n fetchViews,\n is_auth,\n t,\n });\n\n const handleManageView = (view_type: string) => {\n const tempModal = reactive({\n open: true,\n component: 'ViewEditModal',\n compObj: {\n title: view_type == 'personal' ? t('个人视图管理') : t('公共视图管理'),\n data: view_type == 'personal' ? personData.value : publicData.value,\n },\n ok: (ids: any) => {\n if (ids && ids.length > 0) {\n change_view_settings_sort({\n org_id: current_org.id,\n view_settings_ids: ids,\n }).then(() => {\n message.success(t('保存成功'));\n fetchViews();\n });\n } else {\n message.success(t('保存成功'));\n fetchViews();\n }\n },\n cancel: (isEdit: any) => {\n if (isEdit) {\n fetchViews();\n }\n },\n });\n modalBox(tempModal);\n };\n\n return {\n viewTableColumns,\n personData,\n publicData,\n handleApplyView,\n handleSetDefault,\n handleDeleteView,\n handleEditView,\n addView,\n handleManageView,\n is_auth,\n fetchViews,\n selectedRowKeys,\n currentView,\n };\n },\n});\n</script>\n\n<style lang=\"less\" scoped>\n.view-manage-container {\n display: flex;\n gap: 16px;\n height: 400px;\n overflow-y: auto;\n\n .view-section {\n flex: 1;\n border: 1px solid #f0f0f0;\n border-radius: 4px;\n padding: 8px;\n\n .section-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 8px;\n padding-bottom: 4px;\n border-bottom: 1px solid #f0f0f0;\n\n .title {\n font-weight: bold;\n }\n\n .header-actions {\n display: flex;\n align-items: center;\n }\n }\n }\n}\n\n.view-item-row {\n display: flex;\n justify-content: space-between;\n align-items: center;\n width: 100%;\n\n .view-name {\n cursor: pointer;\n flex: 1;\n padding: 4px 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n flex: 0 1 auto;\n &:hover {\n color: #1890ff;\n }\n }\n\n .view-actions {\n display: flex;\n gap: 4px;\n opacity: 0;\n transition: opacity 0.2s;\n }\n\n &:hover .view-actions {\n opacity: 1;\n }\n}\n.view-num {\n display: inline-block;\n white-space: nowrap;\n}\n</style>\n","<template>\n <div class=\"view-manage-container\">\n <div class=\"view-section\">\n <div class=\"section-header\">\n <span class=\"title\">{{ $t('个人视图') }}</span>\n <div class=\"header-actions\">\n <a-button\n type=\"link\"\n size=\"small\"\n @click=\"handleManageView('personal')\"\n >\n <template #icon><setting-outlined /></template>\n </a-button>\n <a-button\n type=\"link\"\n size=\"small\"\n @click=\"addView('personal')\"\n >\n <template #icon><plus-outlined /></template>\n </a-button>\n </div>\n </div>\n <s-table\n :selectedRowKeys=\"selectedRowKeys\"\n :columns=\"viewTableColumns\"\n :dataSource=\"personData\"\n :pagination=\"false\"\n size=\"small\"\n :showHeader=\"false\"\n row-key=\"id\"\n :range-selection=\"false\"\n >\n <template #bodyCell=\"{ column, record }\">\n <template v-if=\"column.dataIndex === 'name'\">\n <div class=\"view-item-row\">\n <span\n class=\"view-name\"\n @click=\"handleApplyView(record)\"\n >\n {{ record.name }}\n <a-tag\n v-if=\"record.is_default\"\n color=\"blue\"\n size=\"small\"\n style=\"margin-left: 4px\"\n >\n {{ $t('默认') }}\n </a-tag>\n <a-tag\n v-if=\"record.is_system\"\n color=\"orange\"\n size=\"small\"\n style=\"margin-left: 4px\"\n >\n {{ $t('系统') }}\n </a-tag>\n </span>\n <div\n class=\"view-actions\"\n v-if=\"!record.is_system || is_auth\"\n >\n <a-tooltip :title=\"$t('设为默认')\">\n <a-button\n type=\"text\"\n size=\"small\"\n @click=\"handleSetDefault(record)\"\n >\n <template #icon>\n <star-filled\n v-if=\"record.is_default\"\n style=\"color: #fadb14\"\n />\n <star-outlined v-else />\n </template>\n </a-button>\n </a-tooltip>\n <a-button\n type=\"text\"\n size=\"small\"\n @click=\"handleEditView(record)\"\n >\n <template #icon><edit-outlined /></template>\n </a-button>\n <a-button\n type=\"text\"\n size=\"small\"\n danger\n @click=\"handleDeleteView(record)\"\n >\n <template #icon><delete-outlined /></template>\n </a-button>\n </div>\n <span\n class=\"view-num\"\n style=\"float: right\"\n :style=\"\n currentView?.id === record.id ? { color: '#1890ff', fontWeight: 'bold' } : {}\n \"\n v-if=\"record.num\"\n :title=\"record.num\"\n >\n {{ record.num > 99 ? '99+' : record.num }}\n </span>\n </div>\n </template>\n </template>\n </s-table>\n </div>\n <div class=\"view-section\">\n <div class=\"section-header\">\n <span class=\"title\">{{ $t('公共视图') }}</span>\n <div class=\"header-actions\">\n <a-button\n type=\"link\"\n size=\"small\"\n @click=\"handleManageView('public')\"\n >\n <template #icon><setting-outlined /></template>\n </a-button>\n <a-button\n type=\"link\"\n size=\"small\"\n @click=\"addView('public')\"\n >\n <template #icon><plus-outlined /></template>\n </a-button>\n </div>\n </div>\n <s-table\n :selectedRowKeys=\"selectedRowKeys\"\n :columns=\"viewTableColumns\"\n :dataSource=\"publicData\"\n :pagination=\"false\"\n size=\"small\"\n :showHeader=\"false\"\n row-key=\"id\"\n :range-selection=\"false\"\n >\n <template #bodyCell=\"{ column, record }\">\n <template v-if=\"column.dataIndex === 'name'\">\n <div class=\"view-item-row\">\n <span\n class=\"view-name\"\n @click=\"handleApplyView(record)\"\n >\n {{ record.name }}\n <a-tag\n v-if=\"record.is_default\"\n color=\"blue\"\n size=\"small\"\n style=\"margin-left: 4px\"\n >\n {{ $t('默认') }}\n </a-tag>\n <a-tag\n v-if=\"record.is_system\"\n color=\"orange\"\n size=\"small\"\n style=\"margin-left: 4px\"\n >\n {{ $t('系统') }}\n </a-tag>\n </span>\n <div\n class=\"view-actions\"\n v-if=\"!record.is_system || is_auth\"\n >\n <a-tooltip :title=\"$t('设为默认')\">\n <a-button\n type=\"text\"\n size=\"small\"\n @click=\"handleSetDefault(record)\"\n >\n <template #icon>\n <star-filled\n v-if=\"record.is_default\"\n style=\"color: #fadb14\"\n />\n <star-outlined v-else />\n </template>\n </a-button>\n </a-tooltip>\n <a-button\n type=\"text\"\n size=\"small\"\n @click=\"handleEditView(record)\"\n >\n <template #icon><edit-outlined /></template>\n </a-button>\n <a-button\n type=\"text\"\n size=\"small\"\n danger\n @click=\"handleDeleteView(record)\"\n >\n <template #icon><delete-outlined /></template>\n </a-button>\n </div>\n <span\n class=\"view-num\"\n style=\"float: right\"\n :style=\"\n currentView?.id === record.id ? { color: '#1890ff', fontWeight: 'bold' } : {}\n \"\n v-if=\"record.num\"\n :title=\"record.num\"\n >\n {{ record.num > 99 ? '99+' : record.num }}\n </span>\n </div>\n </template>\n </template>\n </s-table>\n </div>\n </div>\n</template>\n\n<script lang=\"ts\">\nimport { computed, defineComponent, ref, onMounted, reactive, createVNode } from 'vue';\nimport {\n SettingOutlined,\n PlusOutlined,\n DeleteOutlined,\n EditOutlined,\n StarOutlined,\n StarFilled,\n ExclamationCircleOutlined,\n} from '@ant-design/icons-vue';\nimport { useI18n } from 'vue-i18n';\nimport { useUserStore, useEnv } from 'liyu-pc-base/init-plugin';\nimport {\n delete_view_settings,\n update_view_settings,\n set_view_settings_default,\n refresh_view_settings_cache,\n change_view_settings_sort,\n} from 'liyu-pc-base/api/view-model';\nimport { message, Modal } from 'ant-design-vue';\nimport modalBox from 'liyu-pc-base/components/form-modal/modal-tools';\nimport { useTableProState } from '../utils';\nimport { Column } from '../typing';\nimport { useView } from '../hooks/view';\n\nexport default defineComponent({\n name: 'ViewsConfig',\n components: {\n SettingOutlined,\n PlusOutlined,\n DeleteOutlined,\n EditOutlined,\n StarOutlined,\n StarFilled,\n },\n props: {\n columns: {\n type: Array as () => Array<Column>,\n default: () => [],\n },\n view_key: {\n type: String,\n default: '',\n },\n view_flag_name: {\n type: String,\n default: '',\n },\n is_view: {\n type: Boolean,\n default: false,\n },\n },\n setup(props) {\n const { t } = useI18n();\n const userStore = useUserStore();\n const env = useEnv();\n const current_org = userStore.currentOrg;\n const userid = userStore.userid;\n const VIEW_SYSTEM_EDIT = 'view_system_edit';\n const is_auth = ref(userStore.CHECK_AUTH(VIEW_SYSTEM_EDIT));\n\n const { setViewData, getViewData, viewDataList, fetchViews, currentView, isViewChange } =\n useTableProState();\n\n const viewTableColumns = [{ dataIndex: 'name', key: 'name' }];\n const selectedRowKeys = computed(() => {\n return [currentView.value?.id];\n });\n\n const personData = computed(() => {\n const list = viewDataList.value\n .filter((item: any) => !!item.user_id && item.is_system)\n .sort((a, b) => (a.sort == b.sort ? a.id - b.id : a.sort - b.sort));\n const list1 = viewDataList.value\n .filter((item: any) => !!item.user_id && !item.is_system)\n .sort((a, b) => (a.sort == b.sort ? a.id - b.id : a.sort - b.sort));\n return list.concat(list1);\n });\n\n const publicData = computed(() => {\n const list = viewDataList.value\n .filter((item: any) => !item.user_id && item.is_system)\n .sort((a, b) => (a.sort == b.sort ? a.id - b.id : a.sort - b.sort));\n const list1 = viewDataList.value\n .filter((item: any) => !item.user_id && !item.is_system)\n .sort((a, b) => (a.sort == b.sort ? a.id - b.id : a.sort - b.sort));\n return list.concat(list1);\n });\n\n const handleApplyView = (view: any) => {\n if (currentView.value?.id === view.id) {\n currentView.value = { id: 'no-view' };\n setViewData(null);\n message.warning(t('视图已取消'));\n } else {\n currentView.value = view;\n setViewData(view.data);\n message.success(t('已应用视图:') + view.name);\n }\n };\n\n const handleSetDefault = async (view: any) => {\n try {\n await set_view_settings_default({\n org_id: current_org.id,\n view_settings_id: view.id,\n });\n await refresh_view_settings_cache({\n org_id: current_org.id,\n view_settings_id: view.id,\n });\n message.success(t('设置默认成功'));\n fetchViews();\n } catch (e) {\n message.error(t('设置默认失败'));\n }\n };\n\n const handleDeleteView = (view: any) => {\n Modal.confirm({\n title: t('确认删除视图?'),\n content: t('视图删除后不可恢复,是否确认删除?'),\n icon: createVNode(ExclamationCircleOutlined),\n onOk: async () => {\n await delete_view_settings({\n org_id: current_org.id,\n view_settings_id: view.id,\n });\n message.success(t('删除成功'));\n fetchViews();\n },\n });\n };\n\n const handleEditView = (record: any) => {\n const tempModal = reactive({\n open: true,\n loading: false,\n title: t('编辑视图'),\n form: {\n settings: { labelAlign: 'right', layout: 'vertical', col: [] },\n fields: [\n {\n type: 'input',\n name: 'name',\n label: t('视图名称'),\n disabled: false,\n allowClear: true,\n inputType: 'text',\n defaultValue: record.name,\n placeholder: t('请输入视图名称'),\n },\n ],\n rules: reactive({\n name: [{ required: true, message: t('请输入视图名称') }],\n }),\n model: reactive({\n name: record.name,\n is_system: [record.is_system || false],\n }),\n },\n options: {\n is_system: [{ name: t('设为系统视图'), value: true }],\n },\n ok: async (data: any) => {\n await update_view_settings({\n org_id: current_org.id,\n view_settings_id: record.id,\n name: data.name,\n is_system: data.is_system && data.is_system[0],\n });\n message.success(t('修改成功'));\n fetchViews();\n },\n });\n\n if (is_auth.value) {\n tempModal.form.fields.push({\n type: 'checkbox',\n name: 'is_system',\n label: '',\n disabled: false,\n allowClear: true,\n labelKey: 'name',\n valueKey: 'value',\n defaultValue: [false],\n } as any);\n }\n modalBox(tempModal);\n };\n const { addView } = useView({\n currentView,\n getViewData,\n isViewChange,\n userid,\n view_project__flag: env.VITE_APP_VIEW_PROJECT_FLAG,\n view_menu__flag: props.view_key,\n view_menu__name: props.view_flag_name,\n fetchViews,\n is_auth,\n t,\n });\n\n const handleManageView = (view_type: string) => {\n const tempModal = reactive({\n open: true,\n component: 'ViewEditModal',\n compObj: {\n title: view_type == 'personal' ? t('个人视图管理') : t('公共视图管理'),\n data: view_type == 'personal' ? personData.value : publicData.value,\n },\n ok: (ids: any) => {\n if (ids && ids.length > 0) {\n change_view_settings_sort({\n org_id: current_org.id,\n view_settings_ids: ids,\n }).then(() => {\n message.success(t('保存成功'));\n fetchViews();\n });\n } else {\n message.success(t('保存成功'));\n fetchViews();\n }\n },\n cancel: (isEdit: any) => {\n if (isEdit) {\n fetchViews();\n }\n },\n });\n modalBox(tempModal);\n };\n\n return {\n viewTableColumns,\n personData,\n publicData,\n handleApplyView,\n handleSetDefault,\n handleDeleteView,\n handleEditView,\n addView,\n handleManageView,\n is_auth,\n fetchViews,\n selectedRowKeys,\n currentView,\n };\n },\n});\n</script>\n\n<style lang=\"less\" scoped>\n.view-manage-container {\n display: flex;\n gap: 16px;\n height: 400px;\n overflow-y: auto;\n\n .view-section {\n flex: 1;\n border: 1px solid #f0f0f0;\n border-radius: 4px;\n padding: 8px;\n\n .section-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 8px;\n padding-bottom: 4px;\n border-bottom: 1px solid #f0f0f0;\n\n .title {\n font-weight: bold;\n }\n\n .header-actions {\n display: flex;\n align-items: center;\n }\n }\n }\n}\n\n.view-item-row {\n display: flex;\n justify-content: space-between;\n align-items: center;\n width: 100%;\n\n .view-name {\n cursor: pointer;\n flex: 1;\n padding: 4px 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n flex: 0 1 auto;\n &:hover {\n color: #1890ff;\n }\n }\n\n .view-actions {\n display: flex;\n gap: 4px;\n opacity: 0;\n transition: opacity 0.2s;\n }\n\n &:hover .view-actions {\n opacity: 1;\n }\n}\n.view-num {\n display: inline-block;\n white-space: nowrap;\n}\n</style>\n","<template>\n <div class=\"column-edit-view-wrapper\">\n <a-tabs v-model:activeKey=\"activeTab\">\n <a-tab-pane\n key=\"columns\"\n :tab=\"component_type === 'normal' ? $t('列设置') : $t('字段设置')\"\n >\n <div class=\"tab-content-scroll\">\n <pivot-config-comp\n v-if=\"component_type === 'pivot_table'\"\n :columns=\"columns\"\n :modelValue=\"pivotConfig\"\n @update:modelValue=\"onPivotConfigChange\"\n @change=\"onPivotConfigChange\"\n />\n <columns-config\n v-else-if=\"component_type === 'normal'\"\n :columns=\"columns\"\n @change=\"onColumnChange\"\n />\n </div>\n </a-tab-pane>\n <a-tab-pane\n key=\"views\"\n :tab=\"$t('视图管理')\"\n v-if=\"is_view\"\n >\n <div class=\"tab-content-scroll\">\n <views-config\n :columns=\"columns\"\n :view_key=\"view_key\"\n :view_flag_name=\"view_flag_name\"\n :is_view=\"is_view\"\n />\n </div>\n </a-tab-pane>\n </a-tabs>\n </div>\n</template>\n\n<script lang=\"ts\">\nimport { defineComponent, ref, watch } from 'vue';\nimport { Column, PivotConfig } from '../typing';\nimport ColumnsConfig from './columnsConfig.vue';\nimport PivotConfigComp from './pivotConfig.vue';\nimport ViewsConfig from './viewsConfig.vue';\nimport { useTableProState } from '../utils';\n\nexport default defineComponent({\n name: 'ColumnEditView',\n components: {\n ColumnsConfig,\n PivotConfigComp,\n ViewsConfig,\n },\n props: {\n columns: {\n type: Array as () => Array<Column>,\n default: () => [],\n },\n view_key: {\n type: String,\n default: '',\n },\n view_flag_name: {\n type: String,\n default: '',\n },\n is_view: {\n type: Boolean,\n default: false,\n },\n component_type: {\n type: String,\n default: 'normal',\n },\n pivotConfig: {\n type: Object as () => PivotConfig | null,\n default: () => null,\n },\n },\n emits: ['change', 'pivotConfigChange'],\n setup(props, { emit }) {\n const activeTab = ref('columns');\n\n const onColumnChange = (data: any) => {\n emit('change', data);\n };\n const onPivotConfigChange = (data: PivotConfig) => {\n emit('pivotConfigChange', data);\n };\n const { fetchViews } = useTableProState();\n watch(\n () => activeTab.value,\n val => {\n if (val === 'views') {\n fetchViews();\n }\n },\n );\n\n return {\n activeTab,\n onColumnChange,\n onPivotConfigChange,\n };\n },\n});\n</script>\n\n<style lang=\"less\" scoped>\n.column-edit-view-wrapper {\n padding: 0 8px;\n}\n.tab-content-scroll {\n max-height: 60vh;\n overflow-y: auto;\n}\n</style>\n","<template>\n <div class=\"column-edit-view-wrapper\">\n <a-tabs v-model:activeKey=\"activeTab\">\n <a-tab-pane\n key=\"columns\"\n :tab=\"component_type === 'normal' ? $t('列设置') : $t('字段设置')\"\n >\n <div class=\"tab-content-scroll\">\n <pivot-config-comp\n v-if=\"component_type === 'pivot_table'\"\n :columns=\"columns\"\n :modelValue=\"pivotConfig\"\n @update:modelValue=\"onPivotConfigChange\"\n @change=\"onPivotConfigChange\"\n />\n <columns-config\n v-else-if=\"component_type === 'normal'\"\n :columns=\"columns\"\n @change=\"onColumnChange\"\n />\n </div>\n </a-tab-pane>\n <a-tab-pane\n key=\"views\"\n :tab=\"$t('视图管理')\"\n v-if=\"is_view\"\n >\n <div class=\"tab-content-scroll\">\n <views-config\n :columns=\"columns\"\n :view_key=\"view_key\"\n :view_flag_name=\"view_flag_name\"\n :is_view=\"is_view\"\n />\n </div>\n </a-tab-pane>\n </a-tabs>\n </div>\n</template>\n\n<script lang=\"ts\">\nimport { defineComponent, ref, watch } from 'vue';\nimport { Column, PivotConfig } from '../typing';\nimport ColumnsConfig from './columnsConfig.vue';\nimport PivotConfigComp from './pivotConfig.vue';\nimport ViewsConfig from './viewsConfig.vue';\nimport { useTableProState } from '../utils';\n\nexport default defineComponent({\n name: 'ColumnEditView',\n components: {\n ColumnsConfig,\n PivotConfigComp,\n ViewsConfig,\n },\n props: {\n columns: {\n type: Array as () => Array<Column>,\n default: () => [],\n },\n view_key: {\n type: String,\n default: '',\n },\n view_flag_name: {\n type: String,\n default: '',\n },\n is_view: {\n type: Boolean,\n default: false,\n },\n component_type: {\n type: String,\n default: 'normal',\n },\n pivotConfig: {\n type: Object as () => PivotConfig | null,\n default: () => null,\n },\n },\n emits: ['change', 'pivotConfigChange'],\n setup(props, { emit }) {\n const activeTab = ref('columns');\n\n const onColumnChange = (data: any) => {\n emit('change', data);\n };\n const onPivotConfigChange = (data: PivotConfig) => {\n emit('pivotConfigChange', data);\n };\n const { fetchViews } = useTableProState();\n watch(\n () => activeTab.value,\n val => {\n if (val === 'views') {\n fetchViews();\n }\n },\n );\n\n return {\n activeTab,\n onColumnChange,\n onPivotConfigChange,\n };\n },\n});\n</script>\n\n<style lang=\"less\" scoped>\n.column-edit-view-wrapper {\n padding: 0 8px;\n}\n.tab-content-scroll {\n max-height: 60vh;\n overflow-y: auto;\n}\n</style>\n","import { ConfirmModelConfig } from 'liyu-pc-base/api/typing';\n\nimport { useUserStore } from 'liyu-pc-base/init-plugin';\n\nimport { Modal } from 'ant-design-vue';\nimport Handlebars from 'handlebars';\nimport { HeadBtnConfig } from 'liyu-pc-base/api/typing';\nimport { useRequest } from 'liyu-pc-base/init-plugin';\nimport { getObjListBySelectedRowKeys } from 'liyu-pc-base/utils/function';\nimport { unref } from 'vue';\n\nexport const head_btn_confirm = ({\n dataSource,\n button,\n selectedRowKeys,\n event_obj,\n}: {\n dataSource: any[];\n button: HeadBtnConfig;\n selectedRowKeys: any[];\n event_obj: any;\n}) => {\n const request = useRequest();\n selectedRowKeys = unref(selectedRowKeys);\n const preProcessData = button.preProcessData;\n const model_config = button.model_config as ConfirmModelConfig;\n const init_data = model_config.init_data;\n const batch_api_fields = model_config.batch_api_fields;\n const title = model_config.title;\n const content = model_config.content;\n const ok_url = model_config.ok_url;\n const cancel_url = model_config.cancel_url;\n const method = model_config.method || 'post';\n const userStore = useUserStore();\n const current_org = userStore.currentOrg; // 当前组织org\n const org_id = current_org?.id;\n let api_data = dataSource as any;\n if (preProcessData) {\n api_data = preProcessData({ dataSource, selectedRowKeys });\n }\n if (batch_api_fields) {\n api_data = getObjListBySelectedRowKeys(batch_api_fields, dataSource, selectedRowKeys);\n }\n if (init_data) {\n api_data = { ...api_data, ...init_data };\n }\n api_data = { ...api_data, org_id };\n\n const titleTemplate = Handlebars.compile(title || '');\n const contentTemplate = Handlebars.compile(content || '');\n\n Modal.confirm({\n title: titleTemplate({ record: api_data }),\n content: contentTemplate({ record: api_data }),\n onOk() {\n if (ok_url) {\n request[method](ok_url, api_data).then(() => {\n event_obj.emit('refresh');\n });\n }\n },\n onCancel() {\n if (cancel_url) {\n request[method](cancel_url, api_data).then(() => {\n event_obj.emit('refresh');\n });\n }\n },\n });\n};\n","import { ComponentModelConfig, HeadBtnConfig } from 'liyu-pc-base/api/typing';\n\nimport { useUserStore } from 'liyu-pc-base/init-plugin';\n\nimport Handlebars from 'handlebars';\nimport modalBox from 'liyu-pc-base/components/form-modal/modal-tools';\nimport { useRequest } from 'liyu-pc-base/init-plugin';\nimport { getObjListBySelectedRowKeys } from 'liyu-pc-base/utils/function';\nimport { reactive, unref } from 'vue';\n\nexport const head_btn_custom_component = ({\n dataSource,\n button,\n selectedRowKeys,\n event_obj,\n}: {\n dataSource: any[];\n button: HeadBtnConfig;\n selectedRowKeys: any[];\n event_obj: any;\n}) => {\n const request = useRequest();\n const preProcessData = button.preProcessData;\n const model_config = button.model_config as ComponentModelConfig;\n const title = model_config.title;\n const component = model_config.component;\n const ok_url = model_config.ok_url;\n const cancel_url = model_config.cancel_url;\n const method = model_config.method || 'post';\n const init_data = model_config.init_data;\n const batch_api_fields = model_config.batch_api_fields;\n const userStore = useUserStore();\n const current_org = userStore.currentOrg; // 当前组织org\n const org_id = current_org?.id;\n let api_data = dataSource;\n if (preProcessData) {\n api_data = preProcessData({ dataSource, selectedRowKeys });\n }\n if (init_data) {\n api_data = { ...api_data, ...init_data };\n }\n const tempModal = reactive({\n open: true,\n loading: false,\n component: component,\n record: unref(api_data),\n dataSource: dataSource,\n button: button,\n title: Handlebars.compile(title || '')({ record: api_data }),\n ok: (data: any) => {\n data = { ...data, org_id };\n if (batch_api_fields) {\n data = {\n ...data,\n ...getObjListBySelectedRowKeys(batch_api_fields, dataSource, selectedRowKeys),\n };\n }\n if (ok_url) {\n request[method](ok_url, data).then(() => {\n event_obj.emit('refresh');\n });\n }\n },\n cancel: (data: any) => {\n data = { ...data, org_id };\n if (batch_api_fields) {\n data = {\n ...data,\n ...getObjListBySelectedRowKeys(batch_api_fields, dataSource, selectedRowKeys),\n };\n }\n if (cancel_url) {\n request[method](cancel_url, data).then(() => {\n event_obj.emit('refresh');\n });\n }\n },\n });\n modalBox(tempModal);\n};\n","import { FormModelConfig, HeadBtnConfig } from 'liyu-pc-base/api/typing';\n\nimport { useUserStore } from 'liyu-pc-base/init-plugin';\n\nimport { message } from 'ant-design-vue';\nimport Handlebars from 'handlebars';\nimport modalBox from 'liyu-pc-base/components/form-modal/modal-tools';\nimport { useRequest } from 'liyu-pc-base/init-plugin';\nimport { getObjList, getObjListBySelectedRowKeys } from 'liyu-pc-base/utils/function';\nimport { reactive } from 'vue';\nexport const head_btn_form = ({\n dataSource,\n button,\n selectedRowKeys,\n event_obj,\n}: {\n dataSource: any[];\n button: HeadBtnConfig;\n selectedRowKeys: any[];\n event_obj: any;\n}) => {\n const request = useRequest();\n const preProcessData = button.preProcessData;\n const model_config = button.model_config as FormModelConfig;\n const title = model_config.title;\n const ok_url = model_config.ok_url;\n const cancel_url = model_config.cancel_url;\n const method = model_config.method || 'post';\n const init_data = model_config.init_data;\n const api_fields = model_config.api_fields;\n const batch_api_fields = model_config.batch_api_fields;\n const form_config = model_config.form;\n const userStore = useUserStore();\n const current_org = userStore.currentOrg; // 当前组织org\n const org_id = current_org?.id;\n\n let record = null;\n if (preProcessData) {\n record = preProcessData({ dataSource, selectedRowKeys });\n } else {\n record = dataSource.find(item => selectedRowKeys.includes(item.id));\n }\n\n let model_data = {\n ...form_config.model,\n ...record,\n };\n if (api_fields) {\n model_data = {\n ...model_data,\n ...getObjList(api_fields, record),\n };\n }\n if (init_data) {\n model_data = {\n ...model_data,\n ...init_data,\n };\n }\n // 创建表单模态框配置\n const form_modal_config = reactive({\n settings: form_config.settings || {\n labelAlign: 'right',\n layout: 'vertical',\n col: [],\n },\n dynamicFieldList: form_config.dynamicFieldList || [],\n model: reactive(model_data),\n rules: form_config.rules || {},\n options: form_config.options || {},\n });\n\n // 创建模态框\n const tempModal = reactive({\n open: true,\n loading: false,\n title: Handlebars.compile(title || '')({ record: model_data }),\n form: form_modal_config,\n ok: (data: any) => {\n return new Promise(function (resolve, reject) {\n if (!ok_url) {\n resolve(null);\n return;\n }\n tempModal.loading = true;\n let submit_data = data;\n // if (api_fields) {\n // submit_data = {\n // ...submit_data,\n // ...getObjList(api_fields, data),\n // }\n // }\n if (batch_api_fields) {\n submit_data = {\n ...submit_data,\n ...getObjListBySelectedRowKeys(batch_api_fields, dataSource, selectedRowKeys),\n };\n }\n if (button.beforeCommitProcessData) {\n submit_data = button.beforeCommitProcessData({\n dataSource,\n selectedRowKeys,\n data: submit_data,\n });\n }\n submit_data.org_id = org_id;\n\n request({\n url: ok_url,\n method: method,\n data: submit_data,\n })\n .then(() => {\n message.success('操作成功');\n event_obj.emit('refresh');\n resolve(null);\n })\n .catch(error => {\n reject(error);\n })\n .finally(() => {\n tempModal.loading = false;\n });\n });\n },\n cancel: (data: any) => {\n return new Promise(function (resolve, reject) {\n if (!cancel_url) {\n resolve(null);\n return;\n }\n tempModal.loading = true;\n\n let submit_data = data;\n // if (api_fields) {\n // submit_data = {\n // ...submit_data,\n // ...getObjList(api_fields, data),\n // }\n // }\n if (batch_api_fields) {\n submit_data = {\n ...submit_data,\n ...getObjListBySelectedRowKeys(batch_api_fields, dataSource, selectedRowKeys),\n };\n }\n if (button.beforeCommitProcessData) {\n submit_data = button.beforeCommitProcessData({\n dataSource,\n selectedRowKeys,\n data: submit_data,\n });\n }\n submit_data.org_id = org_id;\n\n request({\n url: cancel_url,\n method: method,\n data: submit_data,\n })\n .then(() => {\n event_obj.emit('refresh');\n resolve(null);\n })\n .catch(error => {\n reject(error);\n })\n .finally(() => {\n tempModal.loading = false;\n });\n });\n },\n });\n\n // 显示模态框\n modalBox(tempModal);\n};\n","<template>\n <template\n v-for=\"(item, index) in children_list\"\n :key=\"index\"\n >\n <template v-if=\"item?.children && item.children.length > 0\">\n <a-sub-menu\n :key=\"index\"\n :title=\"item.name\"\n :disabled=\"item.disabled\"\n >\n <head-btn-children\n :children_list=\"item.children\"\n :selected-row-keys=\"selectedRowKeys\"\n :dataSource=\"dataSource\"\n :current_org=\"current_org\"\n :handleBtnClick=\"handleBtnClick\"\n />\n </a-sub-menu>\n </template>\n <template v-else>\n <a-menu-item\n :key=\"index\"\n :disabled=\"item.disabled\"\n @click=\"\n () => {\n handleBtnClick(item, {\n searchModel: searchConfig.model,\n dataSource: dataSource,\n selectedRowKeys: selectedRowKeys,\n searchConfigOptions: searchConfig.options,\n current_org: current_org,\n });\n }\n \"\n >\n {{ item.name }}\n </a-menu-item>\n </template>\n </template>\n</template>\n<script lang=\"ts\">\nimport { HeadBtnListConfig } from 'liyu-pc-base/api/typing';\nimport { defineComponent, PropType } from 'vue';\n\nexport default defineComponent({\n name: 'HeadBtnChildren',\n props: {\n children_list: {\n type: Array as PropType<HeadBtnListConfig>,\n required: true,\n },\n selectedRowKeys: {\n type: Array as PropType<any[]>,\n required: true,\n },\n dataSource: {\n type: Array as PropType<any[]>,\n required: true,\n },\n current_org: {\n type: Object as PropType<any>,\n required: true,\n },\n handleBtnClick: {\n type: Function as PropType<any>,\n required: true,\n },\n },\n setup(props) {\n return {};\n },\n});\n</script>\n","<template>\n <template\n v-for=\"(item, index) in children_list\"\n :key=\"index\"\n >\n <template v-if=\"item?.children && item.children.length > 0\">\n <a-sub-menu\n :key=\"index\"\n :title=\"item.name\"\n :disabled=\"item.disabled\"\n >\n <head-btn-children\n :children_list=\"item.children\"\n :selected-row-keys=\"selectedRowKeys\"\n :dataSource=\"dataSource\"\n :current_org=\"current_org\"\n :handleBtnClick=\"handleBtnClick\"\n />\n </a-sub-menu>\n </template>\n <template v-else>\n <a-menu-item\n :key=\"index\"\n :disabled=\"item.disabled\"\n @click=\"\n () => {\n handleBtnClick(item, {\n searchModel: searchConfig.model,\n dataSource: dataSource,\n selectedRowKeys: selectedRowKeys,\n searchConfigOptions: searchConfig.options,\n current_org: current_org,\n });\n }\n \"\n >\n {{ item.name }}\n </a-menu-item>\n </template>\n </template>\n</template>\n<script lang=\"ts\">\nimport { HeadBtnListConfig } from 'liyu-pc-base/api/typing';\nimport { defineComponent, PropType } from 'vue';\n\nexport default defineComponent({\n name: 'HeadBtnChildren',\n props: {\n children_list: {\n type: Array as PropType<HeadBtnListConfig>,\n required: true,\n },\n selectedRowKeys: {\n type: Array as PropType<any[]>,\n required: true,\n },\n dataSource: {\n type: Array as PropType<any[]>,\n required: true,\n },\n current_org: {\n type: Object as PropType<any>,\n required: true,\n },\n handleBtnClick: {\n type: Function as PropType<any>,\n required: true,\n },\n },\n setup(props) {\n return {};\n },\n});\n</script>\n","<template>\n <template\n v-for=\"(btn, index) in filter_head_btn_list\"\n :key=\"index\"\n >\n <a-button\n v-if=\"!btn.children || btn.children?.length == 0\"\n :type=\"btn.clazz\"\n size=\"small\"\n style=\"margin-right: 5px\"\n :disabled=\"btn.disabled\"\n @click=\"\n handleBtnClick(btn, {\n dataSource: dataSource,\n selectedRowKeys: selectedRowKeys,\n current_org: current_org,\n router: router,\n })\n \"\n >\n <plus-outlined v-if=\"btn.icon === 'plus-outlined'\" />\n {{ btn.name }}\n </a-button>\n <a-dropdown\n v-else\n v-model:open=\"isMenuOpen[index]\"\n trigger=\"click\"\n >\n <a-button\n :bordered=\"false\"\n size=\"small\"\n >\n {{ btn.name }}\n <down-outlined\n v-if=\"!isMenuOpen[index]\"\n style=\"font-size: 10px; cursor: pointer\"\n />\n <up-outlined\n v-if=\"isMenuOpen[index]\"\n style=\"font-size: 10px; cursor: pointer\"\n />\n </a-button>\n <template #overlay>\n <a-menu>\n <head-btn-children\n :children_list=\"btn.children\"\n :selected-row-keys=\"selectedRowKeys\"\n :dataSource=\"dataSource\"\n :current_org=\"current_org\"\n :handleBtnClick=\"handleBtnClick\"\n />\n </a-menu>\n </template>\n </a-dropdown>\n </template>\n</template>\n<script lang=\"ts\">\nimport { defineComponent, computed, PropType, ref } from 'vue';\nimport { checkCondition, nested_sort_list } from 'liyu-pc-base/utils/function';\nimport { HeadBtnListConfig } from 'liyu-pc-base/api/typing';\nimport { head_btn_confirm } from './head_btn_confirm';\nimport { head_btn_custom_component } from './head_btn_custom_component';\nimport { head_btn_form } from './head_btn_form';\nimport { useI18n } from 'vue-i18n';\nimport { cloneDeep } from 'lodash';\nimport { useRoute } from 'vue-router';\nimport HeadBtnChildren from './headBtnChildren.vue';\n\nexport default defineComponent({\n name: 'HeadBtn',\n props: {\n auth_batch_update_list: {\n type: Array as PropType<HeadBtnListConfig>,\n required: true,\n },\n auth_head_btn_list: {\n type: Array as PropType<HeadBtnListConfig>,\n required: true,\n },\n selectedRowKeys: {\n type: Array as PropType<any[]>,\n required: true,\n },\n dataSource: {\n type: Array as PropType<any[]>,\n required: true,\n },\n current_org: {\n type: Object as PropType<any>,\n required: true,\n },\n router: {\n type: Object as PropType<any>,\n required: true,\n },\n event_obj: {\n type: Object as PropType<any>,\n required: true,\n },\n },\n components: {\n HeadBtnChildren,\n },\n setup(props) {\n const { t } = useI18n();\n const isMenuOpen = ref<Record<string, boolean>>({});\n const route = useRoute();\n const process_list = (\n list: any,\n {\n dataSource,\n selectedRowKeys,\n batchList,\n }: { dataSource: any[]; selectedRowKeys: any[]; batchList: any[] | null },\n ) => {\n if (batchList?.length > 0) {\n const batchGroup = list.find((item: any) => item.name === '批量操作');\n if (batchGroup) {\n if (!batchGroup.children || batchGroup.children.length == 0) {\n batchGroup.children = batchList;\n } else {\n batchGroup.children = [...batchGroup.children, ...batchList];\n }\n } else {\n list.push({\n name: '批量操作',\n order: 1000,\n children: batchList,\n });\n }\n }\n const result = list.filter((button: any) => {\n let data = dataSource;\n // if (button.preProcessData) {\n // data = button.preProcessData({ dataSource: data, selectedRowKeys });\n // }\n let isDisabled = false;\n if (typeof button.is_disabled === 'function') {\n isDisabled = button.is_disabled({ dataSource: data, selectedRowKeys: selectedRowKeys });\n }\n if (typeof button.is_disabled === 'boolean') {\n isDisabled = button.is_disabled;\n }\n if (button.disabled_condition && button.disabled_condition.length > 0) {\n isDisabled = checkCondition({\n conditions: button.disabled_condition,\n dataSource: data,\n selectedRowKeys: selectedRowKeys,\n });\n }\n button.disabled = isDisabled;\n\n if (button.show_condition && button.show_condition.length > 0) {\n return checkCondition({\n conditions: button.show_condition,\n dataSource: data,\n selectedRowKeys: selectedRowKeys,\n });\n }\n\n if (typeof button.is_show === 'function') {\n return button.is_show({ dataSource: data, selectedRowKeys: selectedRowKeys });\n }\n if (typeof button.is_show === 'boolean') {\n return button.is_show;\n }\n return true;\n });\n result.forEach((item: any) => {\n if (item.children) {\n item.children = process_list(item.children, {\n dataSource: dataSource,\n selectedRowKeys: selectedRowKeys,\n batchList: null,\n });\n }\n });\n return result;\n };\n const filter_head_btn_list = computed(() => {\n if (!props.auth_head_btn_list) return [];\n const list = process_list(cloneDeep(props.auth_head_btn_list), {\n dataSource: props.dataSource,\n selectedRowKeys: props.selectedRowKeys,\n batchList: props.auth_batch_update_list,\n });\n nested_sort_list(list);\n return list;\n });\n // 处理按钮点击事件\n const handleBtnClick = (btn: any, params: any) => {\n let action_func = null;\n let query_json = {};\n if (route.query?.query_json) {\n query_json = JSON.parse(route.query?.query_json as any);\n }\n const routeQueryParams = JSON.parse(JSON.stringify({ ...route.query, ...query_json }));\n if (!btn.model_kind) {\n action_func = btn.cb;\n } else if (btn.model_kind === 'confirm') {\n action_func = head_btn_confirm;\n } else if (btn.model_kind === 'custom_component') {\n action_func = head_btn_custom_component;\n } else if (btn.model_kind === 'form') {\n action_func = head_btn_form;\n }\n\n if (!action_func) return;\n\n action_func({\n ...params,\n button: btn,\n t: t,\n current_org: props.current_org,\n routeQueryParams: routeQueryParams,\n event_obj: props.event_obj,\n });\n };\n return {\n filter_head_btn_list,\n handleBtnClick,\n isMenuOpen,\n };\n },\n});\n</script>\n","<template>\n <template\n v-for=\"(btn, index) in filter_head_btn_list\"\n :key=\"index\"\n >\n <a-button\n v-if=\"!btn.children || btn.children?.length == 0\"\n :type=\"btn.clazz\"\n size=\"small\"\n style=\"margin-right: 5px\"\n :disabled=\"btn.disabled\"\n @click=\"\n handleBtnClick(btn, {\n dataSource: dataSource,\n selectedRowKeys: selectedRowKeys,\n current_org: current_org,\n router: router,\n })\n \"\n >\n <plus-outlined v-if=\"btn.icon === 'plus-outlined'\" />\n {{ btn.name }}\n </a-button>\n <a-dropdown\n v-else\n v-model:open=\"isMenuOpen[index]\"\n trigger=\"click\"\n >\n <a-button\n :bordered=\"false\"\n size=\"small\"\n >\n {{ btn.name }}\n <down-outlined\n v-if=\"!isMenuOpen[index]\"\n style=\"font-size: 10px; cursor: pointer\"\n />\n <up-outlined\n v-if=\"isMenuOpen[index]\"\n style=\"font-size: 10px; cursor: pointer\"\n />\n </a-button>\n <template #overlay>\n <a-menu>\n <head-btn-children\n :children_list=\"btn.children\"\n :selected-row-keys=\"selectedRowKeys\"\n :dataSource=\"dataSource\"\n :current_org=\"current_org\"\n :handleBtnClick=\"handleBtnClick\"\n />\n </a-menu>\n </template>\n </a-dropdown>\n </template>\n</template>\n<script lang=\"ts\">\nimport { defineComponent, computed, PropType, ref } from 'vue';\nimport { checkCondition, nested_sort_list } from 'liyu-pc-base/utils/function';\nimport { HeadBtnListConfig } from 'liyu-pc-base/api/typing';\nimport { head_btn_confirm } from './head_btn_confirm';\nimport { head_btn_custom_component } from './head_btn_custom_component';\nimport { head_btn_form } from './head_btn_form';\nimport { useI18n } from 'vue-i18n';\nimport { cloneDeep } from 'lodash';\nimport { useRoute } from 'vue-router';\nimport HeadBtnChildren from './headBtnChildren.vue';\n\nexport default defineComponent({\n name: 'HeadBtn',\n props: {\n auth_batch_update_list: {\n type: Array as PropType<HeadBtnListConfig>,\n required: true,\n },\n auth_head_btn_list: {\n type: Array as PropType<HeadBtnListConfig>,\n required: true,\n },\n selectedRowKeys: {\n type: Array as PropType<any[]>,\n required: true,\n },\n dataSource: {\n type: Array as PropType<any[]>,\n required: true,\n },\n current_org: {\n type: Object as PropType<any>,\n required: true,\n },\n router: {\n type: Object as PropType<any>,\n required: true,\n },\n event_obj: {\n type: Object as PropType<any>,\n required: true,\n },\n },\n components: {\n HeadBtnChildren,\n },\n setup(props) {\n const { t } = useI18n();\n const isMenuOpen = ref<Record<string, boolean>>({});\n const route = useRoute();\n const process_list = (\n list: any,\n {\n dataSource,\n selectedRowKeys,\n batchList,\n }: { dataSource: any[]; selectedRowKeys: any[]; batchList: any[] | null },\n ) => {\n if (batchList?.length > 0) {\n const batchGroup = list.find((item: any) => item.name === '批量操作');\n if (batchGroup) {\n if (!batchGroup.children || batchGroup.children.length == 0) {\n batchGroup.children = batchList;\n } else {\n batchGroup.children = [...batchGroup.children, ...batchList];\n }\n } else {\n list.push({\n name: '批量操作',\n order: 1000,\n children: batchList,\n });\n }\n }\n const result = list.filter((button: any) => {\n let data = dataSource;\n // if (button.preProcessData) {\n // data = button.preProcessData({ dataSource: data, selectedRowKeys });\n // }\n let isDisabled = false;\n if (typeof button.is_disabled === 'function') {\n isDisabled = button.is_disabled({ dataSource: data, selectedRowKeys: selectedRowKeys });\n }\n if (typeof button.is_disabled === 'boolean') {\n isDisabled = button.is_disabled;\n }\n if (button.disabled_condition && button.disabled_condition.length > 0) {\n isDisabled = checkCondition({\n conditions: button.disabled_condition,\n dataSource: data,\n selectedRowKeys: selectedRowKeys,\n });\n }\n button.disabled = isDisabled;\n\n if (button.show_condition && button.show_condition.length > 0) {\n return checkCondition({\n conditions: button.show_condition,\n dataSource: data,\n selectedRowKeys: selectedRowKeys,\n });\n }\n\n if (typeof button.is_show === 'function') {\n return button.is_show({ dataSource: data, selectedRowKeys: selectedRowKeys });\n }\n if (typeof button.is_show === 'boolean') {\n return button.is_show;\n }\n return true;\n });\n result.forEach((item: any) => {\n if (item.children) {\n item.children = process_list(item.children, {\n dataSource: dataSource,\n selectedRowKeys: selectedRowKeys,\n batchList: null,\n });\n }\n });\n return result;\n };\n const filter_head_btn_list = computed(() => {\n if (!props.auth_head_btn_list) return [];\n const list = process_list(cloneDeep(props.auth_head_btn_list), {\n dataSource: props.dataSource,\n selectedRowKeys: props.selectedRowKeys,\n batchList: props.auth_batch_update_list,\n });\n nested_sort_list(list);\n return list;\n });\n // 处理按钮点击事件\n const handleBtnClick = (btn: any, params: any) => {\n let action_func = null;\n let query_json = {};\n if (route.query?.query_json) {\n query_json = JSON.parse(route.query?.query_json as any);\n }\n const routeQueryParams = JSON.parse(JSON.stringify({ ...route.query, ...query_json }));\n if (!btn.model_kind) {\n action_func = btn.cb;\n } else if (btn.model_kind === 'confirm') {\n action_func = head_btn_confirm;\n } else if (btn.model_kind === 'custom_component') {\n action_func = head_btn_custom_component;\n } else if (btn.model_kind === 'form') {\n action_func = head_btn_form;\n }\n\n if (!action_func) return;\n\n action_func({\n ...params,\n button: btn,\n t: t,\n current_org: props.current_org,\n routeQueryParams: routeQueryParams,\n event_obj: props.event_obj,\n });\n };\n return {\n filter_head_btn_list,\n handleBtnClick,\n isMenuOpen,\n };\n },\n});\n</script>\n","<template>\n <a-popover>\n <template #content>\n <a-button\n size=\"small\"\n style=\"margin: 10px 5px\"\n :type=\"refreshType === '手动' ? 'primary' : 'default'\"\n @click=\"selectRefreshType('手动')\"\n >\n {{ $t('手动刷新') }}\n </a-button>\n <a-dropdown class=\"dropdown\">\n <a-button\n size=\"small\"\n style=\"margin: 10px 5px\"\n :type=\"refreshType === '手动' ? 'default' : 'primary'\"\n >\n {{ $t('自动刷新') }}\n <span v-if=\"refreshType !== '手动'\">({{ refreshType }})</span>\n </a-button>\n <template #overlay>\n <a-menu>\n <a-menu-item>\n <a\n href=\"javascript:;\"\n @click=\"selectRefreshType('5s')\"\n >\n 5s\n </a>\n </a-menu-item>\n <a-menu-item>\n <a\n href=\"javascript:;\"\n @click=\"selectRefreshType('10s')\"\n >\n 10s\n </a>\n </a-menu-item>\n <a-menu-item>\n <a\n href=\"javascript:;\"\n @click=\"selectRefreshType('30s')\"\n >\n 30s\n </a>\n </a-menu-item>\n </a-menu>\n </template>\n </a-dropdown>\n </template>\n <reload-outlined\n v-if=\"refreshType === '手动'\"\n @click=\"refresh\"\n />\n <loading-outlined v-if=\"(countdown == -1 || loading) && refreshType !== '手动'\" />\n <span v-if=\"countdown >= 0 && !loading\">{{ countdown + 1 }}s</span>\n </a-popover>\n</template>\n\n<script lang=\"ts\">\nimport { defineComponent, ref, onActivated, onDeactivated, onUnmounted, watch } from 'vue';\nimport { LoadingOutlined, ReloadOutlined } from '@ant-design/icons-vue';\nexport default defineComponent({\n name: 'refreshTypeModal',\n props: {\n refreshType: {\n type: String,\n default: () => '手动',\n },\n loading: {\n type: Boolean,\n default: () => false,\n },\n },\n components: {\n LoadingOutlined,\n ReloadOutlined,\n },\n emits: ['refresh', 'typeChange'],\n setup(props, { emit }) {\n let init = false;\n const countdown: any = ref(0);\n const current_page: any = ref(true);\n\n // 刷新模式切换\n const selectRefreshType = (type: any) => {\n emit('typeChange', type);\n countdown.value = -1;\n if (props.refreshType == '手动') {\n emit('refresh');\n }\n };\n const timer_countdown = setInterval(() => {\n if (countdown.value < 0) {\n switch (props.refreshType) {\n case '手动':\n countdown.value = -1;\n break;\n case '5s':\n countdown.value = 4;\n break;\n case '10s':\n countdown.value = 9;\n break;\n case '30s':\n countdown.value = 29;\n }\n } else if (countdown.value == 0) {\n if (current_page.value && !props.loading && init) {\n emit('refresh', true);\n }\n countdown.value = -1;\n } else {\n countdown.value--;\n }\n }, 1000);\n\n watch(\n () => props.loading,\n () => {\n if (!props.loading) {\n countdown.value = -1;\n init = true;\n }\n },\n );\n\n onActivated(() => {\n if (!current_page.value) {\n current_page.value = true;\n }\n });\n onDeactivated(() => {\n current_page.value = false;\n });\n\n onUnmounted(() => {\n clearInterval(timer_countdown);\n });\n\n const refresh = () => {\n emit('refresh');\n };\n return {\n props,\n countdown,\n refresh,\n selectRefreshType,\n };\n },\n});\n</script>\n","<template>\n <a-popover>\n <template #content>\n <a-button\n size=\"small\"\n style=\"margin: 10px 5px\"\n :type=\"refreshType === '手动' ? 'primary' : 'default'\"\n @click=\"selectRefreshType('手动')\"\n >\n {{ $t('手动刷新') }}\n </a-button>\n <a-dropdown class=\"dropdown\">\n <a-button\n size=\"small\"\n style=\"margin: 10px 5px\"\n :type=\"refreshType === '手动' ? 'default' : 'primary'\"\n >\n {{ $t('自动刷新') }}\n <span v-if=\"refreshType !== '手动'\">({{ refreshType }})</span>\n </a-button>\n <template #overlay>\n <a-menu>\n <a-menu-item>\n <a\n href=\"javascript:;\"\n @click=\"selectRefreshType('5s')\"\n >\n 5s\n </a>\n </a-menu-item>\n <a-menu-item>\n <a\n href=\"javascript:;\"\n @click=\"selectRefreshType('10s')\"\n >\n 10s\n </a>\n </a-menu-item>\n <a-menu-item>\n <a\n href=\"javascript:;\"\n @click=\"selectRefreshType('30s')\"\n >\n 30s\n </a>\n </a-menu-item>\n </a-menu>\n </template>\n </a-dropdown>\n </template>\n <reload-outlined\n v-if=\"refreshType === '手动'\"\n @click=\"refresh\"\n />\n <loading-outlined v-if=\"(countdown == -1 || loading) && refreshType !== '手动'\" />\n <span v-if=\"countdown >= 0 && !loading\">{{ countdown + 1 }}s</span>\n </a-popover>\n</template>\n\n<script lang=\"ts\">\nimport { defineComponent, ref, onActivated, onDeactivated, onUnmounted, watch } from 'vue';\nimport { LoadingOutlined, ReloadOutlined } from '@ant-design/icons-vue';\nexport default defineComponent({\n name: 'refreshTypeModal',\n props: {\n refreshType: {\n type: String,\n default: () => '手动',\n },\n loading: {\n type: Boolean,\n default: () => false,\n },\n },\n components: {\n LoadingOutlined,\n ReloadOutlined,\n },\n emits: ['refresh', 'typeChange'],\n setup(props, { emit }) {\n let init = false;\n const countdown: any = ref(0);\n const current_page: any = ref(true);\n\n // 刷新模式切换\n const selectRefreshType = (type: any) => {\n emit('typeChange', type);\n countdown.value = -1;\n if (props.refreshType == '手动') {\n emit('refresh');\n }\n };\n const timer_countdown = setInterval(() => {\n if (countdown.value < 0) {\n switch (props.refreshType) {\n case '手动':\n countdown.value = -1;\n break;\n case '5s':\n countdown.value = 4;\n break;\n case '10s':\n countdown.value = 9;\n break;\n case '30s':\n countdown.value = 29;\n }\n } else if (countdown.value == 0) {\n if (current_page.value && !props.loading && init) {\n emit('refresh', true);\n }\n countdown.value = -1;\n } else {\n countdown.value--;\n }\n }, 1000);\n\n watch(\n () => props.loading,\n () => {\n if (!props.loading) {\n countdown.value = -1;\n init = true;\n }\n },\n );\n\n onActivated(() => {\n if (!current_page.value) {\n current_page.value = true;\n }\n });\n onDeactivated(() => {\n current_page.value = false;\n });\n\n onUnmounted(() => {\n clearInterval(timer_countdown);\n });\n\n const refresh = () => {\n emit('refresh');\n };\n return {\n props,\n countdown,\n refresh,\n selectRefreshType,\n };\n },\n});\n</script>\n","<template>\n <a-tooltip :title=\"$t('分组')\">\n <a-popover\n title=\"\"\n trigger=\"click\"\n placement=\"bottom\"\n >\n <template #content>\n <div v-if=\"selectedConditionGroup\">\n <a-menu>\n <a-menu-item @click=\"handleClearConditionGroup\">\n {{ $t('取消分组') }}\n </a-menu-item>\n </a-menu>\n </div>\n <a-input\n v-model:value=\"searchGroupKeyword\"\n :allowClear=\"true\"\n :placeholder=\"$t('搜索...')\"\n style=\"width: 240px; margin-right: 25px\"\n >\n <template #prefix>\n <search-outlined />\n </template>\n </a-input>\n <div>\n <a-menu :selectedKeys=\"selectedKeys\">\n <template\n v-for=\"item in condition_group_config_list_filtered\"\n :key=\"item.field_name\"\n >\n <a-menu-item @click=\"handleSetSelectedConditionGroup(item)\">\n {{ $t('按{label}分组', { label: item.label }) }}\n </a-menu-item>\n </template>\n </a-menu>\n </div>\n </template>\n <group-outlined :style=\"selectedConditionGroup ? 'color: #1890ff' : ''\" />\n </a-popover>\n </a-tooltip>\n</template>\n<script setup lang=\"ts\">\nimport { computed, ref } from 'vue';\nimport { ConditionGroupConfigItem, Table } from './typing';\n\ninterface Props {\n config: Table;\n selfEventBus: any;\n}\nconst props = withDefaults(defineProps<Props>(), {\n config: null,\n});\nconst emit = defineEmits(['change']);\nconst selectedConditionGroup = defineModel('selectedConditionGroup', {\n default: null,\n});\nconst groupConditionValue = defineModel('groupConditionValue', {\n default: null,\n});\nconst searchGroupKeyword = ref('');\nconst condition_group_config_list_filtered = computed(() => {\n return props.config?.condition_group_config_list?.filter(item => {\n return item.label.includes(searchGroupKeyword.value);\n });\n});\nconst selectedKeys = computed(() => {\n return selectedConditionGroup.value?.field_name ? [selectedConditionGroup.value.field_name] : [];\n});\n\nconst handleClearConditionGroup = () => {\n groupConditionValue.value = null;\n selectedConditionGroup.value = null;\n emit('change', selectedConditionGroup.value);\n props.selfEventBus.emit('refresh');\n};\nconst handleSetSelectedConditionGroup = (item: ConditionGroupConfigItem) => {\n groupConditionValue.value = null;\n selectedConditionGroup.value = item;\n emit('change', selectedConditionGroup.value);\n props.selfEventBus.emit('refresh');\n};\n</script>\n","<template>\n <a-tooltip :title=\"$t('分组')\">\n <a-popover\n title=\"\"\n trigger=\"click\"\n placement=\"bottom\"\n >\n <template #content>\n <div v-if=\"selectedConditionGroup\">\n <a-menu>\n <a-menu-item @click=\"handleClearConditionGroup\">\n {{ $t('取消分组') }}\n </a-menu-item>\n </a-menu>\n </div>\n <a-input\n v-model:value=\"searchGroupKeyword\"\n :allowClear=\"true\"\n :placeholder=\"$t('搜索...')\"\n style=\"width: 240px; margin-right: 25px\"\n >\n <template #prefix>\n <search-outlined />\n </template>\n </a-input>\n <div>\n <a-menu :selectedKeys=\"selectedKeys\">\n <template\n v-for=\"item in condition_group_config_list_filtered\"\n :key=\"item.field_name\"\n >\n <a-menu-item @click=\"handleSetSelectedConditionGroup(item)\">\n {{ $t('按{label}分组', { label: item.label }) }}\n </a-menu-item>\n </template>\n </a-menu>\n </div>\n </template>\n <group-outlined :style=\"selectedConditionGroup ? 'color: #1890ff' : ''\" />\n </a-popover>\n </a-tooltip>\n</template>\n<script setup lang=\"ts\">\nimport { computed, ref } from 'vue';\nimport { ConditionGroupConfigItem, Table } from './typing';\n\ninterface Props {\n config: Table;\n selfEventBus: any;\n}\nconst props = withDefaults(defineProps<Props>(), {\n config: null,\n});\nconst emit = defineEmits(['change']);\nconst selectedConditionGroup = defineModel('selectedConditionGroup', {\n default: null,\n});\nconst groupConditionValue = defineModel('groupConditionValue', {\n default: null,\n});\nconst searchGroupKeyword = ref('');\nconst condition_group_config_list_filtered = computed(() => {\n return props.config?.condition_group_config_list?.filter(item => {\n return item.label.includes(searchGroupKeyword.value);\n });\n});\nconst selectedKeys = computed(() => {\n return selectedConditionGroup.value?.field_name ? [selectedConditionGroup.value.field_name] : [];\n});\n\nconst handleClearConditionGroup = () => {\n groupConditionValue.value = null;\n selectedConditionGroup.value = null;\n emit('change', selectedConditionGroup.value);\n props.selfEventBus.emit('refresh');\n};\nconst handleSetSelectedConditionGroup = (item: ConditionGroupConfigItem) => {\n groupConditionValue.value = null;\n selectedConditionGroup.value = item;\n emit('change', selectedConditionGroup.value);\n props.selfEventBus.emit('refresh');\n};\n</script>\n","<template>\n <div style=\"max-height: 156px; overflow-y: auto\">\n <a-flex\n v-if=\"selectedConditionGroup && conditionGroupDataList?.length > 0\"\n style=\"padding-left: 24px; padding-bottom: 10px\"\n >\n <a-space\n wrap\n style=\"margin-bottom: 0\"\n >\n <span>{{ $t('按{label}分组', { label: selectedConditionGroup.label }) }}:</span>\n <a-tooltip\n placement=\"bottom\"\n v-for=\"item in conditionGroupDataList\"\n :key=\"item.group_info.value\"\n :title=\"`${item.group_info.display_name ? item.group_info.display_name : $t('空')}`\"\n >\n <a-button\n style=\"padding: 0\"\n :class=\"currentGroupConditionValue == item.group_info.value ? 'link-button' : ''\"\n :type=\"currentGroupConditionValue == item.group_info.value ? 'link' : 'text'\"\n :value=\"item.group_info.value\"\n @click=\"handleChangeConditionGroupValue(item.group_info.value)\"\n >\n <a-space :size=\"3\">\n <span\n :class=\"\n currentGroupConditionValue == item.group_info.value ? 'active-text' : 'text'\n \"\n >\n {{ item.group_info.display_name ? item.group_info.display_name : $t('空') }}\n </span>\n <a-badge\n :count=\"item.count\"\n :overflowCount=\"9999999999\"\n :number-style=\"\n currentGroupConditionValue == item.group_info.value\n ? { backgroundColor: '#f0f9ff', color: '#1b9aee', fontWeight: 600 }\n : { backgroundColor: '#f0f9ff', color: '#1b9aee' }\n \"\n />\n </a-space>\n </a-button>\n </a-tooltip>\n <span>\n <a-button\n type=\"link\"\n @click=\"handleClearConditionGroup\"\n >\n {{ $t('取消分组') }}\n </a-button>\n </span>\n </a-space>\n </a-flex>\n </div>\n</template>\n<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport { Table } from './typing';\nimport { getCurrentGroupConditionValue } from './utils';\n\ninterface Props {\n config: Table;\n selfEventBus: any;\n}\nconst props = withDefaults(defineProps<Props>(), {\n config: null,\n});\nconst emit = defineEmits(['change']);\nconst selectedConditionGroup = defineModel('selectedConditionGroup', {\n default: null,\n});\nconst conditionGroupDataList = defineModel<any[]>('conditionGroupDataList', {\n default: null,\n});\nconst groupConditionValue = defineModel('groupConditionValue', {\n default: null,\n});\nconst handleClearConditionGroup = () => {\n conditionGroupDataList.value = [];\n selectedConditionGroup.value = null;\n groupConditionValue.value = null;\n emit('change', groupConditionValue.value);\n props.selfEventBus.emit('refresh');\n};\nconst handleChangeConditionGroupValue = (value: string) => {\n groupConditionValue.value = value;\n emit('change', value);\n props.selfEventBus.emit('refresh');\n};\nconst currentGroupConditionValue = computed(() => {\n return getCurrentGroupConditionValue(conditionGroupDataList.value, groupConditionValue.value)\n ?.value;\n});\n</script>\n","<template>\n <div style=\"max-height: 156px; overflow-y: auto\">\n <a-flex\n v-if=\"selectedConditionGroup && conditionGroupDataList?.length > 0\"\n style=\"padding-left: 24px; padding-bottom: 10px\"\n >\n <a-space\n wrap\n style=\"margin-bottom: 0\"\n >\n <span>{{ $t('按{label}分组', { label: selectedConditionGroup.label }) }}:</span>\n <a-tooltip\n placement=\"bottom\"\n v-for=\"item in conditionGroupDataList\"\n :key=\"item.group_info.value\"\n :title=\"`${item.group_info.display_name ? item.group_info.display_name : $t('空')}`\"\n >\n <a-button\n style=\"padding: 0\"\n :class=\"currentGroupConditionValue == item.group_info.value ? 'link-button' : ''\"\n :type=\"currentGroupConditionValue == item.group_info.value ? 'link' : 'text'\"\n :value=\"item.group_info.value\"\n @click=\"handleChangeConditionGroupValue(item.group_info.value)\"\n >\n <a-space :size=\"3\">\n <span\n :class=\"\n currentGroupConditionValue == item.group_info.value ? 'active-text' : 'text'\n \"\n >\n {{ item.group_info.display_name ? item.group_info.display_name : $t('空') }}\n </span>\n <a-badge\n :count=\"item.count\"\n :overflowCount=\"9999999999\"\n :number-style=\"\n currentGroupConditionValue == item.group_info.value\n ? { backgroundColor: '#f0f9ff', color: '#1b9aee', fontWeight: 600 }\n : { backgroundColor: '#f0f9ff', color: '#1b9aee' }\n \"\n />\n </a-space>\n </a-button>\n </a-tooltip>\n <span>\n <a-button\n type=\"link\"\n @click=\"handleClearConditionGroup\"\n >\n {{ $t('取消分组') }}\n </a-button>\n </span>\n </a-space>\n </a-flex>\n </div>\n</template>\n<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport { Table } from './typing';\nimport { getCurrentGroupConditionValue } from './utils';\n\ninterface Props {\n config: Table;\n selfEventBus: any;\n}\nconst props = withDefaults(defineProps<Props>(), {\n config: null,\n});\nconst emit = defineEmits(['change']);\nconst selectedConditionGroup = defineModel('selectedConditionGroup', {\n default: null,\n});\nconst conditionGroupDataList = defineModel<any[]>('conditionGroupDataList', {\n default: null,\n});\nconst groupConditionValue = defineModel('groupConditionValue', {\n default: null,\n});\nconst handleClearConditionGroup = () => {\n conditionGroupDataList.value = [];\n selectedConditionGroup.value = null;\n groupConditionValue.value = null;\n emit('change', groupConditionValue.value);\n props.selfEventBus.emit('refresh');\n};\nconst handleChangeConditionGroupValue = (value: string) => {\n groupConditionValue.value = value;\n emit('change', value);\n props.selfEventBus.emit('refresh');\n};\nconst currentGroupConditionValue = computed(() => {\n return getCurrentGroupConditionValue(conditionGroupDataList.value, groupConditionValue.value)\n ?.value;\n});\n</script>\n","<template>\n <div\n class=\"ant-pro-table-list-toolbar\"\n v-if=\"!config?.hide_header\"\n ref=\"headerRef\"\n >\n <div class=\"ant-pro-table-list-toolbar-container\">\n <div class=\"ant-pro-table-list-toolbar-left\">\n <slot name=\"header_bar_before_title\"></slot>\n <div class=\"ant-pro-table-list-toolbar-title\">\n <span v-if=\"config?.show_title\">{{ config?.title }}</span>\n <div\n v-if=\"config?.show_current_view\"\n class=\"current-view-container\"\n >\n <a-tooltip\n v-if=\"currentView?.name\"\n :title=\"'视图:' + currentView?.name\"\n >\n <span class=\"current-view-name\">\n {{ currentView?.name }}\n </span>\n </a-tooltip>\n <template v-if=\"enableEditCurrentView\">\n <span style=\"font-size: 12px; margin-right: 5px; display: inline-block\">\n (已编辑)\n </span>\n <a-dropdown\n v-model:open=\"isDropdown\"\n trigger=\"click\"\n >\n <span class=\"view-menu\">\n {{ $t('保存') }}\n <down-outlined\n v-if=\"!isDropdown\"\n style=\"font-size: 10px; cursor: pointer\"\n />\n <up-outlined\n v-if=\"isDropdown\"\n style=\"font-size: 10px; cursor: pointer\"\n />\n </span>\n <template #overlay>\n <a-menu>\n <a-menu-item>\n <span\n @click=\"\n () => {\n isDropdown = false;\n selfEventBus.emit('saveView');\n }\n \"\n >\n {{ $t('保存视图') }}\n </span>\n </a-menu-item>\n <a-menu-item>\n <span\n @click=\"\n () => {\n isDropdown = false;\n selfEventBus.emit('saveNewView');\n }\n \"\n >\n {{ $t('另存为新视图') }}\n </span>\n </a-menu-item>\n </a-menu>\n </template>\n </a-dropdown>\n <span\n :bordered=\"false\"\n class=\"view-menu\"\n @click=\"\n () => {\n selfEventBus.emit('reinit');\n }\n \"\n >\n {{ $t('重置') }}\n </span>\n </template>\n </div>\n </div>\n <slot name=\"header_bar_after_title\"></slot>\n </div>\n <div class=\"ant-pro-table-list-toolbar-right\">\n <a-space align=\"center\">\n <slot name=\"header_bar_before_btn\"></slot>\n <head-btn\n :auth_batch_update_list=\"auth_batch_update_list\"\n :auth_head_btn_list=\"auth_head_btn_list\"\n :selectedRowKeys=\"selectedRowKeys\"\n :dataSource=\"dataSource\"\n :searchConfig=\"config.query_params || {}\"\n :current_org=\"current_org\"\n :router=\"router\"\n :event_obj=\"selfEventBus\"\n />\n <slot name=\"header_bar_after_btn\"></slot>\n </a-space>\n\n <div class=\"ant-pro-table-list-toolbar-divider\">\n <a-divider type=\"vertical\" />\n </div>\n\n <div\n class=\"ant-pro-table-list-toolbar-setting-item\"\n v-if=\"component_type === 'normal' && config?.condition_group_config_list?.length > 0\"\n >\n <ConditionGroupSelecter\n :config=\"config\"\n :selfEventBus=\"selfEventBus\"\n v-model:selectedConditionGroup=\"selectedConditionGroup\"\n v-model:groupConditionValue=\"groupConditionValue\"\n @change=\"handleSelectedConditionGroupChange\"\n />\n </div>\n <div\n class=\"ant-pro-table-list-toolbar-setting-item\"\n v-if=\"config?.sys_btn?.refresh !== false\"\n >\n <refresh-type-modal\n :refreshType=\"refreshType\"\n :loading=\"loading\"\n @refresh=\"$emit('refresh')\"\n @typeChange=\"$emit('refreshTypeChange', $event)\"\n />\n </div>\n <div\n class=\"ant-pro-table-list-toolbar-setting-item\"\n v-if=\"component_type === 'normal' && config?.sys_btn?.export !== false\"\n >\n <a-tooltip :title=\"$t('导出Excel')\">\n <a-button\n type=\"text\"\n size=\"small\"\n @click=\"$emit('export')\"\n >\n <template #icon>\n <download-outlined></download-outlined>\n </template>\n </a-button>\n </a-tooltip>\n </div>\n <div\n class=\"ant-pro-table-list-toolbar-setting-item\"\n v-if=\"component_type === 'normal' && config?.sys_btn?.table_size !== false\"\n >\n <a-tooltip :title=\"$t('密度')\">\n <a-dropdown\n :trigger=\"['click']\"\n placement=\"bottomRight\"\n >\n <column-height-outlined />\n <template #overlay>\n <a-menu\n :selected-keys=\"[tableSize]\"\n style=\"width: 80px\"\n @click=\"\n ({ key }) => {\n $emit('update:tableSize', key as string);\n $emit('tableSizeChange', key as string);\n }\n \"\n >\n <a-menu-item key=\"default\">\n <a href=\"javascript:\">{{ $t('默认') }}</a>\n </a-menu-item>\n <a-menu-item key=\"middle\">\n <a href=\"javascript:\">{{ $t('中等') }}</a>\n </a-menu-item>\n <a-menu-item key=\"small\">\n <a href=\"javascript:\">{{ $t('紧凑') }}</a>\n </a-menu-item>\n </a-menu>\n </template>\n </a-dropdown>\n </a-tooltip>\n </div>\n <div\n class=\"ant-pro-table-list-toolbar-setting-item\"\n v-if=\"config?.sys_btn?.column_config !== false\"\n >\n <a-tooltip :title=\"$t('设置')\">\n <a-button\n type=\"text\"\n size=\"small\"\n @click=\"settingOpen = true\"\n >\n <template #icon>\n <setting-outlined />\n </template>\n </a-button>\n </a-tooltip>\n </div>\n\n <div\n class=\"ant-pro-table-list-toolbar-setting-item\"\n v-if=\"config?.sys_btn?.full_screen !== false\"\n >\n <a-tooltip :title=\"screenState ? $t('退出全屏') : $t('全屏')\">\n <fullscreen-outlined\n v-if=\"!screenState\"\n @click=\"$emit('setFull')\"\n />\n <fullscreen-exit-outlined\n v-else\n @click=\"$emit('exitFull')\"\n />\n </a-tooltip>\n </div>\n </div>\n </div>\n </div>\n <ConditionGroupView\n :config=\"config\"\n v-model:conditionGroupDataList=\"conditionGroupDataList\"\n v-model:selectedConditionGroup=\"selectedConditionGroup\"\n :selfEventBus=\"selfEventBus\"\n v-model:groupConditionValue=\"groupConditionValue\"\n @change=\"handleGroupConditionValueChange\"\n />\n <a-modal\n :title=\"$t('设置')\"\n width=\"900px\"\n v-model:open=\"settingOpen\"\n >\n <column-edit-view\n :columns=\"columns\"\n :is_view=\"is_view\"\n :view_key=\"view_key\"\n :view_flag_name=\"view_flag_name\"\n :component_type=\"component_type\"\n :pivotConfig=\"localPivotConfig\"\n @change=\"$emit('columnsChange', $event)\"\n @pivotConfigChange=\"onPivotConfigChange\"\n ></column-edit-view>\n <template #footer>\n <a-button @click=\"settingOpen = false\">\n {{ $t('关闭') }}\n </a-button>\n </template>\n </a-modal>\n</template>\n\n<script setup lang=\"ts\">\nimport {\n ColumnHeightOutlined,\n FullscreenExitOutlined,\n FullscreenOutlined,\n DownloadOutlined,\n SettingOutlined,\n} from '@ant-design/icons-vue';\nimport { useResizeObserver } from '@vueuse/core';\nimport { computed, ref, watch } from 'vue';\nimport columnEditView from './tableConfig/index.vue';\nimport HeadBtn from './headBtn.vue';\nimport RefreshTypeModal from './refresh-type-modal/index.vue';\nimport { Column, ConditionGroupConfigItem, Table, PivotConfig } from './typing';\nimport { useTableProState } from './utils';\nimport ConditionGroupSelecter from './ConditionGroupSelecter.vue';\nimport ConditionGroupView from './ConditionGroupView.vue';\nimport { useUserStore } from 'liyu-pc-base/init-plugin';\nimport { cloneDeep } from 'lodash';\n\ninterface Props {\n config?: Table;\n auth_batch_update_list?: any[];\n auth_head_btn_list?: any[];\n selectedRowKeys?: any[];\n dataSource?: any[];\n current_org?: any;\n router?: any;\n selfEventBus?: any;\n loading?: boolean;\n screenState?: boolean;\n tableSize?: string;\n columns?: Column[];\n view_key?: string;\n view_flag_name?: string;\n is_view?: boolean;\n refreshType?: string;\n conditionsParams?: any;\n pivotConfig?: PivotConfig | null;\n component_type?: string;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n config: () => ({} as Table),\n auth_batch_update_list: () => [],\n auth_head_btn_list: () => [],\n selectedRowKeys: () => [],\n dataSource: () => [],\n loading: false,\n screenState: false,\n tableSize: 'small',\n columns: () => [],\n view_key: '',\n view_flag_name: '',\n is_view: true,\n refreshType: '手动',\n conditionsParams: () => null,\n pivotConfig: () => null,\n component_type: 'normal',\n});\n\nconst emit = defineEmits([\n 'refresh',\n 'export',\n 'setFull',\n 'exitFull',\n 'columnsChange',\n 'pivotConfigChange',\n 'viewSelected',\n 'update:tableSize',\n 'heightChange',\n 'refreshTypeChange',\n 'tableSizeChange',\n 'selectedConditionGroupChange',\n 'groupConditionValueChange',\n]);\nconst userStore = useUserStore();\nconst current_org = userStore.currentOrg;\nconst VIEW_SYSTEM_EDIT = 'view_system_edit';\nconst is_view_system_edit_auth = ref(userStore.CHECK_AUTH(VIEW_SYSTEM_EDIT));\nconst enableEditCurrentView = computed(() => {\n if (currentView.value?.is_other_user_view) {\n return false;\n }\n if (currentView.value?.is_system && !is_view_system_edit_auth.value) {\n return false;\n }\n return isViewChange.value && currentView.value && currentView.value.id !== 'no-view';\n});\nconst selectedConditionGroup = defineModel('selectedConditionGroup', {\n default: null,\n});\nconst conditionGroupDataList = defineModel<any[]>('conditionGroupDataList', {\n default: null,\n});\nconst groupConditionValue = defineModel('groupConditionValue', {\n default: null,\n});\nconst settingOpen = ref(false);\nconst headerRef = ref(null);\nuseResizeObserver(headerRef, entries => {\n emit('heightChange', entries[0].contentRect.height);\n});\nconst { currentView, isViewChange } = useTableProState();\nconst isDropdown = ref(false);\nconst handleSelectedConditionGroupChange = (item: ConditionGroupConfigItem) => {\n emit('selectedConditionGroupChange', item);\n};\nconst handleGroupConditionValueChange = (value: any) => {\n emit('groupConditionValueChange', value);\n};\n\n// ============ 数据透视表相关 ============\nconst localPivotConfig = ref<PivotConfig>(\n props.pivotConfig\n ? cloneDeep(props.pivotConfig)\n : { rows: [], columns: [], values: [], indicatorsAsCol: true, rowHierarchyType: 'grid' },\n);\n\nwatch(\n () => props.pivotConfig,\n val => {\n if (val) {\n localPivotConfig.value = cloneDeep(val);\n }\n },\n { deep: true },\n);\n\nconst onPivotConfigChange = (config: PivotConfig) => {\n emit('pivotConfigChange', config);\n};\n</script>\n\n<style lang=\"less\" scoped>\n.ant-pro-table-list-toolbar-container {\n height: 30px;\n line-height: 30px;\n padding: 0 8px;\n}\n.ant-pro-table-list-toolbar-setting-item {\n font-size: 14px;\n}\n.current-view-name {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n display: inline-block;\n max-width: 150px;\n}\n.current-view-container {\n display: flex;\n height: 100%;\n padding: 2px;\n gap: 4px;\n}\n.view-menu {\n font-size: 12px;\n font-weight: normal;\n cursor: pointer;\n padding: 0 4px;\n background: #fafafa;\n border-radius: 4px;\n border: 1px solid #f0f0f0;\n line-height: 26px;\n}\n</style>\n","<template>\n <div\n class=\"ant-pro-table-list-toolbar\"\n v-if=\"!config?.hide_header\"\n ref=\"headerRef\"\n >\n <div class=\"ant-pro-table-list-toolbar-container\">\n <div class=\"ant-pro-table-list-toolbar-left\">\n <slot name=\"header_bar_before_title\"></slot>\n <div class=\"ant-pro-table-list-toolbar-title\">\n <span v-if=\"config?.show_title\">{{ config?.title }}</span>\n <div\n v-if=\"config?.show_current_view\"\n class=\"current-view-container\"\n >\n <a-tooltip\n v-if=\"currentView?.name\"\n :title=\"'视图:' + currentView?.name\"\n >\n <span class=\"current-view-name\">\n {{ currentView?.name }}\n </span>\n </a-tooltip>\n <template v-if=\"enableEditCurrentView\">\n <span style=\"font-size: 12px; margin-right: 5px; display: inline-block\">\n (已编辑)\n </span>\n <a-dropdown\n v-model:open=\"isDropdown\"\n trigger=\"click\"\n >\n <span class=\"view-menu\">\n {{ $t('保存') }}\n <down-outlined\n v-if=\"!isDropdown\"\n style=\"font-size: 10px; cursor: pointer\"\n />\n <up-outlined\n v-if=\"isDropdown\"\n style=\"font-size: 10px; cursor: pointer\"\n />\n </span>\n <template #overlay>\n <a-menu>\n <a-menu-item>\n <span\n @click=\"\n () => {\n isDropdown = false;\n selfEventBus.emit('saveView');\n }\n \"\n >\n {{ $t('保存视图') }}\n </span>\n </a-menu-item>\n <a-menu-item>\n <span\n @click=\"\n () => {\n isDropdown = false;\n selfEventBus.emit('saveNewView');\n }\n \"\n >\n {{ $t('另存为新视图') }}\n </span>\n </a-menu-item>\n </a-menu>\n </template>\n </a-dropdown>\n <span\n :bordered=\"false\"\n class=\"view-menu\"\n @click=\"\n () => {\n selfEventBus.emit('reinit');\n }\n \"\n >\n {{ $t('重置') }}\n </span>\n </template>\n </div>\n </div>\n <slot name=\"header_bar_after_title\"></slot>\n </div>\n <div class=\"ant-pro-table-list-toolbar-right\">\n <a-space align=\"center\">\n <slot name=\"header_bar_before_btn\"></slot>\n <head-btn\n :auth_batch_update_list=\"auth_batch_update_list\"\n :auth_head_btn_list=\"auth_head_btn_list\"\n :selectedRowKeys=\"selectedRowKeys\"\n :dataSource=\"dataSource\"\n :searchConfig=\"config.query_params || {}\"\n :current_org=\"current_org\"\n :router=\"router\"\n :event_obj=\"selfEventBus\"\n />\n <slot name=\"header_bar_after_btn\"></slot>\n </a-space>\n\n <div class=\"ant-pro-table-list-toolbar-divider\">\n <a-divider type=\"vertical\" />\n </div>\n\n <div\n class=\"ant-pro-table-list-toolbar-setting-item\"\n v-if=\"component_type === 'normal' && config?.condition_group_config_list?.length > 0\"\n >\n <ConditionGroupSelecter\n :config=\"config\"\n :selfEventBus=\"selfEventBus\"\n v-model:selectedConditionGroup=\"selectedConditionGroup\"\n v-model:groupConditionValue=\"groupConditionValue\"\n @change=\"handleSelectedConditionGroupChange\"\n />\n </div>\n <div\n class=\"ant-pro-table-list-toolbar-setting-item\"\n v-if=\"config?.sys_btn?.refresh !== false\"\n >\n <refresh-type-modal\n :refreshType=\"refreshType\"\n :loading=\"loading\"\n @refresh=\"$emit('refresh')\"\n @typeChange=\"$emit('refreshTypeChange', $event)\"\n />\n </div>\n <div\n class=\"ant-pro-table-list-toolbar-setting-item\"\n v-if=\"component_type === 'normal' && config?.sys_btn?.export !== false\"\n >\n <a-tooltip :title=\"$t('导出Excel')\">\n <a-button\n type=\"text\"\n size=\"small\"\n @click=\"$emit('export')\"\n >\n <template #icon>\n <download-outlined></download-outlined>\n </template>\n </a-button>\n </a-tooltip>\n </div>\n <div\n class=\"ant-pro-table-list-toolbar-setting-item\"\n v-if=\"component_type === 'normal' && config?.sys_btn?.table_size !== false\"\n >\n <a-tooltip :title=\"$t('密度')\">\n <a-dropdown\n :trigger=\"['click']\"\n placement=\"bottomRight\"\n >\n <column-height-outlined />\n <template #overlay>\n <a-menu\n :selected-keys=\"[tableSize]\"\n style=\"width: 80px\"\n @click=\"\n ({ key }) => {\n $emit('update:tableSize', key as string);\n $emit('tableSizeChange', key as string);\n }\n \"\n >\n <a-menu-item key=\"default\">\n <a href=\"javascript:\">{{ $t('默认') }}</a>\n </a-menu-item>\n <a-menu-item key=\"middle\">\n <a href=\"javascript:\">{{ $t('中等') }}</a>\n </a-menu-item>\n <a-menu-item key=\"small\">\n <a href=\"javascript:\">{{ $t('紧凑') }}</a>\n </a-menu-item>\n </a-menu>\n </template>\n </a-dropdown>\n </a-tooltip>\n </div>\n <div\n class=\"ant-pro-table-list-toolbar-setting-item\"\n v-if=\"config?.sys_btn?.column_config !== false\"\n >\n <a-tooltip :title=\"$t('设置')\">\n <a-button\n type=\"text\"\n size=\"small\"\n @click=\"settingOpen = true\"\n >\n <template #icon>\n <setting-outlined />\n </template>\n </a-button>\n </a-tooltip>\n </div>\n\n <div\n class=\"ant-pro-table-list-toolbar-setting-item\"\n v-if=\"config?.sys_btn?.full_screen !== false\"\n >\n <a-tooltip :title=\"screenState ? $t('退出全屏') : $t('全屏')\">\n <fullscreen-outlined\n v-if=\"!screenState\"\n @click=\"$emit('setFull')\"\n />\n <fullscreen-exit-outlined\n v-else\n @click=\"$emit('exitFull')\"\n />\n </a-tooltip>\n </div>\n </div>\n </div>\n </div>\n <ConditionGroupView\n :config=\"config\"\n v-model:conditionGroupDataList=\"conditionGroupDataList\"\n v-model:selectedConditionGroup=\"selectedConditionGroup\"\n :selfEventBus=\"selfEventBus\"\n v-model:groupConditionValue=\"groupConditionValue\"\n @change=\"handleGroupConditionValueChange\"\n />\n <a-modal\n :title=\"$t('设置')\"\n width=\"900px\"\n v-model:open=\"settingOpen\"\n >\n <column-edit-view\n :columns=\"columns\"\n :is_view=\"is_view\"\n :view_key=\"view_key\"\n :view_flag_name=\"view_flag_name\"\n :component_type=\"component_type\"\n :pivotConfig=\"localPivotConfig\"\n @change=\"$emit('columnsChange', $event)\"\n @pivotConfigChange=\"onPivotConfigChange\"\n ></column-edit-view>\n <template #footer>\n <a-button @click=\"settingOpen = false\">\n {{ $t('关闭') }}\n </a-button>\n </template>\n </a-modal>\n</template>\n\n<script setup lang=\"ts\">\nimport {\n ColumnHeightOutlined,\n FullscreenExitOutlined,\n FullscreenOutlined,\n DownloadOutlined,\n SettingOutlined,\n} from '@ant-design/icons-vue';\nimport { useResizeObserver } from '@vueuse/core';\nimport { computed, ref, watch } from 'vue';\nimport columnEditView from './tableConfig/index.vue';\nimport HeadBtn from './headBtn.vue';\nimport RefreshTypeModal from './refresh-type-modal/index.vue';\nimport { Column, ConditionGroupConfigItem, Table, PivotConfig } from './typing';\nimport { useTableProState } from './utils';\nimport ConditionGroupSelecter from './ConditionGroupSelecter.vue';\nimport ConditionGroupView from './ConditionGroupView.vue';\nimport { useUserStore } from 'liyu-pc-base/init-plugin';\nimport { cloneDeep } from 'lodash';\n\ninterface Props {\n config?: Table;\n auth_batch_update_list?: any[];\n auth_head_btn_list?: any[];\n selectedRowKeys?: any[];\n dataSource?: any[];\n current_org?: any;\n router?: any;\n selfEventBus?: any;\n loading?: boolean;\n screenState?: boolean;\n tableSize?: string;\n columns?: Column[];\n view_key?: string;\n view_flag_name?: string;\n is_view?: boolean;\n refreshType?: string;\n conditionsParams?: any;\n pivotConfig?: PivotConfig | null;\n component_type?: string;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n config: () => ({} as Table),\n auth_batch_update_list: () => [],\n auth_head_btn_list: () => [],\n selectedRowKeys: () => [],\n dataSource: () => [],\n loading: false,\n screenState: false,\n tableSize: 'small',\n columns: () => [],\n view_key: '',\n view_flag_name: '',\n is_view: true,\n refreshType: '手动',\n conditionsParams: () => null,\n pivotConfig: () => null,\n component_type: 'normal',\n});\n\nconst emit = defineEmits([\n 'refresh',\n 'export',\n 'setFull',\n 'exitFull',\n 'columnsChange',\n 'pivotConfigChange',\n 'viewSelected',\n 'update:tableSize',\n 'heightChange',\n 'refreshTypeChange',\n 'tableSizeChange',\n 'selectedConditionGroupChange',\n 'groupConditionValueChange',\n]);\nconst userStore = useUserStore();\nconst current_org = userStore.currentOrg;\nconst VIEW_SYSTEM_EDIT = 'view_system_edit';\nconst is_view_system_edit_auth = ref(userStore.CHECK_AUTH(VIEW_SYSTEM_EDIT));\nconst enableEditCurrentView = computed(() => {\n if (currentView.value?.is_other_user_view) {\n return false;\n }\n if (currentView.value?.is_system && !is_view_system_edit_auth.value) {\n return false;\n }\n return isViewChange.value && currentView.value && currentView.value.id !== 'no-view';\n});\nconst selectedConditionGroup = defineModel('selectedConditionGroup', {\n default: null,\n});\nconst conditionGroupDataList = defineModel<any[]>('conditionGroupDataList', {\n default: null,\n});\nconst groupConditionValue = defineModel('groupConditionValue', {\n default: null,\n});\nconst settingOpen = ref(false);\nconst headerRef = ref(null);\nuseResizeObserver(headerRef, entries => {\n emit('heightChange', entries[0].contentRect.height);\n});\nconst { currentView, isViewChange } = useTableProState();\nconst isDropdown = ref(false);\nconst handleSelectedConditionGroupChange = (item: ConditionGroupConfigItem) => {\n emit('selectedConditionGroupChange', item);\n};\nconst handleGroupConditionValueChange = (value: any) => {\n emit('groupConditionValueChange', value);\n};\n\n// ============ 数据透视表相关 ============\nconst localPivotConfig = ref<PivotConfig>(\n props.pivotConfig\n ? cloneDeep(props.pivotConfig)\n : { rows: [], columns: [], values: [], indicatorsAsCol: true, rowHierarchyType: 'grid' },\n);\n\nwatch(\n () => props.pivotConfig,\n val => {\n if (val) {\n localPivotConfig.value = cloneDeep(val);\n }\n },\n { deep: true },\n);\n\nconst onPivotConfigChange = (config: PivotConfig) => {\n emit('pivotConfigChange', config);\n};\n</script>\n\n<style lang=\"less\" scoped>\n.ant-pro-table-list-toolbar-container {\n height: 30px;\n line-height: 30px;\n padding: 0 8px;\n}\n.ant-pro-table-list-toolbar-setting-item {\n font-size: 14px;\n}\n.current-view-name {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n display: inline-block;\n max-width: 150px;\n}\n.current-view-container {\n display: flex;\n height: 100%;\n padding: 2px;\n gap: 4px;\n}\n.view-menu {\n font-size: 12px;\n font-weight: normal;\n cursor: pointer;\n padding: 0 4px;\n background: #fafafa;\n border-radius: 4px;\n border: 1px solid #f0f0f0;\n line-height: 26px;\n}\n</style>\n","<template>\n <component\n :is=\"'CellSummary_' + item.cellSummaryComponent\"\n v-if=\"item.cellSummaryComponent\"\n :cmpObj=\"{\n item: item,\n total: total,\n }\"\n ></component>\n <span\n v-else-if=\"item !== undefined\"\n :style=\"item.total_color ? item.total_color(item) : null\"\n >\n {{ item.total_content ? item.total_content(item) : total }}\n </span>\n\n <span\n v-else\n :style=\"item.total_color ? item.total_color(total) : null\"\n >\n {{ item.total_content ? item.total_content(total) : total }}\n </span>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed } from 'vue';\n\nconst props = defineProps({\n item: {\n type: Object,\n required: true,\n },\n summaryParams: {\n type: Object,\n required: true,\n },\n});\nconst total = computed(() => {\n let totla: any = 0;\n for (const item of props.summaryParams.pageData) {\n let itemValue = item[props.summaryParams.column.dataIndex];\n itemValue = getValue(itemValue);\n\n if (isNaN(itemValue) || itemValue == null) {\n itemValue = 0;\n }\n totla = add(totla, itemValue);\n }\n\n return totla;\n});\nfunction add(a, b) {\n const precision = Math.max(\n (a.toString().split('.')[1] || '').length,\n (b.toString().split('.')[1] || '').length,\n );\n return parseFloat((a + b).toFixed(precision));\n}\nconst getValue = (value: any) => {\n if (typeof value === 'string') {\n value = parseFloat(value);\n }\n return value;\n};\n</script>\n<style lang=\"less\" scoped></style>\n","<template>\n <component\n :is=\"'CellSummary_' + item.cellSummaryComponent\"\n v-if=\"item.cellSummaryComponent\"\n :cmpObj=\"{\n item: item,\n total: total,\n }\"\n ></component>\n <span\n v-else-if=\"item !== undefined\"\n :style=\"item.total_color ? item.total_color(item) : null\"\n >\n {{ item.total_content ? item.total_content(item) : total }}\n </span>\n\n <span\n v-else\n :style=\"item.total_color ? item.total_color(total) : null\"\n >\n {{ item.total_content ? item.total_content(total) : total }}\n </span>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed } from 'vue';\n\nconst props = defineProps({\n item: {\n type: Object,\n required: true,\n },\n summaryParams: {\n type: Object,\n required: true,\n },\n});\nconst total = computed(() => {\n let totla: any = 0;\n for (const item of props.summaryParams.pageData) {\n let itemValue = item[props.summaryParams.column.dataIndex];\n itemValue = getValue(itemValue);\n\n if (isNaN(itemValue) || itemValue == null) {\n itemValue = 0;\n }\n totla = add(totla, itemValue);\n }\n\n return totla;\n});\nfunction add(a, b) {\n const precision = Math.max(\n (a.toString().split('.')[1] || '').length,\n (b.toString().split('.')[1] || '').length,\n );\n return parseFloat((a + b).toFixed(precision));\n}\nconst getValue = (value: any) => {\n if (typeof value === 'string') {\n value = parseFloat(value);\n }\n return value;\n};\n</script>\n<style lang=\"less\" scoped></style>\n","<template>\n <a-menu\n :items=\"menuItems\"\n size=\"small\"\n mode=\"vertical\"\n @click=\"handleClick\"\n ></a-menu>\n <a-modal\n :title=\"$t('设置')\"\n width=\"1000px\"\n v-model:open=\"settingOpen\"\n >\n <column-edit-view\n :columns=\"columns\"\n :is_view=\"is_view\"\n :view_key=\"view_key\"\n :view_flag_name=\"view_flag_name\"\n @change=\"$emit('columnsChange', $event)\"\n ></column-edit-view>\n <template #footer>\n <a-button @click=\"settingOpen = false\">\n {{ $t('关闭') }}\n </a-button>\n </template>\n </a-modal>\n</template>\n\n<script setup lang=\"ts\">\nimport {\n CopyOutlined,\n ReloadOutlined,\n DownloadOutlined,\n SettingOutlined,\n SaveOutlined,\n AlignLeftOutlined,\n} from '@ant-design/icons-vue';\nimport { copyValue, isNotEmpty } from 'liyu-pc-base/utils/function';\nimport { computed, h, PropType, ref } from 'vue';\nimport columnEditView from './tableConfig/index.vue';\nimport { Column } from './typing';\nimport { useTableProState } from './utils';\nimport { MenuProps } from 'ant-design-vue';\n\nconst props = defineProps({\n contextmenuPopup: {\n type: Object,\n required: true,\n },\n dataSource: {\n type: Array,\n default: () => [],\n },\n columns: {\n type: Array as PropType<Column[]>,\n default: () => [],\n },\n view_key: {\n type: String,\n default: '',\n },\n view_flag_name: {\n type: String,\n default: '',\n },\n is_view: {\n type: Boolean,\n default: false,\n },\n selfEventBus: {\n type: Object,\n },\n});\n\nconst emit = defineEmits(['refresh', 'export', 'columnsChange']);\nconst settingOpen = ref(false);\nconst { currentView, isViewChange } = useTableProState();\nconst menuItems = computed(() => {\n let res: any = [\n {\n key: 'copy',\n icon: () => h(CopyOutlined),\n label: '复制',\n children: [\n {\n key: 'copy_cell',\n icon: () => h(CopyOutlined),\n label: '复制单元格',\n },\n {\n key: 'copy_record',\n icon: () => h(CopyOutlined),\n label: '复制行',\n },\n {\n key: 'copy_column',\n icon: () => h(CopyOutlined),\n label: '复制列',\n },\n ],\n },\n {\n key: 'refresh',\n icon: () => h(ReloadOutlined),\n label: '刷新',\n },\n {\n key: 'export',\n icon: () => h(DownloadOutlined),\n label: '导出',\n },\n {\n key: 'table_config',\n icon: () => h(SettingOutlined),\n label: '设置',\n },\n ];\n if (\n props.is_view &&\n isViewChange.value &&\n currentView.value &&\n currentView.value.id !== 'no-view'\n ) {\n res = [\n ...res,\n {\n key: 'view',\n icon: () => h(AlignLeftOutlined),\n label: '视图',\n children: [\n {\n key: 'save_view',\n icon: () => h(SaveOutlined),\n label: '保存视图',\n },\n {\n key: 'save_new_view',\n icon: () => h(SaveOutlined),\n label: '另存视图',\n },\n {\n key: 'reinit',\n icon: () => h(ReloadOutlined),\n label: '重置',\n },\n ],\n },\n ];\n }\n return res;\n});\n\nconst formatCopyValue = (value: any) => {\n return typeof value === 'object' ? JSON.stringify(value) : value;\n};\n\nconst copyClick = (type: 'cell' | 'column' | 'record') => {\n const { contextmenuPopup, dataSource, columns } = props;\n if (type === 'cell') {\n if (contextmenuPopup.column.key !== 'operation') {\n copyValue(formatCopyValue(contextmenuPopup.text));\n }\n } else if (type === 'column') {\n if (contextmenuPopup.column.key !== 'operation') {\n const { dataIndex } = contextmenuPopup.column;\n const value = dataSource.map((d: any) => formatCopyValue(d[dataIndex])).join('\\r\\n');\n copyValue(value);\n }\n } else if (type === 'record') {\n const record = contextmenuPopup.record;\n const value = columns\n .map((c: any) => (c.dataIndex ? formatCopyValue(record[c.dataIndex]) : ''))\n .filter(c => isNotEmpty(c))\n .join(' ');\n copyValue(value);\n }\n};\n\nconst handleClick: MenuProps['onClick'] = menuInfo => {\n if (menuInfo.key === 'copy_cell') {\n copyClick('cell');\n } else if (menuInfo.key === 'copy_record') {\n copyClick('record');\n } else if (menuInfo.key === 'copy_column') {\n copyClick('column');\n } else if (menuInfo.key === 'refresh') {\n emit('refresh');\n } else if (menuInfo.key === 'export') {\n emit('export');\n } else if (menuInfo.key === 'table_config') {\n settingOpen.value = true;\n } else if (menuInfo.key === 'save_view') {\n props.selfEventBus.emit('saveView');\n } else if (menuInfo.key === 'save_new_view') {\n props.selfEventBus.emit('saveNewView');\n } else if (menuInfo.key === 'reinit') {\n props.selfEventBus.emit('reinit');\n }\n props.contextmenuPopup.hidePopup();\n};\n</script>\n\n<style lang=\"less\" scoped>\n.popup-divider {\n :deep(.ant-divider-horizontal) {\n margin-top: 1px;\n margin-bottom: 1px;\n }\n}\n</style>\n","<template>\n <a-menu\n :items=\"menuItems\"\n size=\"small\"\n mode=\"vertical\"\n @click=\"handleClick\"\n ></a-menu>\n <a-modal\n :title=\"$t('设置')\"\n width=\"1000px\"\n v-model:open=\"settingOpen\"\n >\n <column-edit-view\n :columns=\"columns\"\n :is_view=\"is_view\"\n :view_key=\"view_key\"\n :view_flag_name=\"view_flag_name\"\n @change=\"$emit('columnsChange', $event)\"\n ></column-edit-view>\n <template #footer>\n <a-button @click=\"settingOpen = false\">\n {{ $t('关闭') }}\n </a-button>\n </template>\n </a-modal>\n</template>\n\n<script setup lang=\"ts\">\nimport {\n CopyOutlined,\n ReloadOutlined,\n DownloadOutlined,\n SettingOutlined,\n SaveOutlined,\n AlignLeftOutlined,\n} from '@ant-design/icons-vue';\nimport { copyValue, isNotEmpty } from 'liyu-pc-base/utils/function';\nimport { computed, h, PropType, ref } from 'vue';\nimport columnEditView from './tableConfig/index.vue';\nimport { Column } from './typing';\nimport { useTableProState } from './utils';\nimport { MenuProps } from 'ant-design-vue';\n\nconst props = defineProps({\n contextmenuPopup: {\n type: Object,\n required: true,\n },\n dataSource: {\n type: Array,\n default: () => [],\n },\n columns: {\n type: Array as PropType<Column[]>,\n default: () => [],\n },\n view_key: {\n type: String,\n default: '',\n },\n view_flag_name: {\n type: String,\n default: '',\n },\n is_view: {\n type: Boolean,\n default: false,\n },\n selfEventBus: {\n type: Object,\n },\n});\n\nconst emit = defineEmits(['refresh', 'export', 'columnsChange']);\nconst settingOpen = ref(false);\nconst { currentView, isViewChange } = useTableProState();\nconst menuItems = computed(() => {\n let res: any = [\n {\n key: 'copy',\n icon: () => h(CopyOutlined),\n label: '复制',\n children: [\n {\n key: 'copy_cell',\n icon: () => h(CopyOutlined),\n label: '复制单元格',\n },\n {\n key: 'copy_record',\n icon: () => h(CopyOutlined),\n label: '复制行',\n },\n {\n key: 'copy_column',\n icon: () => h(CopyOutlined),\n label: '复制列',\n },\n ],\n },\n {\n key: 'refresh',\n icon: () => h(ReloadOutlined),\n label: '刷新',\n },\n {\n key: 'export',\n icon: () => h(DownloadOutlined),\n label: '导出',\n },\n {\n key: 'table_config',\n icon: () => h(SettingOutlined),\n label: '设置',\n },\n ];\n if (\n props.is_view &&\n isViewChange.value &&\n currentView.value &&\n currentView.value.id !== 'no-view'\n ) {\n res = [\n ...res,\n {\n key: 'view',\n icon: () => h(AlignLeftOutlined),\n label: '视图',\n children: [\n {\n key: 'save_view',\n icon: () => h(SaveOutlined),\n label: '保存视图',\n },\n {\n key: 'save_new_view',\n icon: () => h(SaveOutlined),\n label: '另存视图',\n },\n {\n key: 'reinit',\n icon: () => h(ReloadOutlined),\n label: '重置',\n },\n ],\n },\n ];\n }\n return res;\n});\n\nconst formatCopyValue = (value: any) => {\n return typeof value === 'object' ? JSON.stringify(value) : value;\n};\n\nconst copyClick = (type: 'cell' | 'column' | 'record') => {\n const { contextmenuPopup, dataSource, columns } = props;\n if (type === 'cell') {\n if (contextmenuPopup.column.key !== 'operation') {\n copyValue(formatCopyValue(contextmenuPopup.text));\n }\n } else if (type === 'column') {\n if (contextmenuPopup.column.key !== 'operation') {\n const { dataIndex } = contextmenuPopup.column;\n const value = dataSource.map((d: any) => formatCopyValue(d[dataIndex])).join('\\r\\n');\n copyValue(value);\n }\n } else if (type === 'record') {\n const record = contextmenuPopup.record;\n const value = columns\n .map((c: any) => (c.dataIndex ? formatCopyValue(record[c.dataIndex]) : ''))\n .filter(c => isNotEmpty(c))\n .join(' ');\n copyValue(value);\n }\n};\n\nconst handleClick: MenuProps['onClick'] = menuInfo => {\n if (menuInfo.key === 'copy_cell') {\n copyClick('cell');\n } else if (menuInfo.key === 'copy_record') {\n copyClick('record');\n } else if (menuInfo.key === 'copy_column') {\n copyClick('column');\n } else if (menuInfo.key === 'refresh') {\n emit('refresh');\n } else if (menuInfo.key === 'export') {\n emit('export');\n } else if (menuInfo.key === 'table_config') {\n settingOpen.value = true;\n } else if (menuInfo.key === 'save_view') {\n props.selfEventBus.emit('saveView');\n } else if (menuInfo.key === 'save_new_view') {\n props.selfEventBus.emit('saveNewView');\n } else if (menuInfo.key === 'reinit') {\n props.selfEventBus.emit('reinit');\n }\n props.contextmenuPopup.hidePopup();\n};\n</script>\n\n<style lang=\"less\" scoped>\n.popup-divider {\n :deep(.ant-divider-horizontal) {\n margin-top: 1px;\n margin-bottom: 1px;\n }\n}\n</style>\n","<template>\n <div\n class=\"table-wraper\"\n ref=\"tableWraperRef\"\n >\n <div ref=\"searchRef\">\n <Search\n v-if=\"\n config?.search_config &&\n config.search_config.length > 0 &&\n !enable_advanced_search_multigroups\n \"\n :searchConfig=\"config?.search_config || []\"\n :autoRefreshOnSearchChange=\"config?.auto_refresh_on_search_change\"\n v-model:searchConditions=\"searchConditions\"\n :event-bus=\"selfEventBus\"\n :searchType=\"search_type\"\n :searchDisplayType=\"config?.search_display_type\"\n :searchColumnCount=\"config?.search_column_count\"\n :viewSearchConfig=\"viewSearchConfig\"\n :disabledShowSearchGroupName=\"config?.disabledShowSearchGroupName\"\n @viewSearchConfigChange=\"viewSearchConfigChange\"\n @change=\"handleSearchChange\"\n ></Search>\n <SearchFormGroup\n v-if=\"\n config?.search_config &&\n config.search_config.length > 0 &&\n enable_advanced_search_multigroups\n \"\n :searchConfig=\"config?.search_config || []\"\n :autoRefreshOnSearchChange=\"config?.auto_refresh_on_search_change\"\n v-model:searchGroups=\"searchGroups\"\n :event-bus=\"selfEventBus\"\n :searchType=\"search_type\"\n :searchDisplayType=\"config?.search_display_type\"\n :searchColumnCount=\"config?.search_column_count\"\n :disabledShowSearchGroupName=\"config?.disabledShowSearchGroupName\"\n @change=\"handleSearchChange\"\n ></SearchFormGroup>\n </div>\n <a-card\n ref=\"elRef\"\n :body-style=\"{ padding: 0 }\"\n >\n <TableHeader\n :config=\"config\"\n :auth_batch_update_list=\"auth_batch_update_list\"\n :auth_head_btn_list=\"auth_head_btn_list\"\n :selectedRowKeys=\"selectedRowKeys\"\n :dataSource=\"dataSource\"\n :current_org=\"current_org\"\n :router=\"router\"\n :selfEventBus=\"selfEventBus\"\n :loading=\"loading\"\n :screenState=\"screenState\"\n v-model:tableSize=\"state.tableSize\"\n :columns=\"columns\"\n :view_key=\"view_key\"\n :view_flag_name=\"config.title\"\n :is_view=\"is_view\"\n :refreshType=\"refreshType\"\n v-model:selectedConditionGroup=\"selectedConditionGroup\"\n v-model:conditionGroupDataList=\"conditionGroupDataList\"\n v-model:groupConditionValue=\"groupConditionValue\"\n @refresh=\"refresh\"\n @export=\"handleExport\"\n @setFull=\"setFull\"\n @exitFull=\"exitFull\"\n @columnsChange=\"onColumnsChange\"\n @heightChange=\"h => (headerHeight = h)\"\n @refreshTypeChange=\"handleRefreshTypeChange\"\n @tableSizeChange=\"handleTableSizeChange\"\n @selectedConditionGroupChange=\"handleSelectedConditionGroupChange\"\n @groupConditionValueChange=\"handleGroupConditionValueChange\"\n >\n <template #header_bar_before_title>\n <slot name=\"header_bar_before_title\"></slot>\n </template>\n <template #header_bar_after_title>\n <slot name=\"header_bar_after_title\"></slot>\n </template>\n <template #header_bar_before_btn>\n <slot name=\"header_bar_before_btn\"></slot>\n </template>\n <template #header_bar_after_btn>\n <slot name=\"header_bar_after_btn\"></slot>\n </template>\n </TableHeader>\n <s-table\n v-if=\"columns?.length > 0\"\n :columns=\"filtedColumns\"\n v-model:selectedRowKeys=\"selectedRowKeys\"\n :data-source=\"dataSource\"\n :bordered=\"true\"\n :size=\"state.tableSize\"\n :height=\"tableHeight\"\n :rowHeight=\"config.rowHeightFunc || config.rowHeight || undefined\"\n :scroll=\"{\n x: tableContentWidth,\n }\"\n :loading=\"loading && !config?.disabled_table_loading\"\n :pagination=\"\n config?.is_pagination\n ? {\n current: state.current,\n pageSize: state.pageSize,\n total: state.total,\n onChange: handlePageChange,\n showSizeChanger: true,\n pageSizeOptions: pageSizeOptions,\n }\n : false\n \"\n :rowKey=\"rowKey\"\n :rowSelection=\"config?.is_selection ? row_selection : null\"\n :custom-cell=\"config?.customCell\"\n :custom-header-cell=\"config?.customHeaderCell\"\n :custom-row=\"config?.customRow\"\n :virtual=\"true\"\n sticky\n summary-fixed\n :preserveRow=\"preserveRow\"\n :style=\"{\n '--row-heigth': `${config.rowHeight}px`,\n }\"\n :class=\"{ 'modify-row-height': !!config.rowHeight }\"\n @change=\"handleChange\"\n @cellClick=\"handleCellClick\"\n @resizeColumn=\"resizeColumn\"\n >\n <template #customFilterDropdown=\"{ confirm, clearFilters, column }\">\n <TableFilterDropdown\n :column=\"column\"\n :searchConfig=\"config.search_config || []\"\n v-model:searchConditions=\"headerSearchConditions\"\n :searchType=\"search_type\"\n :confirm=\"confirm\"\n :clearFilters=\"clearFilters\"\n @search=\"handleSearch\"\n @reset=\"handleReset\"\n />\n </template>\n <template\n #customFilterIcon=\"{ filtered, column }\"\n v-if=\"config?.enable_custom_filter\"\n >\n <FilterFilled\n :style=\"{\n color:\n filtered ||\n filterConditions(headerSearchConditions).some(\n s => s.field_name === column.dataIndex,\n )\n ? '#108ee9'\n : undefined,\n }\"\n />\n </template>\n <template #bodyCell=\"{ column, index, text, record }\">\n <template v-if=\"column.dataIndex == 'index'\">\n {{ index + 1 + state.pageSize * (state.current - 1) }}\n </template>\n <component\n :is=\"'Cell_' + column.cellComponent\"\n v-else-if=\"column.cellComponent\"\n :cmpObj=\"{\n column: column ? column : {},\n index: index,\n text: text,\n dataSource: dataSource,\n record: record ? record : {},\n pageSize: state.pageSize ? state.pageSize : 500,\n current: state.current ? state.current : 1,\n eventBus: eventBus,\n tableHeightY: tableHeight,\n requestParams: config.query_params,\n auth_btn_list: auth_btn_list,\n event_obj: selfEventBus,\n ...(config.cellComponentExt || {}),\n }\"\n ></component>\n\n <template v-else>\n <span\n v-if=\"searchText && searchedColumn === column.dataIndex\"\n :style=\"column.color ? column.color({ column, index, text, record }) : null\"\n >\n <template\n v-for=\"(fragment, i) in text\n .toString()\n .split(new RegExp(`(?<=${searchText})|(?=${searchText})`, 'i'))\"\n >\n <mark\n v-if=\"fragment.toLowerCase() === searchText.toLowerCase()\"\n :key=\"i\"\n class=\"highlight\"\n >\n {{ fragment }}\n </mark>\n <template v-else>{{ fragment }}</template>\n </template>\n </span>\n <span\n v-else\n :style=\"column.color ? column.color({ column, index, text, record }) : null\"\n >\n {{ column.content ? column.content({ column, index, text, record }) : text }}\n </span>\n </template>\n </template>\n <template\n #summary\n v-if=\"summaryColumns.length > 0\"\n >\n <s-table-summary-row>\n <s-table-summary-cell :index=\"0\">合计</s-table-summary-cell>\n <s-table-summary-cell\n v-for=\"item in summaryColumns\"\n :key=\"item.key\"\n :columnKey=\"item.key\"\n >\n <template #default=\"vars\">\n <TableSummary\n :item=\"item\"\n :summaryParams=\"vars\"\n ></TableSummary>\n </template>\n </s-table-summary-cell>\n </s-table-summary-row>\n </template>\n <template #contextmenuPopup=\"contextmenuPopup\">\n <TableContextMenu\n :contextmenuPopup=\"contextmenuPopup\"\n :dataSource=\"dataSource\"\n :columns=\"columns\"\n :view_key=\"view_key\"\n :view_flag_name=\"config.title\"\n :is_view=\"is_view\"\n :self-event-bus=\"selfEventBus\"\n @refresh=\"refresh\"\n @export=\"handleExport\"\n @columnsChange=\"onColumnsChange\"\n ></TableContextMenu>\n </template>\n </s-table>\n </a-card>\n </div>\n <export-excel-modal-view\n v-if=\"exportOpen\"\n :column-list=\"exportExcelColumnList\"\n :columns=\"exportExcelColumn\"\n :current=\"state.current\"\n :datasource=\"dataSource\"\n :filename=\"filename\"\n :pageSize=\"state.pageSize\"\n :total=\"state.total\"\n :requestParams=\"getQueryParams({ type: 'list' })\"\n :queryData=\"config.list_url\"\n v-model:open=\"exportOpen\"\n />\n</template>\n\n<script setup lang=\"ts\">\nimport { FilterFilled } from '@ant-design/icons-vue';\nimport { useResizeObserver } from '@vueuse/core';\nimport { TableProps } from 'ant-design-vue';\nimport dayjs from 'dayjs';\nimport { getApiData } from 'liyu-pc-base/api/api-model';\nimport { filterConditions, genID } from 'liyu-pc-base/utils/function';\nimport { useFullscreen } from 'liyu-pc-base/utils/hooks/useFullscreen';\nimport { debounce, isArray, cloneDeep } from 'lodash';\nimport mitt from 'mitt';\nimport { computed, h, onMounted, onUnmounted, provide, reactive, ref, watch } from 'vue';\nimport { useRouter } from 'vue-router';\nimport Search from './search.vue';\nimport SearchFormGroup from './SearchFormGroup.vue';\nimport TableFilterDropdown from './TableFilterDropdown.vue';\nimport TableHeader from './tableHeader.vue';\nimport TableSummary from './TableSummary.vue';\nimport { useRequiredConditionStore, required_condition_event_obj } from 'liyu-pc-base/init-plugin';\nimport { useI18n } from 'vue-i18n';\nimport { useEnv, useUserStore } from 'liyu-pc-base/init-plugin';\nimport {\n Column,\n SearchConditionItem,\n SearchGroupItem,\n Table,\n TableProState,\n ViewColumnItem,\n ViewData,\n Response,\n ViewSearchItem,\n ConditionGroupConfigItem,\n} from './typing';\nimport {\n fetchViewsData,\n getParamsCount,\n tableProStateSymbol,\n getCurrentGroupConditionValue,\n} from './utils';\nimport TableContextMenu from './TableContextMenu.vue';\nimport { useView } from './hooks/view';\nimport { query_view_settings_list } from 'liyu-pc-base/api/view-model';\nconst DEFAULT_PAGE_SIZE = 50;\nconst props = defineProps({\n config: {\n type: Object as () => Table,\n required: true,\n default: () => ({\n id: '',\n title: '',\n is_normal_model: true,\n modelType: null,\n list_url: '',\n columns: [],\n }),\n },\n eventBus: {\n type: Object,\n required: false,\n },\n initSelectValue: {\n type: Array,\n required: false,\n },\n initValueKey: {\n type: String,\n required: false,\n },\n});\ninterface Emits {\n (e: 'selectChange', selectdRecord: any[], unSelectdRecord: any[]): void;\n (e: 'dataChange', params: { data: any[]; current: number; total: number }): void;\n}\nconst emit = defineEmits<Emits>();\nconst { t } = useI18n();\nconst env = useEnv();\nconst requiredConditionStore = useRequiredConditionStore();\nconst userStore = useUserStore();\nconst userid = userStore.userid;\nconst current_org = userStore.currentOrg;\nconst VIEW_SYSTEM_EDIT = 'view_system_edit';\nconst is_view_system_edit_auth = ref(userStore.CHECK_AUTH(VIEW_SYSTEM_EDIT));\nconst router = useRouter();\nconst dataSource = ref([]);\nconst selectedRowKeys = ref([]);\nconst loading = ref(false);\nconst selfEventBus = mitt();\nconst searchConditions = ref<SearchConditionItem[]>([]);\nconst searchGroups = ref<SearchGroupItem[]>([]);\nconst enable_advanced_search_multigroups = computed(\n () => !!props.config.enable_advanced_search_multigroups,\n);\n/**\n * 表头搜索条件桥接 computed\n * - 未开启 enable_advanced_search_multigroups 时,直接读写 searchConditions\n * - 开启 enable_advanced_search_multigroups 时,读写 searchGroups[0].conditions\n * 使表头筛选(TableFilterDropdown / filter action)与多分组搜索第一个分组联动\n */\nconst headerSearchConditions = computed<SearchConditionItem[]>({\n get() {\n if (enable_advanced_search_multigroups.value) {\n return searchGroups.value[0]?.conditions || [];\n }\n return searchConditions.value;\n },\n set(val) {\n if (enable_advanced_search_multigroups.value) {\n if (searchGroups.value.length > 0) {\n searchGroups.value = searchGroups.value.map((g, i) =>\n i === 0 ? { ...g, conditions: val } : g,\n );\n } else {\n searchGroups.value = [\n {\n id: genID(),\n conditions: val,\n viewSearchConfig: {},\n },\n ];\n }\n } else {\n searchConditions.value = val;\n }\n },\n});\nlet loadDataId = null;\nconst tableWraperRef = ref(null);\nconst tableWraperHeight = ref(null);\nconst searchRef = ref(null);\nconst searchHeight = ref(null);\nconst headerHeight = ref(0);\nconst rowActionWidth = ref(30);\nconst sortedMap = ref({});\nconst sortedList = ref([]);\nconst auth_batch_update_list = ref([]);\nconst auth_head_btn_list = ref<any[]>([]);\nconst auth_btn_list = ref<any[]>([]);\nconst exportOpen = ref(false);\nconst searchText = ref('');\nconst searchedColumn = ref('');\nconst searchInput = ref();\nconst refreshType = ref(props.config.refreshType);\nconst selectedConditionGroup = ref<ConditionGroupConfigItem | null>(null);\nconst conditionGroupDataList = ref<any[]>([]);\nconst groupConditionValue = ref<string | null>(null);\nconst rowKey = computed(() => props.config?.rowKey || 'id');\nconst getAuthBtn = () => {\n auth_btn_list.value = userStore.CHECK_AUTH_BY_BTN_LIST(props.config?.btn_list || []) || [];\n auth_head_btn_list.value =\n userStore.CHECK_AUTH_BY_BTN_LIST(props.config?.head_btn_list || []) || [];\n auth_batch_update_list.value =\n userStore.CHECK_AUTH_BY_BTN_LIST(props.config?.batch_update_list || []) || [];\n};\ngetAuthBtn();\nconst pageSizeOptions = ref(\n props.config?.pageSizeOptions || [\n '10',\n '20',\n '50',\n '100',\n '200',\n '500',\n '1000',\n '3000',\n '10000',\n '50000',\n '60000',\n '70000',\n ],\n);\nconst view_key = computed(() => {\n return `table_pro_${props.config.key}`;\n});\nconst state = reactive({\n current: 1,\n pageSize: props.config?.pageSize || props.config?.query_params?.pageSize || DEFAULT_PAGE_SIZE,\n total: 0,\n tableSize: 'small',\n tableHead: null,\n sum_data: null,\n});\nuseResizeObserver(tableWraperRef, entries => {\n tableWraperHeight.value = entries[0].contentRect.height;\n});\nuseResizeObserver(searchRef, entries => {\n searchHeight.value = entries[0].contentRect.height;\n});\n\nconst preserveRow = () => {\n return false;\n};\nconst getQueryParams = ({ type = 'list', viewData = null, groupDataList = null } = {}) => {\n const getColumnFields = (list: Column[]) => {\n const fields = [];\n list.forEach(item => {\n if (\n item.dataIndex &&\n item.dataIndex !== 'index' &&\n item.dataIndex !== 'action' &&\n item.checked !== false\n ) {\n fields.push(item.dataIndex);\n }\n if (item.children && item.children.length > 0) {\n fields.push(...getColumnFields(item.children));\n }\n });\n return fields;\n };\n\n const sort_fields = [];\n const used_fields = new Set();\n for (const item of sortedList.value) {\n if (item.order == 'descend') {\n sort_fields.push('-' + item.key);\n } else {\n sort_fields.push(item.key);\n }\n used_fields.add(item.key);\n }\n if (props.config.base_sort_fields) {\n for (const item of props.config.base_sort_fields) {\n const field_name = item.startsWith('-') ? item.slice(1) : item;\n if (!used_fields.has(field_name)) {\n sort_fields.push(item);\n }\n }\n }\n const params = {\n ...(props.config.query_params || {}),\n\n sort_fields,\n };\n if (type === 'list') {\n const column_fields = getColumnFields(columns.value || []);\n if (props.config.base_column_fields) {\n column_fields.push(...props.config.base_column_fields);\n }\n params['current'] = state.current;\n params['pageSize'] = state.pageSize;\n params['column_fields'] = column_fields;\n }\n if (search_type.value === 'advanced') {\n if (enable_advanced_search_multigroups.value) {\n const searchGroupConds = (viewData ? viewData.searchGroups || [] : searchGroups.value)\n .map(group => filterConditions(group.conditions))\n .filter(group => group.length > 0);\n const baseConds = filterConditions(props.config.base_conditions);\n const conditionsList = [];\n if (searchGroupConds.length > 0) {\n conditionsList.push({ op: 'and', children: searchGroupConds });\n }\n if (baseConds.length > 0) {\n conditionsList.push({ op: 'and', children: baseConds });\n }\n params['conditions'] = conditionsList;\n } else {\n const conditions = [\n ...filterConditions(props.config.base_conditions),\n ...filterConditions(viewData ? viewData.searchConditions || [] : searchConditions.value),\n ];\n params['conditions'] = [conditions];\n }\n if (type === 'list' || type === 'count') {\n const groupCondition = getCurrentGroupConditionValue(\n groupDataList || conditionGroupDataList.value,\n viewData ? viewData.groupConditionValue : groupConditionValue.value,\n );\n if (groupCondition) {\n params['conditions'] = [\n {\n op: 'and',\n children: params['conditions'],\n },\n {\n op: 'and',\n children: [\n {\n format: selectedConditionGroup.value?.format || 'input',\n class_name: selectedConditionGroup.value?.class_name || 'str',\n field_name: groupCondition.field_name,\n operator: 'eq',\n value: [groupCondition.value],\n },\n ],\n },\n ];\n }\n }\n } else if (search_type.value === 'simple') {\n for (const item of filterConditions(\n viewData ? viewData.searchConditions || [] : searchConditions.value,\n )) {\n const v_count = getParamsCount(item.operator, item);\n let value = item.value;\n if (v_count === 1) {\n value = value[0];\n }\n params[item.field_name] = value;\n }\n }\n if (props.config.get_query_params_func) {\n const newParams = props.config.get_query_params_func({ params, type });\n if (newParams) {\n Object.assign(params, newParams);\n }\n }\n const requiredConditionObj = getRequiredConditionObj();\n if (requiredConditionObj) {\n params['required_condition'] = requiredConditionObj;\n }\n if (props.config.get_db_alias) {\n params['db_alias'] = props.config.get_db_alias();\n }\n\n return params;\n};\nconst [elRef, screenState, { setFull, exitFull }] = useFullscreen();\nconst getGroupDataList = async () => {\n if (!selectedConditionGroup.value) {\n if (conditionGroupDataList.value?.length > 0) {\n conditionGroupDataList.value = [];\n }\n return;\n }\n if (!props.config.query_group_url) {\n console.error('query_group_url 未配置');\n if (conditionGroupDataList.value?.length > 0) {\n conditionGroupDataList.value = [];\n }\n return;\n }\n if (!conditionGroupDataList.value?.length) {\n const params = getQueryParams({ type: 'group' });\n params['group_condition'] = {\n field_name: selectedConditionGroup.value.field_name,\n display_name: selectedConditionGroup.value.display_name,\n order_name: selectedConditionGroup.value.order_name || [],\n };\n const res = await getApiData(params, props.config.query_group_url || '', false, {\n api_log: `tablePro ${props.config.key} ${props.config.title}`,\n });\n conditionGroupDataList.value = res || [];\n }\n};\nconst getData = async () => {\n if (!props.config.list_url) {\n return;\n }\n const currentLoadId = Symbol(); // 唯一值\n loadDataId = currentLoadId;\n try {\n loading.value = true;\n await getGroupDataList();\n const params = getQueryParams({ type: 'list' });\n let response: Response;\n if (props.config.query_data_func) {\n response = await props.config.query_data_func(params);\n } else {\n response = await getApiData(\n params,\n props.config.list_url.replace('__tree', ''),\n props.config.list_url.includes('__tree'),\n {\n api_log: `tablePro ${props.config.key} ${props.config.title}`,\n },\n );\n }\n if (loadDataId !== currentLoadId) {\n return;\n }\n if (props.config.process_data_func) {\n dataSource.value = props.config.process_data_func(response.data);\n } else {\n dataSource.value = response.data || [];\n }\n state.current = response.current;\n state.total = response.total;\n state.tableHead = response.table_head ? response.table_head : null;\n state.sum_data = response.sum_data ?? null;\n emit('dataChange', {\n data: dataSource.value,\n current: response.current,\n total: response.total,\n });\n syncSelectedRowKeys();\n } finally {\n if (loadDataId !== currentLoadId) {\n return;\n }\n loading.value = false;\n }\n};\nconst delayGetDate = debounce(getData, 500);\nconst handlePageChange = (page: any, pageSize: any) => {\n if (state.current == page && state.pageSize == pageSize) {\n return;\n }\n state.current = page ? page : 1;\n state.pageSize = pageSize ? pageSize : DEFAULT_PAGE_SIZE;\n getData();\n};\nconst search_type = computed(() => {\n if (props.config.search_type === 'simple') {\n return props.config.search_type;\n } else {\n return 'advanced';\n }\n});\nconst is_view = computed(() => {\n return props.config?.is_view !== false;\n});\nconst row_selection: any = computed(() => {\n const rowSelectionType = props.config.rowSelectionType || 'checkbox';\n const rowSelectionCheckStrictly = props.config.rowSelectionCheckStrictly || false;\n const onChange = (selectedRowKeys, selectdRecord) => {\n const unSelectdRecord = dataSource.value.filter(item => {\n return !selectedRowKeys.includes(item.id);\n });\n emit('selectChange', selectdRecord, unSelectdRecord);\n };\n return { type: rowSelectionType, checkStrictly: rowSelectionCheckStrictly, onChange };\n});\nconst viewColumnsConfig = ref<Record<string, ViewColumnItem>>({});\nconst viewSearchConfig = ref<Record<string, ViewSearchItem>>({});\nconst filtedColumns = computed(() => {\n const filterRecursive = (list: Column[]) => {\n return list\n .filter(item => item.checked !== false)\n .map(item => {\n if (item.children && item.children.length > 0) {\n const children = filterRecursive(item.children);\n if (children.length > 0) {\n return {\n ...item,\n children,\n };\n }\n return null;\n }\n return item;\n })\n .filter(Boolean);\n };\n return filterRecursive(columns.value);\n});\nconst columns = computed<Column[]>(() => {\n const filterValueMap = {};\n for (const item of headerSearchConditions.value) {\n if (['in', 'eq'].includes(item.operator)) {\n filterValueMap[item.field_name] = item.value;\n }\n }\n const sorted = sortedMap.value || {};\n const baseColumns = [...(props.config.columns || [])];\n\n if (props.config.btn_list && props.config.btn_list.length > 0) {\n const hasAction = baseColumns.some(item => item.dataIndex === 'action');\n if (!hasAction) {\n baseColumns.push({\n title: '操作',\n dataIndex: 'action',\n cellComponent: 'action',\n width: rowActionWidth.value + 20,\n resizable: true,\n fixed: 'right',\n checked: true,\n });\n }\n }\n\n // 合并视图配置,递归合并\n const mergeRecursive = (list: Column[], isChildren = false): Column[] => {\n const merged = list\n .map(item => {\n const key = item.dataIndex || item.key || item.title;\n const viewCol = viewColumnsConfig.value[key] || {};\n const newItem = {\n ...item,\n ...viewCol,\n is_children: isChildren,\n key: key,\n };\n if (newItem.children && newItem.children.length > 0) {\n newItem.children = mergeRecursive(newItem.children, true);\n }\n return newItem;\n })\n .sort((a, b) => {\n const orderA = a.order ?? 999;\n const orderB = b.order ?? 999;\n return orderA - orderB;\n });\n\n return merged.map(item => {\n const key = item.dataIndex || item.key || item.title;\n let ellipsis = item.ellipsis;\n if (item.resizable && item.ellipsis == undefined) {\n ellipsis = true;\n }\n if (item.autoWidth) {\n return {\n ...item,\n minWidth: item.width,\n width: undefined,\n filteredValue: filterValueMap[key] || null,\n sortOrder: sorted[key] || false,\n key: key,\n ellipsis,\n customFilterDropdown:\n props.config.enable_custom_filter &&\n !!props.config.search_config?.find(s => s.field_name === key),\n onFilterDropdownOpenChange: open => {\n if (open) {\n setTimeout(() => {\n searchInput.value?.focus();\n }, 100);\n }\n },\n };\n } else {\n return {\n ...item,\n width: item.width,\n minWidth: undefined,\n filteredValue: filterValueMap[key] || null,\n sortOrder: sorted[key] || false,\n key: key,\n ellipsis,\n customFilterDropdown:\n props.config.enable_custom_filter &&\n !!props.config.search_config?.find(s => s.field_name === key),\n onFilterDropdownOpenChange: open => {\n if (open) {\n setTimeout(() => {\n searchInput.value?.focus();\n }, 100);\n }\n },\n };\n }\n });\n };\n\n const res: Column[] = mergeRecursive(baseColumns);\n // 序号列处理\n const hasIndex = res.some(item => item.dataIndex === 'index');\n if (!hasIndex && !props.config.hide_index_column) {\n res.unshift({\n title: '#',\n dataIndex: 'index',\n key: 'index',\n maxWidth: 50,\n fixed: 'left',\n checked: true,\n autoHeight: true,\n });\n }\n return res;\n});\nconst tableContentWidth = computed(() => {\n let width = 0;\n const processColumns = datas => {\n for (const item of datas) {\n if (item.children && item.children.length > 0) {\n processColumns(item.children);\n } else {\n width += item.width || item.minWidth || 120;\n }\n }\n };\n processColumns(columns.value);\n});\nconst filename = computed(() => {\n const title = props.config.title || 'data';\n const datetime = dayjs().format('YYYYMMDD_HHmmss');\n return `${title}_${datetime}`;\n});\nconst exportExcelColumnList = computed(() => {\n const list: any = [];\n const getLeaves = (cols: Column[]) => {\n cols.forEach(item => {\n if (item.children && item.children.length > 0) {\n getLeaves(item.children);\n } else {\n if (item.dataIndex === 'action' || item.dataIndex === 'index') {\n return;\n }\n list.push({\n checked: item.checked,\n fixed: item.fixed ? item.fixed : false,\n key: item.dataIndex,\n label: item.title,\n width: item.width,\n });\n }\n });\n };\n getLeaves(columns.value);\n return list;\n});\nconst exportExcelColumn = computed(() => {\n const list: any = [];\n const getLeaves = (cols: Column[]) => {\n cols.forEach(item => {\n if (item.children && item.children.length > 0) {\n getLeaves(item.children);\n } else {\n if (item.dataIndex === 'action' || item.dataIndex === 'index') {\n return;\n }\n list.push(item);\n }\n });\n };\n getLeaves(columns.value);\n return list;\n});\nconst handleSearch = ({ confirm, dataIndex, value }) => {\n confirm();\n searchText.value = value;\n searchedColumn.value = dataIndex;\n getData();\n isViewChange.value = true;\n};\n\nconst handleReset = ({ clearFilters, dataIndex }) => {\n clearFilters();\n searchText.value = '';\n const conditions = cloneDeep(headerSearchConditions.value);\n const conditionIndex = conditions.findIndex(item => item.field_name === dataIndex);\n if (conditionIndex > -1) {\n conditions.splice(conditionIndex, 1);\n }\n headerSearchConditions.value = conditions;\n getData();\n isViewChange.value = true;\n};\n\nconst refresh = async () => {\n await getData();\n};\nconst local_refresh = async () => {\n dataSource.value = [...dataSource.value];\n};\nconst handleRefreshTypeChange = type => {\n refreshType.value = type;\n isViewChange.value = true;\n};\nconst paginationHeight = ref(64);\nconst tableHeight = computed(() => {\n if (!tableWraperHeight.value) {\n return 0;\n }\n let value = tableWraperHeight.value - searchHeight.value - headerHeight.value - 4;\n if (props.config.is_pagination) {\n value -= paginationHeight.value;\n }\n console.log('tableWraperHeight', tableWraperHeight.value);\n console.log('searchHeight', searchHeight.value);\n console.log('headerHeight', headerHeight.value);\n console.log('paginationHeight', paginationHeight.value);\n console.log('tableHeight', value);\n return value;\n});\nconst handleTableSizeChange = () => {\n isViewChange.value = true;\n};\nwatch(\n () => state.tableSize,\n () => {\n // 此处设置paginationHeight两次,为了解决切换表格密度后,高度剧烈变化问题。\n paginationHeight.value = 64;\n setTimeout(() => {\n if (state.tableSize === 'small') {\n paginationHeight.value = 56;\n } else if (state.tableSize === 'middle') {\n paginationHeight.value = 56;\n } else if (state.tableSize === 'default') {\n paginationHeight.value = 64;\n }\n }, 200);\n },\n);\nconst syncSelectedRowKeys = () => {\n if (dataSource.value?.length > 0 && props.initValueKey) {\n const valueMap = {};\n selectedRowKeys.value = dataSource.value\n .filter(item => {\n const value = item[props.initValueKey];\n if (props.initSelectValue?.includes(value) && !valueMap[value]) {\n valueMap[value] = true;\n return true;\n }\n })\n .map(item => {\n return item.id;\n });\n }\n};\nconst init = async () => {\n conditionGroupDataList.value = [];\n const defaultSortField = props.config.columns.filter(\n column => column.sorter && column.defaultSortOrder,\n );\n defaultSortField.sort((a, b) => (a.defaultSortIndex || 0) - (b.defaultSortIndex || 0));\n for (const column of defaultSortField) {\n sortedMap.value[column.dataIndex] = column.defaultSortOrder;\n sortedList.value.push({ key: column.dataIndex, order: column.defaultSortOrder });\n }\n const tmpSearchConditions = [];\n if (props.config?.search_config) {\n props.config.search_config.forEach(configItem => {\n if (configItem.default_value) {\n let value = configItem.default_value;\n if (!isArray(value)) {\n value = [value];\n }\n tmpSearchConditions.push({\n field_name: configItem.field_name,\n value: value,\n operator: configItem.default_operator || 'eq',\n format: configItem.format || 'input',\n class_name: configItem.class_name || 'str',\n });\n }\n });\n }\n\n searchConditions.value = tmpSearchConditions;\n if (enable_advanced_search_multigroups.value) {\n if (props.config.default_advanced_search_multigroups) {\n searchGroups.value = props.config.default_advanced_search_multigroups;\n } else {\n searchGroups.value = [\n {\n id: genID(),\n conditions: [...tmpSearchConditions],\n viewSearchConfig: {},\n },\n ];\n }\n\n searchConditions.value = [];\n }\n if (is_view) {\n if (currentView.value?.id !== 'no-view') {\n currentView.value = null;\n await fetchViews();\n if (props.config?.view_uid) {\n const findView = viewDataList.value.find((item: any) => item.uid == props.config?.view_uid);\n if (findView) {\n setViewData(findView.data);\n currentView.value = findView;\n } else {\n const res: any = await query_view_settings_list({\n org_id: current_org.id,\n is_active: true,\n uid: props.config?.view_uid,\n });\n if (res?.length) {\n currentView.value = { ...res[0], is_other_user_view: true };\n }\n }\n }\n if (!currentView.value && viewDataList.value?.length) {\n const tmpData = [...viewDataList.value];\n // 优先级:当前选中视图,默认视图,用户视图,同级按 sort 正序\n const getSortValue = item => {\n let value = item.sort || 0;\n if (item.id !== currentView.value?.id) {\n value *= 1000000;\n }\n if (!item.is_default) {\n value *= 10000;\n }\n if (!item.user_id) {\n value *= 1000;\n }\n return value;\n };\n tmpData.sort((a, b) => getSortValue(a) - getSortValue(b));\n setViewData(tmpData[0].data);\n currentView.value = tmpData[0];\n }\n }\n }\n await getData();\n};\nconst eventReinit = async () => {\n isViewChange.value = false;\n await init();\n};\nconst eventReload = async () => {\n await getData();\n};\nconst flattenedColumns = computed(() => {\n const list = [];\n const getLeaves = (cols: Column[]) => {\n cols.forEach(col => {\n if (col.children && col.children.length > 0) {\n getLeaves(col.children);\n } else {\n list.push(col);\n }\n });\n };\n getLeaves(filtedColumns.value);\n return list;\n});\nconst summaryColumns = computed(() => {\n const list: any = [];\n let index = 0;\n for (const item of flattenedColumns.value) {\n let _index = index;\n if (props.config?.is_selection) {\n _index = index + 1;\n }\n if (item.summary) {\n // if (!props.config.is_selection && props.config.hide_index_column) {\n // console.error('未开启选择(is_selection)且隐藏了序号列(hide_index_column),无法展示\"合计\"');\n // return [];\n // }\n list.push({\n index: _index,\n key: item.key,\n columnKey: item.dataIndex,\n total_color: item.total_color,\n total_content: item.total_content,\n cellSummaryComponent: item.cellSummaryComponent,\n column: item,\n sum_data: state.sum_data,\n });\n }\n index++;\n }\n return list;\n});\nconst getRequiredConditionObj = () => {\n const required_condition = props.config.required_condition;\n if (required_condition) {\n const required_condition_obj = {};\n required_condition.forEach((item: any) => {\n const value = requiredConditionStore.value_map[item.key];\n if (value !== undefined && value !== null) {\n required_condition_obj[item.field_name] = value;\n }\n });\n return required_condition_obj;\n } else {\n return null;\n }\n};\nconst handleChange: TableProps['onChange'] = (pagination, filters, sorter, action) => {\n if (action.action === 'paginate') {\n return;\n } else if (action.action === 'filter') {\n const searchMap = {};\n for (const item of headerSearchConditions.value) {\n searchMap[item.field_name] = item;\n }\n for (const key of Object.keys(filters)) {\n const value = filters[key];\n const item = searchMap[key];\n if (item) {\n if (value?.length > 1) {\n item.operator = 'in';\n } else {\n if (!['in', 'eq'].includes(item.operator)) {\n item.operator = 'in';\n }\n }\n item.value = value;\n } else {\n searchMap[key] = {\n field_name: key,\n operator: 'eq',\n value: value,\n format: 'input',\n class_name: 'str',\n };\n }\n }\n headerSearchConditions.value = Object.values(searchMap);\n getData();\n isViewChange.value = true;\n } else if (action.action === 'sort') {\n const tmpMap = {};\n const tmpList = [];\n if (!isArray(sorter)) {\n tmpMap[sorter.columnKey] = sorter.order;\n tmpList.push({ key: sorter.columnKey, order: sorter.order });\n } else {\n for (const item of sorter) {\n tmpMap[item.columnKey] = item.order;\n tmpList.push({ key: item.columnKey, order: item.order });\n }\n }\n sortedMap.value = tmpMap;\n sortedList.value = tmpList;\n getData();\n isViewChange.value = true;\n }\n};\nconst handleCellClick = (e, cell) => {\n if (!props.config?.is_click_selection) {\n return;\n }\n const rowSelectionType = props.config.rowSelectionType || 'checkbox';\n if (rowSelectionType === 'radio') {\n selectedRowKeys.value = [cell.record.id];\n } else {\n const isSelected = selectedRowKeys.value && selectedRowKeys.value.includes(cell.record.id);\n if (isSelected) {\n selectedRowKeys.value = selectedRowKeys.value.filter(id => {\n return id !== cell.record.id;\n });\n } else {\n selectedRowKeys.value.push(cell.record.id);\n }\n }\n\n const selectdRecord = dataSource.value.filter(item => {\n return selectedRowKeys.value.includes(item.id);\n });\n const unSelectdRecord = dataSource.value.filter(item => {\n return !selectedRowKeys.value.includes(item.id);\n });\n emit('selectChange', selectdRecord, unSelectdRecord);\n};\nconst handleRequiredConditionChange = (key: string) => {\n if (props.config.required_condition) {\n const item = props.config.required_condition.find((item: any) => item.key === key);\n if (item) {\n conditionGroupDataList.value = [];\n getData();\n }\n }\n};\nonMounted(async () => {\n if (!props.config.key) {\n console.error('tablePro config 未配置 key');\n }\n if (!props.config.title) {\n console.error('tablePro config 未配置 title');\n }\n required_condition_event_obj().on('change', handleRequiredConditionChange);\n selfEventBus.on('refresh', refresh);\n selfEventBus.on('local_refresh', local_refresh);\n selfEventBus.on('reinit', eventReinit);\n selfEventBus.on('saveView', saveView);\n selfEventBus.on('saveNewView', addView);\n if (props.eventBus) {\n props.eventBus.on('reinit', eventReinit);\n props.eventBus.on('refresh', refresh);\n props.eventBus.on('local_refresh', local_refresh);\n props.eventBus.on('reload_table', eventReload);\n }\n if (props.config.tableSize) {\n state.tableSize = props.config.tableSize;\n }\n await init();\n});\nconst handleExport = () => {\n exportOpen.value = true;\n};\nconst onColumnsChange = (data: any[]) => {\n if (!props.config || !props.config.columns) return;\n const configObj: Record<string, any> = {};\n\n const processRecursive = (list: any[]) => {\n list.forEach((item, index) => {\n const dataIndex = item.dataIndex || item.key || item.title;\n if (dataIndex === 'index' || dataIndex === 'action') return;\n configObj[dataIndex] = {\n checked: item.checked,\n fixed: item.fixed,\n autoHeight: item.autoHeight,\n autoWidth: item.autoWidth,\n ellipsis: item.ellipsis,\n width: item.width,\n order: index,\n };\n if (item.children && item.children.length > 0) {\n processRecursive(item.children);\n }\n });\n };\n\n processRecursive(data);\n viewColumnsConfig.value = configObj;\n isViewChange.value = true;\n};\nconst setViewData = async (viewData: ViewData) => {\n if (viewData === null) {\n await init();\n isViewChange.value = false;\n return;\n }\n if (viewData.columns) {\n viewColumnsConfig.value = viewData.columns;\n }\n if (enable_advanced_search_multigroups.value) {\n if (viewData.searchGroups && viewData.searchGroups.length > 0) {\n searchGroups.value = viewData.searchGroups;\n } else if (viewData.searchConditions) {\n searchGroups.value = [\n {\n id: genID(),\n conditions: viewData.searchConditions,\n viewSearchConfig: viewData.searchConfig || {},\n },\n ];\n }\n // 保证至少存在一个分组\n if (searchGroups.value.length === 0) {\n searchGroups.value = [\n {\n id: genID(),\n conditions: [],\n viewSearchConfig: {},\n },\n ];\n }\n searchConditions.value = [];\n } else {\n if (viewData.searchConfig) {\n viewSearchConfig.value = viewData.searchConfig;\n }\n if (viewData.searchConditions) {\n searchConditions.value = viewData.searchConditions;\n }\n }\n if (viewData.tableSize) {\n state.tableSize = viewData.tableSize;\n }\n if (viewData.refreshType) {\n refreshType.value = viewData.refreshType;\n }\n if (viewData.sortedList) {\n sortedList.value = viewData.sortedList;\n sortedMap.value = {};\n for (const item of sortedList.value) {\n sortedMap.value[item.key] = item.order;\n }\n }\n if (viewData.groupConditionFieldName && props.config.condition_group_config_list?.length > 0) {\n selectedConditionGroup.value = props.config.condition_group_config_list.find(\n item => item.field_name === viewData.groupConditionFieldName,\n );\n } else {\n selectedConditionGroup.value = null;\n }\n\n groupConditionValue.value = viewData.groupConditionValue;\n\n if (props.config.set_view_callback) {\n props.config.set_view_callback({ viewData });\n }\n await refresh();\n isViewChange.value = false;\n};\nconst resizeColumn = (width, column, action: 'start' | 'move' | 'end') => {\n if (action === 'end') {\n let item = viewColumnsConfig.value[column.dataIndex];\n if (!item) {\n item = {};\n viewColumnsConfig.value[column.dataIndex] = item;\n }\n item.width = width;\n isViewChange.value = true;\n }\n};\nconst viewSearchConfigChange = (config: Record<string, ViewSearchItem>) => {\n viewSearchConfig.value = config;\n isViewChange.value = true;\n};\nconst getViewData = (): ViewData => {\n const viewData: any = {\n columns: viewColumnsConfig.value,\n searchConditions: searchConditions.value,\n tableSize: state.tableSize,\n refreshType: refreshType.value,\n searchConfig: viewSearchConfig.value,\n sortedList: sortedList.value,\n groupConditionFieldName: selectedConditionGroup.value?.field_name,\n groupConditionValue: groupConditionValue.value,\n };\n if (enable_advanced_search_multigroups.value) {\n viewData.searchGroups = searchGroups.value;\n // 将第一个分组的字段配置作为全局 searchConfig 保存,便于单分组模式兼容\n if (searchGroups.value.length > 0) {\n viewData.searchConfig = searchGroups.value[0].viewSearchConfig;\n }\n }\n if (props.config.get_view_data_func) {\n const newViewData = props.config.get_view_data_func({ viewData });\n if (newViewData) {\n Object.assign(viewData, newViewData);\n }\n }\n return viewData;\n};\nconst viewDataList = ref([]);\nconst currentView = ref<any>(null);\nconst isViewChange = ref(false);\nconst fetchViews = async () => {\n const data = await fetchViewsData(\n view_key.value,\n getQueryParams,\n props.config.count_url,\n props.config,\n );\n viewDataList.value = data;\n};\nconst handleSearchChange = () => {\n isViewChange.value = true;\n};\nconst handleGroupConditionValueChange = (value: any) => {\n isViewChange.value = true;\n};\nconst handleSelectedConditionGroupChange = (item: ConditionGroupConfigItem) => {\n conditionGroupDataList.value = [];\n isViewChange.value = true;\n};\nconst { saveView, addView } = useView({\n currentView,\n getViewData,\n isViewChange,\n userid,\n view_project__flag: env.VITE_APP_VIEW_PROJECT_FLAG,\n view_menu__flag: view_key.value,\n view_menu__name: props.config.title,\n fetchViews,\n is_auth: is_view_system_edit_auth,\n t,\n});\n\nprovide<TableProState>(tableProStateSymbol, {\n setViewData,\n getViewData,\n fetchViews,\n viewDataList,\n currentView,\n isViewChange,\n config: props.config,\n});\n\nonUnmounted(() => {\n selfEventBus.off('refresh', refresh);\n selfEventBus.off('local_refresh', local_refresh);\n selfEventBus.off('reinit', eventReinit);\n selfEventBus.off('saveView', saveView);\n selfEventBus.off('saveNewView', addView);\n if (props.eventBus) {\n props.eventBus.off('reinit', eventReinit);\n props.eventBus.off('refresh', refresh);\n props.eventBus.off('local_refresh', local_refresh);\n props.eventBus.off('reload_table', eventReload);\n }\n});\nwatch(\n () => props.initSelectValue,\n () => {\n syncSelectedRowKeys();\n },\n);\nwatch(\n () => props.config.query_params,\n () => {\n delayGetDate();\n },\n {\n deep: true,\n },\n);\nwatch(\n () => props.config.base_conditions,\n () => {\n delayGetDate();\n },\n {\n deep: true,\n },\n);\n\ndefineExpose({\n getViewData,\n setViewData,\n config: props.config,\n columns,\n fetchViews,\n viewDataList,\n currentView,\n isViewChange,\n viewColumnsConfig,\n searchGroups,\n refresh,\n init,\n dataSource,\n selectedRowKeys,\n});\n</script>\n<style lang=\"less\" scoped>\n.btn-wraper {\n display: flex;\n justify-content: flex-end;\n}\n.table-wraper {\n height: 100%;\n overflow: hidden;\n}\n.modify-row-height {\n :deep(.surely-table-header) {\n height: var(--row-heigth) !important;\n }\n :deep(.surely-table-header-cell) {\n height: var(--row-heigth) !important;\n }\n :deep(.surely-table-summary) {\n height: var(--row-heigth) !important;\n }\n}\n.popup-divider {\n :deep(.ant-divider-horizontal) {\n margin-top: 1px;\n margin-bottom: 1px;\n }\n}\n.highlight {\n background-color: rgb(255, 192, 105);\n padding: 0px;\n}\n</style>\n","<template>\n <div\n class=\"table-wraper\"\n ref=\"tableWraperRef\"\n >\n <div ref=\"searchRef\">\n <Search\n v-if=\"\n config?.search_config &&\n config.search_config.length > 0 &&\n !enable_advanced_search_multigroups\n \"\n :searchConfig=\"config?.search_config || []\"\n :autoRefreshOnSearchChange=\"config?.auto_refresh_on_search_change\"\n v-model:searchConditions=\"searchConditions\"\n :event-bus=\"selfEventBus\"\n :searchType=\"search_type\"\n :searchDisplayType=\"config?.search_display_type\"\n :searchColumnCount=\"config?.search_column_count\"\n :viewSearchConfig=\"viewSearchConfig\"\n :disabledShowSearchGroupName=\"config?.disabledShowSearchGroupName\"\n @viewSearchConfigChange=\"viewSearchConfigChange\"\n @change=\"handleSearchChange\"\n ></Search>\n <SearchFormGroup\n v-if=\"\n config?.search_config &&\n config.search_config.length > 0 &&\n enable_advanced_search_multigroups\n \"\n :searchConfig=\"config?.search_config || []\"\n :autoRefreshOnSearchChange=\"config?.auto_refresh_on_search_change\"\n v-model:searchGroups=\"searchGroups\"\n :event-bus=\"selfEventBus\"\n :searchType=\"search_type\"\n :searchDisplayType=\"config?.search_display_type\"\n :searchColumnCount=\"config?.search_column_count\"\n :disabledShowSearchGroupName=\"config?.disabledShowSearchGroupName\"\n @change=\"handleSearchChange\"\n ></SearchFormGroup>\n </div>\n <a-card\n ref=\"elRef\"\n :body-style=\"{ padding: 0 }\"\n >\n <TableHeader\n :config=\"config\"\n :auth_batch_update_list=\"auth_batch_update_list\"\n :auth_head_btn_list=\"auth_head_btn_list\"\n :selectedRowKeys=\"selectedRowKeys\"\n :dataSource=\"dataSource\"\n :current_org=\"current_org\"\n :router=\"router\"\n :selfEventBus=\"selfEventBus\"\n :loading=\"loading\"\n :screenState=\"screenState\"\n v-model:tableSize=\"state.tableSize\"\n :columns=\"columns\"\n :view_key=\"view_key\"\n :view_flag_name=\"config.title\"\n :is_view=\"is_view\"\n :refreshType=\"refreshType\"\n v-model:selectedConditionGroup=\"selectedConditionGroup\"\n v-model:conditionGroupDataList=\"conditionGroupDataList\"\n v-model:groupConditionValue=\"groupConditionValue\"\n @refresh=\"refresh\"\n @export=\"handleExport\"\n @setFull=\"setFull\"\n @exitFull=\"exitFull\"\n @columnsChange=\"onColumnsChange\"\n @heightChange=\"h => (headerHeight = h)\"\n @refreshTypeChange=\"handleRefreshTypeChange\"\n @tableSizeChange=\"handleTableSizeChange\"\n @selectedConditionGroupChange=\"handleSelectedConditionGroupChange\"\n @groupConditionValueChange=\"handleGroupConditionValueChange\"\n >\n <template #header_bar_before_title>\n <slot name=\"header_bar_before_title\"></slot>\n </template>\n <template #header_bar_after_title>\n <slot name=\"header_bar_after_title\"></slot>\n </template>\n <template #header_bar_before_btn>\n <slot name=\"header_bar_before_btn\"></slot>\n </template>\n <template #header_bar_after_btn>\n <slot name=\"header_bar_after_btn\"></slot>\n </template>\n </TableHeader>\n <s-table\n v-if=\"columns?.length > 0\"\n :columns=\"filtedColumns\"\n v-model:selectedRowKeys=\"selectedRowKeys\"\n :data-source=\"dataSource\"\n :bordered=\"true\"\n :size=\"state.tableSize\"\n :height=\"tableHeight\"\n :rowHeight=\"config.rowHeightFunc || config.rowHeight || undefined\"\n :scroll=\"{\n x: tableContentWidth,\n }\"\n :loading=\"loading && !config?.disabled_table_loading\"\n :pagination=\"\n config?.is_pagination\n ? {\n current: state.current,\n pageSize: state.pageSize,\n total: state.total,\n onChange: handlePageChange,\n showSizeChanger: true,\n pageSizeOptions: pageSizeOptions,\n }\n : false\n \"\n :rowKey=\"rowKey\"\n :rowSelection=\"config?.is_selection ? row_selection : null\"\n :custom-cell=\"config?.customCell\"\n :custom-header-cell=\"config?.customHeaderCell\"\n :custom-row=\"config?.customRow\"\n :virtual=\"true\"\n sticky\n summary-fixed\n :preserveRow=\"preserveRow\"\n :style=\"{\n '--row-heigth': `${config.rowHeight}px`,\n }\"\n :class=\"{ 'modify-row-height': !!config.rowHeight }\"\n @change=\"handleChange\"\n @cellClick=\"handleCellClick\"\n @resizeColumn=\"resizeColumn\"\n >\n <template #customFilterDropdown=\"{ confirm, clearFilters, column }\">\n <TableFilterDropdown\n :column=\"column\"\n :searchConfig=\"config.search_config || []\"\n v-model:searchConditions=\"headerSearchConditions\"\n :searchType=\"search_type\"\n :confirm=\"confirm\"\n :clearFilters=\"clearFilters\"\n @search=\"handleSearch\"\n @reset=\"handleReset\"\n />\n </template>\n <template\n #customFilterIcon=\"{ filtered, column }\"\n v-if=\"config?.enable_custom_filter\"\n >\n <FilterFilled\n :style=\"{\n color:\n filtered ||\n filterConditions(headerSearchConditions).some(\n s => s.field_name === column.dataIndex,\n )\n ? '#108ee9'\n : undefined,\n }\"\n />\n </template>\n <template #bodyCell=\"{ column, index, text, record }\">\n <template v-if=\"column.dataIndex == 'index'\">\n {{ index + 1 + state.pageSize * (state.current - 1) }}\n </template>\n <component\n :is=\"'Cell_' + column.cellComponent\"\n v-else-if=\"column.cellComponent\"\n :cmpObj=\"{\n column: column ? column : {},\n index: index,\n text: text,\n dataSource: dataSource,\n record: record ? record : {},\n pageSize: state.pageSize ? state.pageSize : 500,\n current: state.current ? state.current : 1,\n eventBus: eventBus,\n tableHeightY: tableHeight,\n requestParams: config.query_params,\n auth_btn_list: auth_btn_list,\n event_obj: selfEventBus,\n ...(config.cellComponentExt || {}),\n }\"\n ></component>\n\n <template v-else>\n <span\n v-if=\"searchText && searchedColumn === column.dataIndex\"\n :style=\"column.color ? column.color({ column, index, text, record }) : null\"\n >\n <template\n v-for=\"(fragment, i) in text\n .toString()\n .split(new RegExp(`(?<=${searchText})|(?=${searchText})`, 'i'))\"\n >\n <mark\n v-if=\"fragment.toLowerCase() === searchText.toLowerCase()\"\n :key=\"i\"\n class=\"highlight\"\n >\n {{ fragment }}\n </mark>\n <template v-else>{{ fragment }}</template>\n </template>\n </span>\n <span\n v-else\n :style=\"column.color ? column.color({ column, index, text, record }) : null\"\n >\n {{ column.content ? column.content({ column, index, text, record }) : text }}\n </span>\n </template>\n </template>\n <template\n #summary\n v-if=\"summaryColumns.length > 0\"\n >\n <s-table-summary-row>\n <s-table-summary-cell :index=\"0\">合计</s-table-summary-cell>\n <s-table-summary-cell\n v-for=\"item in summaryColumns\"\n :key=\"item.key\"\n :columnKey=\"item.key\"\n >\n <template #default=\"vars\">\n <TableSummary\n :item=\"item\"\n :summaryParams=\"vars\"\n ></TableSummary>\n </template>\n </s-table-summary-cell>\n </s-table-summary-row>\n </template>\n <template #contextmenuPopup=\"contextmenuPopup\">\n <TableContextMenu\n :contextmenuPopup=\"contextmenuPopup\"\n :dataSource=\"dataSource\"\n :columns=\"columns\"\n :view_key=\"view_key\"\n :view_flag_name=\"config.title\"\n :is_view=\"is_view\"\n :self-event-bus=\"selfEventBus\"\n @refresh=\"refresh\"\n @export=\"handleExport\"\n @columnsChange=\"onColumnsChange\"\n ></TableContextMenu>\n </template>\n </s-table>\n </a-card>\n </div>\n <export-excel-modal-view\n v-if=\"exportOpen\"\n :column-list=\"exportExcelColumnList\"\n :columns=\"exportExcelColumn\"\n :current=\"state.current\"\n :datasource=\"dataSource\"\n :filename=\"filename\"\n :pageSize=\"state.pageSize\"\n :total=\"state.total\"\n :requestParams=\"getQueryParams({ type: 'list' })\"\n :queryData=\"config.list_url\"\n v-model:open=\"exportOpen\"\n />\n</template>\n\n<script setup lang=\"ts\">\nimport { FilterFilled } from '@ant-design/icons-vue';\nimport { useResizeObserver } from '@vueuse/core';\nimport { TableProps } from 'ant-design-vue';\nimport dayjs from 'dayjs';\nimport { getApiData } from 'liyu-pc-base/api/api-model';\nimport { filterConditions, genID } from 'liyu-pc-base/utils/function';\nimport { useFullscreen } from 'liyu-pc-base/utils/hooks/useFullscreen';\nimport { debounce, isArray, cloneDeep } from 'lodash';\nimport mitt from 'mitt';\nimport { computed, h, onMounted, onUnmounted, provide, reactive, ref, watch } from 'vue';\nimport { useRouter } from 'vue-router';\nimport Search from './search.vue';\nimport SearchFormGroup from './SearchFormGroup.vue';\nimport TableFilterDropdown from './TableFilterDropdown.vue';\nimport TableHeader from './tableHeader.vue';\nimport TableSummary from './TableSummary.vue';\nimport { useRequiredConditionStore, required_condition_event_obj } from 'liyu-pc-base/init-plugin';\nimport { useI18n } from 'vue-i18n';\nimport { useEnv, useUserStore } from 'liyu-pc-base/init-plugin';\nimport {\n Column,\n SearchConditionItem,\n SearchGroupItem,\n Table,\n TableProState,\n ViewColumnItem,\n ViewData,\n Response,\n ViewSearchItem,\n ConditionGroupConfigItem,\n} from './typing';\nimport {\n fetchViewsData,\n getParamsCount,\n tableProStateSymbol,\n getCurrentGroupConditionValue,\n} from './utils';\nimport TableContextMenu from './TableContextMenu.vue';\nimport { useView } from './hooks/view';\nimport { query_view_settings_list } from 'liyu-pc-base/api/view-model';\nconst DEFAULT_PAGE_SIZE = 50;\nconst props = defineProps({\n config: {\n type: Object as () => Table,\n required: true,\n default: () => ({\n id: '',\n title: '',\n is_normal_model: true,\n modelType: null,\n list_url: '',\n columns: [],\n }),\n },\n eventBus: {\n type: Object,\n required: false,\n },\n initSelectValue: {\n type: Array,\n required: false,\n },\n initValueKey: {\n type: String,\n required: false,\n },\n});\ninterface Emits {\n (e: 'selectChange', selectdRecord: any[], unSelectdRecord: any[]): void;\n (e: 'dataChange', params: { data: any[]; current: number; total: number }): void;\n}\nconst emit = defineEmits<Emits>();\nconst { t } = useI18n();\nconst env = useEnv();\nconst requiredConditionStore = useRequiredConditionStore();\nconst userStore = useUserStore();\nconst userid = userStore.userid;\nconst current_org = userStore.currentOrg;\nconst VIEW_SYSTEM_EDIT = 'view_system_edit';\nconst is_view_system_edit_auth = ref(userStore.CHECK_AUTH(VIEW_SYSTEM_EDIT));\nconst router = useRouter();\nconst dataSource = ref([]);\nconst selectedRowKeys = ref([]);\nconst loading = ref(false);\nconst selfEventBus = mitt();\nconst searchConditions = ref<SearchConditionItem[]>([]);\nconst searchGroups = ref<SearchGroupItem[]>([]);\nconst enable_advanced_search_multigroups = computed(\n () => !!props.config.enable_advanced_search_multigroups,\n);\n/**\n * 表头搜索条件桥接 computed\n * - 未开启 enable_advanced_search_multigroups 时,直接读写 searchConditions\n * - 开启 enable_advanced_search_multigroups 时,读写 searchGroups[0].conditions\n * 使表头筛选(TableFilterDropdown / filter action)与多分组搜索第一个分组联动\n */\nconst headerSearchConditions = computed<SearchConditionItem[]>({\n get() {\n if (enable_advanced_search_multigroups.value) {\n return searchGroups.value[0]?.conditions || [];\n }\n return searchConditions.value;\n },\n set(val) {\n if (enable_advanced_search_multigroups.value) {\n if (searchGroups.value.length > 0) {\n searchGroups.value = searchGroups.value.map((g, i) =>\n i === 0 ? { ...g, conditions: val } : g,\n );\n } else {\n searchGroups.value = [\n {\n id: genID(),\n conditions: val,\n viewSearchConfig: {},\n },\n ];\n }\n } else {\n searchConditions.value = val;\n }\n },\n});\nlet loadDataId = null;\nconst tableWraperRef = ref(null);\nconst tableWraperHeight = ref(null);\nconst searchRef = ref(null);\nconst searchHeight = ref(null);\nconst headerHeight = ref(0);\nconst rowActionWidth = ref(30);\nconst sortedMap = ref({});\nconst sortedList = ref([]);\nconst auth_batch_update_list = ref([]);\nconst auth_head_btn_list = ref<any[]>([]);\nconst auth_btn_list = ref<any[]>([]);\nconst exportOpen = ref(false);\nconst searchText = ref('');\nconst searchedColumn = ref('');\nconst searchInput = ref();\nconst refreshType = ref(props.config.refreshType);\nconst selectedConditionGroup = ref<ConditionGroupConfigItem | null>(null);\nconst conditionGroupDataList = ref<any[]>([]);\nconst groupConditionValue = ref<string | null>(null);\nconst rowKey = computed(() => props.config?.rowKey || 'id');\nconst getAuthBtn = () => {\n auth_btn_list.value = userStore.CHECK_AUTH_BY_BTN_LIST(props.config?.btn_list || []) || [];\n auth_head_btn_list.value =\n userStore.CHECK_AUTH_BY_BTN_LIST(props.config?.head_btn_list || []) || [];\n auth_batch_update_list.value =\n userStore.CHECK_AUTH_BY_BTN_LIST(props.config?.batch_update_list || []) || [];\n};\ngetAuthBtn();\nconst pageSizeOptions = ref(\n props.config?.pageSizeOptions || [\n '10',\n '20',\n '50',\n '100',\n '200',\n '500',\n '1000',\n '3000',\n '10000',\n '50000',\n '60000',\n '70000',\n ],\n);\nconst view_key = computed(() => {\n return `table_pro_${props.config.key}`;\n});\nconst state = reactive({\n current: 1,\n pageSize: props.config?.pageSize || props.config?.query_params?.pageSize || DEFAULT_PAGE_SIZE,\n total: 0,\n tableSize: 'small',\n tableHead: null,\n sum_data: null,\n});\nuseResizeObserver(tableWraperRef, entries => {\n tableWraperHeight.value = entries[0].contentRect.height;\n});\nuseResizeObserver(searchRef, entries => {\n searchHeight.value = entries[0].contentRect.height;\n});\n\nconst preserveRow = () => {\n return false;\n};\nconst getQueryParams = ({ type = 'list', viewData = null, groupDataList = null } = {}) => {\n const getColumnFields = (list: Column[]) => {\n const fields = [];\n list.forEach(item => {\n if (\n item.dataIndex &&\n item.dataIndex !== 'index' &&\n item.dataIndex !== 'action' &&\n item.checked !== false\n ) {\n fields.push(item.dataIndex);\n }\n if (item.children && item.children.length > 0) {\n fields.push(...getColumnFields(item.children));\n }\n });\n return fields;\n };\n\n const sort_fields = [];\n const used_fields = new Set();\n for (const item of sortedList.value) {\n if (item.order == 'descend') {\n sort_fields.push('-' + item.key);\n } else {\n sort_fields.push(item.key);\n }\n used_fields.add(item.key);\n }\n if (props.config.base_sort_fields) {\n for (const item of props.config.base_sort_fields) {\n const field_name = item.startsWith('-') ? item.slice(1) : item;\n if (!used_fields.has(field_name)) {\n sort_fields.push(item);\n }\n }\n }\n const params = {\n ...(props.config.query_params || {}),\n\n sort_fields,\n };\n if (type === 'list') {\n const column_fields = getColumnFields(columns.value || []);\n if (props.config.base_column_fields) {\n column_fields.push(...props.config.base_column_fields);\n }\n params['current'] = state.current;\n params['pageSize'] = state.pageSize;\n params['column_fields'] = column_fields;\n }\n if (search_type.value === 'advanced') {\n if (enable_advanced_search_multigroups.value) {\n const searchGroupConds = (viewData ? viewData.searchGroups || [] : searchGroups.value)\n .map(group => filterConditions(group.conditions))\n .filter(group => group.length > 0);\n const baseConds = filterConditions(props.config.base_conditions);\n const conditionsList = [];\n if (searchGroupConds.length > 0) {\n conditionsList.push({ op: 'and', children: searchGroupConds });\n }\n if (baseConds.length > 0) {\n conditionsList.push({ op: 'and', children: baseConds });\n }\n params['conditions'] = conditionsList;\n } else {\n const conditions = [\n ...filterConditions(props.config.base_conditions),\n ...filterConditions(viewData ? viewData.searchConditions || [] : searchConditions.value),\n ];\n params['conditions'] = [conditions];\n }\n if (type === 'list' || type === 'count') {\n const groupCondition = getCurrentGroupConditionValue(\n groupDataList || conditionGroupDataList.value,\n viewData ? viewData.groupConditionValue : groupConditionValue.value,\n );\n if (groupCondition) {\n params['conditions'] = [\n {\n op: 'and',\n children: params['conditions'],\n },\n {\n op: 'and',\n children: [\n {\n format: selectedConditionGroup.value?.format || 'input',\n class_name: selectedConditionGroup.value?.class_name || 'str',\n field_name: groupCondition.field_name,\n operator: 'eq',\n value: [groupCondition.value],\n },\n ],\n },\n ];\n }\n }\n } else if (search_type.value === 'simple') {\n for (const item of filterConditions(\n viewData ? viewData.searchConditions || [] : searchConditions.value,\n )) {\n const v_count = getParamsCount(item.operator, item);\n let value = item.value;\n if (v_count === 1) {\n value = value[0];\n }\n params[item.field_name] = value;\n }\n }\n if (props.config.get_query_params_func) {\n const newParams = props.config.get_query_params_func({ params, type });\n if (newParams) {\n Object.assign(params, newParams);\n }\n }\n const requiredConditionObj = getRequiredConditionObj();\n if (requiredConditionObj) {\n params['required_condition'] = requiredConditionObj;\n }\n if (props.config.get_db_alias) {\n params['db_alias'] = props.config.get_db_alias();\n }\n\n return params;\n};\nconst [elRef, screenState, { setFull, exitFull }] = useFullscreen();\nconst getGroupDataList = async () => {\n if (!selectedConditionGroup.value) {\n if (conditionGroupDataList.value?.length > 0) {\n conditionGroupDataList.value = [];\n }\n return;\n }\n if (!props.config.query_group_url) {\n console.error('query_group_url 未配置');\n if (conditionGroupDataList.value?.length > 0) {\n conditionGroupDataList.value = [];\n }\n return;\n }\n if (!conditionGroupDataList.value?.length) {\n const params = getQueryParams({ type: 'group' });\n params['group_condition'] = {\n field_name: selectedConditionGroup.value.field_name,\n display_name: selectedConditionGroup.value.display_name,\n order_name: selectedConditionGroup.value.order_name || [],\n };\n const res = await getApiData(params, props.config.query_group_url || '', false, {\n api_log: `tablePro ${props.config.key} ${props.config.title}`,\n });\n conditionGroupDataList.value = res || [];\n }\n};\nconst getData = async () => {\n if (!props.config.list_url) {\n return;\n }\n const currentLoadId = Symbol(); // 唯一值\n loadDataId = currentLoadId;\n try {\n loading.value = true;\n await getGroupDataList();\n const params = getQueryParams({ type: 'list' });\n let response: Response;\n if (props.config.query_data_func) {\n response = await props.config.query_data_func(params);\n } else {\n response = await getApiData(\n params,\n props.config.list_url.replace('__tree', ''),\n props.config.list_url.includes('__tree'),\n {\n api_log: `tablePro ${props.config.key} ${props.config.title}`,\n },\n );\n }\n if (loadDataId !== currentLoadId) {\n return;\n }\n if (props.config.process_data_func) {\n dataSource.value = props.config.process_data_func(response.data);\n } else {\n dataSource.value = response.data || [];\n }\n state.current = response.current;\n state.total = response.total;\n state.tableHead = response.table_head ? response.table_head : null;\n state.sum_data = response.sum_data ?? null;\n emit('dataChange', {\n data: dataSource.value,\n current: response.current,\n total: response.total,\n });\n syncSelectedRowKeys();\n } finally {\n if (loadDataId !== currentLoadId) {\n return;\n }\n loading.value = false;\n }\n};\nconst delayGetDate = debounce(getData, 500);\nconst handlePageChange = (page: any, pageSize: any) => {\n if (state.current == page && state.pageSize == pageSize) {\n return;\n }\n state.current = page ? page : 1;\n state.pageSize = pageSize ? pageSize : DEFAULT_PAGE_SIZE;\n getData();\n};\nconst search_type = computed(() => {\n if (props.config.search_type === 'simple') {\n return props.config.search_type;\n } else {\n return 'advanced';\n }\n});\nconst is_view = computed(() => {\n return props.config?.is_view !== false;\n});\nconst row_selection: any = computed(() => {\n const rowSelectionType = props.config.rowSelectionType || 'checkbox';\n const rowSelectionCheckStrictly = props.config.rowSelectionCheckStrictly || false;\n const onChange = (selectedRowKeys, selectdRecord) => {\n const unSelectdRecord = dataSource.value.filter(item => {\n return !selectedRowKeys.includes(item.id);\n });\n emit('selectChange', selectdRecord, unSelectdRecord);\n };\n return { type: rowSelectionType, checkStrictly: rowSelectionCheckStrictly, onChange };\n});\nconst viewColumnsConfig = ref<Record<string, ViewColumnItem>>({});\nconst viewSearchConfig = ref<Record<string, ViewSearchItem>>({});\nconst filtedColumns = computed(() => {\n const filterRecursive = (list: Column[]) => {\n return list\n .filter(item => item.checked !== false)\n .map(item => {\n if (item.children && item.children.length > 0) {\n const children = filterRecursive(item.children);\n if (children.length > 0) {\n return {\n ...item,\n children,\n };\n }\n return null;\n }\n return item;\n })\n .filter(Boolean);\n };\n return filterRecursive(columns.value);\n});\nconst columns = computed<Column[]>(() => {\n const filterValueMap = {};\n for (const item of headerSearchConditions.value) {\n if (['in', 'eq'].includes(item.operator)) {\n filterValueMap[item.field_name] = item.value;\n }\n }\n const sorted = sortedMap.value || {};\n const baseColumns = [...(props.config.columns || [])];\n\n if (props.config.btn_list && props.config.btn_list.length > 0) {\n const hasAction = baseColumns.some(item => item.dataIndex === 'action');\n if (!hasAction) {\n baseColumns.push({\n title: '操作',\n dataIndex: 'action',\n cellComponent: 'action',\n width: rowActionWidth.value + 20,\n resizable: true,\n fixed: 'right',\n checked: true,\n });\n }\n }\n\n // 合并视图配置,递归合并\n const mergeRecursive = (list: Column[], isChildren = false): Column[] => {\n const merged = list\n .map(item => {\n const key = item.dataIndex || item.key || item.title;\n const viewCol = viewColumnsConfig.value[key] || {};\n const newItem = {\n ...item,\n ...viewCol,\n is_children: isChildren,\n key: key,\n };\n if (newItem.children && newItem.children.length > 0) {\n newItem.children = mergeRecursive(newItem.children, true);\n }\n return newItem;\n })\n .sort((a, b) => {\n const orderA = a.order ?? 999;\n const orderB = b.order ?? 999;\n return orderA - orderB;\n });\n\n return merged.map(item => {\n const key = item.dataIndex || item.key || item.title;\n let ellipsis = item.ellipsis;\n if (item.resizable && item.ellipsis == undefined) {\n ellipsis = true;\n }\n if (item.autoWidth) {\n return {\n ...item,\n minWidth: item.width,\n width: undefined,\n filteredValue: filterValueMap[key] || null,\n sortOrder: sorted[key] || false,\n key: key,\n ellipsis,\n customFilterDropdown:\n props.config.enable_custom_filter &&\n !!props.config.search_config?.find(s => s.field_name === key),\n onFilterDropdownOpenChange: open => {\n if (open) {\n setTimeout(() => {\n searchInput.value?.focus();\n }, 100);\n }\n },\n };\n } else {\n return {\n ...item,\n width: item.width,\n minWidth: undefined,\n filteredValue: filterValueMap[key] || null,\n sortOrder: sorted[key] || false,\n key: key,\n ellipsis,\n customFilterDropdown:\n props.config.enable_custom_filter &&\n !!props.config.search_config?.find(s => s.field_name === key),\n onFilterDropdownOpenChange: open => {\n if (open) {\n setTimeout(() => {\n searchInput.value?.focus();\n }, 100);\n }\n },\n };\n }\n });\n };\n\n const res: Column[] = mergeRecursive(baseColumns);\n // 序号列处理\n const hasIndex = res.some(item => item.dataIndex === 'index');\n if (!hasIndex && !props.config.hide_index_column) {\n res.unshift({\n title: '#',\n dataIndex: 'index',\n key: 'index',\n maxWidth: 50,\n fixed: 'left',\n checked: true,\n autoHeight: true,\n });\n }\n return res;\n});\nconst tableContentWidth = computed(() => {\n let width = 0;\n const processColumns = datas => {\n for (const item of datas) {\n if (item.children && item.children.length > 0) {\n processColumns(item.children);\n } else {\n width += item.width || item.minWidth || 120;\n }\n }\n };\n processColumns(columns.value);\n});\nconst filename = computed(() => {\n const title = props.config.title || 'data';\n const datetime = dayjs().format('YYYYMMDD_HHmmss');\n return `${title}_${datetime}`;\n});\nconst exportExcelColumnList = computed(() => {\n const list: any = [];\n const getLeaves = (cols: Column[]) => {\n cols.forEach(item => {\n if (item.children && item.children.length > 0) {\n getLeaves(item.children);\n } else {\n if (item.dataIndex === 'action' || item.dataIndex === 'index') {\n return;\n }\n list.push({\n checked: item.checked,\n fixed: item.fixed ? item.fixed : false,\n key: item.dataIndex,\n label: item.title,\n width: item.width,\n });\n }\n });\n };\n getLeaves(columns.value);\n return list;\n});\nconst exportExcelColumn = computed(() => {\n const list: any = [];\n const getLeaves = (cols: Column[]) => {\n cols.forEach(item => {\n if (item.children && item.children.length > 0) {\n getLeaves(item.children);\n } else {\n if (item.dataIndex === 'action' || item.dataIndex === 'index') {\n return;\n }\n list.push(item);\n }\n });\n };\n getLeaves(columns.value);\n return list;\n});\nconst handleSearch = ({ confirm, dataIndex, value }) => {\n confirm();\n searchText.value = value;\n searchedColumn.value = dataIndex;\n getData();\n isViewChange.value = true;\n};\n\nconst handleReset = ({ clearFilters, dataIndex }) => {\n clearFilters();\n searchText.value = '';\n const conditions = cloneDeep(headerSearchConditions.value);\n const conditionIndex = conditions.findIndex(item => item.field_name === dataIndex);\n if (conditionIndex > -1) {\n conditions.splice(conditionIndex, 1);\n }\n headerSearchConditions.value = conditions;\n getData();\n isViewChange.value = true;\n};\n\nconst refresh = async () => {\n await getData();\n};\nconst local_refresh = async () => {\n dataSource.value = [...dataSource.value];\n};\nconst handleRefreshTypeChange = type => {\n refreshType.value = type;\n isViewChange.value = true;\n};\nconst paginationHeight = ref(64);\nconst tableHeight = computed(() => {\n if (!tableWraperHeight.value) {\n return 0;\n }\n let value = tableWraperHeight.value - searchHeight.value - headerHeight.value - 4;\n if (props.config.is_pagination) {\n value -= paginationHeight.value;\n }\n console.log('tableWraperHeight', tableWraperHeight.value);\n console.log('searchHeight', searchHeight.value);\n console.log('headerHeight', headerHeight.value);\n console.log('paginationHeight', paginationHeight.value);\n console.log('tableHeight', value);\n return value;\n});\nconst handleTableSizeChange = () => {\n isViewChange.value = true;\n};\nwatch(\n () => state.tableSize,\n () => {\n // 此处设置paginationHeight两次,为了解决切换表格密度后,高度剧烈变化问题。\n paginationHeight.value = 64;\n setTimeout(() => {\n if (state.tableSize === 'small') {\n paginationHeight.value = 56;\n } else if (state.tableSize === 'middle') {\n paginationHeight.value = 56;\n } else if (state.tableSize === 'default') {\n paginationHeight.value = 64;\n }\n }, 200);\n },\n);\nconst syncSelectedRowKeys = () => {\n if (dataSource.value?.length > 0 && props.initValueKey) {\n const valueMap = {};\n selectedRowKeys.value = dataSource.value\n .filter(item => {\n const value = item[props.initValueKey];\n if (props.initSelectValue?.includes(value) && !valueMap[value]) {\n valueMap[value] = true;\n return true;\n }\n })\n .map(item => {\n return item.id;\n });\n }\n};\nconst init = async () => {\n conditionGroupDataList.value = [];\n const defaultSortField = props.config.columns.filter(\n column => column.sorter && column.defaultSortOrder,\n );\n defaultSortField.sort((a, b) => (a.defaultSortIndex || 0) - (b.defaultSortIndex || 0));\n for (const column of defaultSortField) {\n sortedMap.value[column.dataIndex] = column.defaultSortOrder;\n sortedList.value.push({ key: column.dataIndex, order: column.defaultSortOrder });\n }\n const tmpSearchConditions = [];\n if (props.config?.search_config) {\n props.config.search_config.forEach(configItem => {\n if (configItem.default_value) {\n let value = configItem.default_value;\n if (!isArray(value)) {\n value = [value];\n }\n tmpSearchConditions.push({\n field_name: configItem.field_name,\n value: value,\n operator: configItem.default_operator || 'eq',\n format: configItem.format || 'input',\n class_name: configItem.class_name || 'str',\n });\n }\n });\n }\n\n searchConditions.value = tmpSearchConditions;\n if (enable_advanced_search_multigroups.value) {\n if (props.config.default_advanced_search_multigroups) {\n searchGroups.value = props.config.default_advanced_search_multigroups;\n } else {\n searchGroups.value = [\n {\n id: genID(),\n conditions: [...tmpSearchConditions],\n viewSearchConfig: {},\n },\n ];\n }\n\n searchConditions.value = [];\n }\n if (is_view) {\n if (currentView.value?.id !== 'no-view') {\n currentView.value = null;\n await fetchViews();\n if (props.config?.view_uid) {\n const findView = viewDataList.value.find((item: any) => item.uid == props.config?.view_uid);\n if (findView) {\n setViewData(findView.data);\n currentView.value = findView;\n } else {\n const res: any = await query_view_settings_list({\n org_id: current_org.id,\n is_active: true,\n uid: props.config?.view_uid,\n });\n if (res?.length) {\n currentView.value = { ...res[0], is_other_user_view: true };\n }\n }\n }\n if (!currentView.value && viewDataList.value?.length) {\n const tmpData = [...viewDataList.value];\n // 优先级:当前选中视图,默认视图,用户视图,同级按 sort 正序\n const getSortValue = item => {\n let value = item.sort || 0;\n if (item.id !== currentView.value?.id) {\n value *= 1000000;\n }\n if (!item.is_default) {\n value *= 10000;\n }\n if (!item.user_id) {\n value *= 1000;\n }\n return value;\n };\n tmpData.sort((a, b) => getSortValue(a) - getSortValue(b));\n setViewData(tmpData[0].data);\n currentView.value = tmpData[0];\n }\n }\n }\n await getData();\n};\nconst eventReinit = async () => {\n isViewChange.value = false;\n await init();\n};\nconst eventReload = async () => {\n await getData();\n};\nconst flattenedColumns = computed(() => {\n const list = [];\n const getLeaves = (cols: Column[]) => {\n cols.forEach(col => {\n if (col.children && col.children.length > 0) {\n getLeaves(col.children);\n } else {\n list.push(col);\n }\n });\n };\n getLeaves(filtedColumns.value);\n return list;\n});\nconst summaryColumns = computed(() => {\n const list: any = [];\n let index = 0;\n for (const item of flattenedColumns.value) {\n let _index = index;\n if (props.config?.is_selection) {\n _index = index + 1;\n }\n if (item.summary) {\n // if (!props.config.is_selection && props.config.hide_index_column) {\n // console.error('未开启选择(is_selection)且隐藏了序号列(hide_index_column),无法展示\"合计\"');\n // return [];\n // }\n list.push({\n index: _index,\n key: item.key,\n columnKey: item.dataIndex,\n total_color: item.total_color,\n total_content: item.total_content,\n cellSummaryComponent: item.cellSummaryComponent,\n column: item,\n sum_data: state.sum_data,\n });\n }\n index++;\n }\n return list;\n});\nconst getRequiredConditionObj = () => {\n const required_condition = props.config.required_condition;\n if (required_condition) {\n const required_condition_obj = {};\n required_condition.forEach((item: any) => {\n const value = requiredConditionStore.value_map[item.key];\n if (value !== undefined && value !== null) {\n required_condition_obj[item.field_name] = value;\n }\n });\n return required_condition_obj;\n } else {\n return null;\n }\n};\nconst handleChange: TableProps['onChange'] = (pagination, filters, sorter, action) => {\n if (action.action === 'paginate') {\n return;\n } else if (action.action === 'filter') {\n const searchMap = {};\n for (const item of headerSearchConditions.value) {\n searchMap[item.field_name] = item;\n }\n for (const key of Object.keys(filters)) {\n const value = filters[key];\n const item = searchMap[key];\n if (item) {\n if (value?.length > 1) {\n item.operator = 'in';\n } else {\n if (!['in', 'eq'].includes(item.operator)) {\n item.operator = 'in';\n }\n }\n item.value = value;\n } else {\n searchMap[key] = {\n field_name: key,\n operator: 'eq',\n value: value,\n format: 'input',\n class_name: 'str',\n };\n }\n }\n headerSearchConditions.value = Object.values(searchMap);\n getData();\n isViewChange.value = true;\n } else if (action.action === 'sort') {\n const tmpMap = {};\n const tmpList = [];\n if (!isArray(sorter)) {\n tmpMap[sorter.columnKey] = sorter.order;\n tmpList.push({ key: sorter.columnKey, order: sorter.order });\n } else {\n for (const item of sorter) {\n tmpMap[item.columnKey] = item.order;\n tmpList.push({ key: item.columnKey, order: item.order });\n }\n }\n sortedMap.value = tmpMap;\n sortedList.value = tmpList;\n getData();\n isViewChange.value = true;\n }\n};\nconst handleCellClick = (e, cell) => {\n if (!props.config?.is_click_selection) {\n return;\n }\n const rowSelectionType = props.config.rowSelectionType || 'checkbox';\n if (rowSelectionType === 'radio') {\n selectedRowKeys.value = [cell.record.id];\n } else {\n const isSelected = selectedRowKeys.value && selectedRowKeys.value.includes(cell.record.id);\n if (isSelected) {\n selectedRowKeys.value = selectedRowKeys.value.filter(id => {\n return id !== cell.record.id;\n });\n } else {\n selectedRowKeys.value.push(cell.record.id);\n }\n }\n\n const selectdRecord = dataSource.value.filter(item => {\n return selectedRowKeys.value.includes(item.id);\n });\n const unSelectdRecord = dataSource.value.filter(item => {\n return !selectedRowKeys.value.includes(item.id);\n });\n emit('selectChange', selectdRecord, unSelectdRecord);\n};\nconst handleRequiredConditionChange = (key: string) => {\n if (props.config.required_condition) {\n const item = props.config.required_condition.find((item: any) => item.key === key);\n if (item) {\n conditionGroupDataList.value = [];\n getData();\n }\n }\n};\nonMounted(async () => {\n if (!props.config.key) {\n console.error('tablePro config 未配置 key');\n }\n if (!props.config.title) {\n console.error('tablePro config 未配置 title');\n }\n required_condition_event_obj().on('change', handleRequiredConditionChange);\n selfEventBus.on('refresh', refresh);\n selfEventBus.on('local_refresh', local_refresh);\n selfEventBus.on('reinit', eventReinit);\n selfEventBus.on('saveView', saveView);\n selfEventBus.on('saveNewView', addView);\n if (props.eventBus) {\n props.eventBus.on('reinit', eventReinit);\n props.eventBus.on('refresh', refresh);\n props.eventBus.on('local_refresh', local_refresh);\n props.eventBus.on('reload_table', eventReload);\n }\n if (props.config.tableSize) {\n state.tableSize = props.config.tableSize;\n }\n await init();\n});\nconst handleExport = () => {\n exportOpen.value = true;\n};\nconst onColumnsChange = (data: any[]) => {\n if (!props.config || !props.config.columns) return;\n const configObj: Record<string, any> = {};\n\n const processRecursive = (list: any[]) => {\n list.forEach((item, index) => {\n const dataIndex = item.dataIndex || item.key || item.title;\n if (dataIndex === 'index' || dataIndex === 'action') return;\n configObj[dataIndex] = {\n checked: item.checked,\n fixed: item.fixed,\n autoHeight: item.autoHeight,\n autoWidth: item.autoWidth,\n ellipsis: item.ellipsis,\n width: item.width,\n order: index,\n };\n if (item.children && item.children.length > 0) {\n processRecursive(item.children);\n }\n });\n };\n\n processRecursive(data);\n viewColumnsConfig.value = configObj;\n isViewChange.value = true;\n};\nconst setViewData = async (viewData: ViewData) => {\n if (viewData === null) {\n await init();\n isViewChange.value = false;\n return;\n }\n if (viewData.columns) {\n viewColumnsConfig.value = viewData.columns;\n }\n if (enable_advanced_search_multigroups.value) {\n if (viewData.searchGroups && viewData.searchGroups.length > 0) {\n searchGroups.value = viewData.searchGroups;\n } else if (viewData.searchConditions) {\n searchGroups.value = [\n {\n id: genID(),\n conditions: viewData.searchConditions,\n viewSearchConfig: viewData.searchConfig || {},\n },\n ];\n }\n // 保证至少存在一个分组\n if (searchGroups.value.length === 0) {\n searchGroups.value = [\n {\n id: genID(),\n conditions: [],\n viewSearchConfig: {},\n },\n ];\n }\n searchConditions.value = [];\n } else {\n if (viewData.searchConfig) {\n viewSearchConfig.value = viewData.searchConfig;\n }\n if (viewData.searchConditions) {\n searchConditions.value = viewData.searchConditions;\n }\n }\n if (viewData.tableSize) {\n state.tableSize = viewData.tableSize;\n }\n if (viewData.refreshType) {\n refreshType.value = viewData.refreshType;\n }\n if (viewData.sortedList) {\n sortedList.value = viewData.sortedList;\n sortedMap.value = {};\n for (const item of sortedList.value) {\n sortedMap.value[item.key] = item.order;\n }\n }\n if (viewData.groupConditionFieldName && props.config.condition_group_config_list?.length > 0) {\n selectedConditionGroup.value = props.config.condition_group_config_list.find(\n item => item.field_name === viewData.groupConditionFieldName,\n );\n } else {\n selectedConditionGroup.value = null;\n }\n\n groupConditionValue.value = viewData.groupConditionValue;\n\n if (props.config.set_view_callback) {\n props.config.set_view_callback({ viewData });\n }\n await refresh();\n isViewChange.value = false;\n};\nconst resizeColumn = (width, column, action: 'start' | 'move' | 'end') => {\n if (action === 'end') {\n let item = viewColumnsConfig.value[column.dataIndex];\n if (!item) {\n item = {};\n viewColumnsConfig.value[column.dataIndex] = item;\n }\n item.width = width;\n isViewChange.value = true;\n }\n};\nconst viewSearchConfigChange = (config: Record<string, ViewSearchItem>) => {\n viewSearchConfig.value = config;\n isViewChange.value = true;\n};\nconst getViewData = (): ViewData => {\n const viewData: any = {\n columns: viewColumnsConfig.value,\n searchConditions: searchConditions.value,\n tableSize: state.tableSize,\n refreshType: refreshType.value,\n searchConfig: viewSearchConfig.value,\n sortedList: sortedList.value,\n groupConditionFieldName: selectedConditionGroup.value?.field_name,\n groupConditionValue: groupConditionValue.value,\n };\n if (enable_advanced_search_multigroups.value) {\n viewData.searchGroups = searchGroups.value;\n // 将第一个分组的字段配置作为全局 searchConfig 保存,便于单分组模式兼容\n if (searchGroups.value.length > 0) {\n viewData.searchConfig = searchGroups.value[0].viewSearchConfig;\n }\n }\n if (props.config.get_view_data_func) {\n const newViewData = props.config.get_view_data_func({ viewData });\n if (newViewData) {\n Object.assign(viewData, newViewData);\n }\n }\n return viewData;\n};\nconst viewDataList = ref([]);\nconst currentView = ref<any>(null);\nconst isViewChange = ref(false);\nconst fetchViews = async () => {\n const data = await fetchViewsData(\n view_key.value,\n getQueryParams,\n props.config.count_url,\n props.config,\n );\n viewDataList.value = data;\n};\nconst handleSearchChange = () => {\n isViewChange.value = true;\n};\nconst handleGroupConditionValueChange = (value: any) => {\n isViewChange.value = true;\n};\nconst handleSelectedConditionGroupChange = (item: ConditionGroupConfigItem) => {\n conditionGroupDataList.value = [];\n isViewChange.value = true;\n};\nconst { saveView, addView } = useView({\n currentView,\n getViewData,\n isViewChange,\n userid,\n view_project__flag: env.VITE_APP_VIEW_PROJECT_FLAG,\n view_menu__flag: view_key.value,\n view_menu__name: props.config.title,\n fetchViews,\n is_auth: is_view_system_edit_auth,\n t,\n});\n\nprovide<TableProState>(tableProStateSymbol, {\n setViewData,\n getViewData,\n fetchViews,\n viewDataList,\n currentView,\n isViewChange,\n config: props.config,\n});\n\nonUnmounted(() => {\n selfEventBus.off('refresh', refresh);\n selfEventBus.off('local_refresh', local_refresh);\n selfEventBus.off('reinit', eventReinit);\n selfEventBus.off('saveView', saveView);\n selfEventBus.off('saveNewView', addView);\n if (props.eventBus) {\n props.eventBus.off('reinit', eventReinit);\n props.eventBus.off('refresh', refresh);\n props.eventBus.off('local_refresh', local_refresh);\n props.eventBus.off('reload_table', eventReload);\n }\n});\nwatch(\n () => props.initSelectValue,\n () => {\n syncSelectedRowKeys();\n },\n);\nwatch(\n () => props.config.query_params,\n () => {\n delayGetDate();\n },\n {\n deep: true,\n },\n);\nwatch(\n () => props.config.base_conditions,\n () => {\n delayGetDate();\n },\n {\n deep: true,\n },\n);\n\ndefineExpose({\n getViewData,\n setViewData,\n config: props.config,\n columns,\n fetchViews,\n viewDataList,\n currentView,\n isViewChange,\n viewColumnsConfig,\n searchGroups,\n refresh,\n init,\n dataSource,\n selectedRowKeys,\n});\n</script>\n<style lang=\"less\" scoped>\n.btn-wraper {\n display: flex;\n justify-content: flex-end;\n}\n.table-wraper {\n height: 100%;\n overflow: hidden;\n}\n.modify-row-height {\n :deep(.surely-table-header) {\n height: var(--row-heigth) !important;\n }\n :deep(.surely-table-header-cell) {\n height: var(--row-heigth) !important;\n }\n :deep(.surely-table-summary) {\n height: var(--row-heigth) !important;\n }\n}\n.popup-divider {\n :deep(.ant-divider-horizontal) {\n margin-top: 1px;\n margin-bottom: 1px;\n }\n}\n.highlight {\n background-color: rgb(255, 192, 105);\n padding: 0px;\n}\n</style>\n"],"mappings":"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"}
|