liyu-pc-base 1.0.921 → 1.0.925
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-BOg7nm5z.js → FieldRender-DnOLSXTl.js} +1 -1
- package/dist/{FieldRender2-_MtcDkI5.js → FieldRender2-CvxGe238.js} +2 -2
- package/dist/{FormRender3-BtY9d91e.js → FormRender3-CAxOQgue.js} +1 -1
- package/dist/{RemoteSelectPro-CcWTS4f6.js → RemoteSelectPro-CcL_vU1K.js} +1 -1
- package/dist/{SearchRender-ByarFel1.js → SearchRender-Dr_qnvZM.js} +1 -1
- package/dist/components/index.js +7 -7
- package/dist/{dbViewConfig-RGSyUx3F.js → dbViewConfig-BF0QZ_mT.js} +1 -1
- package/dist/{detailTablePro-CqcVbn8O.js → detailTablePro-DxgfGYN3.js} +1 -1
- package/dist/index.js +1 -1
- package/dist/liyu-pc-base.css +1 -1
- package/dist/{tableModal-DSKuV-hn.js → tableModal-DZE5wntG.js} +1 -1
- package/dist/{tablePageHost-B_BOlBNA.js → tablePageHost-hE_1hQv4.js} +82 -44
- package/dist/{tablePro-IAcxxAGI.js → tablePro-t2yDX9oW.js} +16 -11
- package/package.json +1 -1
- package/dist/AttributeNomTable-DHED22ju.js.map +0 -1
- package/dist/AttributeTable-muxdKpWW.js.map +0 -1
- package/dist/FieldRender-BOg7nm5z.js.map +0 -1
- package/dist/FieldRender2-_MtcDkI5.js.map +0 -1
- package/dist/FormRender3-BtY9d91e.js.map +0 -1
- package/dist/ImportExcelModal-Dds857L2.js.map +0 -1
- package/dist/JsonObj-CmylW4Or.js.map +0 -1
- package/dist/JsonStr-JwOPdAYW.js.map +0 -1
- package/dist/RemoteCascader-B2ytkZp7.js.map +0 -1
- package/dist/RemoteFilterSelect-BthY6Fyt.js.map +0 -1
- package/dist/RemoteModal-Dqy32RFN.js.map +0 -1
- package/dist/RemoteSelect-27xLYvyg.js.map +0 -1
- package/dist/RemoteSelectPro-CcWTS4f6.js.map +0 -1
- package/dist/RemoteTable-D_12PvNS.js.map +0 -1
- package/dist/RemoteTable2-DF7gWHYf.js.map +0 -1
- package/dist/RemoteText-DwRLI0xq.js.map +0 -1
- package/dist/RemoteTreeSelectPro-CXMOariR.js.map +0 -1
- package/dist/SearchRender-ByarFel1.js.map +0 -1
- package/dist/TinymceEditor-waI-dlC5.js.map +0 -1
- package/dist/aiGenModel-C9E1ahu8.js.map +0 -1
- package/dist/api/api-model.js.map +0 -1
- package/dist/api/typing.js.map +0 -1
- package/dist/batchCreateUser-B4zAXSR6.js.map +0 -1
- package/dist/boldenText-Bv8Zo7Vh.js.map +0 -1
- package/dist/components/FormRender/utils.js.map +0 -1
- package/dist/components/gridPage/utils.js.map +0 -1
- package/dist/components/index.js.map +0 -1
- package/dist/components/remotePages/utils.js.map +0 -1
- package/dist/dbDataSourceConfig-Hj90tvTR.js.map +0 -1
- package/dist/dbViewConfig-RGSyUx3F.js.map +0 -1
- package/dist/default-DmCqrYQi.js.map +0 -1
- package/dist/detailTablePro-CqcVbn8O.js.map +0 -1
- package/dist/exceljs.min-BPhBd8yF.js.map +0 -1
- package/dist/function-BhYSb8ls.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/init-plugin-CvgtEpwY.js.map +0 -1
- package/dist/lodash-CMVwnWxD.js.map +0 -1
- package/dist/md5-WIoeWMjT.js.map +0 -1
- package/dist/modal-tools-CrXdI5sg.js.map +0 -1
- package/dist/props-util-D7nkeN4W.js.map +0 -1
- package/dist/remotePages-CvjMLjTh.js.map +0 -1
- package/dist/role-manage-C7O8b2SF.js.map +0 -1
- package/dist/syncDataSourceConfig-OZ2mJCJs.js.map +0 -1
- package/dist/syncExportRawData-Dpi-VJuu.js.map +0 -1
- package/dist/syncModelTypeConfig-B2vV_kKb.js.map +0 -1
- package/dist/tableModal-DSKuV-hn.js.map +0 -1
- package/dist/tablePageHost-B_BOlBNA.js.map +0 -1
- package/dist/tablePro-IAcxxAGI.js.map +0 -1
- package/dist/utils/excel.js.map +0 -1
- package/dist/utils/hooks/useFetchData.js.map +0 -1
- package/dist/utils/hooks/useTableColumn.js.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../src/components/FormRender/GeneralFilter/AddConditionModal/index.vue","../../src/components/FormRender/GeneralFilter/AddConditionModal/index.vue","../../src/components/FormRender/GeneralFilter/AddConditionGroupModal/index.vue","../../src/components/FormRender/GeneralFilter/AddConditionGroupModal/index.vue","../../src/components/FormRender/GeneralFilter/data.ts","../../src/components/FormRender/GeneralFilter/index.vue","../../src/components/FormRender/GeneralFilter/index.vue","../../src/components/FormRender/FormRender.vue","../../src/components/FormRender/FormRender.vue","../../src/components/FormRender/FormRender2.vue","../../src/components/FormRender/FormRender2.vue","../../src/constants.ts","../../src/components/SideSearchRender/viewManage.vue","../../src/components/SideSearchRender/viewManage.vue","../../src/components/SideSearchRender/SideSearchRender.vue","../../src/components/SideSearchRender/SideSearchRender.vue","../../src/components/fullLayout/fullLayoutUtils.ts","../../src/components/fullLayout/fullLayout.vue","../../src/components/fullLayout/fullLayout.vue","../../src/components/grid-layout/helpers/dom.ts","../../src/components/grid-layout/helpers/utils.ts","../../src/components/grid-layout/helpers/responsive-utils.ts","../../src/components/grid-layout/helpers/draggable-utils.ts","../../src/components/grid-layout/components/grid-item.vue","../../src/components/grid-layout/components/grid-item.vue","../../src/components/grid-layout/components/grid-layout.vue","../../src/components/grid-layout/components/grid-layout.vue","../../src/components/gridPage/gridView.vue","../../src/components/gridPage/gridView.vue","../../src/components/gridPage/index.ts","../../src/components/gridPage/gridPage.vue","../../src/components/gridPage/gridPage.vue","../../src/components/remotePages/v2/index.vue","../../src/components/remotePages/v2/index.vue","../../src/components/sql_db_view/viewConfigCell.vue","../../src/components/sql_db_view/viewConfigCell.vue","../../src/components/sql_db_view/viewsConfig.vue","../../src/components/sql_db_view/viewsConfig.vue","../../src/components/sql_db_view/leftLayout.vue","../../src/components/sql_db_view/leftLayout.vue","../../src/components/sql_db_view/FilterLoading.vue","../../src/components/sql_db_view/FilterLoading.vue","../../src/components/sql_db_view/configs/demo/example.ts","../../src/components/sql_db_view/pageConfig.ts","../../src/components/sql_db_view/rightTable.vue","../../src/components/sql_db_view/rightTable.vue","../../src/components/sql_db_view/index.vue","../../src/components/sql_db_view/index.vue"],"sourcesContent":["<template>\n <a-modal\n title=\"添加过滤条件\"\n width=\"800px\"\n :open=\"open\"\n transitionName=\"\"\n maskTransitionName=\"\"\n :destroyOnClose=\"true\"\n :confirmLoading=\"loading\"\n centered\n @ok=\"handleSubmit\"\n @cancel=\"\n () => {\n $emit('cancel');\n }\n \"\n >\n <a-tabs v-model:activeKey=\"activeKey\">\n <a-tab-pane\n class=\"my-card\"\n v-for=\"item in tab_list\"\n :key=\"item.key\"\n :tab=\"item.tab_name\"\n >\n <div\n v-for=\"base_search_item in item.base_search_list\"\n :key=\"base_search_item.name\"\n >\n <div style=\"font-size: 14px\">{{ base_search_item.name }}</div>\n <a-space\n wrap\n style=\"padding-left: 10px; margin-bottom: 0\"\n >\n <div\n v-for=\"obj in base_search_item.group\"\n :key=\"obj.field_name\"\n >\n <a-checkbox v-model:checked=\"obj.checked\">\n <span style=\"color: #7d8089\">{{ obj.label }}</span>\n </a-checkbox>\n </div>\n </a-space>\n </div>\n </a-tab-pane>\n </a-tabs>\n </a-modal>\n</template>\n\n<script lang=\"ts\">\nimport { defineComponent, reactive, ref } from 'vue';\n\nexport default defineComponent({\n name: 'AddConditionModal',\n props: {\n open: {\n type: Boolean,\n required: true,\n },\n loading: {\n type: Boolean,\n required: false,\n },\n default_search_condition_config_list: {\n type: Array,\n required: false,\n },\n base_search_condition_config_list: {\n type: Array,\n required: false,\n },\n },\n emits: ['ok', 'cancel'],\n setup(props, { emit }) {\n const activeKey = ref('condition_tab_0');\n const tab_list = ref([]);\n props.default_search_condition_config_list.forEach((item_list: any, index: number) => {\n const base_search_list: any = JSON.parse(\n JSON.stringify(props.base_search_condition_config_list),\n );\n if (base_search_list) {\n base_search_list.forEach((base_search_list: any) => {\n base_search_list.group.forEach(i => {\n item_list.forEach((k: any) => {\n if (i.field_name == k.field_name) {\n i.operator = k.operator;\n i.checked = true;\n }\n });\n });\n });\n }\n tab_list.value.push({\n tab_name: `条件组${index + 1}`,\n key: `condition_tab_${index}`,\n base_search_list: base_search_list,\n });\n });\n const handleSubmit = (e: Event) => {\n e.preventDefault();\n const list = [];\n tab_list.value.forEach(item => {\n const selected_group_list: any = [];\n item.base_search_list.forEach(i => {\n i.group.forEach((temp: any) => {\n if (temp.checked) {\n if (!temp.operator) {\n const operator_list_selected = get_operator_list_selected(temp);\n if (operator_list_selected.length > 0) {\n const [first] = operator_list_selected;\n temp.operator = first;\n }\n }\n selected_group_list.push(temp);\n }\n });\n });\n list.push(selected_group_list);\n });\n emit('ok', { new_list: list });\n };\n const get_operator_list_selected = (condition) => {\n if (condition.operator_list_selected) {\n return condition.operator_list_selected;\n }\n else if (condition.operator_list) {\n return condition.operator_list;\n }\n else {\n return [];\n }\n };\n\n return {\n props,\n activeKey,\n tab_list,\n handleSubmit,\n };\n },\n});\n</script>\n<style scoped>\n.my-card {\n padding: 20px;\n background-color: #f6f7f9;\n}\n</style>\n","<template>\n <a-modal\n title=\"添加过滤条件\"\n width=\"800px\"\n :open=\"open\"\n transitionName=\"\"\n maskTransitionName=\"\"\n :destroyOnClose=\"true\"\n :confirmLoading=\"loading\"\n centered\n @ok=\"handleSubmit\"\n @cancel=\"\n () => {\n $emit('cancel');\n }\n \"\n >\n <a-tabs v-model:activeKey=\"activeKey\">\n <a-tab-pane\n class=\"my-card\"\n v-for=\"item in tab_list\"\n :key=\"item.key\"\n :tab=\"item.tab_name\"\n >\n <div\n v-for=\"base_search_item in item.base_search_list\"\n :key=\"base_search_item.name\"\n >\n <div style=\"font-size: 14px\">{{ base_search_item.name }}</div>\n <a-space\n wrap\n style=\"padding-left: 10px; margin-bottom: 0\"\n >\n <div\n v-for=\"obj in base_search_item.group\"\n :key=\"obj.field_name\"\n >\n <a-checkbox v-model:checked=\"obj.checked\">\n <span style=\"color: #7d8089\">{{ obj.label }}</span>\n </a-checkbox>\n </div>\n </a-space>\n </div>\n </a-tab-pane>\n </a-tabs>\n </a-modal>\n</template>\n\n<script lang=\"ts\">\nimport { defineComponent, reactive, ref } from 'vue';\n\nexport default defineComponent({\n name: 'AddConditionModal',\n props: {\n open: {\n type: Boolean,\n required: true,\n },\n loading: {\n type: Boolean,\n required: false,\n },\n default_search_condition_config_list: {\n type: Array,\n required: false,\n },\n base_search_condition_config_list: {\n type: Array,\n required: false,\n },\n },\n emits: ['ok', 'cancel'],\n setup(props, { emit }) {\n const activeKey = ref('condition_tab_0');\n const tab_list = ref([]);\n props.default_search_condition_config_list.forEach((item_list: any, index: number) => {\n const base_search_list: any = JSON.parse(\n JSON.stringify(props.base_search_condition_config_list),\n );\n if (base_search_list) {\n base_search_list.forEach((base_search_list: any) => {\n base_search_list.group.forEach(i => {\n item_list.forEach((k: any) => {\n if (i.field_name == k.field_name) {\n i.operator = k.operator;\n i.checked = true;\n }\n });\n });\n });\n }\n tab_list.value.push({\n tab_name: `条件组${index + 1}`,\n key: `condition_tab_${index}`,\n base_search_list: base_search_list,\n });\n });\n const handleSubmit = (e: Event) => {\n e.preventDefault();\n const list = [];\n tab_list.value.forEach(item => {\n const selected_group_list: any = [];\n item.base_search_list.forEach(i => {\n i.group.forEach((temp: any) => {\n if (temp.checked) {\n if (!temp.operator) {\n const operator_list_selected = get_operator_list_selected(temp);\n if (operator_list_selected.length > 0) {\n const [first] = operator_list_selected;\n temp.operator = first;\n }\n }\n selected_group_list.push(temp);\n }\n });\n });\n list.push(selected_group_list);\n });\n emit('ok', { new_list: list });\n };\n const get_operator_list_selected = (condition) => {\n if (condition.operator_list_selected) {\n return condition.operator_list_selected;\n }\n else if (condition.operator_list) {\n return condition.operator_list;\n }\n else {\n return [];\n }\n };\n\n return {\n props,\n activeKey,\n tab_list,\n handleSubmit,\n };\n },\n});\n</script>\n<style scoped>\n.my-card {\n padding: 20px;\n background-color: #f6f7f9;\n}\n</style>\n","<template>\n <a-modal\n title=\"添加过滤条件组\"\n width=\"800px\"\n :open=\"open\"\n transitionName=\"\"\n maskTransitionName=\"\"\n :destroyOnClose=\"true\"\n :confirmLoading=\"loading\"\n centered\n @ok=\"handleSubmit\"\n @cancel=\"\n () => {\n $emit('cancel');\n }\n \"\n >\n\n <a-tab-pane class=\"my-card\" v-for=\"item in tab_list\"\n :key=\"item.key\" :tab=\"item.tab_name\">\n <div v-for=\"base_search_item in item.base_search_list\" :key=\"base_search_item.name\">\n <div style=\"font-size: 14px;\">{{base_search_item.name}}</div>\n <a-space wrap>\n <div v-for=\"obj in base_search_item.group\" :key=\"obj.field_name\">\n <a-checkbox v-model:checked=\"obj.checked\" >\n <span style=\"color:#7d8089\">{{ obj.label }}</span>\n </a-checkbox>\n </div>\n </a-space>\n </div>\n </a-tab-pane>\n\n <a-tabs v-model:activeKey=\"activeKey\">\n <a-tab-pane class=\"my-card\" v-for=\"item in tab_list\"\n :key=\"item.key\" :tab=\"item.tab_name\">\n <div v-for=\"base_search_item in item.base_search_list\" :key=\"base_search_item.name\">\n <div style=\"font-size: 14px;\">{{base_search_item.name}}</div>\n <a-space wrap style=\"padding-left: 10px; margin-bottom:0\">\n <div v-for=\"obj in base_search_item.group\" :key=\"obj.field_name\">\n <a-checkbox v-model:checked=\"obj.checked\" >\n <span style=\"color:#7d8089\">{{ obj.label }}</span>\n </a-checkbox>\n </div>\n </a-space>\n </div>\n </a-tab-pane>\n </a-tabs>\n </a-modal>\n</template>\n\n<script lang=\"ts\">\nimport { defineComponent, reactive, ref } from 'vue';\nimport { message } from 'ant-design-vue';\nexport default defineComponent({\n name: 'AddConditionGroupModal',\n props: {\n open: {\n type: Boolean,\n required: true,\n },\n loading: {\n type: Boolean,\n required: false,\n },\n default_search_condition_config_list: {\n type: Array,\n required: false,\n },\n base_search_condition_config_list: {\n type: Array,\n required: false,\n },\n },\n emits: ['ok', 'cancel'],\n setup(props, { emit }) {\n const tab_list = ref([]);\n const get_operator_list_selected = (condition) => {\n if (condition.operator_list_selected) {\n return condition.operator_list_selected;\n }\n else if (condition.operator_list) {\n return condition.operator_list;\n }\n else {\n return [];\n }\n };\n props.default_search_condition_config_list?.forEach((item_list:any, index:number)=>{\n const base_search_list:any = JSON.parse(JSON.stringify(props.base_search_condition_config_list));\n if(base_search_list){\n base_search_list.forEach((base_search_list:any)=>{\n base_search_list.group.forEach(i=>{\n item_list.forEach((k:any)=>{\n if(i.field_name == k.field_name){\n i.checked = true;\n }\n });\n });\n });\n }\n tab_list.value.push({\n tab_name:`条件组${index+1}`,\n key:`condition_tab_${index}`,\n base_search_list: base_search_list,\n });\n });\n const index = props.default_search_condition_config_list?.length || 0;\n const new_search_list = [];\n props.base_search_condition_config_list.forEach((item:any)=>{\n const new_group = [];\n item.group.forEach(i=>{\n const operator_list_selected = get_operator_list_selected(i);\n if(i.default_operator){\n i.operator = i.default_operator;\n }\n if(!operator_list_selected.includes(i.operator)){\n i.operator = null;\n }\n if(!i.operator && operator_list_selected.length>0){\n const [first] = operator_list_selected;\n i.operator = first;\n }\n const new_i = { ...i, checked:false };\n new_group.push(new_i);\n });\n new_search_list.push({\n name:item.name,\n group:new_group,\n });\n });\n tab_list.value.push({\n tab_name:`条件组${index+1}`,\n key:`condition_tab_${index}`,\n base_search_list: new_search_list,\n });\n const activeKey = ref(`condition_tab_${index}`);\n\n const handleSubmit = (e: Event) => {\n e.preventDefault();\n const list = [];\n tab_list.value.forEach(item=>{\n const selected_group_list:any = [];\n item.base_search_list.forEach(i=>{\n i.group.forEach((temp:any)=>{\n if(temp.checked){\n selected_group_list.push(temp);\n }\n });\n });\n if(selected_group_list.length>0){\n list.push(selected_group_list);\n }\n });\n if(list.length==0){\n message.error('新增条件组未增加新的字段,自动取消');\n emit('cancel');//关闭对话框\n }else{\n emit('ok', { new_list: list });\n }\n };\n\n return {\n props,\n activeKey,\n tab_list,\n handleSubmit,\n get_operator_list_selected,\n };\n },\n});\n</script>\n<style scoped>\n.my-card{\n padding:20px;\n background-color: #f6f7f9;\n}\n</style>","<template>\n <a-modal\n title=\"添加过滤条件组\"\n width=\"800px\"\n :open=\"open\"\n transitionName=\"\"\n maskTransitionName=\"\"\n :destroyOnClose=\"true\"\n :confirmLoading=\"loading\"\n centered\n @ok=\"handleSubmit\"\n @cancel=\"\n () => {\n $emit('cancel');\n }\n \"\n >\n\n <a-tab-pane class=\"my-card\" v-for=\"item in tab_list\"\n :key=\"item.key\" :tab=\"item.tab_name\">\n <div v-for=\"base_search_item in item.base_search_list\" :key=\"base_search_item.name\">\n <div style=\"font-size: 14px;\">{{base_search_item.name}}</div>\n <a-space wrap>\n <div v-for=\"obj in base_search_item.group\" :key=\"obj.field_name\">\n <a-checkbox v-model:checked=\"obj.checked\" >\n <span style=\"color:#7d8089\">{{ obj.label }}</span>\n </a-checkbox>\n </div>\n </a-space>\n </div>\n </a-tab-pane>\n\n <a-tabs v-model:activeKey=\"activeKey\">\n <a-tab-pane class=\"my-card\" v-for=\"item in tab_list\"\n :key=\"item.key\" :tab=\"item.tab_name\">\n <div v-for=\"base_search_item in item.base_search_list\" :key=\"base_search_item.name\">\n <div style=\"font-size: 14px;\">{{base_search_item.name}}</div>\n <a-space wrap style=\"padding-left: 10px; margin-bottom:0\">\n <div v-for=\"obj in base_search_item.group\" :key=\"obj.field_name\">\n <a-checkbox v-model:checked=\"obj.checked\" >\n <span style=\"color:#7d8089\">{{ obj.label }}</span>\n </a-checkbox>\n </div>\n </a-space>\n </div>\n </a-tab-pane>\n </a-tabs>\n </a-modal>\n</template>\n\n<script lang=\"ts\">\nimport { defineComponent, reactive, ref } from 'vue';\nimport { message } from 'ant-design-vue';\nexport default defineComponent({\n name: 'AddConditionGroupModal',\n props: {\n open: {\n type: Boolean,\n required: true,\n },\n loading: {\n type: Boolean,\n required: false,\n },\n default_search_condition_config_list: {\n type: Array,\n required: false,\n },\n base_search_condition_config_list: {\n type: Array,\n required: false,\n },\n },\n emits: ['ok', 'cancel'],\n setup(props, { emit }) {\n const tab_list = ref([]);\n const get_operator_list_selected = (condition) => {\n if (condition.operator_list_selected) {\n return condition.operator_list_selected;\n }\n else if (condition.operator_list) {\n return condition.operator_list;\n }\n else {\n return [];\n }\n };\n props.default_search_condition_config_list?.forEach((item_list:any, index:number)=>{\n const base_search_list:any = JSON.parse(JSON.stringify(props.base_search_condition_config_list));\n if(base_search_list){\n base_search_list.forEach((base_search_list:any)=>{\n base_search_list.group.forEach(i=>{\n item_list.forEach((k:any)=>{\n if(i.field_name == k.field_name){\n i.checked = true;\n }\n });\n });\n });\n }\n tab_list.value.push({\n tab_name:`条件组${index+1}`,\n key:`condition_tab_${index}`,\n base_search_list: base_search_list,\n });\n });\n const index = props.default_search_condition_config_list?.length || 0;\n const new_search_list = [];\n props.base_search_condition_config_list.forEach((item:any)=>{\n const new_group = [];\n item.group.forEach(i=>{\n const operator_list_selected = get_operator_list_selected(i);\n if(i.default_operator){\n i.operator = i.default_operator;\n }\n if(!operator_list_selected.includes(i.operator)){\n i.operator = null;\n }\n if(!i.operator && operator_list_selected.length>0){\n const [first] = operator_list_selected;\n i.operator = first;\n }\n const new_i = { ...i, checked:false };\n new_group.push(new_i);\n });\n new_search_list.push({\n name:item.name,\n group:new_group,\n });\n });\n tab_list.value.push({\n tab_name:`条件组${index+1}`,\n key:`condition_tab_${index}`,\n base_search_list: new_search_list,\n });\n const activeKey = ref(`condition_tab_${index}`);\n\n const handleSubmit = (e: Event) => {\n e.preventDefault();\n const list = [];\n tab_list.value.forEach(item=>{\n const selected_group_list:any = [];\n item.base_search_list.forEach(i=>{\n i.group.forEach((temp:any)=>{\n if(temp.checked){\n selected_group_list.push(temp);\n }\n });\n });\n if(selected_group_list.length>0){\n list.push(selected_group_list);\n }\n });\n if(list.length==0){\n message.error('新增条件组未增加新的字段,自动取消');\n emit('cancel');//关闭对话框\n }else{\n emit('ok', { new_list: list });\n }\n };\n\n return {\n props,\n activeKey,\n tab_list,\n handleSubmit,\n get_operator_list_selected,\n };\n },\n});\n</script>\n<style scoped>\n.my-card{\n padding:20px;\n background-color: #f6f7f9;\n}\n</style>","export const get_options_eq = t => {\n const options_eq = [\n { value: '上月', label: '上月' },\n { value: '本月', label: '本月' },\n { value: '今日', label: '今日' },\n { value: '昨日', label: '昨日' },\n { value: '期初', label: '期初' },\n ];\n return {\n options_eq,\n };\n};\n","<template>\n <a-space v-if=\"!is_massage_default\">\n <a-button\n type=\"link\"\n v-if=\"is_show_normal_search\"\n @click=\"handleShowSearchRender\"\n >\n {{ $t('普通') }}\n </a-button>\n <a-button\n v-if=\"!isShowForm\"\n type=\"link\"\n @click=\"\n () => {\n isShowForm = true;\n $emit('resize');\n }\n \"\n >\n <span class=\"expand-btn\">{{ $t('展开') }}</span>\n </a-button>\n <a-button\n v-else\n type=\"link\"\n @click=\"\n () => {\n isShowForm = false;\n $emit('resize');\n }\n \"\n >\n {{ $t('隐藏') }}\n </a-button>\n </a-space>\n <span v-show=\"!isShowForm\">\n <span\n v-for=\"(item, index) in default_search_condition_config_list\"\n :key=\"index\"\n >\n <a-tag>{{ $t('条件组') }}{{ index + 1 }}:</a-tag>\n <span\n v-for=\"condition in item\"\n :key=\"condition.field_name\"\n >\n <a-tag\n v-show=\"isShowSearchTag(index, condition)\"\n color=\"green\"\n >\n {{ condition.label }}: {{ transferValueFunc(index, condition) }}\n <close-outlined\n style=\"cursor: pointer; margin-left: 5px\"\n @click=\"handleDelSearch(index, condition.field_name)\"\n />\n </a-tag>\n </span>\n </span>\n </span>\n <div\n v-if=\"delayShow || isShowForm\"\n class=\"card\"\n v-show=\"isShowForm\"\n >\n <div\n v-for=\"(group_item, group_index) in default_search_condition_config_list\"\n :key=\"group_index\"\n >\n <div\n class=\"condition-group\"\n v-if=\"default_search_condition_config_list.length > 1\"\n >\n {{ $t('条件组') }} {{ group_index + 1 }}\n </div>\n <a-space\n :wrap=\"true\"\n align=\"center\"\n :size=\"0\"\n >\n <a-space-compact\n block\n v-for=\"(condition, k) in group_item\"\n :key=\"condition.field_name\"\n size=\"middle\"\n @mouseenter=\"handleMouseEnter(group_index, condition)\"\n @mouseleave=\"handleMouseLeave(group_index, condition)\"\n >\n <a-input-group compact>\n <a-tooltip :title=\"condition.label\">\n <a-cascader\n :value=\"condition.label\"\n style=\"width: 125px\"\n :options=\"searchItemOptionsDict[group_index]\"\n showSearch\n :allowClear=\"false\"\n :placeholder=\"$t('请选择...')\"\n @change=\"value => onChangeSearchItem(value, group_index, condition, k)\"\n />\n </a-tooltip>\n <a-tooltip :title=\"get_operator_type_map(condition.format, condition.operator)\">\n <a-select\n v-if=\"get_operator_list_selected(condition).length > 0\"\n :dropdownMatchSelectWidth=\"false\"\n v-model:value=\"condition.operator\"\n @change=\"value => onChangeOperator(value, group_index, condition)\"\n style=\"width: 100px\"\n >\n <a-select-option\n v-for=\"item in get_operator_list_selected(condition)\"\n :value=\"item\"\n :key=\"item\"\n >\n {{ get_operator_type_map(condition.format, item) }}\n </a-select-option>\n </a-select>\n </a-tooltip>\n <span\n style=\"width: 315px; height: 40px\"\n v-if=\"condition_model_dict && condition_model_dict[group_index]\"\n >\n <template\n v-if=\"['is_or_not_blank_or_null', 'is_or_not_null'].includes(condition.operator)\"\n >\n <field-render-2\n :is_show_label=\"false\"\n v-model:label=\"labelModel[condition.field_name]\"\n v-model:value=\"condition_model_dict[group_index][condition.field_name]\"\n :field=\"{\n ...condition,\n type: 'select',\n mode: 'default',\n format: 'choices',\n class_name: 'str',\n placeholder: '',\n }\"\n :formModel=\"condition_model_dict[group_index]\"\n :options=\"is_or_not_blank_or_null_options\"\n :validateInfos=\"validateInfos\"\n />\n </template>\n <template v-else-if=\"['input'].includes(condition.format)\">\n <template\n v-if=\"condition.operator === 'between' || condition.operator === 'notbetween'\"\n >\n <template v-if=\"condition.type === 'datepicker'\">\n <field-render-2\n :is_show_label=\"false\"\n v-model:label=\"labelModel[condition.field_name]\"\n v-model:value=\"condition_model_dict[group_index][condition.field_name]\"\n :field=\"{ ...condition, type: 'rangepicker', format: condition.dateFormat }\"\n :formModel=\"condition_model_dict[group_index]\"\n :options=\"condition.options\"\n :validateInfos=\"validateInfos\"\n />\n </template>\n <template v-else-if=\"condition.type === 'monthpicker'\">\n <field-render-2\n :is_show_label=\"false\"\n v-model:label=\"labelModel[condition.field_name]\"\n v-model:value=\"condition_model_dict[group_index][condition.field_name]\"\n :field=\"{\n ...condition,\n type: 'monthrangepicker',\n format: condition.dateFormat,\n }\"\n :formModel=\"condition_model_dict[group_index]\"\n :options=\"condition.options\"\n :validateInfos=\"validateInfos\"\n />\n </template>\n <template v-else-if=\"condition.type === 'timepicker'\">\n <field-render-2\n :is_show_label=\"false\"\n v-model:label=\"labelModel[condition.field_name]\"\n v-model:value=\"condition_model_dict[group_index][condition.field_name]\"\n :field=\"{\n ...condition,\n type: 'timerangepicker',\n format: condition.dateFormat,\n }\"\n :formModel=\"condition_model_dict[group_index]\"\n :options=\"condition.options\"\n :validateInfos=\"validateInfos\"\n />\n </template>\n <template v-else>\n <a-flex>\n <field-render-2\n :is_show_label=\"false\"\n v-model:label=\"labelModel[condition.field_name]\"\n v-model:value=\"condition_model_dict[group_index][condition.field_name][0]\"\n :field=\"condition\"\n :formModel=\"condition_model_dict[group_index]\"\n :options=\"condition.options\"\n :validateInfos=\"validateInfos\"\n />\n <div class=\"range\">~</div>\n <field-render-2\n :is_show_label=\"false\"\n v-model:label=\"labelModel[condition.field_name]\"\n v-model:value=\"condition_model_dict[group_index][condition.field_name][1]\"\n :field=\"condition\"\n :formModel=\"condition_model_dict[group_index]\"\n :options=\"condition.options\"\n :validateInfos=\"validateInfos\"\n />\n </a-flex>\n </template>\n </template>\n <template v-else-if=\"condition.operator === '_eq'\">\n <field-render-2\n :is_show_label=\"false\"\n v-model:label=\"labelModel[condition.field_name]\"\n v-model:value=\"condition_model_dict[group_index][condition.field_name]\"\n :field=\"{\n ...condition,\n type: 'select',\n mode: 'default',\n format: 'choices',\n class_name: 'str',\n placeholder: '',\n }\"\n :formModel=\"condition_model_dict[group_index]\"\n :options=\"options_eq\"\n :validateInfos=\"validateInfos\"\n />\n </template>\n <template\n v-else-if=\"\n condition.type === 'datepicker' ||\n condition.type === 'monthpicker' ||\n condition.type === 'timepicker'\n \"\n >\n <field-render-2\n :is_show_label=\"false\"\n v-model:label=\"labelModel[condition.field_name]\"\n v-model:value=\"condition_model_dict[group_index][condition.field_name]\"\n :field=\"{ ...condition, format: condition.dateFormat }\"\n :formModel=\"condition_model_dict[group_index]\"\n :options=\"condition.options\"\n :validateInfos=\"validateInfos\"\n />\n </template>\n <template v-else>\n <field-render-2\n :is_show_label=\"false\"\n v-model:label=\"labelModel[condition.field_name]\"\n v-model:value=\"condition_model_dict[group_index][condition.field_name]\"\n :field=\"condition\"\n :formModel=\"condition_model_dict[group_index]\"\n :options=\"condition.options\"\n :validateInfos=\"validateInfos\"\n />\n </template>\n </template>\n <template v-else-if=\"['choices', 'remote'].includes(condition.format)\">\n <template v-if=\"condition.format === 'choices'\">\n <field-render-2\n :is_show_label=\"false\"\n v-model:label=\"labelModel[condition.field_name]\"\n v-model:value=\"condition_model_dict[group_index][condition.field_name]\"\n :field=\"condition\"\n :formModel=\"condition_model_dict[group_index]\"\n :options=\"condition.options\"\n :validateInfos=\"validateInfos\"\n />\n </template>\n <template v-else-if=\"condition.format === 'remote'\">\n <field-render-2\n :is_show_label=\"false\"\n v-model:label=\"labelModel[condition.field_name]\"\n v-model:value=\"condition_model_dict[group_index][condition.field_name]\"\n :field=\"{ ...condition, name: condition?.field_name }\"\n :formModel=\"condition_model_dict[group_index]\"\n :options=\"condition.options\"\n :validateInfos=\"validateInfos\"\n />\n </template>\n </template>\n </span>\n <span\n class=\"close-icon\"\n v-if=\"deleteBtnDict && deleteBtnDict[group_index]\"\n >\n <a-tooltip\n title=\"删除此条件\"\n v-if=\"\n deleteBtnDict[group_index][condition.field_name] &&\n (default_search_condition_config_list[0].length > 1 ||\n default_search_condition_config_list.length > 1) &&\n !is_massage_default\n \"\n >\n <close-circle-outlined @click=\"handleDeleteFormItem(group_index, condition)\" />\n </a-tooltip>\n </span>\n </a-input-group>\n </a-space-compact>\n </a-space>\n <a-divider\n class=\"divider\"\n style=\"margin: 0\"\n v-if=\"\n default_search_condition_config_list.length > 1 &&\n group_index != default_search_condition_config_list.length - 1\n \"\n >\n 或\n </a-divider>\n </div>\n </div>\n <div\n class=\"search-bar\"\n v-if=\"isShowForm && !is_massage_default\"\n >\n <a-space>\n <a-button\n size=\"small\"\n type=\"primary\"\n @click=\"handleAddConditions\"\n >\n {{ $t('添加条件') }}\n </a-button>\n <a-button\n size=\"small\"\n type=\"primary\"\n @click=\"handleAddGroupCondition\"\n >\n {{ $t('添加条件组') }}\n </a-button>\n <a-button\n size=\"small\"\n type=\"primary\"\n @click=\"handleSearch\"\n >\n {{ $t('查询') }}\n </a-button>\n </a-space>\n </div>\n\n <add-condition-modal\n v-if=\"addConditionModal.open\"\n :open=\"addConditionModal.open\"\n :default_search_condition_config_list=\"default_search_condition_config_list\"\n :base_search_condition_config_list=\"base_search_condition_config_list\"\n @ok=\"handleAddConditionOk\"\n @cancel=\"handleAddConditionCancel\"\n />\n\n <add-condition-group-modal\n v-if=\"addConditionGroupModal.open\"\n :open=\"addConditionGroupModal.open\"\n :default_search_condition_config_list=\"default_search_condition_config_list\"\n :base_search_condition_config_list=\"base_search_condition_config_list\"\n @ok=\"handleAddGroupConditionOK\"\n @cancel=\"handleAddGroupConditionCancel\"\n />\n</template>\n<script lang=\"ts\">\nimport {\n defineComponent,\n onMounted,\n reactive,\n ref,\n computed,\n watch,\n PropType,\n nextTick,\n onUnmounted,\n} from 'vue';\nimport FieldRender from 'liyu-pc-base/components/FormRender/FieldRender.vue';\nimport AddConditionModal from 'liyu-pc-base/components/FormRender/GeneralFilter/AddConditionModal/index.vue';\nimport AddConditionGroupModal from 'liyu-pc-base/components/FormRender/GeneralFilter/AddConditionGroupModal/index.vue';\nimport { isNotEmpty } from 'liyu-pc-base/utils/function';\nimport {\n CloseCircleOutlined,\n CloseOutlined,\n LeftOutlined,\n RightOutlined,\n} from '@ant-design/icons-vue';\nimport { useI18n } from 'vue-i18n';\nimport { get_options_eq } from 'liyu-pc-base/components/FormRender/GeneralFilter/data';\nimport moment from 'moment';\nimport FieldRender2 from 'liyu-pc-base/components/FormRender/FieldRender2.vue';\nimport { get_operator_type_map } from 'liyu-pc-base/utils/function';\n\nexport default defineComponent({\n name: 'GeneralFilter',\n props: {\n base_search_condition_config_list: {\n type: Array as PropType<any[]>,\n },\n default_search_condition_config_list: {\n type: Array as PropType<any[]>,\n },\n is_show_normal_search: {\n type: Boolean,\n default: () => false,\n },\n is_clear_model: {\n type: Boolean,\n default: () => false,\n },\n is_show_advantage: {\n type: Boolean,\n default: () => false,\n },\n is_massage_default: {\n type: Boolean,\n default: () => false,\n },\n eventBus: {\n type: Object,\n required: false,\n },\n delayShow: {\n type: Boolean,\n default: () => true,\n },\n },\n components: {\n FieldRender2,\n CloseOutlined,\n LeftOutlined,\n RightOutlined,\n FieldRender,\n AddConditionGroupModal,\n AddConditionModal,\n CloseCircleOutlined,\n },\n emits: [\n 'search',\n 'resize',\n 'update_default_search_condition_config_list',\n 'onShowSearchRender',\n 'delSearch',\n 'onChangeValue',\n 'update:is_clear_model',\n ],\n setup(props, { emit }) {\n const isShowForm = ref(props.is_massage_default);\n const labelModel = ref({});\n const { t } = useI18n();\n const { options_eq } = get_options_eq(t);\n //条件组-->\n const condition_model_dict = ref([]);\n const validateInfos = {};\n const source_default_search_condition_config_list = ref(null);\n const 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 if (!source_default_search_condition_config_list.value) {\n source_default_search_condition_config_list.value = JSON.parse(\n JSON.stringify(props.default_search_condition_config_list),\n );\n }\n\n const operator_type_count_map = {\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 istartswith: 1,\n endswith: 1,\n iendswith: 1,\n notbetween: 2,\n notin: 0,\n notcontains: 1,\n noticontains: 1,\n notstartswith: 1,\n notistartswith: 1,\n notendswith: 1,\n notiendswith: 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 const is2DArray = arr => {\n const [first] = [arr];\n return Array.isArray(first) && arr.every(subArray => Array.isArray(subArray));\n };\n let old_operator = null;\n const onChangeOperator = (operator, index, condition) => {\n //不同操作类型,设置不同的默认值\n // if (condition_model_dict.value[index][condition.field_name]) {\n // return;\n // }\n const value = condition_model_dict.value[index][condition.field_name];\n if (get_operator_list_selected(condition).includes('_eq')) {\n if (operator == '_eq') {\n condition_model_dict.value[index][condition.field_name] = null;\n old_operator = operator;\n emit('onChangeValue', { model: condition_model_dict.value });\n return;\n } else if (old_operator == '_eq') {\n condition_model_dict.value[index][condition.field_name] = null;\n old_operator = operator;\n emit('onChangeValue', { model: condition_model_dict.value });\n return;\n }\n }\n if (get_operator_list_selected(condition).includes('not_blank_not_null')) {\n if (operator == 'not_blank_not_null') {\n condition_model_dict.value[index][condition.field_name] = '是';\n old_operator = operator;\n emit('onChangeValue', { model: condition_model_dict.value });\n return;\n } else if (old_operator == 'not_blank_not_null') {\n condition_model_dict.value[index][condition.field_name] = null;\n old_operator = operator;\n emit('onChangeValue', { model: condition_model_dict.value });\n return;\n }\n }\n if (\n get_operator_list_selected(condition).includes('is_or_not_blank_or_null') ||\n get_operator_list_selected(condition).includes('is_or_not_null')\n ) {\n if (operator == 'is_or_not_blank_or_null' || operator == 'is_or_not_null') {\n condition_model_dict.value[index][condition.field_name] = null;\n old_operator = operator;\n emit('onChangeValue', { model: condition_model_dict.value });\n return;\n } else if (old_operator == 'is_or_not_blank_or_null' || old_operator == 'is_or_not_null') {\n condition_model_dict.value[index][condition.field_name] = null;\n old_operator = operator;\n emit('onChangeValue', { model: condition_model_dict.value });\n return;\n }\n }\n if (value instanceof Array && is2DArray(value)) {\n // 级联类型,默认值默认清空\n condition_model_dict.value[index][condition.field_name] = undefined;\n } else if (operator_type_count_map[operator] == 1) {\n if (value instanceof Array) {\n const [first] = condition_model_dict.value[index][condition.field_name];\n if (isNotEmpty(first)) {\n condition_model_dict.value[index][condition.field_name] = first;\n } else {\n condition_model_dict.value[index][condition.field_name] = null;\n }\n } else {\n condition_model_dict.value[index][condition.field_name] = value ? value : null;\n }\n const is = options_eq.some(\n obj => obj.value === condition_model_dict.value[index][condition.field_name],\n );\n if (is) {\n condition_model_dict.value[index][condition.field_name] = null;\n }\n } else if (operator_type_count_map[operator] == 2) {\n if (condition_model_dict.value[index][condition.field_name] instanceof Array) {\n const [first, seconds] = condition_model_dict.value[index][condition.field_name];\n condition_model_dict.value[index][condition.field_name] = [first, seconds];\n } else if (condition_model_dict.value[index][condition.field_name]) {\n const first = condition_model_dict.value[index][condition.field_name];\n condition_model_dict.value[index][condition.field_name] = [first, null];\n } else {\n condition_model_dict.value[index][condition.field_name] = [null, null];\n }\n const is = options_eq.some(\n obj => obj.value === condition_model_dict.value[index][condition.field_name][0],\n );\n if (is) {\n condition_model_dict.value[index][condition.field_name] = [null, null];\n }\n } else { \n condition_model_dict.value[index][condition.field_name] = undefined;\n }\n old_operator = operator;\n emit('onChangeValue', { model: condition_model_dict.value });\n // console.log('onChangeValue');\n };\n\n const addConditionModal = reactive({\n open: false,\n });\n const handleAddConditions = () => {\n addConditionModal.open = true;\n };\n const handleAddConditionOk = (data: any) => {\n props.default_search_condition_config_list.forEach((item: any, index: any) => {\n data.new_list.forEach((item1: any, index1: any) => {\n if (index == index1) {\n item.forEach((item2: any) => {\n item1.forEach((item3: any) => {\n if (item2.field_name == item3.field_name) {\n item3.value = item2.value;\n item3.operator = item2.operator;\n }\n });\n });\n }\n });\n });\n //保存后处理 new_list\n emit('update_default_search_condition_config_list', { new_list: data.new_list });\n // refreshCondition();\n addConditionModal.open = false;\n };\n const handleAddConditionCancel = () => {\n addConditionModal.open = false;\n };\n\n const addConditionGroupModal = reactive({\n open: false,\n });\n const handleAddGroupCondition = () => {\n addConditionGroupModal.open = true;\n };\n const handleAddGroupConditionOK = (data: any) => {\n props.default_search_condition_config_list.forEach((item: any, index: any) => {\n data.new_list.forEach((item1: any, index1: any) => {\n if (index == index1) {\n item.forEach((item2: any) => {\n item1.forEach((item3: any) => {\n if (item2.field_name == item3.field_name) {\n item3.value = item2.value;\n item3.operator = item2.operator;\n }\n });\n });\n }\n });\n });\n emit('update_default_search_condition_config_list', { new_list: data.new_list });\n // refreshCondition();\n addConditionGroupModal.open = false;\n };\n const handleAddGroupConditionCancel = () => {\n addConditionGroupModal.open = false;\n };\n const handleSearch = () => {\n isShowForm.value = false;\n console.log('condition_model_dict.value', condition_model_dict.value);\n emit('search', { model: condition_model_dict.value });\n };\n const refreshCondition = (update_all = false) => {\n if (props.base_search_condition_config_list.length == 0) {\n return;\n }\n props.default_search_condition_config_list?.forEach((item_list: any, index: number) => {\n deleteBtnDict[index] = {};\n if (!condition_model_dict.value[index]) {\n condition_model_dict.value[index] = {};\n }\n props.base_search_condition_config_list.forEach((i: any) => {\n i.group?.forEach((group_item: any) => {\n item_list.forEach((k: any) => {\n if (group_item.field_name == k.field_name) {\n const value = condition_model_dict.value[index][k.field_name];\n if (value == undefined || update_all) {\n if (operator_type_count_map[k.operator] == 1) {\n if (k.value !== undefined) {\n condition_model_dict.value[index][k.field_name] = k.value;\n } else {\n condition_model_dict.value[index][k.field_name] = null;\n }\n } else if (operator_type_count_map[k.operator] == 2) {\n if (k.value !== undefined) {\n condition_model_dict.value[index][k.field_name] = k.value;\n } else {\n condition_model_dict.value[index][k.field_name] = [null, null];\n }\n } else if (operator_type_count_map[k.operator] == 0) {\n if (k.value !== undefined) {\n condition_model_dict.value[index][k.field_name] = k.value;\n } else {\n condition_model_dict.value[index][k.field_name] = [];\n }\n }\n }\n Object.assign(k, { ...group_item, operator: k.operator }); // 保持表单项原有选择的查询条件\n if (k.operator == 'eq' && k.mode != 'default') {\n group_item.mode = 'default';\n Object.assign(k, { model: 'default' });\n } else if (['in', 'notin'].includes(k.operator) && k.mode != 'multiple') {\n group_item.mode = 'multiple';\n Object.assign(k, { model: 'multiple' });\n }\n }\n });\n });\n });\n });\n };\n const onFilterChanged = () => {\n refreshCondition(true);\n };\n\n const deleteBtnDict = reactive({}); // 表单项的删除按钮是否显示\n const handleMouseEnter = (index: any, form_item: any) => {\n deleteBtnDict[index][form_item.field_name] = true;\n };\n const handleMouseLeave = (index: any, form_item: any) => {\n deleteBtnDict[index][form_item.field_name] = false;\n };\n const handleDeleteFormItem = (index: any, condition: any) => {\n //default_search_condition_config_list 不允许删除最后一个条件组的条件项\n const new_list = [];\n props.default_search_condition_config_list.forEach((item_list: any, index_: number) => {\n if (index_ !== index) {\n new_list.push(item_list);\n } else {\n const list = [];\n item_list.forEach((k: any) => {\n if (k.field_name !== condition.field_name) {\n list.push(k);\n }\n });\n if (list.length > 0) {\n new_list.push(list);\n }\n }\n });\n emit('update_default_search_condition_config_list', { new_list: new_list });\n // refreshCondition();\n };\n const handleDelSearch = (index, filed_name) => {\n if (condition_model_dict.value[index][filed_name] instanceof Array) {\n condition_model_dict.value[index][filed_name].length = 0;\n } else {\n condition_model_dict.value[index][filed_name] = null;\n }\n emit('onChangeValue', { model: condition_model_dict.value });\n emit('delSearch', { model: JSON.parse(JSON.stringify(condition_model_dict.value)) });\n };\n\n const onChangeSearchItem = (value: any, group_index, condition: any, condition_index) => {\n if (value instanceof Array && value.length > 0) {\n const selected_field_name = value[value.length - 1];\n let new_condition = null;\n props.base_search_condition_config_list.forEach(item_list => {\n item_list.group.forEach(i => {\n if (i.field_name === selected_field_name) {\n new_condition = JSON.parse(JSON.stringify(i));\n if (new_condition.default_operator) {\n new_condition.operator = new_condition.default_operator;\n } else if (get_operator_list_selected(new_condition).length > 0) {\n const [first] = get_operator_list_selected(new_condition);\n new_condition.operator = first;\n }\n }\n });\n });\n\n if (new_condition) {\n const new_list = JSON.parse(JSON.stringify(props.default_search_condition_config_list));\n new_list.forEach((item_list, i) => {\n if (i === group_index) {\n item_list.forEach((item, k) => {\n if (item.field_name == condition.field_name && k == condition_index) {\n item_list.splice(k, 1, new_condition);\n delete condition_model_dict.value[group_index][item.field_name];\n }\n });\n }\n });\n emit('update_default_search_condition_config_list', {\n new_list: new_list,\n });\n }\n refreshCondition();\n }\n };\n\n const searchItemOptionsDict: any = computed(() => {\n const dict = {};\n props.default_search_condition_config_list.forEach((group_item, index) => {\n dict[index] = [];\n const filter_field_name_list = group_item.map(item => item.field_name);\n props.base_search_condition_config_list.forEach(item => {\n const filter_list = item.group.filter(\n i => !filter_field_name_list.includes(i.field_name),\n );\n const o = {\n value: item.name,\n label: item.name,\n children: filter_list.map(i => {\n return {\n value: i.field_name,\n label: i.label,\n };\n }),\n };\n dict[index].push(o);\n });\n });\n return dict;\n });\n\n const isShowSearchTag = (index, condition) => {\n const value = condition_model_dict.value[index]?.[condition.field_name];\n if (value instanceof Array) {\n const [first] = value;\n if (isNotEmpty(first)) {\n return true;\n }\n } else if (isNotEmpty(value)) {\n return true;\n }\n return false;\n };\n\n const transferValueFunc = (index, condition) => {\n const str_list: any = [];\n const value = condition_model_dict.value[index]?.[condition.field_name];\n if (\n condition.operator === 'is_or_not_blank_or_null' ||\n condition.operator === 'is_or_not_null'\n ) {\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 (condition.operator === '_eq') {\n if (['上月', '本月', '今日', '昨日', '期初'].includes(value)) {\n return t(value);\n }\n } else if (labelModel.value[condition.field_name] != undefined) {\n return `${get_operator_type_map(condition.format, condition.operator)} ${\n labelModel.value[condition.field_name]\n }`;\n } else if (value instanceof Array && condition.field_name_list instanceof Array) {\n let transfer_value;\n if (condition.field_name_list) {\n if (value instanceof Array) {\n transfer_value = value.join(',');\n } else {\n transfer_value = value;\n }\n }\n return `${get_operator_type_map(condition.format, condition.operator)} ${transfer_value}`;\n } else if (value instanceof Array && condition.options instanceof Array) {\n value.forEach(item => {\n condition.options.forEach(i => {\n if (item == i.value) {\n str_list.push(i.label);\n }\n });\n });\n return `${get_operator_type_map(condition.format, condition.operator)} ${str_list.join(\n ',',\n )}`;\n } else {\n let transfer_value;\n if (condition.options) {\n condition.options.forEach(i => {\n if (value == i.value) {\n transfer_value = i.label;\n }\n });\n } else if (condition.type == 'monthpicker' && condition.dateFormat) {\n if (value instanceof Array) {\n const str_list = [];\n value.forEach(i => {\n if (i) {\n str_list.push(moment(i).format(condition.dateFormat));\n } else {\n str_list.push(i);\n }\n });\n transfer_value = str_list.join(',');\n } else {\n transfer_value = moment(value).format(condition.dateFormat);\n }\n } else {\n transfer_value = value;\n }\n return `${get_operator_type_map(condition.format, condition.operator)} ${transfer_value}`;\n }\n };\n\n const handleShowSearchRender = () => {\n emit('onShowSearchRender');\n };\n\n const get_operator_list_selected = condition => {\n if (condition.operator_list_selected) {\n return condition.operator_list_selected;\n } else if (condition.operator_list) {\n return condition.operator_list;\n } else {\n return [];\n }\n };\n\n watch(\n () => condition_model_dict.value,\n () => {\n emit('onChangeValue', { model: condition_model_dict.value });\n // console.log('onChangeValue_watch');\n },\n { deep: true },\n );\n watch(\n () => props.default_search_condition_config_list,\n () => {\n if (props.default_search_condition_config_list?.length == 0) {\n emit('update_default_search_condition_config_list', {\n new_list: source_default_search_condition_config_list.value,\n });\n return;\n }\n refreshCondition();\n },\n { deep: true },\n );\n watch(\n () => props.base_search_condition_config_list,\n () => {\n refreshCondition();\n },\n { deep: true },\n );\n\n watch(\n () => props.is_clear_model,\n () => {\n if (props.is_clear_model) {\n condition_model_dict.value = {};\n refreshCondition();\n emit('update:is_clear_model', false);\n }\n },\n );\n onMounted(() => {\n refreshCondition();\n if (props.eventBus) {\n props.eventBus.on('filterChange', onFilterChanged);\n }\n });\n onUnmounted(() => {\n if (props.eventBus) {\n props.eventBus.off('filterChange', onFilterChanged);\n }\n });\n return {\n props,\n t,\n isShowForm,\n labelModel,\n get_operator_type_map,\n condition_model_dict,\n addConditionModal,\n handleAddConditions,\n handleAddConditionOk,\n handleAddConditionCancel,\n onChangeOperator,\n handleAddGroupCondition,\n handleSearch,\n\n addConditionGroupModal,\n handleAddGroupConditionOK,\n handleAddGroupConditionCancel,\n validateInfos,\n\n deleteBtnDict,\n handleMouseEnter,\n handleMouseLeave,\n handleDeleteFormItem,\n handleDelSearch,\n\n searchItemOptionsDict,\n onChangeSearchItem,\n transferValueFunc,\n isShowSearchTag,\n handleShowSearchRender,\n options_eq,\n get_operator_list_selected,\n is_or_not_blank_or_null_options,\n };\n },\n});\n</script>\n<style lang=\"less\" scoped>\n.card {\n overflow: auto;\n max-height: 300px;\n background: #f2f5f7;\n}\n\n.condition-group {\n padding: 5px;\n}\n\n.range {\n margin-top: 5px;\n}\n\n.close-icon {\n width: 15px;\n margin-top: 5px;\n margin-left: 5px;\n color: red;\n}\n\n.search-bar {\n background: #f2f5f7;\n text-align: right;\n}\n\n:deep(.divider .ant-divider) {\n margin: 0;\n}\n</style>\n","<template>\n <a-space v-if=\"!is_massage_default\">\n <a-button\n type=\"link\"\n v-if=\"is_show_normal_search\"\n @click=\"handleShowSearchRender\"\n >\n {{ $t('普通') }}\n </a-button>\n <a-button\n v-if=\"!isShowForm\"\n type=\"link\"\n @click=\"\n () => {\n isShowForm = true;\n $emit('resize');\n }\n \"\n >\n <span class=\"expand-btn\">{{ $t('展开') }}</span>\n </a-button>\n <a-button\n v-else\n type=\"link\"\n @click=\"\n () => {\n isShowForm = false;\n $emit('resize');\n }\n \"\n >\n {{ $t('隐藏') }}\n </a-button>\n </a-space>\n <span v-show=\"!isShowForm\">\n <span\n v-for=\"(item, index) in default_search_condition_config_list\"\n :key=\"index\"\n >\n <a-tag>{{ $t('条件组') }}{{ index + 1 }}:</a-tag>\n <span\n v-for=\"condition in item\"\n :key=\"condition.field_name\"\n >\n <a-tag\n v-show=\"isShowSearchTag(index, condition)\"\n color=\"green\"\n >\n {{ condition.label }}: {{ transferValueFunc(index, condition) }}\n <close-outlined\n style=\"cursor: pointer; margin-left: 5px\"\n @click=\"handleDelSearch(index, condition.field_name)\"\n />\n </a-tag>\n </span>\n </span>\n </span>\n <div\n v-if=\"delayShow || isShowForm\"\n class=\"card\"\n v-show=\"isShowForm\"\n >\n <div\n v-for=\"(group_item, group_index) in default_search_condition_config_list\"\n :key=\"group_index\"\n >\n <div\n class=\"condition-group\"\n v-if=\"default_search_condition_config_list.length > 1\"\n >\n {{ $t('条件组') }} {{ group_index + 1 }}\n </div>\n <a-space\n :wrap=\"true\"\n align=\"center\"\n :size=\"0\"\n >\n <a-space-compact\n block\n v-for=\"(condition, k) in group_item\"\n :key=\"condition.field_name\"\n size=\"middle\"\n @mouseenter=\"handleMouseEnter(group_index, condition)\"\n @mouseleave=\"handleMouseLeave(group_index, condition)\"\n >\n <a-input-group compact>\n <a-tooltip :title=\"condition.label\">\n <a-cascader\n :value=\"condition.label\"\n style=\"width: 125px\"\n :options=\"searchItemOptionsDict[group_index]\"\n showSearch\n :allowClear=\"false\"\n :placeholder=\"$t('请选择...')\"\n @change=\"value => onChangeSearchItem(value, group_index, condition, k)\"\n />\n </a-tooltip>\n <a-tooltip :title=\"get_operator_type_map(condition.format, condition.operator)\">\n <a-select\n v-if=\"get_operator_list_selected(condition).length > 0\"\n :dropdownMatchSelectWidth=\"false\"\n v-model:value=\"condition.operator\"\n @change=\"value => onChangeOperator(value, group_index, condition)\"\n style=\"width: 100px\"\n >\n <a-select-option\n v-for=\"item in get_operator_list_selected(condition)\"\n :value=\"item\"\n :key=\"item\"\n >\n {{ get_operator_type_map(condition.format, item) }}\n </a-select-option>\n </a-select>\n </a-tooltip>\n <span\n style=\"width: 315px; height: 40px\"\n v-if=\"condition_model_dict && condition_model_dict[group_index]\"\n >\n <template\n v-if=\"['is_or_not_blank_or_null', 'is_or_not_null'].includes(condition.operator)\"\n >\n <field-render-2\n :is_show_label=\"false\"\n v-model:label=\"labelModel[condition.field_name]\"\n v-model:value=\"condition_model_dict[group_index][condition.field_name]\"\n :field=\"{\n ...condition,\n type: 'select',\n mode: 'default',\n format: 'choices',\n class_name: 'str',\n placeholder: '',\n }\"\n :formModel=\"condition_model_dict[group_index]\"\n :options=\"is_or_not_blank_or_null_options\"\n :validateInfos=\"validateInfos\"\n />\n </template>\n <template v-else-if=\"['input'].includes(condition.format)\">\n <template\n v-if=\"condition.operator === 'between' || condition.operator === 'notbetween'\"\n >\n <template v-if=\"condition.type === 'datepicker'\">\n <field-render-2\n :is_show_label=\"false\"\n v-model:label=\"labelModel[condition.field_name]\"\n v-model:value=\"condition_model_dict[group_index][condition.field_name]\"\n :field=\"{ ...condition, type: 'rangepicker', format: condition.dateFormat }\"\n :formModel=\"condition_model_dict[group_index]\"\n :options=\"condition.options\"\n :validateInfos=\"validateInfos\"\n />\n </template>\n <template v-else-if=\"condition.type === 'monthpicker'\">\n <field-render-2\n :is_show_label=\"false\"\n v-model:label=\"labelModel[condition.field_name]\"\n v-model:value=\"condition_model_dict[group_index][condition.field_name]\"\n :field=\"{\n ...condition,\n type: 'monthrangepicker',\n format: condition.dateFormat,\n }\"\n :formModel=\"condition_model_dict[group_index]\"\n :options=\"condition.options\"\n :validateInfos=\"validateInfos\"\n />\n </template>\n <template v-else-if=\"condition.type === 'timepicker'\">\n <field-render-2\n :is_show_label=\"false\"\n v-model:label=\"labelModel[condition.field_name]\"\n v-model:value=\"condition_model_dict[group_index][condition.field_name]\"\n :field=\"{\n ...condition,\n type: 'timerangepicker',\n format: condition.dateFormat,\n }\"\n :formModel=\"condition_model_dict[group_index]\"\n :options=\"condition.options\"\n :validateInfos=\"validateInfos\"\n />\n </template>\n <template v-else>\n <a-flex>\n <field-render-2\n :is_show_label=\"false\"\n v-model:label=\"labelModel[condition.field_name]\"\n v-model:value=\"condition_model_dict[group_index][condition.field_name][0]\"\n :field=\"condition\"\n :formModel=\"condition_model_dict[group_index]\"\n :options=\"condition.options\"\n :validateInfos=\"validateInfos\"\n />\n <div class=\"range\">~</div>\n <field-render-2\n :is_show_label=\"false\"\n v-model:label=\"labelModel[condition.field_name]\"\n v-model:value=\"condition_model_dict[group_index][condition.field_name][1]\"\n :field=\"condition\"\n :formModel=\"condition_model_dict[group_index]\"\n :options=\"condition.options\"\n :validateInfos=\"validateInfos\"\n />\n </a-flex>\n </template>\n </template>\n <template v-else-if=\"condition.operator === '_eq'\">\n <field-render-2\n :is_show_label=\"false\"\n v-model:label=\"labelModel[condition.field_name]\"\n v-model:value=\"condition_model_dict[group_index][condition.field_name]\"\n :field=\"{\n ...condition,\n type: 'select',\n mode: 'default',\n format: 'choices',\n class_name: 'str',\n placeholder: '',\n }\"\n :formModel=\"condition_model_dict[group_index]\"\n :options=\"options_eq\"\n :validateInfos=\"validateInfos\"\n />\n </template>\n <template\n v-else-if=\"\n condition.type === 'datepicker' ||\n condition.type === 'monthpicker' ||\n condition.type === 'timepicker'\n \"\n >\n <field-render-2\n :is_show_label=\"false\"\n v-model:label=\"labelModel[condition.field_name]\"\n v-model:value=\"condition_model_dict[group_index][condition.field_name]\"\n :field=\"{ ...condition, format: condition.dateFormat }\"\n :formModel=\"condition_model_dict[group_index]\"\n :options=\"condition.options\"\n :validateInfos=\"validateInfos\"\n />\n </template>\n <template v-else>\n <field-render-2\n :is_show_label=\"false\"\n v-model:label=\"labelModel[condition.field_name]\"\n v-model:value=\"condition_model_dict[group_index][condition.field_name]\"\n :field=\"condition\"\n :formModel=\"condition_model_dict[group_index]\"\n :options=\"condition.options\"\n :validateInfos=\"validateInfos\"\n />\n </template>\n </template>\n <template v-else-if=\"['choices', 'remote'].includes(condition.format)\">\n <template v-if=\"condition.format === 'choices'\">\n <field-render-2\n :is_show_label=\"false\"\n v-model:label=\"labelModel[condition.field_name]\"\n v-model:value=\"condition_model_dict[group_index][condition.field_name]\"\n :field=\"condition\"\n :formModel=\"condition_model_dict[group_index]\"\n :options=\"condition.options\"\n :validateInfos=\"validateInfos\"\n />\n </template>\n <template v-else-if=\"condition.format === 'remote'\">\n <field-render-2\n :is_show_label=\"false\"\n v-model:label=\"labelModel[condition.field_name]\"\n v-model:value=\"condition_model_dict[group_index][condition.field_name]\"\n :field=\"{ ...condition, name: condition?.field_name }\"\n :formModel=\"condition_model_dict[group_index]\"\n :options=\"condition.options\"\n :validateInfos=\"validateInfos\"\n />\n </template>\n </template>\n </span>\n <span\n class=\"close-icon\"\n v-if=\"deleteBtnDict && deleteBtnDict[group_index]\"\n >\n <a-tooltip\n title=\"删除此条件\"\n v-if=\"\n deleteBtnDict[group_index][condition.field_name] &&\n (default_search_condition_config_list[0].length > 1 ||\n default_search_condition_config_list.length > 1) &&\n !is_massage_default\n \"\n >\n <close-circle-outlined @click=\"handleDeleteFormItem(group_index, condition)\" />\n </a-tooltip>\n </span>\n </a-input-group>\n </a-space-compact>\n </a-space>\n <a-divider\n class=\"divider\"\n style=\"margin: 0\"\n v-if=\"\n default_search_condition_config_list.length > 1 &&\n group_index != default_search_condition_config_list.length - 1\n \"\n >\n 或\n </a-divider>\n </div>\n </div>\n <div\n class=\"search-bar\"\n v-if=\"isShowForm && !is_massage_default\"\n >\n <a-space>\n <a-button\n size=\"small\"\n type=\"primary\"\n @click=\"handleAddConditions\"\n >\n {{ $t('添加条件') }}\n </a-button>\n <a-button\n size=\"small\"\n type=\"primary\"\n @click=\"handleAddGroupCondition\"\n >\n {{ $t('添加条件组') }}\n </a-button>\n <a-button\n size=\"small\"\n type=\"primary\"\n @click=\"handleSearch\"\n >\n {{ $t('查询') }}\n </a-button>\n </a-space>\n </div>\n\n <add-condition-modal\n v-if=\"addConditionModal.open\"\n :open=\"addConditionModal.open\"\n :default_search_condition_config_list=\"default_search_condition_config_list\"\n :base_search_condition_config_list=\"base_search_condition_config_list\"\n @ok=\"handleAddConditionOk\"\n @cancel=\"handleAddConditionCancel\"\n />\n\n <add-condition-group-modal\n v-if=\"addConditionGroupModal.open\"\n :open=\"addConditionGroupModal.open\"\n :default_search_condition_config_list=\"default_search_condition_config_list\"\n :base_search_condition_config_list=\"base_search_condition_config_list\"\n @ok=\"handleAddGroupConditionOK\"\n @cancel=\"handleAddGroupConditionCancel\"\n />\n</template>\n<script lang=\"ts\">\nimport {\n defineComponent,\n onMounted,\n reactive,\n ref,\n computed,\n watch,\n PropType,\n nextTick,\n onUnmounted,\n} from 'vue';\nimport FieldRender from 'liyu-pc-base/components/FormRender/FieldRender.vue';\nimport AddConditionModal from 'liyu-pc-base/components/FormRender/GeneralFilter/AddConditionModal/index.vue';\nimport AddConditionGroupModal from 'liyu-pc-base/components/FormRender/GeneralFilter/AddConditionGroupModal/index.vue';\nimport { isNotEmpty } from 'liyu-pc-base/utils/function';\nimport {\n CloseCircleOutlined,\n CloseOutlined,\n LeftOutlined,\n RightOutlined,\n} from '@ant-design/icons-vue';\nimport { useI18n } from 'vue-i18n';\nimport { get_options_eq } from 'liyu-pc-base/components/FormRender/GeneralFilter/data';\nimport moment from 'moment';\nimport FieldRender2 from 'liyu-pc-base/components/FormRender/FieldRender2.vue';\nimport { get_operator_type_map } from 'liyu-pc-base/utils/function';\n\nexport default defineComponent({\n name: 'GeneralFilter',\n props: {\n base_search_condition_config_list: {\n type: Array as PropType<any[]>,\n },\n default_search_condition_config_list: {\n type: Array as PropType<any[]>,\n },\n is_show_normal_search: {\n type: Boolean,\n default: () => false,\n },\n is_clear_model: {\n type: Boolean,\n default: () => false,\n },\n is_show_advantage: {\n type: Boolean,\n default: () => false,\n },\n is_massage_default: {\n type: Boolean,\n default: () => false,\n },\n eventBus: {\n type: Object,\n required: false,\n },\n delayShow: {\n type: Boolean,\n default: () => true,\n },\n },\n components: {\n FieldRender2,\n CloseOutlined,\n LeftOutlined,\n RightOutlined,\n FieldRender,\n AddConditionGroupModal,\n AddConditionModal,\n CloseCircleOutlined,\n },\n emits: [\n 'search',\n 'resize',\n 'update_default_search_condition_config_list',\n 'onShowSearchRender',\n 'delSearch',\n 'onChangeValue',\n 'update:is_clear_model',\n ],\n setup(props, { emit }) {\n const isShowForm = ref(props.is_massage_default);\n const labelModel = ref({});\n const { t } = useI18n();\n const { options_eq } = get_options_eq(t);\n //条件组-->\n const condition_model_dict = ref([]);\n const validateInfos = {};\n const source_default_search_condition_config_list = ref(null);\n const 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 if (!source_default_search_condition_config_list.value) {\n source_default_search_condition_config_list.value = JSON.parse(\n JSON.stringify(props.default_search_condition_config_list),\n );\n }\n\n const operator_type_count_map = {\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 istartswith: 1,\n endswith: 1,\n iendswith: 1,\n notbetween: 2,\n notin: 0,\n notcontains: 1,\n noticontains: 1,\n notstartswith: 1,\n notistartswith: 1,\n notendswith: 1,\n notiendswith: 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 const is2DArray = arr => {\n const [first] = [arr];\n return Array.isArray(first) && arr.every(subArray => Array.isArray(subArray));\n };\n let old_operator = null;\n const onChangeOperator = (operator, index, condition) => {\n //不同操作类型,设置不同的默认值\n // if (condition_model_dict.value[index][condition.field_name]) {\n // return;\n // }\n const value = condition_model_dict.value[index][condition.field_name];\n if (get_operator_list_selected(condition).includes('_eq')) {\n if (operator == '_eq') {\n condition_model_dict.value[index][condition.field_name] = null;\n old_operator = operator;\n emit('onChangeValue', { model: condition_model_dict.value });\n return;\n } else if (old_operator == '_eq') {\n condition_model_dict.value[index][condition.field_name] = null;\n old_operator = operator;\n emit('onChangeValue', { model: condition_model_dict.value });\n return;\n }\n }\n if (get_operator_list_selected(condition).includes('not_blank_not_null')) {\n if (operator == 'not_blank_not_null') {\n condition_model_dict.value[index][condition.field_name] = '是';\n old_operator = operator;\n emit('onChangeValue', { model: condition_model_dict.value });\n return;\n } else if (old_operator == 'not_blank_not_null') {\n condition_model_dict.value[index][condition.field_name] = null;\n old_operator = operator;\n emit('onChangeValue', { model: condition_model_dict.value });\n return;\n }\n }\n if (\n get_operator_list_selected(condition).includes('is_or_not_blank_or_null') ||\n get_operator_list_selected(condition).includes('is_or_not_null')\n ) {\n if (operator == 'is_or_not_blank_or_null' || operator == 'is_or_not_null') {\n condition_model_dict.value[index][condition.field_name] = null;\n old_operator = operator;\n emit('onChangeValue', { model: condition_model_dict.value });\n return;\n } else if (old_operator == 'is_or_not_blank_or_null' || old_operator == 'is_or_not_null') {\n condition_model_dict.value[index][condition.field_name] = null;\n old_operator = operator;\n emit('onChangeValue', { model: condition_model_dict.value });\n return;\n }\n }\n if (value instanceof Array && is2DArray(value)) {\n // 级联类型,默认值默认清空\n condition_model_dict.value[index][condition.field_name] = undefined;\n } else if (operator_type_count_map[operator] == 1) {\n if (value instanceof Array) {\n const [first] = condition_model_dict.value[index][condition.field_name];\n if (isNotEmpty(first)) {\n condition_model_dict.value[index][condition.field_name] = first;\n } else {\n condition_model_dict.value[index][condition.field_name] = null;\n }\n } else {\n condition_model_dict.value[index][condition.field_name] = value ? value : null;\n }\n const is = options_eq.some(\n obj => obj.value === condition_model_dict.value[index][condition.field_name],\n );\n if (is) {\n condition_model_dict.value[index][condition.field_name] = null;\n }\n } else if (operator_type_count_map[operator] == 2) {\n if (condition_model_dict.value[index][condition.field_name] instanceof Array) {\n const [first, seconds] = condition_model_dict.value[index][condition.field_name];\n condition_model_dict.value[index][condition.field_name] = [first, seconds];\n } else if (condition_model_dict.value[index][condition.field_name]) {\n const first = condition_model_dict.value[index][condition.field_name];\n condition_model_dict.value[index][condition.field_name] = [first, null];\n } else {\n condition_model_dict.value[index][condition.field_name] = [null, null];\n }\n const is = options_eq.some(\n obj => obj.value === condition_model_dict.value[index][condition.field_name][0],\n );\n if (is) {\n condition_model_dict.value[index][condition.field_name] = [null, null];\n }\n } else { \n condition_model_dict.value[index][condition.field_name] = undefined;\n }\n old_operator = operator;\n emit('onChangeValue', { model: condition_model_dict.value });\n // console.log('onChangeValue');\n };\n\n const addConditionModal = reactive({\n open: false,\n });\n const handleAddConditions = () => {\n addConditionModal.open = true;\n };\n const handleAddConditionOk = (data: any) => {\n props.default_search_condition_config_list.forEach((item: any, index: any) => {\n data.new_list.forEach((item1: any, index1: any) => {\n if (index == index1) {\n item.forEach((item2: any) => {\n item1.forEach((item3: any) => {\n if (item2.field_name == item3.field_name) {\n item3.value = item2.value;\n item3.operator = item2.operator;\n }\n });\n });\n }\n });\n });\n //保存后处理 new_list\n emit('update_default_search_condition_config_list', { new_list: data.new_list });\n // refreshCondition();\n addConditionModal.open = false;\n };\n const handleAddConditionCancel = () => {\n addConditionModal.open = false;\n };\n\n const addConditionGroupModal = reactive({\n open: false,\n });\n const handleAddGroupCondition = () => {\n addConditionGroupModal.open = true;\n };\n const handleAddGroupConditionOK = (data: any) => {\n props.default_search_condition_config_list.forEach((item: any, index: any) => {\n data.new_list.forEach((item1: any, index1: any) => {\n if (index == index1) {\n item.forEach((item2: any) => {\n item1.forEach((item3: any) => {\n if (item2.field_name == item3.field_name) {\n item3.value = item2.value;\n item3.operator = item2.operator;\n }\n });\n });\n }\n });\n });\n emit('update_default_search_condition_config_list', { new_list: data.new_list });\n // refreshCondition();\n addConditionGroupModal.open = false;\n };\n const handleAddGroupConditionCancel = () => {\n addConditionGroupModal.open = false;\n };\n const handleSearch = () => {\n isShowForm.value = false;\n console.log('condition_model_dict.value', condition_model_dict.value);\n emit('search', { model: condition_model_dict.value });\n };\n const refreshCondition = (update_all = false) => {\n if (props.base_search_condition_config_list.length == 0) {\n return;\n }\n props.default_search_condition_config_list?.forEach((item_list: any, index: number) => {\n deleteBtnDict[index] = {};\n if (!condition_model_dict.value[index]) {\n condition_model_dict.value[index] = {};\n }\n props.base_search_condition_config_list.forEach((i: any) => {\n i.group?.forEach((group_item: any) => {\n item_list.forEach((k: any) => {\n if (group_item.field_name == k.field_name) {\n const value = condition_model_dict.value[index][k.field_name];\n if (value == undefined || update_all) {\n if (operator_type_count_map[k.operator] == 1) {\n if (k.value !== undefined) {\n condition_model_dict.value[index][k.field_name] = k.value;\n } else {\n condition_model_dict.value[index][k.field_name] = null;\n }\n } else if (operator_type_count_map[k.operator] == 2) {\n if (k.value !== undefined) {\n condition_model_dict.value[index][k.field_name] = k.value;\n } else {\n condition_model_dict.value[index][k.field_name] = [null, null];\n }\n } else if (operator_type_count_map[k.operator] == 0) {\n if (k.value !== undefined) {\n condition_model_dict.value[index][k.field_name] = k.value;\n } else {\n condition_model_dict.value[index][k.field_name] = [];\n }\n }\n }\n Object.assign(k, { ...group_item, operator: k.operator }); // 保持表单项原有选择的查询条件\n if (k.operator == 'eq' && k.mode != 'default') {\n group_item.mode = 'default';\n Object.assign(k, { model: 'default' });\n } else if (['in', 'notin'].includes(k.operator) && k.mode != 'multiple') {\n group_item.mode = 'multiple';\n Object.assign(k, { model: 'multiple' });\n }\n }\n });\n });\n });\n });\n };\n const onFilterChanged = () => {\n refreshCondition(true);\n };\n\n const deleteBtnDict = reactive({}); // 表单项的删除按钮是否显示\n const handleMouseEnter = (index: any, form_item: any) => {\n deleteBtnDict[index][form_item.field_name] = true;\n };\n const handleMouseLeave = (index: any, form_item: any) => {\n deleteBtnDict[index][form_item.field_name] = false;\n };\n const handleDeleteFormItem = (index: any, condition: any) => {\n //default_search_condition_config_list 不允许删除最后一个条件组的条件项\n const new_list = [];\n props.default_search_condition_config_list.forEach((item_list: any, index_: number) => {\n if (index_ !== index) {\n new_list.push(item_list);\n } else {\n const list = [];\n item_list.forEach((k: any) => {\n if (k.field_name !== condition.field_name) {\n list.push(k);\n }\n });\n if (list.length > 0) {\n new_list.push(list);\n }\n }\n });\n emit('update_default_search_condition_config_list', { new_list: new_list });\n // refreshCondition();\n };\n const handleDelSearch = (index, filed_name) => {\n if (condition_model_dict.value[index][filed_name] instanceof Array) {\n condition_model_dict.value[index][filed_name].length = 0;\n } else {\n condition_model_dict.value[index][filed_name] = null;\n }\n emit('onChangeValue', { model: condition_model_dict.value });\n emit('delSearch', { model: JSON.parse(JSON.stringify(condition_model_dict.value)) });\n };\n\n const onChangeSearchItem = (value: any, group_index, condition: any, condition_index) => {\n if (value instanceof Array && value.length > 0) {\n const selected_field_name = value[value.length - 1];\n let new_condition = null;\n props.base_search_condition_config_list.forEach(item_list => {\n item_list.group.forEach(i => {\n if (i.field_name === selected_field_name) {\n new_condition = JSON.parse(JSON.stringify(i));\n if (new_condition.default_operator) {\n new_condition.operator = new_condition.default_operator;\n } else if (get_operator_list_selected(new_condition).length > 0) {\n const [first] = get_operator_list_selected(new_condition);\n new_condition.operator = first;\n }\n }\n });\n });\n\n if (new_condition) {\n const new_list = JSON.parse(JSON.stringify(props.default_search_condition_config_list));\n new_list.forEach((item_list, i) => {\n if (i === group_index) {\n item_list.forEach((item, k) => {\n if (item.field_name == condition.field_name && k == condition_index) {\n item_list.splice(k, 1, new_condition);\n delete condition_model_dict.value[group_index][item.field_name];\n }\n });\n }\n });\n emit('update_default_search_condition_config_list', {\n new_list: new_list,\n });\n }\n refreshCondition();\n }\n };\n\n const searchItemOptionsDict: any = computed(() => {\n const dict = {};\n props.default_search_condition_config_list.forEach((group_item, index) => {\n dict[index] = [];\n const filter_field_name_list = group_item.map(item => item.field_name);\n props.base_search_condition_config_list.forEach(item => {\n const filter_list = item.group.filter(\n i => !filter_field_name_list.includes(i.field_name),\n );\n const o = {\n value: item.name,\n label: item.name,\n children: filter_list.map(i => {\n return {\n value: i.field_name,\n label: i.label,\n };\n }),\n };\n dict[index].push(o);\n });\n });\n return dict;\n });\n\n const isShowSearchTag = (index, condition) => {\n const value = condition_model_dict.value[index]?.[condition.field_name];\n if (value instanceof Array) {\n const [first] = value;\n if (isNotEmpty(first)) {\n return true;\n }\n } else if (isNotEmpty(value)) {\n return true;\n }\n return false;\n };\n\n const transferValueFunc = (index, condition) => {\n const str_list: any = [];\n const value = condition_model_dict.value[index]?.[condition.field_name];\n if (\n condition.operator === 'is_or_not_blank_or_null' ||\n condition.operator === 'is_or_not_null'\n ) {\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 (condition.operator === '_eq') {\n if (['上月', '本月', '今日', '昨日', '期初'].includes(value)) {\n return t(value);\n }\n } else if (labelModel.value[condition.field_name] != undefined) {\n return `${get_operator_type_map(condition.format, condition.operator)} ${\n labelModel.value[condition.field_name]\n }`;\n } else if (value instanceof Array && condition.field_name_list instanceof Array) {\n let transfer_value;\n if (condition.field_name_list) {\n if (value instanceof Array) {\n transfer_value = value.join(',');\n } else {\n transfer_value = value;\n }\n }\n return `${get_operator_type_map(condition.format, condition.operator)} ${transfer_value}`;\n } else if (value instanceof Array && condition.options instanceof Array) {\n value.forEach(item => {\n condition.options.forEach(i => {\n if (item == i.value) {\n str_list.push(i.label);\n }\n });\n });\n return `${get_operator_type_map(condition.format, condition.operator)} ${str_list.join(\n ',',\n )}`;\n } else {\n let transfer_value;\n if (condition.options) {\n condition.options.forEach(i => {\n if (value == i.value) {\n transfer_value = i.label;\n }\n });\n } else if (condition.type == 'monthpicker' && condition.dateFormat) {\n if (value instanceof Array) {\n const str_list = [];\n value.forEach(i => {\n if (i) {\n str_list.push(moment(i).format(condition.dateFormat));\n } else {\n str_list.push(i);\n }\n });\n transfer_value = str_list.join(',');\n } else {\n transfer_value = moment(value).format(condition.dateFormat);\n }\n } else {\n transfer_value = value;\n }\n return `${get_operator_type_map(condition.format, condition.operator)} ${transfer_value}`;\n }\n };\n\n const handleShowSearchRender = () => {\n emit('onShowSearchRender');\n };\n\n const get_operator_list_selected = condition => {\n if (condition.operator_list_selected) {\n return condition.operator_list_selected;\n } else if (condition.operator_list) {\n return condition.operator_list;\n } else {\n return [];\n }\n };\n\n watch(\n () => condition_model_dict.value,\n () => {\n emit('onChangeValue', { model: condition_model_dict.value });\n // console.log('onChangeValue_watch');\n },\n { deep: true },\n );\n watch(\n () => props.default_search_condition_config_list,\n () => {\n if (props.default_search_condition_config_list?.length == 0) {\n emit('update_default_search_condition_config_list', {\n new_list: source_default_search_condition_config_list.value,\n });\n return;\n }\n refreshCondition();\n },\n { deep: true },\n );\n watch(\n () => props.base_search_condition_config_list,\n () => {\n refreshCondition();\n },\n { deep: true },\n );\n\n watch(\n () => props.is_clear_model,\n () => {\n if (props.is_clear_model) {\n condition_model_dict.value = {};\n refreshCondition();\n emit('update:is_clear_model', false);\n }\n },\n );\n onMounted(() => {\n refreshCondition();\n if (props.eventBus) {\n props.eventBus.on('filterChange', onFilterChanged);\n }\n });\n onUnmounted(() => {\n if (props.eventBus) {\n props.eventBus.off('filterChange', onFilterChanged);\n }\n });\n return {\n props,\n t,\n isShowForm,\n labelModel,\n get_operator_type_map,\n condition_model_dict,\n addConditionModal,\n handleAddConditions,\n handleAddConditionOk,\n handleAddConditionCancel,\n onChangeOperator,\n handleAddGroupCondition,\n handleSearch,\n\n addConditionGroupModal,\n handleAddGroupConditionOK,\n handleAddGroupConditionCancel,\n validateInfos,\n\n deleteBtnDict,\n handleMouseEnter,\n handleMouseLeave,\n handleDeleteFormItem,\n handleDelSearch,\n\n searchItemOptionsDict,\n onChangeSearchItem,\n transferValueFunc,\n isShowSearchTag,\n handleShowSearchRender,\n options_eq,\n get_operator_list_selected,\n is_or_not_blank_or_null_options,\n };\n },\n});\n</script>\n<style lang=\"less\" scoped>\n.card {\n overflow: auto;\n max-height: 300px;\n background: #f2f5f7;\n}\n\n.condition-group {\n padding: 5px;\n}\n\n.range {\n margin-top: 5px;\n}\n\n.close-icon {\n width: 15px;\n margin-top: 5px;\n margin-left: 5px;\n color: red;\n}\n\n.search-bar {\n background: #f2f5f7;\n text-align: right;\n}\n\n:deep(.divider .ant-divider) {\n margin: 0;\n}\n</style>\n","<template>\n <a-form\n ref=\"form\"\n autocomplete=\"off\"\n :model=\"model\"\n :rules=\"form.rules\"\n :layout=\"form.settings.layout\"\n :validateTrigger=\"false\"\n :label-col=\"\n form.settings.layout == 'vertical'\n ? undefined\n : form.settings.labelCol\n ? form.settings.labelCol\n : form.settings.col && form.settings.col.length > 0\n ? { span: 6 }\n : { span: 4 }\n \"\n :wrapper-col=\"\n form.settings.layout == 'vertical'\n ? undefined\n : form.settings.wrapperCol\n ? form.settings.wrapperCol\n : form.settings.col && form.settings.col.length > 0\n ? { span: 18 }\n : { span: 20 }\n \"\n :labelAlign=\"form.settings.labelAlign\"\n scrollToFirstError\n >\n <a-row\n :gutter=\"20\"\n style=\"margin: 0\"\n >\n <template v-if=\"form.settings.col && form.settings.col.length > 0\">\n <a-col\n v-for=\"col in fieldList\"\n :xl=\"24 / fieldList.length\"\n :lg=\"24\"\n :md=\"24\"\n :sm=\"24\"\n :xs=\"24\"\n >\n <field-render\n v-for=\"field in form.fields.slice(col[0], col[1])\"\n v-model:value=\"model[field.name]\"\n :field=\"field\"\n :formModel=\"model\"\n :key=\"field.name\"\n :validateInfos=\"validateInfos\"\n :options=\"options[field.datasource ? field.datasource : field.name]\"\n />\n </a-col>\n </template>\n <a-col\n v-if=\"!form.settings.col || form.settings.col.length === 0\"\n :xl=\"24\"\n :lg=\"24\"\n :md=\"24\"\n :sm=\"24\"\n :xs=\"24\"\n >\n <template v-for=\"field in form.fields\">\n <field-render\n v-model:value=\"model[field.name]\"\n v-model:label=\"model[field.name2]\"\n v-if=\"field.name2\"\n :field=\"field\"\n :formModel=\"model\"\n :key=\"field.name\"\n :validateInfos=\"validateInfos\"\n :options=\"options[field.datasource ? field.datasource : field.name]\"\n />\n <field-render\n v-model:value=\"model[field.name]\"\n v-else\n :field=\"field\"\n :formModel=\"model\"\n :key=\"field.name\"\n :validateInfos=\"validateInfos\"\n :options=\"options[field.datasource ? field.datasource : field.name]\"\n />\n </template>\n </a-col>\n </a-row>\n </a-form>\n</template>\n<script lang=\"ts\">\nimport { defineComponent, watch } from 'vue';\n\nexport default defineComponent({\n name: 'FormRender',\n components: {},\n props: {\n model: {\n type: Object,\n required: true,\n },\n form: {\n type: Object,\n required: true,\n },\n options: {\n type: Object,\n required: true,\n },\n validateInfos: {\n type: Object,\n default: () => {},\n },\n },\n setup(props) {\n if (props.form.watch) {\n for (const k in props.form.watch) {\n watch(\n () => props.model[k],\n () => {\n props.form.watch[k](props.model, props.form);\n },\n );\n }\n }\n },\n\n data() {\n return {\n fieldList: [] as any[],\n };\n },\n methods: {\n validate() {\n return (this.$refs.form as any).validate();\n },\n reset() {\n (this.$refs.form as any).resetFields();\n },\n disable(name: string | number) {\n // eslint-disable-next-line vue/no-mutating-props\n this.form.fields[name].disabled = true;\n },\n disableAll() {\n this.form.fields.forEach((item: any) => {\n item.disabled = true;\n });\n },\n },\n created() {\n let a = 0;\n if (this.form.settings.col && this.form.settings.col.length > 0) {\n this.form.settings.col.forEach((item: number, i: number) => {\n a = a + item;\n if (i === 0) {\n this.fieldList.push([0, a]);\n } else {\n this.fieldList.push([a - item, a]);\n }\n });\n }\n },\n});\n</script>\n","<template>\n <a-form\n ref=\"form\"\n autocomplete=\"off\"\n :model=\"model\"\n :rules=\"form.rules\"\n :layout=\"form.settings.layout\"\n :validateTrigger=\"false\"\n :label-col=\"\n form.settings.layout == 'vertical'\n ? undefined\n : form.settings.labelCol\n ? form.settings.labelCol\n : form.settings.col && form.settings.col.length > 0\n ? { span: 6 }\n : { span: 4 }\n \"\n :wrapper-col=\"\n form.settings.layout == 'vertical'\n ? undefined\n : form.settings.wrapperCol\n ? form.settings.wrapperCol\n : form.settings.col && form.settings.col.length > 0\n ? { span: 18 }\n : { span: 20 }\n \"\n :labelAlign=\"form.settings.labelAlign\"\n scrollToFirstError\n >\n <a-row\n :gutter=\"20\"\n style=\"margin: 0\"\n >\n <template v-if=\"form.settings.col && form.settings.col.length > 0\">\n <a-col\n v-for=\"col in fieldList\"\n :xl=\"24 / fieldList.length\"\n :lg=\"24\"\n :md=\"24\"\n :sm=\"24\"\n :xs=\"24\"\n >\n <field-render\n v-for=\"field in form.fields.slice(col[0], col[1])\"\n v-model:value=\"model[field.name]\"\n :field=\"field\"\n :formModel=\"model\"\n :key=\"field.name\"\n :validateInfos=\"validateInfos\"\n :options=\"options[field.datasource ? field.datasource : field.name]\"\n />\n </a-col>\n </template>\n <a-col\n v-if=\"!form.settings.col || form.settings.col.length === 0\"\n :xl=\"24\"\n :lg=\"24\"\n :md=\"24\"\n :sm=\"24\"\n :xs=\"24\"\n >\n <template v-for=\"field in form.fields\">\n <field-render\n v-model:value=\"model[field.name]\"\n v-model:label=\"model[field.name2]\"\n v-if=\"field.name2\"\n :field=\"field\"\n :formModel=\"model\"\n :key=\"field.name\"\n :validateInfos=\"validateInfos\"\n :options=\"options[field.datasource ? field.datasource : field.name]\"\n />\n <field-render\n v-model:value=\"model[field.name]\"\n v-else\n :field=\"field\"\n :formModel=\"model\"\n :key=\"field.name\"\n :validateInfos=\"validateInfos\"\n :options=\"options[field.datasource ? field.datasource : field.name]\"\n />\n </template>\n </a-col>\n </a-row>\n </a-form>\n</template>\n<script lang=\"ts\">\nimport { defineComponent, watch } from 'vue';\n\nexport default defineComponent({\n name: 'FormRender',\n components: {},\n props: {\n model: {\n type: Object,\n required: true,\n },\n form: {\n type: Object,\n required: true,\n },\n options: {\n type: Object,\n required: true,\n },\n validateInfos: {\n type: Object,\n default: () => {},\n },\n },\n setup(props) {\n if (props.form.watch) {\n for (const k in props.form.watch) {\n watch(\n () => props.model[k],\n () => {\n props.form.watch[k](props.model, props.form);\n },\n );\n }\n }\n },\n\n data() {\n return {\n fieldList: [] as any[],\n };\n },\n methods: {\n validate() {\n return (this.$refs.form as any).validate();\n },\n reset() {\n (this.$refs.form as any).resetFields();\n },\n disable(name: string | number) {\n // eslint-disable-next-line vue/no-mutating-props\n this.form.fields[name].disabled = true;\n },\n disableAll() {\n this.form.fields.forEach((item: any) => {\n item.disabled = true;\n });\n },\n },\n created() {\n let a = 0;\n if (this.form.settings.col && this.form.settings.col.length > 0) {\n this.form.settings.col.forEach((item: number, i: number) => {\n a = a + item;\n if (i === 0) {\n this.fieldList.push([0, a]);\n } else {\n this.fieldList.push([a - item, a]);\n }\n });\n }\n },\n});\n</script>\n","<template>\n <a-form\n ref=\"form\"\n autocomplete=\"off\"\n :model=\"model\"\n :rules=\"form.rules\"\n scrollToFirstError\n >\n <a-row\n gutter=\"5\"\n v-for=\"row in form.fieldList\"\n type=\"flex\"\n >\n <a-col\n v-for=\"field in row\"\n :span=\"field.span\"\n >\n <template v-for=\"field in form.fields\">\n <field-render\n v-model:value=\"model[field.name]\"\n v-model:label=\"model[field.name2]\"\n v-if=\"field.name2\"\n :field=\"field\"\n :formModel=\"model\"\n :key=\"field.name\"\n :validateInfos=\"validateInfos\"\n :options=\"options[field.datasource ? field.datasource : field.name]\"\n />\n <field-render\n v-model:value=\"model[field.name]\"\n v-else\n :field=\"field\"\n :formModel=\"model\"\n :key=\"field.name\"\n :validateInfos=\"validateInfos\"\n :options=\"options[field.datasource ? field.datasource : field.name]\"\n />\n </template>\n </a-col>\n </a-row>\n </a-form>\n</template>\n<script lang=\"ts\">\nimport { defineComponent, watch } from 'vue';\n\nexport default defineComponent({\n name: 'FormRender2',\n components: {},\n props: {\n model: {\n type: Object,\n required: true,\n },\n form: {\n type: Object,\n required: true,\n },\n options: {\n type: Object,\n required: true,\n },\n validateInfos: {\n type: Object,\n default: () => {},\n },\n },\n setup(props) {\n if (props.form.watch) {\n for (const k in props.form.watch) {\n watch(\n () => props.model[k],\n () => {\n props.form.watch[k](props.model, props.form);\n },\n );\n }\n }\n },\n\n data() {\n return {};\n },\n methods: {\n validate() {\n return (this.$refs.form as any).validate();\n },\n reset() {\n (this.$refs.form as any).resetFields();\n },\n disable(name: string | number) {\n // eslint-disable-next-line vue/no-mutating-props\n this.form.fields[name].disabled = true;\n },\n disableAll() {\n this.form.fields.forEach((item: any) => {\n item.disabled = true;\n });\n },\n },\n created() {},\n});\n</script>\n","<template>\n <a-form\n ref=\"form\"\n autocomplete=\"off\"\n :model=\"model\"\n :rules=\"form.rules\"\n scrollToFirstError\n >\n <a-row\n gutter=\"5\"\n v-for=\"row in form.fieldList\"\n type=\"flex\"\n >\n <a-col\n v-for=\"field in row\"\n :span=\"field.span\"\n >\n <template v-for=\"field in form.fields\">\n <field-render\n v-model:value=\"model[field.name]\"\n v-model:label=\"model[field.name2]\"\n v-if=\"field.name2\"\n :field=\"field\"\n :formModel=\"model\"\n :key=\"field.name\"\n :validateInfos=\"validateInfos\"\n :options=\"options[field.datasource ? field.datasource : field.name]\"\n />\n <field-render\n v-model:value=\"model[field.name]\"\n v-else\n :field=\"field\"\n :formModel=\"model\"\n :key=\"field.name\"\n :validateInfos=\"validateInfos\"\n :options=\"options[field.datasource ? field.datasource : field.name]\"\n />\n </template>\n </a-col>\n </a-row>\n </a-form>\n</template>\n<script lang=\"ts\">\nimport { defineComponent, watch } from 'vue';\n\nexport default defineComponent({\n name: 'FormRender2',\n components: {},\n props: {\n model: {\n type: Object,\n required: true,\n },\n form: {\n type: Object,\n required: true,\n },\n options: {\n type: Object,\n required: true,\n },\n validateInfos: {\n type: Object,\n default: () => {},\n },\n },\n setup(props) {\n if (props.form.watch) {\n for (const k in props.form.watch) {\n watch(\n () => props.model[k],\n () => {\n props.form.watch[k](props.model, props.form);\n },\n );\n }\n }\n },\n\n data() {\n return {};\n },\n methods: {\n validate() {\n return (this.$refs.form as any).validate();\n },\n reset() {\n (this.$refs.form as any).resetFields();\n },\n disable(name: string | number) {\n // eslint-disable-next-line vue/no-mutating-props\n this.form.fields[name].disabled = true;\n },\n disableAll() {\n this.form.fields.forEach((item: any) => {\n item.disabled = true;\n });\n },\n },\n created() {},\n});\n</script>\n","export const CUSTOM_VIEW_DATA_USER = 'customviewdatauser';\n","<template>\n <a-card :body-style=\"{ padding: 0, height: height + 87 + 'px', overflowY: 'auto' }\">\n <a-collapse\n v-model:activeKey=\"viewKey\"\n :bordered=\"false\"\n class=\"collapses\"\n style=\"background: rgb(255, 255, 255)\"\n >\n <template #expandIcon=\"{ isActive }\">\n <caret-right-outlined :rotate=\"isActive ? 90 : 0\" />\n </template>\n <a-collapse-panel\n :key=\"'1'\"\n :style=\"customStyle\"\n >\n <template #header>\n <span style=\"font-weight: 700\">{{ $t('个人视图') }}</span>\n </template>\n <template #extra>\n <a-tooltip>\n <template #title>{{ $t('个人视图管理') }}</template>\n <setting-outlined\n style=\"margin-right: 10px\"\n @click.stop=\"editView('personal')\"\n />\n </a-tooltip>\n <a-tooltip>\n <template #title>{{ $t('新建个人视图') }}</template>\n <plus-outlined @click.stop=\"addView('personal')\" />\n </a-tooltip>\n </template>\n <a-table\n v-if=\"personData.length > 0\"\n :columns=\"columns\"\n :customRow=\"customRow\"\n :dataSource=\"personData\"\n :pagination=\"false\"\n :showHeader=\"false\"\n :size=\"'small'\"\n >\n <template #bodyCell=\"{ column, record }\">\n <div\n class=\"table\"\n v-if=\"column.dataIndex === 'name'\"\n style=\"width: 100%; cursor: pointer\"\n @click=\"changeView(record)\"\n >\n <a-tooltip\n :title=\"record.name\"\n :color=\"appStore.primaryColor\"\n placement=\"left\"\n :destroyTooltipOnHide=\"true\"\n :overlayStyle=\"{ maxWidth: '200px' }\"\n >\n <div style=\"max-width: 130px; float: left; white-space: nowrap; overflow: hidden\">\n {{ record.name }}\n </div>\n </a-tooltip>\n <span\n class=\"num\"\n style=\"float: right\"\n :style=\"\n currentViewObj.id === record.id ? { color: '#1890ff', fontWeight: 'bold' } : {}\n \"\n >\n {{ record.num }}\n </span>\n <a-dropdown class=\"dropdown\">\n <span\n style=\"float: right; font-weight: 800\"\n @click.stop=\"\"\n >\n · · ·\n </span>\n <template #overlay>\n <a-menu>\n <a-menu-item v-if=\"!record.is_system || is_auth\">\n <a\n href=\"javascript:;\"\n @click=\"handleSubmit(record, 'personal')\"\n >\n {{ $t('编辑') }}\n </a>\n </a-menu-item>\n <a-menu-item>\n <a\n href=\"javascript:;\"\n @click=\"handleShare(record)\"\n >\n {{ $t('分享视图') }}\n </a>\n </a-menu-item>\n <a-menu-item v-if=\"!record.is_system || is_auth\">\n <a\n href=\"javascript:;\"\n @click=\"handleDelet(record)\"\n >\n {{ $t('删除') }}\n </a>\n </a-menu-item>\n </a-menu>\n </template>\n </a-dropdown>\n </div>\n </template>\n </a-table>\n </a-collapse-panel>\n <a-collapse-panel\n :key=\"'2'\"\n :style=\"customStyle\"\n >\n <template #header>\n <span style=\"font-weight: 700\">{{ $t('公共视图') }}</span>\n </template>\n <template #extra>\n <a-tooltip>\n <template #title>{{ $t('公共视图管理') }}</template>\n <setting-outlined\n style=\"margin-right: 10px\"\n @click.stop=\"editView('public')\"\n />\n </a-tooltip>\n <a-tooltip>\n <template #title>{{ $t('新建公共视图') }}</template>\n <plus-outlined @click.stop=\"addView('public')\" />\n </a-tooltip>\n </template>\n <a-table\n v-if=\"publicData.length > 0\"\n :columns=\"columns\"\n :customRow=\"customRow\"\n :dataSource=\"publicData\"\n :pagination=\"false\"\n :showHeader=\"false\"\n :size=\"'small'\"\n >\n <template #bodyCell=\"{ column, record }\">\n <div\n class=\"table\"\n v-if=\"column.dataIndex === 'name'\"\n style=\"width: 100%; cursor: pointer\"\n @click=\"changeView(record)\"\n >\n <a-tooltip\n :title=\"record.name\"\n :color=\"appStore.primaryColor\"\n placement=\"left\"\n :destroyTooltipOnHide=\"true\"\n :overlayStyle=\"{ maxWidth: '200px' }\"\n >\n <div style=\"max-width: 130px; float: left; white-space: nowrap; overflow: hidden\">\n {{ record.name }}\n </div>\n </a-tooltip>\n <span\n class=\"num\"\n style=\"float: right\"\n :style=\"\n currentViewObj.id === record.id ? { color: '#1890ff', fontWeight: 'bold' } : {}\n \"\n >\n {{ record.num }}\n </span>\n <a-dropdown class=\"dropdown\">\n <span\n style=\"float: right; font-weight: 800\"\n @click.stop=\"\"\n >\n · · ·\n </span>\n <template #overlay>\n <a-menu>\n <a-menu-item v-if=\"!record.is_system || is_auth\">\n <a\n href=\"javascript:;\"\n @click=\"handleSubmit(record, 'public')\"\n >\n {{ $t('编辑') }}\n </a>\n </a-menu-item>\n <a-menu-item>\n <a\n href=\"javascript:;\"\n @click=\"handleShare(record)\"\n >\n {{ $t('分享视图') }}\n </a>\n </a-menu-item>\n <a-menu-item v-if=\"!record.is_system || is_auth\">\n <a\n href=\"javascript:;\"\n @click=\"handleDelet(record)\"\n >\n {{ $t('删除') }}\n </a>\n </a-menu-item>\n </a-menu>\n </template>\n </a-dropdown>\n </div>\n </template>\n </a-table>\n </a-collapse-panel>\n </a-collapse>\n </a-card>\n</template>\n\n<script lang=\"ts\">\nimport {\n computed,\n createVNode,\n defineComponent,\n onActivated,\n onMounted,\n onUnmounted,\n PropType,\n reactive,\n ref,\n watch,\n} from 'vue';\nimport {\n CaretRightOutlined,\n ExclamationCircleOutlined,\n PlusOutlined,\n SettingOutlined,\n} from '@ant-design/icons-vue';\nimport modalBox from 'liyu-pc-base/components/form-modal/modal-tools';\nimport { message, Modal } from 'ant-design-vue';\nimport { useUserStore } from 'liyu-pc-base/init-plugin';\nimport { useAppStore } from 'liyu-pc-base/init-plugin';\nimport {\n change_view_settings_sort,\n create_view_settings,\n delete_view_settings,\n query_view_settings_list,\n refresh_view_settings_cache,\n set_view_settings_default,\n update_view_settings,\n} from 'liyu-pc-base/api/view-model';\nimport { sourceStore } from 'liyu-pc-base/init-plugin';\nimport { copyValue } from 'liyu-pc-base/utils/function';\nimport { getApiData } from 'liyu-pc-base/api/api-model';\nimport { getPageConfig } from 'liyu-pc-base/components/remotePages/index';\nimport { useI18n } from 'vue-i18n';\nimport { useRequiredConditionStore } from 'liyu-pc-base/init-plugin';\nimport { required_condition_event_obj } from 'liyu-pc-base/init-plugin';\nimport { useEnv } from 'liyu-pc-base/init-plugin';\nimport { CUSTOM_VIEW_DATA_USER } from 'liyu-pc-base/constants';\n\nconst VIEW_SYSTEM_EDIT = 'view_system_edit';\nconst columns = [\n {\n title: '',\n dataIndex: 'name',\n key: 'name',\n },\n];\nexport default defineComponent({\n name: 'ViewManage',\n components: {\n CaretRightOutlined,\n PlusOutlined,\n SettingOutlined,\n },\n props: {\n currentViewObj: {\n type: Object,\n required: true,\n },\n menu_flag: {\n type: String,\n required: true,\n },\n menu_name: {\n type: String,\n required: true,\n },\n countData: {\n type: String,\n required: true,\n },\n create_num: {\n type: Number,\n required: true,\n },\n current_num: {\n type: Number,\n required: true,\n },\n count_num: {\n type: Number,\n required: true,\n },\n height: {\n type: Number,\n required: true,\n },\n modalType: {\n type: String,\n },\n app_flag: {\n type: String,\n },\n allBaseConfigMap: {\n type: Object,\n required: true,\n },\n searchConfigFields: {\n type: Array as PropType<any[]>,\n required: true,\n },\n },\n emits: ['change'],\n setup(props, { emit }) {\n const env = useEnv();\n const requiredConditionStore = useRequiredConditionStore();\n const userStore = useUserStore();\n const appStore = useAppStore();\n const current_org = userStore.currentOrg;\n const userid = userStore.userid;\n const is_auth = ref(userStore.CHECK_AUTH(VIEW_SYSTEM_EDIT));\n const viewData = ref([]); // 视图数据\n const { t } = useI18n();\n let mergedConfig: any;\n const personData = computed(() => {\n const list = viewData.value\n .filter((item: any) => !!item.user_id && item.is_system)\n .map((item: any) => {\n return item;\n })\n .sort((a, b) => (a.sort == b.sort ? a.id - b.id : a.sort - b.sort));\n const list1 = viewData.value\n .filter((item: any) => !!item.user_id && !item.is_system)\n .map((item: any) => {\n return item;\n })\n .sort((a, b) => (a.sort == b.sort ? a.id - b.id : a.sort - b.sort));\n return list.concat(list1);\n }); // 个人视图数据\n const publicData = computed(() => {\n const list = viewData.value\n .filter((item: any) => !item.user_id && item.is_system)\n .map((item: any) => {\n return item;\n })\n .sort((a, b) => (a.sort == b.sort ? a.id - b.id : a.sort - b.sort));\n const list1 = viewData.value\n .filter((item: any) => !item.user_id && !item.is_system)\n .map((item: any) => {\n return item;\n })\n .sort((a, b) => (a.sort == b.sort ? a.id - b.id : a.sort - b.sort));\n return list.concat(list1);\n }); // 公共视图数据\n const viewNameList = computed(() => {\n return viewData.value.map((item: any) => {\n return item.name;\n });\n }); // 视图名称列表,用于创建、修改时查重\n const filterConditions = (conditions: any) => {\n const res = [];\n for (const group of conditions) {\n const group_item = [];\n for (const item of group) {\n if (props.allBaseConfigMap[item.field_name]) {\n group_item.push(item);\n }\n }\n if (group_item.length > 0) {\n res.push(group_item);\n }\n }\n return res;\n };\n const filter_search_model = (search_model: any) => {\n const res = {};\n const fieldMap = {};\n if (!search_model) {\n return res;\n }\n if (props.searchConfigFields?.length) {\n for (const item of props.searchConfigFields) {\n fieldMap[item.name] = item;\n }\n }\n for (const key of Object.keys(search_model)) {\n if (fieldMap[key]) {\n res[key] = search_model[key];\n }\n }\n return res;\n };\n const fetchData = async ({\n id,\n search_model,\n filter_map,\n sort_fields,\n group_condition,\n conditions,\n isShowGeneralFilter,\n }) => {\n return new Promise(resolve => {\n if (!props.countData && !mergedConfig?.countData) {\n console.error('无count接口');\n resolve(null);\n }\n const obj: any = {\n org_id: current_org.id,\n ...filter_search_model(search_model || {}),\n ...filter_map,\n sort_fields: sort_fields,\n };\n if (isShowGeneralFilter) {\n obj.group_condition = group_condition;\n obj.conditions = filterConditions(conditions);\n }\n obj.required_condition = getRequiredConditionObj();\n let db_alias = null;\n const page_config = getPageConfig(props.app_flag, props.modalType, null, t, {\n use_store: true,\n to_i18n: true,\n enable_btn: false,\n });\n if (page_config.get_db_alias) {\n db_alias = page_config.get_db_alias();\n }\n obj.db_alias = db_alias;\n getApiData(obj, mergedConfig?.countData ? mergedConfig.countData : props.countData)\n .then((res: any) => {\n viewData.value.forEach((item: any) => {\n if (item.id == id) {\n item.num = res;\n }\n });\n resolve(null);\n })\n .catch(error => {\n console.log('error', error);\n message.error(t('获取数据失败, 请刷新页面'));\n });\n });\n };\n const setCount = async (list: any) => {\n for (const item of list) {\n try {\n await fetchData(item);\n } catch (error) {\n console.log('error', error);\n message.error(t('获取数据失败, 请刷新页面'));\n }\n }\n };\n // 查询视图、刷新count\n const viewRefresh = async () => {\n const res = await getApiData(\n {\n org_id: current_org.id,\n user_id: userid,\n view_project__flag: env.VITE_APP_VIEW_PROJECT_FLAG,\n view_menu__flag: props.modalType,\n history_id: null,\n sort_fields: ['sort', 'create_time'],\n is_cache: false,\n },\n '/view/get_view_settings_for_user',\n );\n mergedConfig = getPageConfig(props.app_flag, props.modalType, null, t, {\n use_store: true,\n to_i18n: true,\n enable_btn: false,\n });\n if (mergedConfig?.isView === false) {\n window.location.hash = '';\n emit('change', null, {}, true, true);\n return;\n }\n requiredConditionStore.set_required_condition(\n props.modalType,\n mergedConfig.required_condition,\n );\n viewData.value.length = 0;\n let list: any = [];\n const count_search_list: any = [];\n if (res && res.system_user_datas && res.system_user_datas.length > 0) {\n list = list.concat(res.system_user_datas);\n }\n if (res && res.system_public_datas && res.system_public_datas.length > 0) {\n list = list.concat(res.system_public_datas);\n }\n if (res && res.public_datas && res.public_datas.length > 0) {\n list = list.concat(res.public_datas);\n }\n if (res && res.user_datas && res.user_datas.length > 0) {\n list = list.concat(res.user_datas);\n }\n list.forEach((item: any) => {\n let search_model: any = null;\n let filter_map: any = null;\n let group_condition: any = null;\n let conditions: any = null;\n if (item.data.isShowGeneralFilter) {\n search_model = {};\n filter_map = {};\n group_condition = item.data.group_condition;\n conditions = item.data.conditions;\n } else {\n search_model = item.data.search_model;\n filter_map = item.data.filter_map;\n group_condition = {};\n conditions = [];\n }\n viewData.value.push({\n ...item,\n search_model,\n filter_map,\n sort_fields: item.data.sort_fields,\n group_condition: group_condition,\n conditions: conditions,\n });\n count_search_list.push({\n id: item.id,\n isShowGeneralFilter: item.data.isShowGeneralFilter,\n search_model,\n filter_map,\n sort_fields: item.data.sort_fields,\n group_condition,\n conditions,\n });\n });\n if (count_search_list.length > 0) {\n setCount(count_search_list);\n }\n handleHashChange(null);\n };\n // 根据hash选定当前视图数据 event返回(视图数据,是否刷新页面,是否可自我保存)\n const handleHashChange = (uid: any) => {\n let hash = null;\n if (uid) {\n hash = uid;\n } else if (window.location.hash) {\n hash = window.location.hash.substring(1); // 去掉 # 符号\n }\n if (hash) {\n // 分享的视图链接打开\n const list = viewData.value.filter((item: any) => item.uid == hash);\n if (list && list.length > 0) {\n emit('change', null, { ...list[0], ...list[0].data }, true, true);\n } else {\n query_view_settings_list({\n org_id: current_org.id,\n conditions: [\n [\n {\n field_name: 'is_active',\n operator: 'in',\n value: [true],\n format: 'choices',\n class_name: 'bool',\n },\n {\n field_name: 'view_menu__flag',\n operator: 'eq',\n value: [props.menu_flag],\n format: 'input',\n class_name: 'str',\n },\n {\n field_name: 'uid',\n operator: 'eq',\n value: [hash],\n format: 'input',\n class_name: 'str',\n },\n ],\n ],\n }).then((res: any) => {\n if (res && res.data && res.data.length > 0) {\n emit(\n 'change',\n null,\n {\n ...res.data[0],\n ...res.data[0].data,\n },\n true,\n false,\n );\n } else {\n const list = viewData.value.filter((item: any) => !item.user_id && item.is_default);\n if (list && list.length > 0) {\n window.location.hash = list[0].uid;\n emit('change', null, { ...list[0], ...list[0].data }, true, true);\n return;\n }\n let obj = viewData.value\n .sort((a, b) => (a.sort == b.sort ? a.id - b.id : a.sort - b.sort))\n .find((item: any) => !item.user_id);\n if (obj && obj.uid) {\n window.location.hash = obj.uid;\n emit('change', null, { ...obj, ...obj.data }, true, true);\n } else {\n obj = viewData.value\n .sort((a, b) => (a.sort == b.sort ? a.id - b.id : a.sort - b.sort))\n .find((item: any) => item.user_id);\n if (obj && obj.uid) {\n window.location.hash = obj.uid;\n emit('change', null, { ...obj, ...obj.data }, true, true);\n } else {\n const obj = {\n uid: null,\n view_menu__flag: props.menu_flag,\n column: {},\n search_model: {},\n filter_map: {},\n sort_fields: [],\n filtered_value: {},\n sort_orders: [],\n };\n emit('change', null, obj, true, false);\n window.location.hash = '';\n }\n }\n }\n });\n }\n } else {\n let current_uid = '';\n if (sourceStore().get(CUSTOM_VIEW_DATA_USER)) {\n current_uid = sourceStore().get(CUSTOM_VIEW_DATA_USER)?.[props.menu_flag]; // 菜单当前视图uid\n }\n if (current_uid) {\n window.location.hash = current_uid;\n handleHashChange(current_uid);\n } else {\n // 优先选择非系统视图的默认视图\n const list = viewData.value.filter(\n (item: any) => !item.user_id && item.is_default && !item.is_system,\n );\n if (list && list.length > 0) {\n window.location.hash = list[0].uid;\n emit('change', null, { ...list[0], ...list[0].data }, true, true);\n return;\n }\n // 其次选择系统视图默认视图(多个默认选择第一个)\n const list_is_system = viewData.value.filter(\n (item: any) => !item.user_id && item.is_default && item.is_system,\n );\n if (list_is_system && list_is_system.length > 0) {\n window.location.hash = list_is_system[0].uid;\n emit('change', null, { ...list_is_system[0], ...list_is_system[0].data }, true, true);\n return;\n }\n let obj = viewData.value\n .sort((a, b) => (a.sort == b.sort ? a.id - b.id : a.sort - b.sort))\n .find((item: any) => !item.user_id);\n if (obj && obj.uid) {\n window.location.hash = obj.uid;\n emit('change', null, { ...obj, ...obj.data }, true, true);\n } else {\n obj = viewData.value\n .sort((a, b) => (a.sort == b.sort ? a.id - b.id : a.sort - b.sort))\n .find((item: any) => item.user_id);\n if (obj && obj.uid) {\n window.location.hash = obj.uid;\n emit('change', null, { ...obj, ...obj.data }, true, true);\n } else {\n window.location.hash = '';\n const obj = {\n uid: null,\n view_menu__flag: props.menu_flag,\n column: {},\n search_model: {},\n filter_map: {},\n sort_fields: [],\n filtered_value: {},\n sort_orders: [],\n };\n emit('change', null, obj, true, false);\n }\n }\n }\n }\n };\n const viewKey = ref(['1', '2']); // 视图数据展开控制key\n const customStyle =\n 'background: #ffffff;border-radius: 4px;margin-bottom: 2px;border: 0;overflow: hidden;';\n const customRow = (record: any) => {\n return props.currentViewObj && record && record.id === props.currentViewObj.id\n ? { style: { backgroundColor: '#ddf1ff' } }\n : { style: {} };\n };\n // 切换视图\n const changeView = (record: any) => {\n window.location.hash = record.uid;\n handleHashChange(record.uid);\n refreshCount([record]);\n };\n const process_default_search_for_view = (data: any) => {\n const res = [];\n for (const gropu of data) {\n const group_item = [];\n for (const item of gropu) {\n group_item.push({\n field_name: item.field_name,\n format: item.format,\n operator: item.operator,\n class_name: item.class_name,\n value: item.value,\n });\n }\n res.push(group_item);\n }\n return res;\n };\n // 保存修改视图\n const viewSubmit = ({ updateView, record }) => {\n if (record.name != updateView.name && viewNameList.value.includes(updateView.name)) {\n message.error(t('视图名称已存在'));\n return;\n }\n if (record?.id) {\n const list = viewData.value.filter((item: any) => record?.id == item.id);\n if (updateView.is_submit?.[0]) {\n const view = {\n ...list[0].data,\n search_model: { ...props.currentViewObj.search_model, current: 1 },\n filter_map: props.currentViewObj.filter_map,\n sort_fields: props.currentViewObj.sort_fields,\n filtered_value: props.currentViewObj.filtered_value,\n sort_orders: props.currentViewObj.sort_orders,\n column: props.currentViewObj.column,\n isShowGeneralFilter: props.currentViewObj.isShowGeneralFilter,\n conditions: props.currentViewObj.conditions,\n group_condition: props.currentViewObj.group_condition,\n group_record: props.currentViewObj.group_record,\n default_search_condition_config_list: process_default_search_for_view(\n props.currentViewObj.default_search_condition_config_list,\n ),\n };\n delete view.is_system; // 存储时不记录is_system,防止后端直接修改,前端不起效\n update_view_settings({\n org_id: current_org.id,\n view_settings_id: record?.id,\n is_system: updateView.is_system?.[0],\n name: updateView.name,\n data: JSON.stringify(view),\n }).then((res: any) => {\n if (updateView.is_default?.[0]) {\n set_view_settings_default({\n org_id: current_org.id,\n view_settings_id: record?.id,\n }).then(() => {\n refresh_view_settings_cache({\n org_id: current_org.id,\n view_settings_id: record?.id,\n }).then(() => {\n message.success(t('保存成功'));\n if (res.id == props.currentViewObj?.id) {\n emit('change', null, { ...res, ...res.data }, false, true);\n } else {\n viewData.value.forEach((item: any) => {\n if (item.id == res.id) {\n Object.assign(item, { ...res, ...res.data });\n }\n });\n }\n viewRefresh();\n });\n });\n } else {\n refresh_view_settings_cache({\n org_id: current_org.id,\n view_settings_id: record?.id,\n }).then(() => {\n message.success(t('保存成功'));\n if (res.id == props.currentViewObj?.id) {\n emit('change', null, { ...res, ...res.data }, false, true);\n } else {\n viewData.value.forEach((item: any) => {\n if (item.id == res.id) {\n Object.assign(item, { ...res, ...res.data });\n }\n });\n }\n viewRefresh();\n });\n }\n });\n } else {\n update_view_settings({\n org_id: current_org.id,\n view_settings_id: record?.id,\n is_system: updateView.is_system?.[0],\n name: updateView.name,\n }).then((res: any) => {\n if (updateView.is_default?.[0]) {\n set_view_settings_default({\n org_id: current_org.id,\n view_settings_id: record?.id,\n }).then(() => {\n refresh_view_settings_cache({\n org_id: current_org.id,\n view_settings_id: record?.id,\n }).then(() => {\n message.success(t('保存成功'));\n if (res.id == props.currentViewObj?.id) {\n emit('change', null, { ...res, ...res.data }, false, true);\n } else {\n viewData.value.forEach((item: any) => {\n if (item.id == res.id) {\n Object.assign(item, { ...res, ...res.data });\n }\n });\n }\n viewRefresh();\n });\n });\n } else {\n refresh_view_settings_cache({\n org_id: current_org.id,\n view_settings_id: record?.id,\n }).then(() => {\n message.success(t('保存成功'));\n if (res.id == props.currentViewObj?.id) {\n emit('change', null, { ...res, ...res.data }, false, true);\n } else {\n viewData.value.forEach((item: any) => {\n if (item.id == res.id) {\n Object.assign(item, { ...res, ...res.data });\n }\n });\n }\n viewRefresh();\n });\n }\n });\n }\n } else {\n let view: any = {};\n if (updateView.is_submit?.[0]) {\n view = {\n search_model: { ...props.currentViewObj.search_model, current: 1 },\n filter_map: props.currentViewObj.filter_map,\n sort_fields: props.currentViewObj.sort_fields,\n filtered_value: props.currentViewObj.filtered_value,\n sort_orders: props.currentViewObj.sort_orders,\n column: props.currentViewObj.column,\n isShowGeneralFilter: props.currentViewObj.isShowGeneralFilter,\n conditions: props.currentViewObj.conditions,\n group_condition: props.currentViewObj.group_condition,\n group_record: props.currentViewObj.group_record,\n default_search_condition_config_list: process_default_search_for_view(\n props.currentViewObj.default_search_condition_config_list,\n ),\n };\n delete view.is_system; // 存储时不记录is_system,防止后端直接修改,前端不起效\n } else {\n view = {\n column: {},\n search_model: {},\n filter_map: {},\n sort_fields: [],\n filtered_value: {},\n sort_orders: [],\n isShowGeneralFilter: null,\n conditions: [],\n group_condition: {},\n group_record: {},\n };\n }\n create_view_settings({\n org_id: current_org.id,\n user_id: updateView.view_type == 'personal' ? userid : null,\n name: updateView.name,\n view_project__flag: env.VITE_APP_VIEW_PROJECT_FLAG,\n view_menu__flag: props.menu_flag,\n view_menu__name: props.menu_name,\n is_system: false,\n data: JSON.stringify(view),\n }).then((res: any) => {\n emit('change', null, { ...res, ...res.data }, true, true);\n if (res.id) {\n viewData.value = viewData.value.concat([\n {\n ...res,\n },\n ]);\n setCount([\n {\n id: res.id,\n search_model: view.search_model,\n filter_map: view.filter_map,\n sort_fields: view.sort_fields,\n group_condition: view.group_condition,\n conditions: view.conditions,\n isShowGeneralFilter: view.isShowGeneralFilter,\n },\n ]);\n window.location.hash = res.uid;\n handleHashChange(res.uid);\n }\n });\n }\n };\n // 视图编辑按钮\n const handleSubmit = (record: any, view_type: string) => {\n let is_submit: any = [false];\n if (props.currentViewObj.id == record.id) {\n is_submit = [true];\n }\n const tempModal = reactive({\n open: true,\n loading: false,\n title: t('编辑视图'),\n form: {\n settings: {\n labelAlign: 'right',\n layout: 'vertical',\n col: [],\n },\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 type: 'checkbox',\n name: 'is_submit',\n label: '',\n disabled: false,\n allowClear: true,\n labelKey: 'name',\n valueKey: 'value',\n defaultValue: [false],\n placeholder: '',\n },\n ],\n rules: reactive({\n name: [\n {\n required: true,\n message: t('请输入视图名称'),\n },\n ],\n }),\n model: reactive({\n name: record.name,\n is_submit: is_submit,\n is_default: [record?.is_default ? record?.is_default : false],\n is_system: [record?.is_system ? record?.is_system : false],\n }),\n },\n options: {\n is_submit: [\n {\n name: t('将当前过滤条件、排序、显示属性、视图和分组等设置更新到该视图中'),\n value: true,\n },\n ],\n is_default: [\n {\n name: t('设为默认视图'),\n value: true,\n },\n ],\n is_system: [\n {\n name: t('设为系统视图'),\n value: true,\n },\n ],\n },\n ok: (data: any) => {\n return new Promise(function (resolve) {\n viewSubmit({ updateView: data, record: record });\n resolve(null);\n });\n },\n });\n if (view_type == 'public') {\n tempModal.form.fields.push({\n type: 'checkbox',\n name: 'is_default',\n label: '',\n disabled: false,\n allowClear: true,\n labelKey: 'name',\n valueKey: 'value',\n defaultValue: [false],\n placeholder: '',\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 placeholder: '',\n });\n }\n }\n modalBox(tempModal);\n };\n // 添加视图\n const addView = (view_type: any) => {\n const tempModal = reactive({\n open: true,\n loading: false,\n title: t('新建视图'),\n form: {\n settings: {\n labelAlign: 'right',\n layout: 'vertical',\n col: [],\n },\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 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 },\n {\n type: 'checkbox',\n name: 'is_submit',\n label: '',\n disabled: false,\n allowClear: true,\n labelKey: 'name',\n valueKey: 'value',\n defaultValue: [false],\n placeholder: '',\n },\n ],\n rules: reactive({\n name: [\n {\n required: true,\n message: t('请输入视图名称'),\n },\n ],\n }),\n model: reactive({\n name: null,\n view_type: view_type,\n is_submit: [true],\n }),\n },\n options: {\n view_type: [\n { name: t('个人视图(仅自己可见)'), value: 'personal' },\n { name: t('公共视图(项目成员均可见)'), value: 'public' },\n ],\n is_submit: [\n {\n name: t('将当前过滤条件、排序、显示属性、视图和分组等设置更新到该视图中'),\n value: true,\n },\n ],\n },\n ok: (data: any) => {\n return new Promise(function (resolve) {\n if (viewNameList.value.includes(data.name)) {\n message.error(t('视图名称已存在'));\n return;\n }\n viewSubmit({ updateView: data, record: data });\n resolve(null);\n });\n },\n });\n modalBox(tempModal);\n };\n // 管理视图\n const editView = (view_type: any) => {\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 viewRefresh();\n });\n } else {\n message.success(t('保存成功'));\n viewRefresh();\n }\n },\n cancel: (isEdit: any) => {\n if (isEdit) {\n viewRefresh();\n }\n },\n });\n modalBox(tempModal);\n };\n // 分享视图\n const handleShare = (record: any) => {\n let url = '';\n const index = window.location.href.indexOf('#');\n if (index !== -1) {\n // 如果找到了 #,则截取它之前的部分\n url = window.location.href.substring(0, index) + '#' + record.uid;\n } else {\n // 如果没有找到 #,则返回原始字符串\n url = window.location.href + '#' + record.uid;\n }\n copyValue({ val: url, message: t('复制成功') });\n };\n // 删除视图\n const handleDelet = (record: any) => {\n Modal.confirm({\n title: () =>\n `${t('确认删除此')}【${record.name}】${record?.user_id ? t('个人视图') : t('公共视图')}?`,\n content: t('视图删除后不可恢复,视图下工作项不受影响,是否确认删除?'),\n icon: () => createVNode(ExclamationCircleOutlined),\n okText: t('确定'),\n onOk() {\n return new Promise(resolve => {\n delete_view_settings({\n org_id: current_org.id,\n view_settings_id: record?.id,\n })\n .then(() => {\n viewData.value = viewData.value.filter((item: any) => item.id != record.id);\n handleHashChange(null);\n message.success(t('删除成功'));\n })\n .finally(() => {\n resolve(null);\n });\n }).catch(() => console.log('Oops errors!'));\n },\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n onCancel() {},\n });\n };\n const getRequiredConditionObj = () => {\n const page_config = getPageConfig(props.app_flag, props.modalType, null, t, {\n use_store: true,\n to_i18n: true,\n enable_btn: false,\n });\n const required_condition = page_config.required_condition;\n const required_condition_obj = {};\n if (required_condition) {\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 }\n return required_condition_obj;\n };\n // 刷新Count (视图record,uid) => {}\n const refreshCount = (list: any) => {\n const count_search_list = [];\n list.forEach((item: any) => {\n let search_model: any = null;\n let filter_map: any = null;\n let group_condition: any = null;\n let conditions: any = null;\n if (item.data.isShowGeneralFilter) {\n search_model = {};\n filter_map = {};\n group_condition = item.data.group_condition;\n conditions = item.data.conditions;\n } else {\n search_model = item.data.search_model;\n filter_map = item.data.filter_map;\n group_condition = {};\n conditions = [];\n }\n\n count_search_list.push({\n id: item.id,\n search_model,\n filter_map,\n sort_fields: item.data.sort_fields,\n group_condition,\n conditions,\n isShowGeneralFilter: item.data.isShowGeneralFilter,\n });\n });\n setCount(count_search_list);\n };\n watch(\n () => props.current_num, // 监听保存当前视图\n () => {\n Modal.confirm({\n title: () => t('确定覆盖视图吗?'),\n content: t('当前视图原有的数据会被覆盖'),\n icon: () => createVNode(ExclamationCircleOutlined),\n okText: t('确定'),\n onOk() {\n return new Promise(resolve => {\n viewSubmit({\n updateView: {\n is_submit: [true],\n is_system: [props.currentViewObj.is_system],\n name: props.currentViewObj.name,\n },\n record: props.currentViewObj,\n });\n resolve(null);\n }).catch(() => console.log('Oops errors!'));\n },\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n onCancel() {},\n });\n },\n );\n watch(\n () => props.create_num, // 监听另存为\n () => {\n const tempModal = reactive({\n open: true,\n loading: false,\n title: t('新建视图'),\n form: {\n settings: {\n labelAlign: 'right',\n layout: 'vertical',\n col: [],\n },\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 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 },\n ],\n rules: reactive({\n name: [\n {\n required: true,\n message: t('请输入视图名称'),\n },\n ],\n }),\n model: reactive({\n name: null,\n view_type: 'personal',\n is_submit: [true],\n }),\n },\n options: {\n view_type: [\n { name: t('个人视图(仅自己可见)'), value: 'personal' },\n { name: t('公共视图(项目成员均可见)'), value: 'public' },\n ],\n is_submit: [\n {\n name: t('将当前过滤条件、排序、显示属性、视图和分组等设置更新到该视图中'),\n value: true,\n },\n ],\n },\n ok: (data: any) => {\n return new Promise(function (resolve) {\n const viewNameList = viewData.value.map((item: any) => item.name);\n if (viewNameList.includes(data.name)) {\n message.error(t('视图名称已存在'));\n return;\n }\n viewSubmit({ updateView: data, record: data });\n resolve(null);\n });\n },\n });\n modalBox(tempModal);\n },\n );\n\n watch(\n () => props.count_num, // 监听刷新当前视图count\n () => {\n refreshCount(viewData.value);\n },\n );\n const handleRequiredConditionChange = (key: string) => {\n const page_config = getPageConfig(props.currentViewObj.app_flag, props.modalType, null, t, {\n use_store: true,\n to_i18n: true,\n enable_btn: false,\n });\n if (page_config.required_condition) {\n const item = page_config.required_condition.find((item: any) => item.key === key);\n if (item) {\n viewRefresh();\n }\n }\n };\n onMounted(() => {\n viewRefresh();\n required_condition_event_obj().on('change', handleRequiredConditionChange);\n });\n onUnmounted(() => {\n required_condition_event_obj().off('change', handleRequiredConditionChange);\n });\n // 页面重新进入刷新count\n onActivated(() => {\n refreshCount(viewData.value);\n });\n return {\n props,\n viewKey,\n customStyle,\n columns,\n personData,\n publicData,\n is_auth,\n addView,\n editView,\n customRow,\n changeView,\n handleSubmit,\n handleShare,\n handleDelet,\n appStore,\n };\n },\n});\n</script>\n<style lang=\"less\">\n.collapses .ant-collapse-item .ant-collapse-content .ant-collapse-content-box {\n padding: 0;\n}\n\n.num {\n display: inline-block;\n}\n\n.dropdown {\n display: none;\n}\n\n.table:hover .dropdown {\n display: inline-block;\n}\n\n.table:hover .num {\n display: none;\n}\n</style>\n","<template>\n <a-card :body-style=\"{ padding: 0, height: height + 87 + 'px', overflowY: 'auto' }\">\n <a-collapse\n v-model:activeKey=\"viewKey\"\n :bordered=\"false\"\n class=\"collapses\"\n style=\"background: rgb(255, 255, 255)\"\n >\n <template #expandIcon=\"{ isActive }\">\n <caret-right-outlined :rotate=\"isActive ? 90 : 0\" />\n </template>\n <a-collapse-panel\n :key=\"'1'\"\n :style=\"customStyle\"\n >\n <template #header>\n <span style=\"font-weight: 700\">{{ $t('个人视图') }}</span>\n </template>\n <template #extra>\n <a-tooltip>\n <template #title>{{ $t('个人视图管理') }}</template>\n <setting-outlined\n style=\"margin-right: 10px\"\n @click.stop=\"editView('personal')\"\n />\n </a-tooltip>\n <a-tooltip>\n <template #title>{{ $t('新建个人视图') }}</template>\n <plus-outlined @click.stop=\"addView('personal')\" />\n </a-tooltip>\n </template>\n <a-table\n v-if=\"personData.length > 0\"\n :columns=\"columns\"\n :customRow=\"customRow\"\n :dataSource=\"personData\"\n :pagination=\"false\"\n :showHeader=\"false\"\n :size=\"'small'\"\n >\n <template #bodyCell=\"{ column, record }\">\n <div\n class=\"table\"\n v-if=\"column.dataIndex === 'name'\"\n style=\"width: 100%; cursor: pointer\"\n @click=\"changeView(record)\"\n >\n <a-tooltip\n :title=\"record.name\"\n :color=\"appStore.primaryColor\"\n placement=\"left\"\n :destroyTooltipOnHide=\"true\"\n :overlayStyle=\"{ maxWidth: '200px' }\"\n >\n <div style=\"max-width: 130px; float: left; white-space: nowrap; overflow: hidden\">\n {{ record.name }}\n </div>\n </a-tooltip>\n <span\n class=\"num\"\n style=\"float: right\"\n :style=\"\n currentViewObj.id === record.id ? { color: '#1890ff', fontWeight: 'bold' } : {}\n \"\n >\n {{ record.num }}\n </span>\n <a-dropdown class=\"dropdown\">\n <span\n style=\"float: right; font-weight: 800\"\n @click.stop=\"\"\n >\n · · ·\n </span>\n <template #overlay>\n <a-menu>\n <a-menu-item v-if=\"!record.is_system || is_auth\">\n <a\n href=\"javascript:;\"\n @click=\"handleSubmit(record, 'personal')\"\n >\n {{ $t('编辑') }}\n </a>\n </a-menu-item>\n <a-menu-item>\n <a\n href=\"javascript:;\"\n @click=\"handleShare(record)\"\n >\n {{ $t('分享视图') }}\n </a>\n </a-menu-item>\n <a-menu-item v-if=\"!record.is_system || is_auth\">\n <a\n href=\"javascript:;\"\n @click=\"handleDelet(record)\"\n >\n {{ $t('删除') }}\n </a>\n </a-menu-item>\n </a-menu>\n </template>\n </a-dropdown>\n </div>\n </template>\n </a-table>\n </a-collapse-panel>\n <a-collapse-panel\n :key=\"'2'\"\n :style=\"customStyle\"\n >\n <template #header>\n <span style=\"font-weight: 700\">{{ $t('公共视图') }}</span>\n </template>\n <template #extra>\n <a-tooltip>\n <template #title>{{ $t('公共视图管理') }}</template>\n <setting-outlined\n style=\"margin-right: 10px\"\n @click.stop=\"editView('public')\"\n />\n </a-tooltip>\n <a-tooltip>\n <template #title>{{ $t('新建公共视图') }}</template>\n <plus-outlined @click.stop=\"addView('public')\" />\n </a-tooltip>\n </template>\n <a-table\n v-if=\"publicData.length > 0\"\n :columns=\"columns\"\n :customRow=\"customRow\"\n :dataSource=\"publicData\"\n :pagination=\"false\"\n :showHeader=\"false\"\n :size=\"'small'\"\n >\n <template #bodyCell=\"{ column, record }\">\n <div\n class=\"table\"\n v-if=\"column.dataIndex === 'name'\"\n style=\"width: 100%; cursor: pointer\"\n @click=\"changeView(record)\"\n >\n <a-tooltip\n :title=\"record.name\"\n :color=\"appStore.primaryColor\"\n placement=\"left\"\n :destroyTooltipOnHide=\"true\"\n :overlayStyle=\"{ maxWidth: '200px' }\"\n >\n <div style=\"max-width: 130px; float: left; white-space: nowrap; overflow: hidden\">\n {{ record.name }}\n </div>\n </a-tooltip>\n <span\n class=\"num\"\n style=\"float: right\"\n :style=\"\n currentViewObj.id === record.id ? { color: '#1890ff', fontWeight: 'bold' } : {}\n \"\n >\n {{ record.num }}\n </span>\n <a-dropdown class=\"dropdown\">\n <span\n style=\"float: right; font-weight: 800\"\n @click.stop=\"\"\n >\n · · ·\n </span>\n <template #overlay>\n <a-menu>\n <a-menu-item v-if=\"!record.is_system || is_auth\">\n <a\n href=\"javascript:;\"\n @click=\"handleSubmit(record, 'public')\"\n >\n {{ $t('编辑') }}\n </a>\n </a-menu-item>\n <a-menu-item>\n <a\n href=\"javascript:;\"\n @click=\"handleShare(record)\"\n >\n {{ $t('分享视图') }}\n </a>\n </a-menu-item>\n <a-menu-item v-if=\"!record.is_system || is_auth\">\n <a\n href=\"javascript:;\"\n @click=\"handleDelet(record)\"\n >\n {{ $t('删除') }}\n </a>\n </a-menu-item>\n </a-menu>\n </template>\n </a-dropdown>\n </div>\n </template>\n </a-table>\n </a-collapse-panel>\n </a-collapse>\n </a-card>\n</template>\n\n<script lang=\"ts\">\nimport {\n computed,\n createVNode,\n defineComponent,\n onActivated,\n onMounted,\n onUnmounted,\n PropType,\n reactive,\n ref,\n watch,\n} from 'vue';\nimport {\n CaretRightOutlined,\n ExclamationCircleOutlined,\n PlusOutlined,\n SettingOutlined,\n} from '@ant-design/icons-vue';\nimport modalBox from 'liyu-pc-base/components/form-modal/modal-tools';\nimport { message, Modal } from 'ant-design-vue';\nimport { useUserStore } from 'liyu-pc-base/init-plugin';\nimport { useAppStore } from 'liyu-pc-base/init-plugin';\nimport {\n change_view_settings_sort,\n create_view_settings,\n delete_view_settings,\n query_view_settings_list,\n refresh_view_settings_cache,\n set_view_settings_default,\n update_view_settings,\n} from 'liyu-pc-base/api/view-model';\nimport { sourceStore } from 'liyu-pc-base/init-plugin';\nimport { copyValue } from 'liyu-pc-base/utils/function';\nimport { getApiData } from 'liyu-pc-base/api/api-model';\nimport { getPageConfig } from 'liyu-pc-base/components/remotePages/index';\nimport { useI18n } from 'vue-i18n';\nimport { useRequiredConditionStore } from 'liyu-pc-base/init-plugin';\nimport { required_condition_event_obj } from 'liyu-pc-base/init-plugin';\nimport { useEnv } from 'liyu-pc-base/init-plugin';\nimport { CUSTOM_VIEW_DATA_USER } from 'liyu-pc-base/constants';\n\nconst VIEW_SYSTEM_EDIT = 'view_system_edit';\nconst columns = [\n {\n title: '',\n dataIndex: 'name',\n key: 'name',\n },\n];\nexport default defineComponent({\n name: 'ViewManage',\n components: {\n CaretRightOutlined,\n PlusOutlined,\n SettingOutlined,\n },\n props: {\n currentViewObj: {\n type: Object,\n required: true,\n },\n menu_flag: {\n type: String,\n required: true,\n },\n menu_name: {\n type: String,\n required: true,\n },\n countData: {\n type: String,\n required: true,\n },\n create_num: {\n type: Number,\n required: true,\n },\n current_num: {\n type: Number,\n required: true,\n },\n count_num: {\n type: Number,\n required: true,\n },\n height: {\n type: Number,\n required: true,\n },\n modalType: {\n type: String,\n },\n app_flag: {\n type: String,\n },\n allBaseConfigMap: {\n type: Object,\n required: true,\n },\n searchConfigFields: {\n type: Array as PropType<any[]>,\n required: true,\n },\n },\n emits: ['change'],\n setup(props, { emit }) {\n const env = useEnv();\n const requiredConditionStore = useRequiredConditionStore();\n const userStore = useUserStore();\n const appStore = useAppStore();\n const current_org = userStore.currentOrg;\n const userid = userStore.userid;\n const is_auth = ref(userStore.CHECK_AUTH(VIEW_SYSTEM_EDIT));\n const viewData = ref([]); // 视图数据\n const { t } = useI18n();\n let mergedConfig: any;\n const personData = computed(() => {\n const list = viewData.value\n .filter((item: any) => !!item.user_id && item.is_system)\n .map((item: any) => {\n return item;\n })\n .sort((a, b) => (a.sort == b.sort ? a.id - b.id : a.sort - b.sort));\n const list1 = viewData.value\n .filter((item: any) => !!item.user_id && !item.is_system)\n .map((item: any) => {\n return item;\n })\n .sort((a, b) => (a.sort == b.sort ? a.id - b.id : a.sort - b.sort));\n return list.concat(list1);\n }); // 个人视图数据\n const publicData = computed(() => {\n const list = viewData.value\n .filter((item: any) => !item.user_id && item.is_system)\n .map((item: any) => {\n return item;\n })\n .sort((a, b) => (a.sort == b.sort ? a.id - b.id : a.sort - b.sort));\n const list1 = viewData.value\n .filter((item: any) => !item.user_id && !item.is_system)\n .map((item: any) => {\n return item;\n })\n .sort((a, b) => (a.sort == b.sort ? a.id - b.id : a.sort - b.sort));\n return list.concat(list1);\n }); // 公共视图数据\n const viewNameList = computed(() => {\n return viewData.value.map((item: any) => {\n return item.name;\n });\n }); // 视图名称列表,用于创建、修改时查重\n const filterConditions = (conditions: any) => {\n const res = [];\n for (const group of conditions) {\n const group_item = [];\n for (const item of group) {\n if (props.allBaseConfigMap[item.field_name]) {\n group_item.push(item);\n }\n }\n if (group_item.length > 0) {\n res.push(group_item);\n }\n }\n return res;\n };\n const filter_search_model = (search_model: any) => {\n const res = {};\n const fieldMap = {};\n if (!search_model) {\n return res;\n }\n if (props.searchConfigFields?.length) {\n for (const item of props.searchConfigFields) {\n fieldMap[item.name] = item;\n }\n }\n for (const key of Object.keys(search_model)) {\n if (fieldMap[key]) {\n res[key] = search_model[key];\n }\n }\n return res;\n };\n const fetchData = async ({\n id,\n search_model,\n filter_map,\n sort_fields,\n group_condition,\n conditions,\n isShowGeneralFilter,\n }) => {\n return new Promise(resolve => {\n if (!props.countData && !mergedConfig?.countData) {\n console.error('无count接口');\n resolve(null);\n }\n const obj: any = {\n org_id: current_org.id,\n ...filter_search_model(search_model || {}),\n ...filter_map,\n sort_fields: sort_fields,\n };\n if (isShowGeneralFilter) {\n obj.group_condition = group_condition;\n obj.conditions = filterConditions(conditions);\n }\n obj.required_condition = getRequiredConditionObj();\n let db_alias = null;\n const page_config = getPageConfig(props.app_flag, props.modalType, null, t, {\n use_store: true,\n to_i18n: true,\n enable_btn: false,\n });\n if (page_config.get_db_alias) {\n db_alias = page_config.get_db_alias();\n }\n obj.db_alias = db_alias;\n getApiData(obj, mergedConfig?.countData ? mergedConfig.countData : props.countData)\n .then((res: any) => {\n viewData.value.forEach((item: any) => {\n if (item.id == id) {\n item.num = res;\n }\n });\n resolve(null);\n })\n .catch(error => {\n console.log('error', error);\n message.error(t('获取数据失败, 请刷新页面'));\n });\n });\n };\n const setCount = async (list: any) => {\n for (const item of list) {\n try {\n await fetchData(item);\n } catch (error) {\n console.log('error', error);\n message.error(t('获取数据失败, 请刷新页面'));\n }\n }\n };\n // 查询视图、刷新count\n const viewRefresh = async () => {\n const res = await getApiData(\n {\n org_id: current_org.id,\n user_id: userid,\n view_project__flag: env.VITE_APP_VIEW_PROJECT_FLAG,\n view_menu__flag: props.modalType,\n history_id: null,\n sort_fields: ['sort', 'create_time'],\n is_cache: false,\n },\n '/view/get_view_settings_for_user',\n );\n mergedConfig = getPageConfig(props.app_flag, props.modalType, null, t, {\n use_store: true,\n to_i18n: true,\n enable_btn: false,\n });\n if (mergedConfig?.isView === false) {\n window.location.hash = '';\n emit('change', null, {}, true, true);\n return;\n }\n requiredConditionStore.set_required_condition(\n props.modalType,\n mergedConfig.required_condition,\n );\n viewData.value.length = 0;\n let list: any = [];\n const count_search_list: any = [];\n if (res && res.system_user_datas && res.system_user_datas.length > 0) {\n list = list.concat(res.system_user_datas);\n }\n if (res && res.system_public_datas && res.system_public_datas.length > 0) {\n list = list.concat(res.system_public_datas);\n }\n if (res && res.public_datas && res.public_datas.length > 0) {\n list = list.concat(res.public_datas);\n }\n if (res && res.user_datas && res.user_datas.length > 0) {\n list = list.concat(res.user_datas);\n }\n list.forEach((item: any) => {\n let search_model: any = null;\n let filter_map: any = null;\n let group_condition: any = null;\n let conditions: any = null;\n if (item.data.isShowGeneralFilter) {\n search_model = {};\n filter_map = {};\n group_condition = item.data.group_condition;\n conditions = item.data.conditions;\n } else {\n search_model = item.data.search_model;\n filter_map = item.data.filter_map;\n group_condition = {};\n conditions = [];\n }\n viewData.value.push({\n ...item,\n search_model,\n filter_map,\n sort_fields: item.data.sort_fields,\n group_condition: group_condition,\n conditions: conditions,\n });\n count_search_list.push({\n id: item.id,\n isShowGeneralFilter: item.data.isShowGeneralFilter,\n search_model,\n filter_map,\n sort_fields: item.data.sort_fields,\n group_condition,\n conditions,\n });\n });\n if (count_search_list.length > 0) {\n setCount(count_search_list);\n }\n handleHashChange(null);\n };\n // 根据hash选定当前视图数据 event返回(视图数据,是否刷新页面,是否可自我保存)\n const handleHashChange = (uid: any) => {\n let hash = null;\n if (uid) {\n hash = uid;\n } else if (window.location.hash) {\n hash = window.location.hash.substring(1); // 去掉 # 符号\n }\n if (hash) {\n // 分享的视图链接打开\n const list = viewData.value.filter((item: any) => item.uid == hash);\n if (list && list.length > 0) {\n emit('change', null, { ...list[0], ...list[0].data }, true, true);\n } else {\n query_view_settings_list({\n org_id: current_org.id,\n conditions: [\n [\n {\n field_name: 'is_active',\n operator: 'in',\n value: [true],\n format: 'choices',\n class_name: 'bool',\n },\n {\n field_name: 'view_menu__flag',\n operator: 'eq',\n value: [props.menu_flag],\n format: 'input',\n class_name: 'str',\n },\n {\n field_name: 'uid',\n operator: 'eq',\n value: [hash],\n format: 'input',\n class_name: 'str',\n },\n ],\n ],\n }).then((res: any) => {\n if (res && res.data && res.data.length > 0) {\n emit(\n 'change',\n null,\n {\n ...res.data[0],\n ...res.data[0].data,\n },\n true,\n false,\n );\n } else {\n const list = viewData.value.filter((item: any) => !item.user_id && item.is_default);\n if (list && list.length > 0) {\n window.location.hash = list[0].uid;\n emit('change', null, { ...list[0], ...list[0].data }, true, true);\n return;\n }\n let obj = viewData.value\n .sort((a, b) => (a.sort == b.sort ? a.id - b.id : a.sort - b.sort))\n .find((item: any) => !item.user_id);\n if (obj && obj.uid) {\n window.location.hash = obj.uid;\n emit('change', null, { ...obj, ...obj.data }, true, true);\n } else {\n obj = viewData.value\n .sort((a, b) => (a.sort == b.sort ? a.id - b.id : a.sort - b.sort))\n .find((item: any) => item.user_id);\n if (obj && obj.uid) {\n window.location.hash = obj.uid;\n emit('change', null, { ...obj, ...obj.data }, true, true);\n } else {\n const obj = {\n uid: null,\n view_menu__flag: props.menu_flag,\n column: {},\n search_model: {},\n filter_map: {},\n sort_fields: [],\n filtered_value: {},\n sort_orders: [],\n };\n emit('change', null, obj, true, false);\n window.location.hash = '';\n }\n }\n }\n });\n }\n } else {\n let current_uid = '';\n if (sourceStore().get(CUSTOM_VIEW_DATA_USER)) {\n current_uid = sourceStore().get(CUSTOM_VIEW_DATA_USER)?.[props.menu_flag]; // 菜单当前视图uid\n }\n if (current_uid) {\n window.location.hash = current_uid;\n handleHashChange(current_uid);\n } else {\n // 优先选择非系统视图的默认视图\n const list = viewData.value.filter(\n (item: any) => !item.user_id && item.is_default && !item.is_system,\n );\n if (list && list.length > 0) {\n window.location.hash = list[0].uid;\n emit('change', null, { ...list[0], ...list[0].data }, true, true);\n return;\n }\n // 其次选择系统视图默认视图(多个默认选择第一个)\n const list_is_system = viewData.value.filter(\n (item: any) => !item.user_id && item.is_default && item.is_system,\n );\n if (list_is_system && list_is_system.length > 0) {\n window.location.hash = list_is_system[0].uid;\n emit('change', null, { ...list_is_system[0], ...list_is_system[0].data }, true, true);\n return;\n }\n let obj = viewData.value\n .sort((a, b) => (a.sort == b.sort ? a.id - b.id : a.sort - b.sort))\n .find((item: any) => !item.user_id);\n if (obj && obj.uid) {\n window.location.hash = obj.uid;\n emit('change', null, { ...obj, ...obj.data }, true, true);\n } else {\n obj = viewData.value\n .sort((a, b) => (a.sort == b.sort ? a.id - b.id : a.sort - b.sort))\n .find((item: any) => item.user_id);\n if (obj && obj.uid) {\n window.location.hash = obj.uid;\n emit('change', null, { ...obj, ...obj.data }, true, true);\n } else {\n window.location.hash = '';\n const obj = {\n uid: null,\n view_menu__flag: props.menu_flag,\n column: {},\n search_model: {},\n filter_map: {},\n sort_fields: [],\n filtered_value: {},\n sort_orders: [],\n };\n emit('change', null, obj, true, false);\n }\n }\n }\n }\n };\n const viewKey = ref(['1', '2']); // 视图数据展开控制key\n const customStyle =\n 'background: #ffffff;border-radius: 4px;margin-bottom: 2px;border: 0;overflow: hidden;';\n const customRow = (record: any) => {\n return props.currentViewObj && record && record.id === props.currentViewObj.id\n ? { style: { backgroundColor: '#ddf1ff' } }\n : { style: {} };\n };\n // 切换视图\n const changeView = (record: any) => {\n window.location.hash = record.uid;\n handleHashChange(record.uid);\n refreshCount([record]);\n };\n const process_default_search_for_view = (data: any) => {\n const res = [];\n for (const gropu of data) {\n const group_item = [];\n for (const item of gropu) {\n group_item.push({\n field_name: item.field_name,\n format: item.format,\n operator: item.operator,\n class_name: item.class_name,\n value: item.value,\n });\n }\n res.push(group_item);\n }\n return res;\n };\n // 保存修改视图\n const viewSubmit = ({ updateView, record }) => {\n if (record.name != updateView.name && viewNameList.value.includes(updateView.name)) {\n message.error(t('视图名称已存在'));\n return;\n }\n if (record?.id) {\n const list = viewData.value.filter((item: any) => record?.id == item.id);\n if (updateView.is_submit?.[0]) {\n const view = {\n ...list[0].data,\n search_model: { ...props.currentViewObj.search_model, current: 1 },\n filter_map: props.currentViewObj.filter_map,\n sort_fields: props.currentViewObj.sort_fields,\n filtered_value: props.currentViewObj.filtered_value,\n sort_orders: props.currentViewObj.sort_orders,\n column: props.currentViewObj.column,\n isShowGeneralFilter: props.currentViewObj.isShowGeneralFilter,\n conditions: props.currentViewObj.conditions,\n group_condition: props.currentViewObj.group_condition,\n group_record: props.currentViewObj.group_record,\n default_search_condition_config_list: process_default_search_for_view(\n props.currentViewObj.default_search_condition_config_list,\n ),\n };\n delete view.is_system; // 存储时不记录is_system,防止后端直接修改,前端不起效\n update_view_settings({\n org_id: current_org.id,\n view_settings_id: record?.id,\n is_system: updateView.is_system?.[0],\n name: updateView.name,\n data: JSON.stringify(view),\n }).then((res: any) => {\n if (updateView.is_default?.[0]) {\n set_view_settings_default({\n org_id: current_org.id,\n view_settings_id: record?.id,\n }).then(() => {\n refresh_view_settings_cache({\n org_id: current_org.id,\n view_settings_id: record?.id,\n }).then(() => {\n message.success(t('保存成功'));\n if (res.id == props.currentViewObj?.id) {\n emit('change', null, { ...res, ...res.data }, false, true);\n } else {\n viewData.value.forEach((item: any) => {\n if (item.id == res.id) {\n Object.assign(item, { ...res, ...res.data });\n }\n });\n }\n viewRefresh();\n });\n });\n } else {\n refresh_view_settings_cache({\n org_id: current_org.id,\n view_settings_id: record?.id,\n }).then(() => {\n message.success(t('保存成功'));\n if (res.id == props.currentViewObj?.id) {\n emit('change', null, { ...res, ...res.data }, false, true);\n } else {\n viewData.value.forEach((item: any) => {\n if (item.id == res.id) {\n Object.assign(item, { ...res, ...res.data });\n }\n });\n }\n viewRefresh();\n });\n }\n });\n } else {\n update_view_settings({\n org_id: current_org.id,\n view_settings_id: record?.id,\n is_system: updateView.is_system?.[0],\n name: updateView.name,\n }).then((res: any) => {\n if (updateView.is_default?.[0]) {\n set_view_settings_default({\n org_id: current_org.id,\n view_settings_id: record?.id,\n }).then(() => {\n refresh_view_settings_cache({\n org_id: current_org.id,\n view_settings_id: record?.id,\n }).then(() => {\n message.success(t('保存成功'));\n if (res.id == props.currentViewObj?.id) {\n emit('change', null, { ...res, ...res.data }, false, true);\n } else {\n viewData.value.forEach((item: any) => {\n if (item.id == res.id) {\n Object.assign(item, { ...res, ...res.data });\n }\n });\n }\n viewRefresh();\n });\n });\n } else {\n refresh_view_settings_cache({\n org_id: current_org.id,\n view_settings_id: record?.id,\n }).then(() => {\n message.success(t('保存成功'));\n if (res.id == props.currentViewObj?.id) {\n emit('change', null, { ...res, ...res.data }, false, true);\n } else {\n viewData.value.forEach((item: any) => {\n if (item.id == res.id) {\n Object.assign(item, { ...res, ...res.data });\n }\n });\n }\n viewRefresh();\n });\n }\n });\n }\n } else {\n let view: any = {};\n if (updateView.is_submit?.[0]) {\n view = {\n search_model: { ...props.currentViewObj.search_model, current: 1 },\n filter_map: props.currentViewObj.filter_map,\n sort_fields: props.currentViewObj.sort_fields,\n filtered_value: props.currentViewObj.filtered_value,\n sort_orders: props.currentViewObj.sort_orders,\n column: props.currentViewObj.column,\n isShowGeneralFilter: props.currentViewObj.isShowGeneralFilter,\n conditions: props.currentViewObj.conditions,\n group_condition: props.currentViewObj.group_condition,\n group_record: props.currentViewObj.group_record,\n default_search_condition_config_list: process_default_search_for_view(\n props.currentViewObj.default_search_condition_config_list,\n ),\n };\n delete view.is_system; // 存储时不记录is_system,防止后端直接修改,前端不起效\n } else {\n view = {\n column: {},\n search_model: {},\n filter_map: {},\n sort_fields: [],\n filtered_value: {},\n sort_orders: [],\n isShowGeneralFilter: null,\n conditions: [],\n group_condition: {},\n group_record: {},\n };\n }\n create_view_settings({\n org_id: current_org.id,\n user_id: updateView.view_type == 'personal' ? userid : null,\n name: updateView.name,\n view_project__flag: env.VITE_APP_VIEW_PROJECT_FLAG,\n view_menu__flag: props.menu_flag,\n view_menu__name: props.menu_name,\n is_system: false,\n data: JSON.stringify(view),\n }).then((res: any) => {\n emit('change', null, { ...res, ...res.data }, true, true);\n if (res.id) {\n viewData.value = viewData.value.concat([\n {\n ...res,\n },\n ]);\n setCount([\n {\n id: res.id,\n search_model: view.search_model,\n filter_map: view.filter_map,\n sort_fields: view.sort_fields,\n group_condition: view.group_condition,\n conditions: view.conditions,\n isShowGeneralFilter: view.isShowGeneralFilter,\n },\n ]);\n window.location.hash = res.uid;\n handleHashChange(res.uid);\n }\n });\n }\n };\n // 视图编辑按钮\n const handleSubmit = (record: any, view_type: string) => {\n let is_submit: any = [false];\n if (props.currentViewObj.id == record.id) {\n is_submit = [true];\n }\n const tempModal = reactive({\n open: true,\n loading: false,\n title: t('编辑视图'),\n form: {\n settings: {\n labelAlign: 'right',\n layout: 'vertical',\n col: [],\n },\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 type: 'checkbox',\n name: 'is_submit',\n label: '',\n disabled: false,\n allowClear: true,\n labelKey: 'name',\n valueKey: 'value',\n defaultValue: [false],\n placeholder: '',\n },\n ],\n rules: reactive({\n name: [\n {\n required: true,\n message: t('请输入视图名称'),\n },\n ],\n }),\n model: reactive({\n name: record.name,\n is_submit: is_submit,\n is_default: [record?.is_default ? record?.is_default : false],\n is_system: [record?.is_system ? record?.is_system : false],\n }),\n },\n options: {\n is_submit: [\n {\n name: t('将当前过滤条件、排序、显示属性、视图和分组等设置更新到该视图中'),\n value: true,\n },\n ],\n is_default: [\n {\n name: t('设为默认视图'),\n value: true,\n },\n ],\n is_system: [\n {\n name: t('设为系统视图'),\n value: true,\n },\n ],\n },\n ok: (data: any) => {\n return new Promise(function (resolve) {\n viewSubmit({ updateView: data, record: record });\n resolve(null);\n });\n },\n });\n if (view_type == 'public') {\n tempModal.form.fields.push({\n type: 'checkbox',\n name: 'is_default',\n label: '',\n disabled: false,\n allowClear: true,\n labelKey: 'name',\n valueKey: 'value',\n defaultValue: [false],\n placeholder: '',\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 placeholder: '',\n });\n }\n }\n modalBox(tempModal);\n };\n // 添加视图\n const addView = (view_type: any) => {\n const tempModal = reactive({\n open: true,\n loading: false,\n title: t('新建视图'),\n form: {\n settings: {\n labelAlign: 'right',\n layout: 'vertical',\n col: [],\n },\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 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 },\n {\n type: 'checkbox',\n name: 'is_submit',\n label: '',\n disabled: false,\n allowClear: true,\n labelKey: 'name',\n valueKey: 'value',\n defaultValue: [false],\n placeholder: '',\n },\n ],\n rules: reactive({\n name: [\n {\n required: true,\n message: t('请输入视图名称'),\n },\n ],\n }),\n model: reactive({\n name: null,\n view_type: view_type,\n is_submit: [true],\n }),\n },\n options: {\n view_type: [\n { name: t('个人视图(仅自己可见)'), value: 'personal' },\n { name: t('公共视图(项目成员均可见)'), value: 'public' },\n ],\n is_submit: [\n {\n name: t('将当前过滤条件、排序、显示属性、视图和分组等设置更新到该视图中'),\n value: true,\n },\n ],\n },\n ok: (data: any) => {\n return new Promise(function (resolve) {\n if (viewNameList.value.includes(data.name)) {\n message.error(t('视图名称已存在'));\n return;\n }\n viewSubmit({ updateView: data, record: data });\n resolve(null);\n });\n },\n });\n modalBox(tempModal);\n };\n // 管理视图\n const editView = (view_type: any) => {\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 viewRefresh();\n });\n } else {\n message.success(t('保存成功'));\n viewRefresh();\n }\n },\n cancel: (isEdit: any) => {\n if (isEdit) {\n viewRefresh();\n }\n },\n });\n modalBox(tempModal);\n };\n // 分享视图\n const handleShare = (record: any) => {\n let url = '';\n const index = window.location.href.indexOf('#');\n if (index !== -1) {\n // 如果找到了 #,则截取它之前的部分\n url = window.location.href.substring(0, index) + '#' + record.uid;\n } else {\n // 如果没有找到 #,则返回原始字符串\n url = window.location.href + '#' + record.uid;\n }\n copyValue({ val: url, message: t('复制成功') });\n };\n // 删除视图\n const handleDelet = (record: any) => {\n Modal.confirm({\n title: () =>\n `${t('确认删除此')}【${record.name}】${record?.user_id ? t('个人视图') : t('公共视图')}?`,\n content: t('视图删除后不可恢复,视图下工作项不受影响,是否确认删除?'),\n icon: () => createVNode(ExclamationCircleOutlined),\n okText: t('确定'),\n onOk() {\n return new Promise(resolve => {\n delete_view_settings({\n org_id: current_org.id,\n view_settings_id: record?.id,\n })\n .then(() => {\n viewData.value = viewData.value.filter((item: any) => item.id != record.id);\n handleHashChange(null);\n message.success(t('删除成功'));\n })\n .finally(() => {\n resolve(null);\n });\n }).catch(() => console.log('Oops errors!'));\n },\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n onCancel() {},\n });\n };\n const getRequiredConditionObj = () => {\n const page_config = getPageConfig(props.app_flag, props.modalType, null, t, {\n use_store: true,\n to_i18n: true,\n enable_btn: false,\n });\n const required_condition = page_config.required_condition;\n const required_condition_obj = {};\n if (required_condition) {\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 }\n return required_condition_obj;\n };\n // 刷新Count (视图record,uid) => {}\n const refreshCount = (list: any) => {\n const count_search_list = [];\n list.forEach((item: any) => {\n let search_model: any = null;\n let filter_map: any = null;\n let group_condition: any = null;\n let conditions: any = null;\n if (item.data.isShowGeneralFilter) {\n search_model = {};\n filter_map = {};\n group_condition = item.data.group_condition;\n conditions = item.data.conditions;\n } else {\n search_model = item.data.search_model;\n filter_map = item.data.filter_map;\n group_condition = {};\n conditions = [];\n }\n\n count_search_list.push({\n id: item.id,\n search_model,\n filter_map,\n sort_fields: item.data.sort_fields,\n group_condition,\n conditions,\n isShowGeneralFilter: item.data.isShowGeneralFilter,\n });\n });\n setCount(count_search_list);\n };\n watch(\n () => props.current_num, // 监听保存当前视图\n () => {\n Modal.confirm({\n title: () => t('确定覆盖视图吗?'),\n content: t('当前视图原有的数据会被覆盖'),\n icon: () => createVNode(ExclamationCircleOutlined),\n okText: t('确定'),\n onOk() {\n return new Promise(resolve => {\n viewSubmit({\n updateView: {\n is_submit: [true],\n is_system: [props.currentViewObj.is_system],\n name: props.currentViewObj.name,\n },\n record: props.currentViewObj,\n });\n resolve(null);\n }).catch(() => console.log('Oops errors!'));\n },\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n onCancel() {},\n });\n },\n );\n watch(\n () => props.create_num, // 监听另存为\n () => {\n const tempModal = reactive({\n open: true,\n loading: false,\n title: t('新建视图'),\n form: {\n settings: {\n labelAlign: 'right',\n layout: 'vertical',\n col: [],\n },\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 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 },\n ],\n rules: reactive({\n name: [\n {\n required: true,\n message: t('请输入视图名称'),\n },\n ],\n }),\n model: reactive({\n name: null,\n view_type: 'personal',\n is_submit: [true],\n }),\n },\n options: {\n view_type: [\n { name: t('个人视图(仅自己可见)'), value: 'personal' },\n { name: t('公共视图(项目成员均可见)'), value: 'public' },\n ],\n is_submit: [\n {\n name: t('将当前过滤条件、排序、显示属性、视图和分组等设置更新到该视图中'),\n value: true,\n },\n ],\n },\n ok: (data: any) => {\n return new Promise(function (resolve) {\n const viewNameList = viewData.value.map((item: any) => item.name);\n if (viewNameList.includes(data.name)) {\n message.error(t('视图名称已存在'));\n return;\n }\n viewSubmit({ updateView: data, record: data });\n resolve(null);\n });\n },\n });\n modalBox(tempModal);\n },\n );\n\n watch(\n () => props.count_num, // 监听刷新当前视图count\n () => {\n refreshCount(viewData.value);\n },\n );\n const handleRequiredConditionChange = (key: string) => {\n const page_config = getPageConfig(props.currentViewObj.app_flag, props.modalType, null, t, {\n use_store: true,\n to_i18n: true,\n enable_btn: false,\n });\n if (page_config.required_condition) {\n const item = page_config.required_condition.find((item: any) => item.key === key);\n if (item) {\n viewRefresh();\n }\n }\n };\n onMounted(() => {\n viewRefresh();\n required_condition_event_obj().on('change', handleRequiredConditionChange);\n });\n onUnmounted(() => {\n required_condition_event_obj().off('change', handleRequiredConditionChange);\n });\n // 页面重新进入刷新count\n onActivated(() => {\n refreshCount(viewData.value);\n });\n return {\n props,\n viewKey,\n customStyle,\n columns,\n personData,\n publicData,\n is_auth,\n addView,\n editView,\n customRow,\n changeView,\n handleSubmit,\n handleShare,\n handleDelet,\n appStore,\n };\n },\n});\n</script>\n<style lang=\"less\">\n.collapses .ant-collapse-item .ant-collapse-content .ant-collapse-content-box {\n padding: 0;\n}\n\n.num {\n display: inline-block;\n}\n\n.dropdown {\n display: none;\n}\n\n.table:hover .dropdown {\n display: inline-block;\n}\n\n.table:hover .num {\n display: none;\n}\n</style>\n","<template>\n <a-card :body-style=\"{ padding: 0, height: selectObj.height + 96 + 'px', overflowY: 'auto' }\">\n <view-manage\n :select-obj=\"selectObj\"\n @change=\"change\"\n />\n </a-card>\n</template>\n\n<script lang=\"ts\">\nimport { defineComponent, ref } from 'vue';\n// import SideFieldRender from 'liyu-pc-base/components/SideSearchRender/SideFieldRender.vue';\n// import { ReloadOutlined } from '@ant-design/icons-vue';\nimport ViewManage from 'liyu-pc-base/components/SideSearchRender/viewManage.vue';\n\nexport default defineComponent({\n name: 'SideSearchRender',\n components: {\n ViewManage,\n },\n props: {\n selectObj: {\n type: Object,\n required: true,\n },\n },\n emits: ['change'],\n setup(props, { emit }) {\n const change = (data: any, is_refresh: any, is_ownView: any) => {\n emit('change', data, is_refresh, is_ownView);\n };\n return {\n props,\n change,\n };\n },\n});\n</script>\n<style lang=\"less\">\n.collapses .ant-collapse-item .ant-collapse-content .ant-collapse-content-box {\n padding: 0;\n}\n</style>\n","<template>\n <a-card :body-style=\"{ padding: 0, height: selectObj.height + 96 + 'px', overflowY: 'auto' }\">\n <view-manage\n :select-obj=\"selectObj\"\n @change=\"change\"\n />\n </a-card>\n</template>\n\n<script lang=\"ts\">\nimport { defineComponent, ref } from 'vue';\n// import SideFieldRender from 'liyu-pc-base/components/SideSearchRender/SideFieldRender.vue';\n// import { ReloadOutlined } from '@ant-design/icons-vue';\nimport ViewManage from 'liyu-pc-base/components/SideSearchRender/viewManage.vue';\n\nexport default defineComponent({\n name: 'SideSearchRender',\n components: {\n ViewManage,\n },\n props: {\n selectObj: {\n type: Object,\n required: true,\n },\n },\n emits: ['change'],\n setup(props, { emit }) {\n const change = (data: any, is_refresh: any, is_ownView: any) => {\n emit('change', data, is_refresh, is_ownView);\n };\n return {\n props,\n change,\n };\n },\n});\n</script>\n<style lang=\"less\">\n.collapses .ant-collapse-item .ant-collapse-content .ant-collapse-content-box {\n padding: 0;\n}\n</style>\n","import { inject, Ref } from 'vue';\nexport const fullLayoutStateSymbol = Symbol('fullLayoutState');\nexport interface FullLayoutState {\n fullLayoutRef: Ref<HTMLElement | null>;\n}\nexport const useFullLayoutState = (): FullLayoutState => {\n const state = inject<FullLayoutState>(fullLayoutStateSymbol);\n return state;\n};\n","<template>\n <div\n ref=\"fullLayoutRef\"\n class=\"full-layout\"\n >\n <slot></slot>\n </div>\n</template>\n<script setup lang=\"ts\">\n// ============================================================================\n// v2:高度改为「纯 CSS 撑满」,删除原先的 JS 测量(量 top → calc(100vh - top))。\n//\n// 旧实现删掉的两个根因:\n// ① 非活动标签被 KeepAlive 移出文档(@vue/runtime-core 的 storageContainer 从不挂到\n// document),此时 getBoundingClientRect() 全为 0 → top 被写成 0 → height 变成\n// calc(100vh - 0px),比正确值高出一整条 header + 多标签栏;\n// ② 靠 setTimeout(200) 猜「布局已稳定」,而会改动顶部高度的信号远不止 multiTab /\n// layout(还有 fixedHeader / multiTabFixed / splitMenus / device / 过渡动画时长),\n// 且 onDeactivated 未清理定时器 → 200ms 内切页仍会写坏。\n//\n// 现在:.full-layout 绝对定位挂到直接父级 .ant-pro-basicLayout-content 上\n// (liyu-pc-lib/src/components/base-layouts/basic-layout.less 声明了\n// position: relative + margin: 24px 24px 0),沿用原来的 -24px 负 margin 抵消父级 margin。\n// 几何与旧实现逐像素一致,但不再依赖任何测量时机。\n//\n// ★ 硬约束:直接父级必须是 position: relative(否则 containing block 退化为视口)。\n// ============================================================================\nimport { provide, shallowRef } from 'vue';\nimport { FullLayoutState, fullLayoutStateSymbol } from './fullLayoutUtils';\n\nconst fullLayoutRef = shallowRef<HTMLElement | null>(null);\nprovide<FullLayoutState>(fullLayoutStateSymbol, {\n fullLayoutRef,\n});\n</script>\n<style scoped lang=\"less\">\n.full-layout {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n // 负 margin 与 inset 叠加:盒子再向外扩 24px,用于抵消父级\n // .ant-pro-basicLayout-content 的 margin: 24px 24px 0。\n margin: -24px -24px 0px -24px;\n overflow: auto;\n}\n</style>\n","<template>\n <div\n ref=\"fullLayoutRef\"\n class=\"full-layout\"\n >\n <slot></slot>\n </div>\n</template>\n<script setup lang=\"ts\">\n// ============================================================================\n// v2:高度改为「纯 CSS 撑满」,删除原先的 JS 测量(量 top → calc(100vh - top))。\n//\n// 旧实现删掉的两个根因:\n// ① 非活动标签被 KeepAlive 移出文档(@vue/runtime-core 的 storageContainer 从不挂到\n// document),此时 getBoundingClientRect() 全为 0 → top 被写成 0 → height 变成\n// calc(100vh - 0px),比正确值高出一整条 header + 多标签栏;\n// ② 靠 setTimeout(200) 猜「布局已稳定」,而会改动顶部高度的信号远不止 multiTab /\n// layout(还有 fixedHeader / multiTabFixed / splitMenus / device / 过渡动画时长),\n// 且 onDeactivated 未清理定时器 → 200ms 内切页仍会写坏。\n//\n// 现在:.full-layout 绝对定位挂到直接父级 .ant-pro-basicLayout-content 上\n// (liyu-pc-lib/src/components/base-layouts/basic-layout.less 声明了\n// position: relative + margin: 24px 24px 0),沿用原来的 -24px 负 margin 抵消父级 margin。\n// 几何与旧实现逐像素一致,但不再依赖任何测量时机。\n//\n// ★ 硬约束:直接父级必须是 position: relative(否则 containing block 退化为视口)。\n// ============================================================================\nimport { provide, shallowRef } from 'vue';\nimport { FullLayoutState, fullLayoutStateSymbol } from './fullLayoutUtils';\n\nconst fullLayoutRef = shallowRef<HTMLElement | null>(null);\nprovide<FullLayoutState>(fullLayoutStateSymbol, {\n fullLayoutRef,\n});\n</script>\n<style scoped lang=\"less\">\n.full-layout {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n // 负 margin 与 inset 叠加:盒子再向外扩 24px,用于抵消父级\n // .ant-pro-basicLayout-content 的 margin: 24px 24px 0。\n margin: -24px -24px 0px -24px;\n overflow: auto;\n}\n</style>\n","let currentDir = 'auto';\n\n// let currentDir = 'auto'\n\nfunction hasDocument() {\n return typeof document !== 'undefined';\n}\n\nfunction hasWindow() {\n return typeof window !== 'undefined';\n}\n\nexport function getDocumentDir() {\n if (!hasDocument()) {\n return currentDir;\n }\n const direction =\n typeof document.dir !== 'undefined'\n ? document.dir\n : document.getElementsByTagName('html')[0].getAttribute('dir');\n return direction;\n}\n\nexport function setDocumentDir(dir: string) {\n // export function setDocumentDir(dir){\n if (!hasDocument) {\n currentDir = dir;\n return;\n }\n\n const html = document.getElementsByTagName('html')[0];\n html.setAttribute('dir', dir);\n}\n\nexport function addWindowEventListener(event: string, callback: () => void) {\n if (!hasWindow) {\n callback();\n return;\n }\n window.addEventListener(event, callback);\n}\n\nexport function removeWindowEventListener(event: string, callback: () => void) {\n if (!hasWindow) {\n return;\n }\n window.removeEventListener(event, callback);\n}\n","export type LayoutItem = {\n i: string;\n x?: number | string;\n y?: number | string;\n h: number | string;\n w: number | string;\n top_i?: string;\n left_i?: string;\n minW?: number;\n minH?: number;\n maxW?: number;\n maxH?: number;\n static?: boolean;\n moved?: boolean;\n isDraggable?: boolean;\n isResizable?: boolean;\n};\nexport type Layout = Array<LayoutItem>;\n\nconst getNum = (v: number | string): number => (typeof v === 'number' ? v : parseFloat(v) || 0);\n\nconst isAbsoluteValue = (v: number | string): boolean =>\n typeof v === 'string' &&\n (v.includes('px') || v.includes('calc') || v.includes('grow') || v.includes('%'));\n\n/**\n * Return the bottom coordinate of the layout.\n *\n * @param {Array} layout Layout array.\n * @return {Number} Bottom coordinate.\n */\nexport function bottom(layout: Layout): number {\n let max = 0;\n for (let i = 0, len = layout.length; i < len; i++) {\n const l = layout[i];\n const valY = l.y ?? 0;\n const valH = l.h ?? 0;\n const bottomY = getNum(valY) + getNum(valH);\n if (bottomY > max) max = bottomY;\n }\n return max;\n}\n\n// Fast path to cloning, since this is monomorphic\nexport function cloneLayoutItem(layoutItem: LayoutItem): LayoutItem {\n return JSON.parse(JSON.stringify(layoutItem));\n}\n\nexport function cloneLayout(layout: Layout): Layout {\n const newLayout = Array(layout.length);\n for (let i = 0, len = layout.length; i < len; i++) {\n newLayout[i] = cloneLayoutItem(layout[i]);\n }\n return newLayout;\n}\n\n/**\n * Given two layoutitems, check if they collide.\n *\n * @return {Boolean} True if colliding.\n */\nexport function collides(l1: LayoutItem, l2: LayoutItem): boolean {\n if (l1 === l2) return false; // same element\n const x1 = getNum(l1.x),\n y1 = getNum(l1.y),\n w1 = getNum(l1.w),\n h1 = getNum(l1.h);\n const x2 = getNum(l2.x),\n y2 = getNum(l2.y),\n w2 = getNum(l2.w),\n h2 = getNum(l2.h);\n if (x1 + w1 <= x2) return false; // l1 is left of l2\n if (x1 >= x2 + w2) return false; // l1 is right of l2\n if (y1 + h1 <= y2) return false; // l1 is above l2\n if (y1 >= y2 + h2) return false; // l1 is below l2\n return true; // boxes overlap\n}\n\n/**\n * Given a layout, compact it. This involves going down each y coordinate and removing gaps\n * between items.\n *\n * @param {Array} layout Layout.\n * @param {Boolean} verticalCompact Whether or not to compact the layout\n * vertically.\n * @return {Array} Compacted Layout.\n */\nexport function compact(layout: Layout, verticalCompact: boolean): Layout {\n const compareWith = getStatics(layout);\n const sorted = sortLayoutItemsByRowCol(layout);\n const out = Array(layout.length);\n\n for (let i = 0, len = sorted.length; i < len; i++) {\n let l = sorted[i];\n\n if (!l.static) {\n l = compactItem(compareWith, l, verticalCompact);\n compareWith.push(l);\n }\n\n out[layout.indexOf(l)] = l;\n l.moved = false;\n }\n\n return out;\n}\n\n/**\n * Compact an item in the layout.\n */\nexport function compactItem(\n compareWith: Layout,\n l: LayoutItem,\n verticalCompact: boolean,\n): LayoutItem {\n if (verticalCompact && !isAbsoluteValue(l.y) && l.top_i === undefined && l.left_i === undefined) {\n while (getNum(l.y) > 0 && !getFirstCollision(compareWith, l)) {\n l.y = getNum(l.y) - 1;\n }\n }\n\n let collides = {} as LayoutItem | void;\n while ((collides = getFirstCollision(compareWith, l))) {\n if (isAbsoluteValue(l.y) || l.top_i !== undefined || l.left_i !== undefined) break;\n l.y = getNum(collides.y) + getNum(collides.h);\n }\n return l;\n}\n\n/**\n * Given a layout, make sure all elements fit within its bounds.\n *\n * @param {Array} layout Layout array.\n * @param {Number} bounds Number of columns.\n */\nexport function correctBounds(layout: Layout, bounds: { cols: number }): Layout {\n const collidesWith = getStatics(layout);\n for (let i = 0, len = layout.length; i < len; i++) {\n const l = layout[i];\n const lx = getNum(l.x);\n const lw = getNum(l.w);\n\n if (\n lx + lw > bounds.cols &&\n !isAbsoluteValue(l.x) &&\n !isAbsoluteValue(l.w) &&\n l.left_i === undefined\n ) {\n l.x = bounds.cols - lw;\n }\n if (lx < 0 && !isAbsoluteValue(l.x) && l.left_i === undefined) {\n l.x = 0;\n l.w = bounds.cols;\n }\n if (!l.static) collidesWith.push(l);\n else {\n while (getFirstCollision(collidesWith, l)) {\n if (isAbsoluteValue(l.y) || l.top_i !== undefined || l.left_i !== undefined) break;\n l.y = getNum(l.y) + 1;\n }\n }\n }\n return layout;\n}\n\n/**\n * Get a layout item by ID. Used so we can override later on if necessary.\n *\n * @param {Array} layout Layout array.\n * @param {String} id ID\n * @return {LayoutItem} Item at ID.\n */\nexport function getLayoutItem(layout: Layout, id: string): LayoutItem | undefined {\n for (let i = 0, len = layout.length; i < len; i++) {\n if (layout[i].i === id) return layout[i];\n }\n}\n\n/**\n * Returns the first item this layout collides with.\n * It doesn't appear to matter which order we approach this from, although\n * perhaps that is the wrong thing to do.\n *\n * @param {Object} layoutItem Layout item.\n * @return {Object|undefined} A colliding layout item, or undefined.\n */\nexport function getFirstCollision(layout: Layout, layoutItem: LayoutItem): LayoutItem | void {\n for (let i = 0, len = layout.length; i < len; i++) {\n if (collides(layout[i], layoutItem)) return layout[i];\n }\n}\n\nexport function getAllCollisions(layout: Layout, layoutItem: LayoutItem): Layout {\n return layout.filter(l => collides(l, layoutItem));\n}\n\n/**\n * Get all static elements.\n * @param {Array} layout Array of layout objects.\n * @return {Array} Array of static layout items..\n */\nexport function getStatics(layout: Layout): Layout {\n return layout.filter(l => l.static);\n}\n\n/**\n * Move an element. Responsible for doing cascading movements of other elements.\n *\n * @param {Array} layout Full layout to modify.\n * @param {LayoutItem} l element to move.\n * @param {Number} [x] X position in grid units.\n * @param {Number} [y] Y position in grid units.\n * @param {Boolean} [isUserAction] If true, designates that the item we're moving is\n * being dragged/resized by th euser.\n */\nexport function moveElement(\n layout: Layout,\n l: LayoutItem,\n x: number | void,\n y: number,\n isUserAction: boolean,\n preventCollision = false,\n) {\n if (l.static) return layout;\n\n const oldX = l.x;\n const oldY = l.y;\n\n const movingUp = y && getNum(l.y) > y;\n if (typeof x === 'number') l.x = x;\n if (typeof y === 'number') l.y = y;\n l.moved = true;\n\n let sorted = sortLayoutItemsByRowCol(layout);\n if (movingUp) sorted = sorted.reverse();\n const collisions = getAllCollisions(sorted, l);\n\n if (preventCollision && collisions.length) {\n l.x = oldX;\n l.y = oldY;\n l.moved = false;\n return layout;\n }\n\n for (let i = 0, len = collisions.length; i < len; i++) {\n const collision = collisions[i];\n if (collision.moved) continue;\n if (\n getNum(l.y) > getNum(collision.y) &&\n getNum(l.y) - getNum(collision.y) > getNum(collision.h) / 4\n )\n continue;\n\n if (collision.static) {\n layout = moveElementAwayFromCollision(layout, collision, l, isUserAction);\n } else {\n layout = moveElementAwayFromCollision(layout, l, collision, isUserAction);\n }\n }\n\n return layout;\n}\n\n/**\n * This is where the magic needs to happen - given a collision, move an element away from the collision.\n * We attempt to move it up if there's room, otherwise it goes below.\n *\n * @param {Array} layout Full layout to modify.\n * @param {LayoutItem} collidesWith Layout item we're colliding with.\n * @param {LayoutItem} itemToMove Layout item we're moving.\n * @param {Boolean} [isUserAction] If true, designates that the item we're moving is being dragged/resized\n * by the user.\n */\nexport function moveElementAwayFromCollision(\n layout: Layout,\n collidesWith: LayoutItem,\n itemToMove: LayoutItem,\n isUserAction: boolean,\n) {\n const preventCollision = false;\n if (isUserAction) {\n const fakeItem: LayoutItem = {\n x: itemToMove.x,\n y: itemToMove.y,\n w: itemToMove.w,\n h: itemToMove.h,\n i: '-1',\n };\n fakeItem.y = Math.max(getNum(collidesWith.y) - getNum(itemToMove.h), 0);\n if (!getFirstCollision(layout, fakeItem)) {\n return moveElement(layout, itemToMove, undefined, fakeItem.y as number, preventCollision);\n }\n }\n\n return moveElement(\n layout,\n itemToMove,\n undefined,\n (getNum(itemToMove.y) + 1) as number,\n preventCollision,\n );\n}\n\nexport function setTransform(\n top: number | string,\n left: number | string,\n width: number | string,\n height: number | string,\n) {\n const leftStr = typeof left === 'number' ? left + 'px' : left;\n const topStr = typeof top === 'number' ? (top < 0 ? 0 : top) + 'px' : top;\n const translate = 'translate3d(' + leftStr + ',' + topStr + ', 0)';\n return {\n transform: translate,\n WebkitTransform: translate,\n MozTransform: translate,\n msTransform: translate,\n OTransform: translate,\n width: typeof width === 'number' ? width + 'px' : width,\n height: typeof height === 'number' ? height + 'px' : height,\n position: 'absolute' as const,\n };\n}\n\nexport function setTransformRtl(\n top: number | string,\n right: number | string,\n width: number | string,\n height: number | string,\n) {\n const rightStr = typeof right === 'number' ? right * -1 + 'px' : 'calc(' + right + ' * -1)';\n const topStr = typeof top === 'number' ? (top < 0 ? 0 : top) + 'px' : top;\n const translate = 'translate3d(' + rightStr + ',' + topStr + ', 0)';\n return {\n transform: translate,\n WebkitTransform: translate,\n MozTransform: translate,\n msTransform: translate,\n OTransform: translate,\n width: typeof width === 'number' ? width + 'px' : width,\n height: typeof height === 'number' ? height + 'px' : height,\n position: 'absolute' as const,\n };\n}\n\nexport function setTopLeft(\n top: number | string,\n left: number | string,\n width: number | string,\n height: number | string,\n) {\n return {\n top: typeof top === 'number' ? top + 'px' : top,\n left: typeof left === 'number' ? left + 'px' : left,\n width: typeof width === 'number' ? width + 'px' : width,\n height: typeof height === 'number' ? height + 'px' : height,\n position: 'absolute' as const,\n };\n}\n\nexport function setTopRight(\n top: number | string,\n right: number | string,\n width: number | string,\n height: number | string,\n) {\n return {\n top: typeof top === 'number' ? top + 'px' : top,\n right: typeof right === 'number' ? right + 'px' : right,\n width: typeof width === 'number' ? width + 'px' : width,\n height: typeof height === 'number' ? height + 'px' : height,\n position: 'absolute' as const,\n };\n}\n\nexport function sortLayoutItemsByRowCol(layout: Layout): Layout {\n return [...layout].sort((a, b) => {\n const ax = getNum(a.x);\n const ay = getNum(a.y);\n const bx = getNum(b.x);\n const by = getNum(b.y);\n\n if (ay === by && ax === bx) {\n return 0;\n }\n\n if (ay > by || (ay === by && ax > bx)) {\n return 1;\n }\n\n return -1;\n });\n}\n\nexport function validateLayout(layout: Layout, contextName = 'Layout'): void {\n const subProps = ['x', 'y', 'w', 'h'];\n if (!Array.isArray(layout)) throw new Error(contextName + ' must be an array!');\n for (let i = 0, len = layout.length; i < len; i++) {\n const item = layout[i];\n for (let j = 0; j < subProps.length; j++) {\n const key = subProps[j] as keyof LayoutItem;\n\n if (key === 'y' && 'top_i' in item) continue;\n if (key === 'x' && 'left_i' in item) continue;\n const val = item[key];\n if (typeof val !== 'number' && typeof val !== 'string') {\n throw new Error(\n 'VueGridLayout: ' +\n contextName +\n '[' +\n i +\n '].' +\n subProps[j] +\n ' must be a number or string!',\n );\n }\n }\n if (item.static !== undefined && typeof item.static !== 'boolean') {\n throw new Error('VueGridLayout: ' + contextName + '[' + i + '].static must be a boolean!');\n }\n }\n}\n","import { cloneLayout, compact, correctBounds } from './utils';\n\n/**\n * Given breakpoints, return an array of breakpoints sorted by width. This is usually\n * e.g. ['xxs', 'xs', 'sm', ...]\n *\n * @param {Object} breakpoints Key/value pair of breakpoint names to widths.\n * @return {Array} Sorted breakpoints.\n */\nexport function sortBreakpoints(breakpoints: any) {\n const keys = Object.keys(breakpoints);\n return keys.sort((a, b) => {\n return breakpoints[a] - breakpoints[b];\n });\n}\n\n/**\n * Given a width, find the highest breakpoint that matches is valid for it (width > breakpoint).\n *\n * @param {Object} breakpoints Breakpoints object (e.g. {lg: 1200, md: 960, ...})\n * @param {Number} width Screen width.\n * @return {String} Highest breakpoint that is less than width.\n */\nexport function getBreakpointFromWidth(breakpoints: any, width: number) {\n const sorted = sortBreakpoints(breakpoints);\n let matching = sorted[0];\n for (let i = 1, len = sorted.length; i < len; i++) {\n const breakpointName = sorted[i];\n if (width > breakpoints[breakpointName]) matching = breakpointName;\n }\n return matching;\n}\n\n/**\n * Given a breakpoint, get the # of cols set for it.\n * @param {String} breakpoint Breakpoint name.\n * @param {Object} cols Map of breakpoints to cols.\n * @return {Number} Number of cols.\n */\nexport function getColsFromBreakpoint(breakpoint: string, cols: any): number {\n if (!cols[breakpoint]) {\n throw new Error(\n 'ResponsiveGridLayout: `cols` entry for breakpoint ' + breakpoint + ' is missing!',\n );\n }\n return cols[breakpoint];\n}\n\n/**\n * Given existing layouts and a new breakpoint, find or generate a new layout.\n *\n * This finds the layout above the new one and generates from it, if it exists.\n *\n * @param {Array} orgLayout Original layout.\n * @param {Object} layouts Existing layouts.\n * @param {Array} breakpoints All breakpoints.\n * @param {String} breakpoint New breakpoint.\n * @param {String} breakpoint Last breakpoint (for fallback).\n * @param {Number} cols Column count at new breakpoint.\n * @param {Boolean} verticalCompact Whether or not to compact the layout\n * vertically.\n * @return {Array} New layout.\n */\nexport function findOrGenerateResponsiveLayout(\n orgLayout: any[],\n layouts: any,\n breakpoints: any[],\n breakpoint: string,\n lastBreakpoint: number,\n cols: number,\n verticalCompact: boolean,\n) {\n // If it already exists, just return it.\n if (layouts[breakpoint]) return cloneLayout(layouts[breakpoint]);\n // Find or generate the next layout\n let layout = orgLayout;\n\n const breakpointsSorted = sortBreakpoints(breakpoints);\n const breakpointsAbove = breakpointsSorted.slice(breakpointsSorted.indexOf(breakpoint));\n for (let i = 0, len = breakpointsAbove.length; i < len; i++) {\n const b = breakpointsAbove[i];\n if (layouts[b]) {\n layout = layouts[b];\n break;\n }\n }\n layout = cloneLayout(layout || []); // clone layout so we don't modify existing items\n return compact(correctBounds(layout, { cols }), verticalCompact);\n}\n\nexport function generateResponsiveLayout(\n layout: any,\n breakpoints: any,\n breakpoint: any,\n lastBreakpoint: any,\n cols: any,\n verticalCompact: any,\n) {\n // If it already exists, just return it.\n /* if (layouts[breakpoint]) return cloneLayout(layouts[breakpoint]);\n // Find or generate the next layout\n let layout = layouts[lastBreakpoint];*/\n /* const breakpointsSorted = sortBreakpoints(breakpoints);\nconst breakpointsAbove = breakpointsSorted.slice(breakpointsSorted.indexOf(breakpoint));\nfor (let i = 0, len = breakpointsAbove.length; i < len; i++) {\n const b = breakpointsAbove[i];\n if (layouts[b]) {\n layout = layouts[b];\n break;\n }\n}*/\n layout = cloneLayout(layout || []); // clone layout so we don't modify existing items\n return compact(correctBounds(layout, { cols }), verticalCompact);\n}\n","// Get from offsetParent\nexport function offsetXYFromParentOf(evt: MouseEvent): { x: number; y: number } {\n const offsetParent = (evt.target as HTMLElement).offsetParent || document.body;\n const offsetParentRect =\n offsetParent === document.body ? { left: 0, top: 0 } : offsetParent.getBoundingClientRect();\n\n const x = evt.clientX + offsetParent.scrollLeft - offsetParentRect.left;\n const y = evt.clientY + offsetParent.scrollTop - offsetParentRect.top;\n\n /* const x = Math.round(evt.clientX + offsetParent.scrollLeft - offsetParentRect.left);\n const y = Math.round(evt.clientY + offsetParent.scrollTop - offsetParentRect.top);*/\n\n return { x, y };\n}\n\n// Get {x, y} positions from event.\nexport function getControlPosition(e: MouseEvent): { x: number; y: number } {\n return offsetXYFromParentOf(e);\n}\n\nfunction isNum(num: any): boolean {\n return typeof num === 'number' && !isNaN(num);\n}\n\n// Create an data object exposed by <DraggableCore>'s events\nexport function createCoreData(\n lastX: number,\n lastY: number,\n x: number,\n y: number,\n): { deltaX: number; deltaY: number; lastX: number; lastY: number; x: number; y: number } {\n // State changes are often (but not always!) async. We want the latest value.\n const isStart = !isNum(lastX);\n\n if (isStart) {\n // If this is our first move, use the x and y as last coords.\n return {\n deltaX: 0,\n deltaY: 0,\n lastX: x,\n lastY: y,\n x,\n y,\n };\n }\n // Otherwise calculate proper values.\n return {\n deltaX: x - lastX,\n deltaY: y - lastY,\n lastX,\n lastY,\n x,\n y,\n };\n}\n","<template>\n <div\n ref=\"item\"\n class=\"vue-grid-item\"\n :class=\"classObj\"\n :style=\"style\"\n >\n <slot></slot>\n <span\n v-if=\"resizableAndNotStatic\"\n ref=\"handle\"\n :class=\"resizableHandleClass\"\n ></span>\n <!--<span v-if=\"draggable\" ref=\"dragHandle\" class=\"vue-draggable-handle\"></span>-->\n </div>\n</template>\n<script setup lang=\"ts\">\nimport interact from 'interactjs';\nimport { computed, getCurrentInstance, inject, onBeforeUnmount, onMounted, ref, watch } from 'vue';\nimport { getDocumentDir } from '../helpers/dom';\nimport { createCoreData, getControlPosition } from '../helpers/draggable-utils';\nimport { setTopLeft, setTopRight, setTransform, setTransformRtl } from '../helpers/utils';\nimport type { Layout, LayoutItem } from '../helpers/utils';\ndefineOptions({\n name: 'GridItem',\n});\n\nconst props = withDefaults(defineProps<LayoutItem & { usePercentages?: boolean }>(), {\n isDraggable: null,\n isResizable: null,\n static: false,\n minH: 1,\n minW: 1,\n maxH: Infinity,\n maxW: Infinity,\n dragIgnoreFrom: 'a, button',\n dragAllowFrom: null,\n resizeIgnoreFrom: 'a, button',\n usePercentages: null,\n});\n\nconst emit = defineEmits<{\n (\n e: 'container-resized',\n i: string | number,\n h: number | string,\n w: number | string,\n height: string,\n width: string,\n ): void;\n (\n e: 'resize',\n i: string | number,\n h: number | string,\n w: number | string,\n height: number,\n width: number,\n ): void;\n (\n e: 'resized',\n i: string | number,\n h: number | string,\n w: number | string,\n height: number,\n width: number,\n ): void;\n (e: 'move', i: string | number, x: number | string, y: number | string): void;\n (e: 'moved', i: string | number, x: number | string, y: number | string): void;\n}>();\n\nconst eventBus = inject<any>('eventBus');\nconst injectedUsePercentages = inject<boolean>('usePercentages', false);\nconst layout = inject<Layout>('layout');\n\nconst item = ref<HTMLElement | null>(null);\nconst handle = ref<HTMLElement | null>(null);\n\nconst cols = ref(1);\nconst containerWidth = ref(100);\nconst containerHeight = ref(100);\nconst rowHeight = ref(10);\nconst margin = ref([10, 10]);\nconst maxRows = ref(Infinity);\nconst draggable = ref<boolean | null>(null);\nconst resizable = ref<boolean | null>(null);\nconst useCssTransforms = ref(true);\nconst isDragging = ref(false);\nconst dragging = ref<any>(null);\nconst isResizing = ref(false);\nconst resizing = ref<any>(null);\nconst lastX = ref(NaN);\nconst lastY = ref(NaN);\nconst lastW = ref(NaN);\nconst lastH = ref(NaN);\nconst style = ref<Record<string, any>>({});\nconst rtl = ref(false);\nconst dragEventSet = ref(false);\nconst resizeEventSet = ref(false);\nconst previousW = ref<number | string | null>(null);\nconst previousH = ref<number | string | null>(null);\nconst previousX = ref<number | string | null>(null);\nconst previousY = ref<number | string | null>(null);\nconst innerX = ref<number | string>(props.x);\nconst innerY = ref<number | string>(props.y);\nconst innerW = ref<number | string>(props.w);\nconst innerH = ref<number | string>(props.h);\nconst interactObj = ref<any>(null);\n\nconst getVal = (v: number | string): number => (typeof v === 'number' ? v : parseFloat(v) || 0);\n\nconst parseUnit = (val: string | number | undefined, pos?: string | number): string => {\n if (val === undefined || val === null) return '0%';\n if (typeof val === 'number') return val + '%';\n if (val.endsWith('%') || val.endsWith('px') || val.includes('calc')) return val;\n if (val === 'grow') {\n if (pos !== undefined) {\n const p = typeof pos === 'number' ? pos + '%' : pos;\n return `calc(100% - ${p})`;\n }\n return '100%';\n }\n return val.includes('%') || val.includes('px') || val.includes('calc') ? val : val + '%';\n};\n\nconst usePercentagesInternal = computed(() => {\n return props.usePercentages !== null ? props.usePercentages : injectedUsePercentages;\n});\n\nconst resizableAndNotStatic = computed(() => {\n return resizable.value && !props.static;\n});\n\nconst draggableOrResizableAndNotStatic = computed(() => {\n return (draggable.value || resizable.value) && !props.static;\n});\n\nconst isAndroid = computed(() => {\n return navigator.userAgent.toLowerCase().indexOf('android') !== -1;\n});\n\nconst renderRtl = computed(() => {\n const instance = getCurrentInstance();\n const parent = instance?.parent?.proxy as any;\n return parent?.isMirrored ? !rtl.value : rtl.value;\n});\n\nconst classObj = computed(() => {\n return {\n 'vue-resizable': resizableAndNotStatic.value,\n static: props.static,\n resizing: isResizing.value,\n 'vue-draggable-dragging': isDragging.value,\n cssTransforms: useCssTransforms.value,\n 'render-rtl': renderRtl.value,\n 'disable-userselect': isDragging.value,\n 'no-touch': isAndroid.value && draggableOrResizableAndNotStatic.value,\n };\n});\n\nconst resizableHandleClass = computed(() => {\n if (renderRtl.value) {\n return 'vue-resizable-handle vue-rtl-resizable-handle';\n }\n return 'vue-resizable-handle';\n});\n\nconst calcColWidth = () => {\n return (containerWidth.value - (margin.value[0] || 10) * (cols.value + 1)) / cols.value;\n};\n\nconst calcPosition = (\n x: number | string,\n y: number | string,\n w: number | string,\n h: number | string,\n) => {\n if (usePercentagesInternal.value) {\n const out: any = {\n width: parseUnit(w, x),\n height: parseUnit(h, y),\n top: parseUnit(y),\n };\n if (renderRtl.value) {\n out.right = parseUnit(x);\n } else {\n out.left = parseUnit(x);\n }\n return out;\n }\n\n const colWidth = calcColWidth();\n let out: any = null;\n const nx = getVal(x);\n const ny = getVal(y);\n const nw = getVal(w);\n const nh = getVal(h);\n\n if (renderRtl.value) {\n out = {\n right:\n typeof x === 'string' && (x.includes('calc') || x.includes('px'))\n ? x\n : Math.round(colWidth * nx + (nx + 1) * margin.value[0]),\n top:\n typeof y === 'string' && (y.includes('calc') || y.includes('px'))\n ? y\n : Math.round(rowHeight.value * ny + (ny + 1) * margin.value[1]),\n width:\n typeof w === 'string' && (w.includes('calc') || w.includes('px'))\n ? w\n : nw === Infinity\n ? nw\n : Math.round(colWidth * nw + Math.max(0, nw - 1) * margin.value[0]),\n height:\n typeof h === 'string' && (h.includes('calc') || h.includes('px'))\n ? h\n : nh === Infinity\n ? nh\n : Math.round(rowHeight.value * nh + Math.max(0, nh - 1) * margin.value[1]),\n };\n } else {\n out = {\n left:\n typeof x === 'string' && (x.includes('calc') || x.includes('px'))\n ? x\n : Math.round(colWidth * nx + (nx + 1) * margin.value[0]),\n top:\n typeof y === 'string' && (y.includes('calc') || y.includes('px'))\n ? y\n : Math.round(rowHeight.value * ny + (ny + 1) * margin.value[1]),\n width:\n typeof w === 'string' && (w.includes('calc') || w.includes('px'))\n ? w\n : nw === Infinity\n ? nw\n : Math.round(colWidth * nw + Math.max(0, nw - 1) * margin.value[0]),\n height:\n typeof h === 'string' && (h.includes('calc') || h.includes('px'))\n ? h\n : nh === Infinity\n ? nh\n : Math.round(rowHeight.value * nh + Math.max(0, nh - 1) * margin.value[1]),\n };\n }\n return out;\n};\n\nconst resolveItemValue = (id: string, prop: 'x' | 'y'): string | number => {\n if (!layout) return 0;\n const item = (layout as any).find((l: any) => l.i === id);\n if (!item) return 0;\n\n if (prop === 'y') {\n if (item.top_i !== undefined && item.top_i !== null) {\n const refItem = (layout as any).find((l: any) => l.i === item.top_i);\n const refY = resolveItemValue(item.top_i, 'y');\n return `calc(${parseUnit(refY)} + ${parseUnit(refItem?.h ?? 0)})`;\n }\n return item.y ?? 0;\n } else {\n if (item.left_i !== undefined && item.left_i !== null) {\n const refItem = (layout as any).find((l: any) => l.i === item.left_i);\n const refX = resolveItemValue(item.left_i, 'x');\n return `calc(${parseUnit(refX)} + ${parseUnit(refItem?.w ?? 0)})`;\n }\n return item.x ?? 0;\n }\n};\n\nconst createStyle = () => {\n if (!usePercentagesInternal.value) {\n const px = getVal(props.x);\n const pw = getVal(props.w);\n if (px + pw > cols.value) {\n innerX.value = 0;\n innerW.value = pw > cols.value ? cols.value : pw;\n } else {\n innerX.value = props.x;\n innerW.value = props.w;\n }\n } else {\n innerX.value = props.x;\n innerW.value = props.w;\n }\n\n const actualX = resolveItemValue(String(props.i), 'x');\n const actualY = resolveItemValue(String(props.i), 'y');\n\n const pos = calcPosition(actualX, actualY, innerW.value, innerH.value);\n if (isDragging.value) {\n pos.top = dragging.value.top;\n if (typeof pos.top === 'number') pos.top += 'px';\n if (renderRtl.value) {\n pos.right = dragging.value.left;\n if (typeof pos.right === 'number') pos.right += 'px';\n } else {\n pos.left = dragging.value.left;\n if (typeof pos.left === 'number') pos.left += 'px';\n }\n }\n if (isResizing.value) {\n pos.width = resizing.value.width;\n if (typeof pos.width === 'number') pos.width += 'px';\n pos.height = resizing.value.height;\n if (typeof pos.height === 'number') pos.height += 'px';\n }\n let s: any = null;\n\n if (useCssTransforms.value && (isDragging.value || isResizing.value)) {\n const getPx = (v: any, containerSize: number) => {\n if (typeof v === 'number') return v;\n if (typeof v !== 'string') return 0;\n if (v.endsWith('%')) return (parseFloat(v) / 100) * containerSize;\n if (v.endsWith('px')) return parseFloat(v);\n if (v.includes('calc')) {\n // Simple heuristic for calc(100% - pos)\n if (v.includes('100%')) {\n const parts = v.split('-');\n if (parts.length > 1) {\n return containerSize - getPx(parts[1].trim().replace(')', ''), containerSize);\n }\n }\n }\n return parseFloat(v) || 0;\n };\n\n const topPx = getPx(pos.top, containerHeight.value);\n const widthPx = getPx(pos.width, containerWidth.value);\n const heightPx = getPx(pos.height, containerHeight.value);\n\n if (renderRtl.value) {\n const rightPx = getPx(pos.right, containerWidth.value);\n s = setTransformRtl(topPx, rightPx, widthPx, heightPx);\n } else {\n const leftPx = getPx(pos.left, containerWidth.value);\n s = setTransform(topPx, leftPx, widthPx, heightPx);\n }\n } else if (useCssTransforms.value && !usePercentagesInternal.value) {\n if (renderRtl.value) {\n s = setTransformRtl(pos.top, pos.right!, pos.width, pos.height);\n } else {\n s = setTransform(pos.top, pos.left!, pos.width, pos.height);\n }\n } else {\n if (renderRtl.value) {\n s = setTopRight(pos.top, pos.right!, pos.width, pos.height);\n } else {\n s = setTopLeft(pos.top, pos.left!, pos.width, pos.height);\n }\n }\n\n for (const key of ['top', 'left', 'right', 'width', 'height']) {\n if (s[key] !== undefined && typeof s[key] === 'number') {\n s[key] += 'px';\n }\n }\n\n style.value = s;\n};\n\nconst emitContainerResized = () => {\n const styleProps: any = {};\n for (const prop of ['width', 'height']) {\n let val = style.value[prop];\n if (typeof val === 'string' && (val.includes('calc') || val.includes('%'))) {\n if (item.value) {\n val = prop === 'width' ? item.value.offsetWidth + 'px' : item.value.offsetHeight + 'px';\n } else {\n return;\n }\n }\n const matches = String(val).match(/^(\\d+(\\.\\d+)?)px$/);\n if (!matches) return;\n styleProps[prop] = matches[1];\n }\n emit('container-resized', props.i, props.h, props.w, styleProps.height, styleProps.width);\n};\n\nconst calcXY = (top: number, left: number) => {\n if (usePercentagesInternal.value) {\n let x = (left / containerWidth.value) * 100;\n let y = (top / containerHeight.value) * 100;\n\n x = Math.max(Math.min(x, 100 - getVal(innerW.value)), 0);\n y = Math.max(Math.min(y, 100 - getVal(innerH.value)), 0);\n return { x, y };\n }\n\n const colWidth = calcColWidth();\n let x = Math.round((left - margin.value[0]) / (colWidth + margin.value[0]));\n let y = Math.round((top - margin.value[1]) / (rowHeight.value + margin.value[1]));\n x = Math.max(Math.min(x, cols.value - getVal(innerW.value)), 0);\n y = Math.max(Math.min(y, maxRows.value - getVal(innerH.value)), 0);\n return { x, y };\n};\n\nconst calcWH = (height: number, width: number, autoSizeFlag = false) => {\n if (usePercentagesInternal.value) {\n let w = (width / containerWidth.value) * 100;\n let h = (height / containerHeight.value) * 100;\n\n w = Math.max(Math.min(w, 100 - getVal(innerX.value)), 0);\n h = Math.max(Math.min(h, 100 - getVal(innerY.value)), 0);\n return { w, h };\n }\n\n const colWidth = calcColWidth();\n let w = Math.round((width + margin.value[0]) / (colWidth + margin.value[0]));\n let h = 0;\n if (!autoSizeFlag) {\n h = Math.round((height + margin.value[1]) / (rowHeight.value + margin.value[1]));\n } else {\n h = Math.ceil((height + margin.value[1]) / (rowHeight.value + margin.value[1]));\n }\n w = Math.max(Math.min(w, cols.value - getVal(innerX.value)), 0);\n h = Math.max(Math.min(h, maxRows.value - getVal(innerY.value)), 0);\n return { w, h };\n};\n\nconst handleDrag = (event: any) => {\n if (props.static) return;\n if (isResizing.value) return;\n const position = getControlPosition(event);\n if (position === null) return;\n const { x, y } = position;\n const newPosition = { top: 0, left: 0 };\n switch (event.type) {\n case 'dragstart': {\n previousX.value = innerX.value;\n previousY.value = innerY.value;\n const parentRect = event.target.offsetParent.getBoundingClientRect();\n const clientRect = event.target.getBoundingClientRect();\n if (renderRtl.value) {\n newPosition.left = (clientRect.right - parentRect.right) * -1;\n } else {\n newPosition.left = clientRect.left - parentRect.left;\n }\n newPosition.top = clientRect.top - parentRect.top;\n dragging.value = newPosition;\n isDragging.value = true;\n break;\n }\n case 'dragend': {\n if (!isDragging.value) return;\n const parentRect = event.target.offsetParent.getBoundingClientRect();\n const clientRect = event.target.getBoundingClientRect();\n if (renderRtl.value) {\n newPosition.left = (clientRect.right - parentRect.right) * -1;\n } else {\n newPosition.left = clientRect.left - parentRect.left;\n }\n newPosition.top = clientRect.top - parentRect.top;\n dragging.value = null;\n isDragging.value = false;\n break;\n }\n case 'dragmove': {\n const coreEvent = createCoreData(lastX.value, lastY.value, x, y);\n if (renderRtl.value) {\n newPosition.left = dragging.value.left - coreEvent.deltaX;\n } else {\n newPosition.left = dragging.value.left + coreEvent.deltaX;\n }\n newPosition.top = dragging.value.top + coreEvent.deltaY;\n dragging.value = newPosition;\n break;\n }\n }\n let pos = calcXY(newPosition.top, newPosition.left);\n lastX.value = x;\n lastY.value = y;\n if (getVal(innerX.value) !== pos.x || getVal(innerY.value) !== pos.y) {\n emit('move', props.i, pos.x, pos.y);\n }\n if (\n event.type === 'dragend' &&\n (getVal(previousX.value!) !== pos.x || getVal(previousY.value!) !== pos.y)\n ) {\n emit('moved', props.i, pos.x, pos.y);\n }\n if (usePercentagesInternal.value) {\n eventBus.emit('dragEvent', {\n eventType: event.type,\n i: props.i,\n x: pos.x,\n y: pos.y,\n h: innerH.value,\n w: innerW.value,\n });\n } else {\n eventBus.emit('dragEvent', {\n eventType: event.type,\n i: props.i,\n x: pos.x,\n y: pos.y,\n h: getVal(innerH.value),\n w: getVal(innerW.value),\n });\n }\n};\n\nconst handleResize = (event: any) => {\n if (props.static) return;\n const position = getControlPosition(event);\n if (position == null) return;\n const { x, y } = position;\n const newSize = { width: 0, height: 0 };\n let posStyle: any = null;\n switch (event.type) {\n case 'resizestart': {\n previousW.value = innerW.value;\n previousH.value = innerH.value;\n posStyle = calcPosition(innerX.value, innerY.value, innerW.value, innerH.value);\n\n const getPx = (v: any, containerSize: number) => {\n if (typeof v === 'number') return v;\n if (typeof v !== 'string') return 0;\n if (v.endsWith('%')) return (parseFloat(v) / 100) * containerSize;\n if (v.endsWith('px')) return parseFloat(v);\n return parseFloat(v) || 0;\n };\n\n newSize.width = getPx(posStyle.width, containerWidth.value);\n newSize.height = getPx(posStyle.height, containerHeight.value);\n\n resizing.value = newSize;\n isResizing.value = true;\n break;\n }\n case 'resizemove': {\n const coreEvent = createCoreData(lastW.value, lastH.value, x, y);\n if (renderRtl.value) {\n newSize.width = resizing.value.width - coreEvent.deltaX;\n } else {\n newSize.width = resizing.value.width + coreEvent.deltaX;\n }\n newSize.height = resizing.value.height + coreEvent.deltaY;\n resizing.value = newSize;\n break;\n }\n case 'resizeend': {\n posStyle = calcPosition(innerX.value, innerY.value, innerW.value, innerH.value);\n\n const getPx = (v: any, containerSize: number) => {\n if (typeof v === 'number') return v;\n if (typeof v !== 'string') return 0;\n if (v.endsWith('%')) return (parseFloat(v) / 100) * containerSize;\n if (v.endsWith('px')) return parseFloat(v);\n return parseFloat(v) || 0;\n };\n\n newSize.width = getPx(posStyle.width, containerWidth.value);\n newSize.height = getPx(posStyle.height, containerHeight.value);\n\n resizing.value = null;\n isResizing.value = false;\n break;\n }\n }\n const pos = calcWH(newSize.height, newSize.width);\n if (!usePercentagesInternal.value) {\n if (pos.w < props.minW) pos.w = props.minW;\n if (pos.w > props.maxW) pos.w = props.maxW;\n if (pos.h < props.minH) pos.h = props.minH;\n if (pos.h > props.maxH) pos.h = props.maxH;\n if (pos.h < 1) pos.h = 1;\n if (pos.w < 1) pos.w = 1;\n }\n lastW.value = x;\n lastH.value = y;\n if (getVal(innerW.value) !== pos.w || getVal(innerH.value) !== pos.h) {\n emit('resize', props.i, pos.h, pos.w, newSize.height, newSize.width);\n }\n if (\n event.type === 'resizeend' &&\n (getVal(previousW.value!) !== pos.w || getVal(previousH.value!) !== pos.h)\n ) {\n emit('resized', props.i, pos.h, pos.w, newSize.height, newSize.width);\n }\n eventBus.emit('resizeEvent', {\n eventType: event.type,\n i: props.i,\n x: getVal(innerX.value),\n y: getVal(innerY.value),\n h: pos.h,\n w: pos.w,\n });\n};\n\nconst tryMakeDraggable = () => {\n if (interactObj.value === null || interactObj.value === undefined) {\n interactObj.value = interact(item.value as any);\n }\n if (draggable.value && !props.static) {\n const opts = {\n ignoreFrom: props.dragIgnoreFrom,\n allowFrom: props.dragAllowFrom,\n };\n interactObj.value.draggable(opts);\n if (!dragEventSet.value) {\n dragEventSet.value = true;\n interactObj.value.on('dragstart dragmove dragend', (event: any) => {\n handleDrag(event);\n });\n }\n } else {\n interactObj.value.draggable({\n enabled: false,\n });\n }\n};\n\nconst tryMakeResizable = () => {\n if (interactObj.value === null || interactObj.value === undefined) {\n interactObj.value = interact(item.value as any);\n }\n if (resizable.value && !props.static) {\n let maximumPx: any;\n let minimumPx: any;\n\n if (usePercentagesInternal.value) {\n maximumPx = {\n width: (props.maxW / 100) * containerWidth.value,\n height: (props.maxH / 100) * containerHeight.value,\n };\n minimumPx = {\n width: (props.minW / 100) * containerWidth.value,\n height: (props.minH / 100) * containerHeight.value,\n };\n } else {\n const maximum = calcPosition(0, 0, props.maxW, props.maxH);\n const minimum = calcPosition(0, 0, props.minW, props.minH);\n maximumPx = {\n width: parseFloat(maximum.width),\n height: parseFloat(maximum.height),\n };\n minimumPx = {\n width: parseFloat(minimum.width),\n height: parseFloat(minimum.height),\n };\n }\n\n const opts = {\n preserveAspectRatio: true,\n edges: {\n left: false,\n right: '.' + resizableHandleClass.value,\n bottom: '.' + resizableHandleClass.value,\n top: false,\n },\n ignoreFrom: props.resizeIgnoreFrom,\n restrictSize: {\n min: minimumPx,\n max: maximumPx,\n },\n };\n interactObj.value.resizable(opts);\n if (!resizeEventSet.value) {\n resizeEventSet.value = true;\n interactObj.value.on('resizestart resizemove resizeend', (event: any) => {\n handleResize(event);\n });\n }\n } else {\n interactObj.value.resizable({\n enabled: false,\n });\n }\n};\n\nconst updateWidth = (width: number, colNum?: number) => {\n containerWidth.value = width || 100;\n if (colNum !== undefined && colNum !== null) {\n cols.value = colNum;\n }\n if (item.value && item.value.parentElement) {\n containerHeight.value = item.value.parentElement.offsetHeight || 100;\n }\n};\n\nconst compact = () => {\n createStyle();\n};\n\nconst autoSize = () => {\n previousW.value = innerW.value;\n previousH.value = innerH.value;\n if (item.value && item.value.firstElementChild) {\n const newSize = item.value.firstElementChild.getBoundingClientRect();\n const pos = calcWH(newSize.height, newSize.width, true);\n if (!usePercentagesInternal.value) {\n if (pos.w < props.minW) pos.w = props.minW;\n if (pos.w > props.maxW) pos.w = props.maxW;\n if (pos.h < props.minH) pos.h = props.minH;\n if (pos.h > props.maxH) pos.h = props.maxH;\n if (pos.h < 1) pos.h = 1;\n if (pos.w < 1) pos.w = 1;\n }\n if (getVal(innerW.value) !== pos.w || getVal(innerH.value) !== pos.h) {\n emit('resize', props.i, pos.h, pos.w, newSize.height, newSize.width);\n }\n if (getVal(previousW.value!) !== pos.w || getVal(previousH.value!) !== pos.h) {\n emit('resized', props.i, pos.h, pos.w, newSize.height, newSize.width);\n eventBus.emit('resizeEvent', {\n eventType: 'resizeend',\n i: props.i,\n x: getVal(innerX.value),\n y: getVal(innerY.value),\n h: pos.h,\n w: pos.w,\n });\n }\n }\n};\n\nconst updateWidthHandler = (width: number) => {\n updateWidth(width);\n};\nconst compactHandler = () => {\n compact();\n};\nconst setDraggableHandler = (isDraggable: boolean) => {\n if (props.isDraggable === null) {\n draggable.value = isDraggable;\n }\n};\nconst setResizableHandler = (isResizable: boolean) => {\n if (props.isResizable === null) {\n resizable.value = isResizable;\n }\n};\nconst setRowHeightHandler = (val: number) => {\n rowHeight.value = val;\n};\nconst setMaxRowsHandler = (val: number) => {\n maxRows.value = val;\n};\nconst directionchangeHandler = () => {\n rtl.value = getDocumentDir() === 'rtl';\n compact();\n};\nconst setColNum = (colNum: any) => {\n cols.value = parseInt(colNum, 10);\n};\n\nonMounted(() => {\n const instance = getCurrentInstance();\n const parent = instance?.parent?.proxy as any;\n\n cols.value = parent.colNum;\n rowHeight.value = parent.rowHeight;\n containerWidth.value = parent.width !== null && parent.width !== 0 ? parent.width : 100;\n margin.value = parent.margin !== undefined ? parent.margin : [10, 10];\n maxRows.value = parent.maxRows;\n\n if (item.value && item.value.parentElement) {\n containerHeight.value = item.value.parentElement.offsetHeight || 100;\n if (containerWidth.value === 100) {\n containerWidth.value = item.value.parentElement.offsetWidth || 100;\n }\n }\n\n if (props.isDraggable === null) {\n draggable.value = parent.isDraggable;\n } else {\n draggable.value = props.isDraggable;\n }\n if (props.isResizable === null) {\n resizable.value = parent.isResizable;\n } else {\n resizable.value = props.isResizable;\n }\n useCssTransforms.value = parent.useCssTransforms;\n\n eventBus.on('updateWidth', updateWidthHandler);\n eventBus.on('compact', compactHandler);\n eventBus.on('setDraggable', setDraggableHandler);\n eventBus.on('setResizable', setResizableHandler);\n eventBus.on('setRowHeight', setRowHeightHandler);\n eventBus.on('setMaxRows', setMaxRowsHandler);\n eventBus.on('directionchange', directionchangeHandler);\n eventBus.on('setColNum', setColNum);\n rtl.value = getDocumentDir() === 'rtl';\n\n createStyle();\n});\n\nonBeforeUnmount(() => {\n eventBus.off('updateWidth', updateWidthHandler);\n eventBus.off('compact', compactHandler);\n eventBus.off('setDraggable', setDraggableHandler);\n eventBus.off('setResizable', setResizableHandler);\n eventBus.off('setRowHeight', setRowHeightHandler);\n eventBus.off('setMaxRows', setMaxRowsHandler);\n eventBus.off('directionchange', directionchangeHandler);\n eventBus.off('setColNum', setColNum);\n if (interactObj.value) {\n interactObj.value.unset();\n }\n});\n\nwatch(\n () => props.isDraggable,\n () => {\n draggable.value = props.isDraggable;\n },\n);\n\nwatch(\n () => props.static,\n () => {\n tryMakeDraggable();\n tryMakeResizable();\n },\n);\n\nwatch(draggable, () => {\n tryMakeDraggable();\n});\n\nwatch(\n () => props.isResizable,\n () => {\n resizable.value = props.isResizable;\n },\n);\n\nwatch(resizable, () => {\n tryMakeResizable();\n});\n\nwatch(rowHeight, () => {\n createStyle();\n emitContainerResized();\n});\n\nwatch(cols, () => {\n tryMakeResizable();\n createStyle();\n emitContainerResized();\n});\n\nwatch(containerWidth, () => {\n tryMakeResizable();\n createStyle();\n emitContainerResized();\n});\n\nwatch(containerHeight, () => {\n tryMakeResizable();\n createStyle();\n emitContainerResized();\n});\n\nwatch(\n () => props.x,\n newVal => {\n innerX.value = newVal;\n createStyle();\n },\n);\n\nwatch(\n () => props.y,\n newVal => {\n innerY.value = newVal;\n createStyle();\n },\n);\n\nwatch(\n () => props.h,\n newVal => {\n innerH.value = newVal;\n createStyle();\n },\n);\n\nwatch(\n () => props.w,\n newVal => {\n innerW.value = newVal;\n createStyle();\n },\n);\n\nwatch(renderRtl, () => {\n tryMakeResizable();\n createStyle();\n});\n\nwatch(\n () => props.minH,\n () => {\n tryMakeResizable();\n },\n);\n\nwatch(\n () => props.maxH,\n () => {\n tryMakeResizable();\n },\n);\n\nwatch(\n () => props.minW,\n () => {\n tryMakeResizable();\n },\n);\n\nwatch(\n () => props.maxW,\n () => {\n tryMakeResizable();\n },\n);\n\nwatch(\n () => {\n const instance = getCurrentInstance();\n const parent = instance?.parent?.proxy as any;\n return parent?.margin;\n },\n val => {\n if (!val || (val[0] === margin.value[0] && val[1] === margin.value[1])) {\n return;\n }\n margin.value = val.map((m: any) => Number(m));\n createStyle();\n emitContainerResized();\n },\n);\n\ndefineExpose({\n autoSize,\n compact,\n updateWidth,\n});\n</script>\n\n<style>\n.vue-grid-item {\n transition: none;\n transition-property: left, top, right;\n /* add right for rtl */\n}\n.vue-grid-item.no-touch {\n -ms-touch-action: none;\n touch-action: none;\n}\n\n.vue-grid-item.cssTransforms {\n right: auto;\n left: 0;\n transition-property: transform;\n}\n\n.vue-grid-item.cssTransforms.render-rtl {\n right: 0;\n left: auto;\n}\n\n.vue-grid-item.resizing {\n z-index: 3;\n opacity: 0.6;\n}\n\n.vue-grid-item.vue-draggable-dragging {\n z-index: 3;\n transition: none;\n}\n\n.vue-grid-item.vue-grid-placeholder {\n z-index: 2;\n background: pink;\n transition-duration: 100ms;\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n -o-user-select: none;\n user-select: none;\n}\n\n.vue-grid-item > .vue-resizable-handle {\n position: absolute;\n right: 0;\n bottom: 0;\n box-sizing: border-box;\n width: 20px;\n height: 20px;\n padding: 0 3px 3px 0;\n background: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/Pg08IS0tIEdlbmVyYXRvcjogQWRvYmUgRmlyZXdvcmtzIENTNiwgRXhwb3J0IFNWRyBFeHRlbnNpb24gYnkgQWFyb24gQmVhbGwgKGh0dHA6Ly9maXJld29ya3MuYWJlYWxsLmNvbSkgLiBWZXJzaW9uOiAwLjYuMSAgLS0+DTwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+DTxzdmcgaWQ9IlVudGl0bGVkLVBhZ2UlMjAxIiB2aWV3Qm94PSIwIDAgNiA2IiBzdHlsZT0iYmFja2dyb3VuZC1jb2xvcjojZmZmZmZmMDAiIHZlcnNpb249IjEuMSINCXhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHhtbDpzcGFjZT0icHJlc2VydmUiDQl4PSIwcHgiIHk9IjBweCIgd2lkdGg9IjZweCIgaGVpZ2h0PSI2cHgiDT4NCTxnIG9wYWNpdHk9IjAuMzAyIj4NCQk8cGF0aCBkPSJNIDYgNiBMIDAgNiBMIDAgNC4yIEwgNCA0LjIgTCA0LjIgNC4yIEwgNC4yIDAgTCA2IDAgTCA2IDYgTCA2IDYgWiIgZmlsbD0iIzAwMDAwMCIvPg0JPC9nPg08L3N2Zz4=');\n background-repeat: no-repeat;\n background-position: bottom right;\n background-origin: content-box;\n cursor: se-resize;\n}\n\n.vue-grid-item > .vue-rtl-resizable-handle {\n right: auto;\n bottom: 0;\n left: 0;\n padding-left: 3px;\n background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTAuMDAwMDAwMDAwMDAwMDAyIiBoZWlnaHQ9IjEwLjAwMDAwMDAwMDAwMDAwMiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KIDwhLS0gQ3JlYXRlZCB3aXRoIE1ldGhvZCBEcmF3IC0gaHR0cDovL2dpdGh1Yi5jb20vZHVvcGl4ZWwvTWV0aG9kLURyYXcvIC0tPgogPGc+CiAgPHRpdGxlPmJhY2tncm91bmQ8L3RpdGxlPgogIDxyZWN0IGZpbGw9Im5vbmUiIGlkPSJjYW52YXNfYmFja2dyb3VuZCIgaGVpZ2h0PSIxMiIgd2lkdGg9IjEyIiB5PSItMSIgeD0iLTEiLz4KICA8ZyBkaXNwbGF5PSJub25lIiBvdmVyZmxvdz0idmlzaWJsZSIgeT0iMCIgeD0iMCIgaGVpZ2h0PSIxMDAlIiB3aWR0aD0iMTAwJSIgaWQ9ImNhbnZhc0dyaWQiPgogICA8cmVjdCBmaWxsPSJ1cmwoI2dyaWRwYXR0ZXJuKSIgc3Ryb2tlLXdpZHRoPSIwIiB5PSIwIiB4PSIwIiBoZWlnaHQ9IjEwMCUiIHdpZHRoPSIxMDAlIi8+CiAgPC9nPgogPC9nPgogPGc+CiAgPHRpdGxlPkxheWVyIDE8L3RpdGxlPgogIDxsaW5lIGNhbnZhcz0iI2ZmZmZmZiIgY2FudmFzLW9wYWNpdHk9IjEiIHN0cm9rZS1saW5lY2FwPSJ1bmRlZmluZWQiIHN0cm9rZS1saW5lam9pbj0idW5kZWZpbmVkIiBpZD0ic3ZnXzEiIHkyPSItNzAuMTc4NDA3IiB4Mj0iMTI0LjQ2NDA3NSIgeTE9Ii0zOC4zOTI3MzciIHgxPSIxNDQuODIxMjg5IiBzdHJva2Utd2lkdGg9IjEuNSIgc3Ryb2tlPSIjMDAwIiBmaWxsPSJub25lIi8+CiAgPGxpbmUgc3Ryb2tlPSIjNjY2NjY2IiBzdHJva2UtbGluZWNhcD0idW5kZWZpbmVkIiBzdHJva2UtbGluZWpvaW49InVuZGVmaW5lZCIgaWQ9InN2Z181IiB5Mj0iOS4xMDY5NTciIHgyPSIwLjk0NzI0NyIgeTE9Ii0wLjAxODEyOCIgeDE9IjAuOTQ3MjQ3IiBzdHJva2Utd2lkdGg9IjIiIGZpbGw9Im5vbmUiLz4KICA8bGluZSBzdHJva2UtbGluZWNhcD0idW5kZWZpbmVkIiBzdHJva2UtbGluZWpvaW49InVuZGVmaW5lZCIgaWQ9InN2Z183IiB5Mj0iOSIgeDI9IjEwLjA3MzUyOSIgeTE9IjkiIHgxPSItMC42NTU2NCIgc3Ryb2tlLXdpZHRoPSIwIiBzdHJva2U9IiM2NjY2NjYiIGZpbGw9Im5vbmUiLz4KIDwvZz4KPC9zdmc+);\n background-repeat: no-repeat;\n background-position: bottom left;\n background-origin: content-box;\n cursor: sw-resize;\n}\n\n.vue-grid-item.disable-userselect {\n user-select: none;\n}\n</style>\n","<template>\n <div\n ref=\"item\"\n class=\"vue-grid-item\"\n :class=\"classObj\"\n :style=\"style\"\n >\n <slot></slot>\n <span\n v-if=\"resizableAndNotStatic\"\n ref=\"handle\"\n :class=\"resizableHandleClass\"\n ></span>\n <!--<span v-if=\"draggable\" ref=\"dragHandle\" class=\"vue-draggable-handle\"></span>-->\n </div>\n</template>\n<script setup lang=\"ts\">\nimport interact from 'interactjs';\nimport { computed, getCurrentInstance, inject, onBeforeUnmount, onMounted, ref, watch } from 'vue';\nimport { getDocumentDir } from '../helpers/dom';\nimport { createCoreData, getControlPosition } from '../helpers/draggable-utils';\nimport { setTopLeft, setTopRight, setTransform, setTransformRtl } from '../helpers/utils';\nimport type { Layout, LayoutItem } from '../helpers/utils';\ndefineOptions({\n name: 'GridItem',\n});\n\nconst props = withDefaults(defineProps<LayoutItem & { usePercentages?: boolean }>(), {\n isDraggable: null,\n isResizable: null,\n static: false,\n minH: 1,\n minW: 1,\n maxH: Infinity,\n maxW: Infinity,\n dragIgnoreFrom: 'a, button',\n dragAllowFrom: null,\n resizeIgnoreFrom: 'a, button',\n usePercentages: null,\n});\n\nconst emit = defineEmits<{\n (\n e: 'container-resized',\n i: string | number,\n h: number | string,\n w: number | string,\n height: string,\n width: string,\n ): void;\n (\n e: 'resize',\n i: string | number,\n h: number | string,\n w: number | string,\n height: number,\n width: number,\n ): void;\n (\n e: 'resized',\n i: string | number,\n h: number | string,\n w: number | string,\n height: number,\n width: number,\n ): void;\n (e: 'move', i: string | number, x: number | string, y: number | string): void;\n (e: 'moved', i: string | number, x: number | string, y: number | string): void;\n}>();\n\nconst eventBus = inject<any>('eventBus');\nconst injectedUsePercentages = inject<boolean>('usePercentages', false);\nconst layout = inject<Layout>('layout');\n\nconst item = ref<HTMLElement | null>(null);\nconst handle = ref<HTMLElement | null>(null);\n\nconst cols = ref(1);\nconst containerWidth = ref(100);\nconst containerHeight = ref(100);\nconst rowHeight = ref(10);\nconst margin = ref([10, 10]);\nconst maxRows = ref(Infinity);\nconst draggable = ref<boolean | null>(null);\nconst resizable = ref<boolean | null>(null);\nconst useCssTransforms = ref(true);\nconst isDragging = ref(false);\nconst dragging = ref<any>(null);\nconst isResizing = ref(false);\nconst resizing = ref<any>(null);\nconst lastX = ref(NaN);\nconst lastY = ref(NaN);\nconst lastW = ref(NaN);\nconst lastH = ref(NaN);\nconst style = ref<Record<string, any>>({});\nconst rtl = ref(false);\nconst dragEventSet = ref(false);\nconst resizeEventSet = ref(false);\nconst previousW = ref<number | string | null>(null);\nconst previousH = ref<number | string | null>(null);\nconst previousX = ref<number | string | null>(null);\nconst previousY = ref<number | string | null>(null);\nconst innerX = ref<number | string>(props.x);\nconst innerY = ref<number | string>(props.y);\nconst innerW = ref<number | string>(props.w);\nconst innerH = ref<number | string>(props.h);\nconst interactObj = ref<any>(null);\n\nconst getVal = (v: number | string): number => (typeof v === 'number' ? v : parseFloat(v) || 0);\n\nconst parseUnit = (val: string | number | undefined, pos?: string | number): string => {\n if (val === undefined || val === null) return '0%';\n if (typeof val === 'number') return val + '%';\n if (val.endsWith('%') || val.endsWith('px') || val.includes('calc')) return val;\n if (val === 'grow') {\n if (pos !== undefined) {\n const p = typeof pos === 'number' ? pos + '%' : pos;\n return `calc(100% - ${p})`;\n }\n return '100%';\n }\n return val.includes('%') || val.includes('px') || val.includes('calc') ? val : val + '%';\n};\n\nconst usePercentagesInternal = computed(() => {\n return props.usePercentages !== null ? props.usePercentages : injectedUsePercentages;\n});\n\nconst resizableAndNotStatic = computed(() => {\n return resizable.value && !props.static;\n});\n\nconst draggableOrResizableAndNotStatic = computed(() => {\n return (draggable.value || resizable.value) && !props.static;\n});\n\nconst isAndroid = computed(() => {\n return navigator.userAgent.toLowerCase().indexOf('android') !== -1;\n});\n\nconst renderRtl = computed(() => {\n const instance = getCurrentInstance();\n const parent = instance?.parent?.proxy as any;\n return parent?.isMirrored ? !rtl.value : rtl.value;\n});\n\nconst classObj = computed(() => {\n return {\n 'vue-resizable': resizableAndNotStatic.value,\n static: props.static,\n resizing: isResizing.value,\n 'vue-draggable-dragging': isDragging.value,\n cssTransforms: useCssTransforms.value,\n 'render-rtl': renderRtl.value,\n 'disable-userselect': isDragging.value,\n 'no-touch': isAndroid.value && draggableOrResizableAndNotStatic.value,\n };\n});\n\nconst resizableHandleClass = computed(() => {\n if (renderRtl.value) {\n return 'vue-resizable-handle vue-rtl-resizable-handle';\n }\n return 'vue-resizable-handle';\n});\n\nconst calcColWidth = () => {\n return (containerWidth.value - (margin.value[0] || 10) * (cols.value + 1)) / cols.value;\n};\n\nconst calcPosition = (\n x: number | string,\n y: number | string,\n w: number | string,\n h: number | string,\n) => {\n if (usePercentagesInternal.value) {\n const out: any = {\n width: parseUnit(w, x),\n height: parseUnit(h, y),\n top: parseUnit(y),\n };\n if (renderRtl.value) {\n out.right = parseUnit(x);\n } else {\n out.left = parseUnit(x);\n }\n return out;\n }\n\n const colWidth = calcColWidth();\n let out: any = null;\n const nx = getVal(x);\n const ny = getVal(y);\n const nw = getVal(w);\n const nh = getVal(h);\n\n if (renderRtl.value) {\n out = {\n right:\n typeof x === 'string' && (x.includes('calc') || x.includes('px'))\n ? x\n : Math.round(colWidth * nx + (nx + 1) * margin.value[0]),\n top:\n typeof y === 'string' && (y.includes('calc') || y.includes('px'))\n ? y\n : Math.round(rowHeight.value * ny + (ny + 1) * margin.value[1]),\n width:\n typeof w === 'string' && (w.includes('calc') || w.includes('px'))\n ? w\n : nw === Infinity\n ? nw\n : Math.round(colWidth * nw + Math.max(0, nw - 1) * margin.value[0]),\n height:\n typeof h === 'string' && (h.includes('calc') || h.includes('px'))\n ? h\n : nh === Infinity\n ? nh\n : Math.round(rowHeight.value * nh + Math.max(0, nh - 1) * margin.value[1]),\n };\n } else {\n out = {\n left:\n typeof x === 'string' && (x.includes('calc') || x.includes('px'))\n ? x\n : Math.round(colWidth * nx + (nx + 1) * margin.value[0]),\n top:\n typeof y === 'string' && (y.includes('calc') || y.includes('px'))\n ? y\n : Math.round(rowHeight.value * ny + (ny + 1) * margin.value[1]),\n width:\n typeof w === 'string' && (w.includes('calc') || w.includes('px'))\n ? w\n : nw === Infinity\n ? nw\n : Math.round(colWidth * nw + Math.max(0, nw - 1) * margin.value[0]),\n height:\n typeof h === 'string' && (h.includes('calc') || h.includes('px'))\n ? h\n : nh === Infinity\n ? nh\n : Math.round(rowHeight.value * nh + Math.max(0, nh - 1) * margin.value[1]),\n };\n }\n return out;\n};\n\nconst resolveItemValue = (id: string, prop: 'x' | 'y'): string | number => {\n if (!layout) return 0;\n const item = (layout as any).find((l: any) => l.i === id);\n if (!item) return 0;\n\n if (prop === 'y') {\n if (item.top_i !== undefined && item.top_i !== null) {\n const refItem = (layout as any).find((l: any) => l.i === item.top_i);\n const refY = resolveItemValue(item.top_i, 'y');\n return `calc(${parseUnit(refY)} + ${parseUnit(refItem?.h ?? 0)})`;\n }\n return item.y ?? 0;\n } else {\n if (item.left_i !== undefined && item.left_i !== null) {\n const refItem = (layout as any).find((l: any) => l.i === item.left_i);\n const refX = resolveItemValue(item.left_i, 'x');\n return `calc(${parseUnit(refX)} + ${parseUnit(refItem?.w ?? 0)})`;\n }\n return item.x ?? 0;\n }\n};\n\nconst createStyle = () => {\n if (!usePercentagesInternal.value) {\n const px = getVal(props.x);\n const pw = getVal(props.w);\n if (px + pw > cols.value) {\n innerX.value = 0;\n innerW.value = pw > cols.value ? cols.value : pw;\n } else {\n innerX.value = props.x;\n innerW.value = props.w;\n }\n } else {\n innerX.value = props.x;\n innerW.value = props.w;\n }\n\n const actualX = resolveItemValue(String(props.i), 'x');\n const actualY = resolveItemValue(String(props.i), 'y');\n\n const pos = calcPosition(actualX, actualY, innerW.value, innerH.value);\n if (isDragging.value) {\n pos.top = dragging.value.top;\n if (typeof pos.top === 'number') pos.top += 'px';\n if (renderRtl.value) {\n pos.right = dragging.value.left;\n if (typeof pos.right === 'number') pos.right += 'px';\n } else {\n pos.left = dragging.value.left;\n if (typeof pos.left === 'number') pos.left += 'px';\n }\n }\n if (isResizing.value) {\n pos.width = resizing.value.width;\n if (typeof pos.width === 'number') pos.width += 'px';\n pos.height = resizing.value.height;\n if (typeof pos.height === 'number') pos.height += 'px';\n }\n let s: any = null;\n\n if (useCssTransforms.value && (isDragging.value || isResizing.value)) {\n const getPx = (v: any, containerSize: number) => {\n if (typeof v === 'number') return v;\n if (typeof v !== 'string') return 0;\n if (v.endsWith('%')) return (parseFloat(v) / 100) * containerSize;\n if (v.endsWith('px')) return parseFloat(v);\n if (v.includes('calc')) {\n // Simple heuristic for calc(100% - pos)\n if (v.includes('100%')) {\n const parts = v.split('-');\n if (parts.length > 1) {\n return containerSize - getPx(parts[1].trim().replace(')', ''), containerSize);\n }\n }\n }\n return parseFloat(v) || 0;\n };\n\n const topPx = getPx(pos.top, containerHeight.value);\n const widthPx = getPx(pos.width, containerWidth.value);\n const heightPx = getPx(pos.height, containerHeight.value);\n\n if (renderRtl.value) {\n const rightPx = getPx(pos.right, containerWidth.value);\n s = setTransformRtl(topPx, rightPx, widthPx, heightPx);\n } else {\n const leftPx = getPx(pos.left, containerWidth.value);\n s = setTransform(topPx, leftPx, widthPx, heightPx);\n }\n } else if (useCssTransforms.value && !usePercentagesInternal.value) {\n if (renderRtl.value) {\n s = setTransformRtl(pos.top, pos.right!, pos.width, pos.height);\n } else {\n s = setTransform(pos.top, pos.left!, pos.width, pos.height);\n }\n } else {\n if (renderRtl.value) {\n s = setTopRight(pos.top, pos.right!, pos.width, pos.height);\n } else {\n s = setTopLeft(pos.top, pos.left!, pos.width, pos.height);\n }\n }\n\n for (const key of ['top', 'left', 'right', 'width', 'height']) {\n if (s[key] !== undefined && typeof s[key] === 'number') {\n s[key] += 'px';\n }\n }\n\n style.value = s;\n};\n\nconst emitContainerResized = () => {\n const styleProps: any = {};\n for (const prop of ['width', 'height']) {\n let val = style.value[prop];\n if (typeof val === 'string' && (val.includes('calc') || val.includes('%'))) {\n if (item.value) {\n val = prop === 'width' ? item.value.offsetWidth + 'px' : item.value.offsetHeight + 'px';\n } else {\n return;\n }\n }\n const matches = String(val).match(/^(\\d+(\\.\\d+)?)px$/);\n if (!matches) return;\n styleProps[prop] = matches[1];\n }\n emit('container-resized', props.i, props.h, props.w, styleProps.height, styleProps.width);\n};\n\nconst calcXY = (top: number, left: number) => {\n if (usePercentagesInternal.value) {\n let x = (left / containerWidth.value) * 100;\n let y = (top / containerHeight.value) * 100;\n\n x = Math.max(Math.min(x, 100 - getVal(innerW.value)), 0);\n y = Math.max(Math.min(y, 100 - getVal(innerH.value)), 0);\n return { x, y };\n }\n\n const colWidth = calcColWidth();\n let x = Math.round((left - margin.value[0]) / (colWidth + margin.value[0]));\n let y = Math.round((top - margin.value[1]) / (rowHeight.value + margin.value[1]));\n x = Math.max(Math.min(x, cols.value - getVal(innerW.value)), 0);\n y = Math.max(Math.min(y, maxRows.value - getVal(innerH.value)), 0);\n return { x, y };\n};\n\nconst calcWH = (height: number, width: number, autoSizeFlag = false) => {\n if (usePercentagesInternal.value) {\n let w = (width / containerWidth.value) * 100;\n let h = (height / containerHeight.value) * 100;\n\n w = Math.max(Math.min(w, 100 - getVal(innerX.value)), 0);\n h = Math.max(Math.min(h, 100 - getVal(innerY.value)), 0);\n return { w, h };\n }\n\n const colWidth = calcColWidth();\n let w = Math.round((width + margin.value[0]) / (colWidth + margin.value[0]));\n let h = 0;\n if (!autoSizeFlag) {\n h = Math.round((height + margin.value[1]) / (rowHeight.value + margin.value[1]));\n } else {\n h = Math.ceil((height + margin.value[1]) / (rowHeight.value + margin.value[1]));\n }\n w = Math.max(Math.min(w, cols.value - getVal(innerX.value)), 0);\n h = Math.max(Math.min(h, maxRows.value - getVal(innerY.value)), 0);\n return { w, h };\n};\n\nconst handleDrag = (event: any) => {\n if (props.static) return;\n if (isResizing.value) return;\n const position = getControlPosition(event);\n if (position === null) return;\n const { x, y } = position;\n const newPosition = { top: 0, left: 0 };\n switch (event.type) {\n case 'dragstart': {\n previousX.value = innerX.value;\n previousY.value = innerY.value;\n const parentRect = event.target.offsetParent.getBoundingClientRect();\n const clientRect = event.target.getBoundingClientRect();\n if (renderRtl.value) {\n newPosition.left = (clientRect.right - parentRect.right) * -1;\n } else {\n newPosition.left = clientRect.left - parentRect.left;\n }\n newPosition.top = clientRect.top - parentRect.top;\n dragging.value = newPosition;\n isDragging.value = true;\n break;\n }\n case 'dragend': {\n if (!isDragging.value) return;\n const parentRect = event.target.offsetParent.getBoundingClientRect();\n const clientRect = event.target.getBoundingClientRect();\n if (renderRtl.value) {\n newPosition.left = (clientRect.right - parentRect.right) * -1;\n } else {\n newPosition.left = clientRect.left - parentRect.left;\n }\n newPosition.top = clientRect.top - parentRect.top;\n dragging.value = null;\n isDragging.value = false;\n break;\n }\n case 'dragmove': {\n const coreEvent = createCoreData(lastX.value, lastY.value, x, y);\n if (renderRtl.value) {\n newPosition.left = dragging.value.left - coreEvent.deltaX;\n } else {\n newPosition.left = dragging.value.left + coreEvent.deltaX;\n }\n newPosition.top = dragging.value.top + coreEvent.deltaY;\n dragging.value = newPosition;\n break;\n }\n }\n let pos = calcXY(newPosition.top, newPosition.left);\n lastX.value = x;\n lastY.value = y;\n if (getVal(innerX.value) !== pos.x || getVal(innerY.value) !== pos.y) {\n emit('move', props.i, pos.x, pos.y);\n }\n if (\n event.type === 'dragend' &&\n (getVal(previousX.value!) !== pos.x || getVal(previousY.value!) !== pos.y)\n ) {\n emit('moved', props.i, pos.x, pos.y);\n }\n if (usePercentagesInternal.value) {\n eventBus.emit('dragEvent', {\n eventType: event.type,\n i: props.i,\n x: pos.x,\n y: pos.y,\n h: innerH.value,\n w: innerW.value,\n });\n } else {\n eventBus.emit('dragEvent', {\n eventType: event.type,\n i: props.i,\n x: pos.x,\n y: pos.y,\n h: getVal(innerH.value),\n w: getVal(innerW.value),\n });\n }\n};\n\nconst handleResize = (event: any) => {\n if (props.static) return;\n const position = getControlPosition(event);\n if (position == null) return;\n const { x, y } = position;\n const newSize = { width: 0, height: 0 };\n let posStyle: any = null;\n switch (event.type) {\n case 'resizestart': {\n previousW.value = innerW.value;\n previousH.value = innerH.value;\n posStyle = calcPosition(innerX.value, innerY.value, innerW.value, innerH.value);\n\n const getPx = (v: any, containerSize: number) => {\n if (typeof v === 'number') return v;\n if (typeof v !== 'string') return 0;\n if (v.endsWith('%')) return (parseFloat(v) / 100) * containerSize;\n if (v.endsWith('px')) return parseFloat(v);\n return parseFloat(v) || 0;\n };\n\n newSize.width = getPx(posStyle.width, containerWidth.value);\n newSize.height = getPx(posStyle.height, containerHeight.value);\n\n resizing.value = newSize;\n isResizing.value = true;\n break;\n }\n case 'resizemove': {\n const coreEvent = createCoreData(lastW.value, lastH.value, x, y);\n if (renderRtl.value) {\n newSize.width = resizing.value.width - coreEvent.deltaX;\n } else {\n newSize.width = resizing.value.width + coreEvent.deltaX;\n }\n newSize.height = resizing.value.height + coreEvent.deltaY;\n resizing.value = newSize;\n break;\n }\n case 'resizeend': {\n posStyle = calcPosition(innerX.value, innerY.value, innerW.value, innerH.value);\n\n const getPx = (v: any, containerSize: number) => {\n if (typeof v === 'number') return v;\n if (typeof v !== 'string') return 0;\n if (v.endsWith('%')) return (parseFloat(v) / 100) * containerSize;\n if (v.endsWith('px')) return parseFloat(v);\n return parseFloat(v) || 0;\n };\n\n newSize.width = getPx(posStyle.width, containerWidth.value);\n newSize.height = getPx(posStyle.height, containerHeight.value);\n\n resizing.value = null;\n isResizing.value = false;\n break;\n }\n }\n const pos = calcWH(newSize.height, newSize.width);\n if (!usePercentagesInternal.value) {\n if (pos.w < props.minW) pos.w = props.minW;\n if (pos.w > props.maxW) pos.w = props.maxW;\n if (pos.h < props.minH) pos.h = props.minH;\n if (pos.h > props.maxH) pos.h = props.maxH;\n if (pos.h < 1) pos.h = 1;\n if (pos.w < 1) pos.w = 1;\n }\n lastW.value = x;\n lastH.value = y;\n if (getVal(innerW.value) !== pos.w || getVal(innerH.value) !== pos.h) {\n emit('resize', props.i, pos.h, pos.w, newSize.height, newSize.width);\n }\n if (\n event.type === 'resizeend' &&\n (getVal(previousW.value!) !== pos.w || getVal(previousH.value!) !== pos.h)\n ) {\n emit('resized', props.i, pos.h, pos.w, newSize.height, newSize.width);\n }\n eventBus.emit('resizeEvent', {\n eventType: event.type,\n i: props.i,\n x: getVal(innerX.value),\n y: getVal(innerY.value),\n h: pos.h,\n w: pos.w,\n });\n};\n\nconst tryMakeDraggable = () => {\n if (interactObj.value === null || interactObj.value === undefined) {\n interactObj.value = interact(item.value as any);\n }\n if (draggable.value && !props.static) {\n const opts = {\n ignoreFrom: props.dragIgnoreFrom,\n allowFrom: props.dragAllowFrom,\n };\n interactObj.value.draggable(opts);\n if (!dragEventSet.value) {\n dragEventSet.value = true;\n interactObj.value.on('dragstart dragmove dragend', (event: any) => {\n handleDrag(event);\n });\n }\n } else {\n interactObj.value.draggable({\n enabled: false,\n });\n }\n};\n\nconst tryMakeResizable = () => {\n if (interactObj.value === null || interactObj.value === undefined) {\n interactObj.value = interact(item.value as any);\n }\n if (resizable.value && !props.static) {\n let maximumPx: any;\n let minimumPx: any;\n\n if (usePercentagesInternal.value) {\n maximumPx = {\n width: (props.maxW / 100) * containerWidth.value,\n height: (props.maxH / 100) * containerHeight.value,\n };\n minimumPx = {\n width: (props.minW / 100) * containerWidth.value,\n height: (props.minH / 100) * containerHeight.value,\n };\n } else {\n const maximum = calcPosition(0, 0, props.maxW, props.maxH);\n const minimum = calcPosition(0, 0, props.minW, props.minH);\n maximumPx = {\n width: parseFloat(maximum.width),\n height: parseFloat(maximum.height),\n };\n minimumPx = {\n width: parseFloat(minimum.width),\n height: parseFloat(minimum.height),\n };\n }\n\n const opts = {\n preserveAspectRatio: true,\n edges: {\n left: false,\n right: '.' + resizableHandleClass.value,\n bottom: '.' + resizableHandleClass.value,\n top: false,\n },\n ignoreFrom: props.resizeIgnoreFrom,\n restrictSize: {\n min: minimumPx,\n max: maximumPx,\n },\n };\n interactObj.value.resizable(opts);\n if (!resizeEventSet.value) {\n resizeEventSet.value = true;\n interactObj.value.on('resizestart resizemove resizeend', (event: any) => {\n handleResize(event);\n });\n }\n } else {\n interactObj.value.resizable({\n enabled: false,\n });\n }\n};\n\nconst updateWidth = (width: number, colNum?: number) => {\n containerWidth.value = width || 100;\n if (colNum !== undefined && colNum !== null) {\n cols.value = colNum;\n }\n if (item.value && item.value.parentElement) {\n containerHeight.value = item.value.parentElement.offsetHeight || 100;\n }\n};\n\nconst compact = () => {\n createStyle();\n};\n\nconst autoSize = () => {\n previousW.value = innerW.value;\n previousH.value = innerH.value;\n if (item.value && item.value.firstElementChild) {\n const newSize = item.value.firstElementChild.getBoundingClientRect();\n const pos = calcWH(newSize.height, newSize.width, true);\n if (!usePercentagesInternal.value) {\n if (pos.w < props.minW) pos.w = props.minW;\n if (pos.w > props.maxW) pos.w = props.maxW;\n if (pos.h < props.minH) pos.h = props.minH;\n if (pos.h > props.maxH) pos.h = props.maxH;\n if (pos.h < 1) pos.h = 1;\n if (pos.w < 1) pos.w = 1;\n }\n if (getVal(innerW.value) !== pos.w || getVal(innerH.value) !== pos.h) {\n emit('resize', props.i, pos.h, pos.w, newSize.height, newSize.width);\n }\n if (getVal(previousW.value!) !== pos.w || getVal(previousH.value!) !== pos.h) {\n emit('resized', props.i, pos.h, pos.w, newSize.height, newSize.width);\n eventBus.emit('resizeEvent', {\n eventType: 'resizeend',\n i: props.i,\n x: getVal(innerX.value),\n y: getVal(innerY.value),\n h: pos.h,\n w: pos.w,\n });\n }\n }\n};\n\nconst updateWidthHandler = (width: number) => {\n updateWidth(width);\n};\nconst compactHandler = () => {\n compact();\n};\nconst setDraggableHandler = (isDraggable: boolean) => {\n if (props.isDraggable === null) {\n draggable.value = isDraggable;\n }\n};\nconst setResizableHandler = (isResizable: boolean) => {\n if (props.isResizable === null) {\n resizable.value = isResizable;\n }\n};\nconst setRowHeightHandler = (val: number) => {\n rowHeight.value = val;\n};\nconst setMaxRowsHandler = (val: number) => {\n maxRows.value = val;\n};\nconst directionchangeHandler = () => {\n rtl.value = getDocumentDir() === 'rtl';\n compact();\n};\nconst setColNum = (colNum: any) => {\n cols.value = parseInt(colNum, 10);\n};\n\nonMounted(() => {\n const instance = getCurrentInstance();\n const parent = instance?.parent?.proxy as any;\n\n cols.value = parent.colNum;\n rowHeight.value = parent.rowHeight;\n containerWidth.value = parent.width !== null && parent.width !== 0 ? parent.width : 100;\n margin.value = parent.margin !== undefined ? parent.margin : [10, 10];\n maxRows.value = parent.maxRows;\n\n if (item.value && item.value.parentElement) {\n containerHeight.value = item.value.parentElement.offsetHeight || 100;\n if (containerWidth.value === 100) {\n containerWidth.value = item.value.parentElement.offsetWidth || 100;\n }\n }\n\n if (props.isDraggable === null) {\n draggable.value = parent.isDraggable;\n } else {\n draggable.value = props.isDraggable;\n }\n if (props.isResizable === null) {\n resizable.value = parent.isResizable;\n } else {\n resizable.value = props.isResizable;\n }\n useCssTransforms.value = parent.useCssTransforms;\n\n eventBus.on('updateWidth', updateWidthHandler);\n eventBus.on('compact', compactHandler);\n eventBus.on('setDraggable', setDraggableHandler);\n eventBus.on('setResizable', setResizableHandler);\n eventBus.on('setRowHeight', setRowHeightHandler);\n eventBus.on('setMaxRows', setMaxRowsHandler);\n eventBus.on('directionchange', directionchangeHandler);\n eventBus.on('setColNum', setColNum);\n rtl.value = getDocumentDir() === 'rtl';\n\n createStyle();\n});\n\nonBeforeUnmount(() => {\n eventBus.off('updateWidth', updateWidthHandler);\n eventBus.off('compact', compactHandler);\n eventBus.off('setDraggable', setDraggableHandler);\n eventBus.off('setResizable', setResizableHandler);\n eventBus.off('setRowHeight', setRowHeightHandler);\n eventBus.off('setMaxRows', setMaxRowsHandler);\n eventBus.off('directionchange', directionchangeHandler);\n eventBus.off('setColNum', setColNum);\n if (interactObj.value) {\n interactObj.value.unset();\n }\n});\n\nwatch(\n () => props.isDraggable,\n () => {\n draggable.value = props.isDraggable;\n },\n);\n\nwatch(\n () => props.static,\n () => {\n tryMakeDraggable();\n tryMakeResizable();\n },\n);\n\nwatch(draggable, () => {\n tryMakeDraggable();\n});\n\nwatch(\n () => props.isResizable,\n () => {\n resizable.value = props.isResizable;\n },\n);\n\nwatch(resizable, () => {\n tryMakeResizable();\n});\n\nwatch(rowHeight, () => {\n createStyle();\n emitContainerResized();\n});\n\nwatch(cols, () => {\n tryMakeResizable();\n createStyle();\n emitContainerResized();\n});\n\nwatch(containerWidth, () => {\n tryMakeResizable();\n createStyle();\n emitContainerResized();\n});\n\nwatch(containerHeight, () => {\n tryMakeResizable();\n createStyle();\n emitContainerResized();\n});\n\nwatch(\n () => props.x,\n newVal => {\n innerX.value = newVal;\n createStyle();\n },\n);\n\nwatch(\n () => props.y,\n newVal => {\n innerY.value = newVal;\n createStyle();\n },\n);\n\nwatch(\n () => props.h,\n newVal => {\n innerH.value = newVal;\n createStyle();\n },\n);\n\nwatch(\n () => props.w,\n newVal => {\n innerW.value = newVal;\n createStyle();\n },\n);\n\nwatch(renderRtl, () => {\n tryMakeResizable();\n createStyle();\n});\n\nwatch(\n () => props.minH,\n () => {\n tryMakeResizable();\n },\n);\n\nwatch(\n () => props.maxH,\n () => {\n tryMakeResizable();\n },\n);\n\nwatch(\n () => props.minW,\n () => {\n tryMakeResizable();\n },\n);\n\nwatch(\n () => props.maxW,\n () => {\n tryMakeResizable();\n },\n);\n\nwatch(\n () => {\n const instance = getCurrentInstance();\n const parent = instance?.parent?.proxy as any;\n return parent?.margin;\n },\n val => {\n if (!val || (val[0] === margin.value[0] && val[1] === margin.value[1])) {\n return;\n }\n margin.value = val.map((m: any) => Number(m));\n createStyle();\n emitContainerResized();\n },\n);\n\ndefineExpose({\n autoSize,\n compact,\n updateWidth,\n});\n</script>\n\n<style>\n.vue-grid-item {\n transition: none;\n transition-property: left, top, right;\n /* add right for rtl */\n}\n.vue-grid-item.no-touch {\n -ms-touch-action: none;\n touch-action: none;\n}\n\n.vue-grid-item.cssTransforms {\n right: auto;\n left: 0;\n transition-property: transform;\n}\n\n.vue-grid-item.cssTransforms.render-rtl {\n right: 0;\n left: auto;\n}\n\n.vue-grid-item.resizing {\n z-index: 3;\n opacity: 0.6;\n}\n\n.vue-grid-item.vue-draggable-dragging {\n z-index: 3;\n transition: none;\n}\n\n.vue-grid-item.vue-grid-placeholder {\n z-index: 2;\n background: pink;\n transition-duration: 100ms;\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n -o-user-select: none;\n user-select: none;\n}\n\n.vue-grid-item > .vue-resizable-handle {\n position: absolute;\n right: 0;\n bottom: 0;\n box-sizing: border-box;\n width: 20px;\n height: 20px;\n padding: 0 3px 3px 0;\n background: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/Pg08IS0tIEdlbmVyYXRvcjogQWRvYmUgRmlyZXdvcmtzIENTNiwgRXhwb3J0IFNWRyBFeHRlbnNpb24gYnkgQWFyb24gQmVhbGwgKGh0dHA6Ly9maXJld29ya3MuYWJlYWxsLmNvbSkgLiBWZXJzaW9uOiAwLjYuMSAgLS0+DTwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+DTxzdmcgaWQ9IlVudGl0bGVkLVBhZ2UlMjAxIiB2aWV3Qm94PSIwIDAgNiA2IiBzdHlsZT0iYmFja2dyb3VuZC1jb2xvcjojZmZmZmZmMDAiIHZlcnNpb249IjEuMSINCXhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHhtbDpzcGFjZT0icHJlc2VydmUiDQl4PSIwcHgiIHk9IjBweCIgd2lkdGg9IjZweCIgaGVpZ2h0PSI2cHgiDT4NCTxnIG9wYWNpdHk9IjAuMzAyIj4NCQk8cGF0aCBkPSJNIDYgNiBMIDAgNiBMIDAgNC4yIEwgNCA0LjIgTCA0LjIgNC4yIEwgNC4yIDAgTCA2IDAgTCA2IDYgTCA2IDYgWiIgZmlsbD0iIzAwMDAwMCIvPg0JPC9nPg08L3N2Zz4=');\n background-repeat: no-repeat;\n background-position: bottom right;\n background-origin: content-box;\n cursor: se-resize;\n}\n\n.vue-grid-item > .vue-rtl-resizable-handle {\n right: auto;\n bottom: 0;\n left: 0;\n padding-left: 3px;\n background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTAuMDAwMDAwMDAwMDAwMDAyIiBoZWlnaHQ9IjEwLjAwMDAwMDAwMDAwMDAwMiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KIDwhLS0gQ3JlYXRlZCB3aXRoIE1ldGhvZCBEcmF3IC0gaHR0cDovL2dpdGh1Yi5jb20vZHVvcGl4ZWwvTWV0aG9kLURyYXcvIC0tPgogPGc+CiAgPHRpdGxlPmJhY2tncm91bmQ8L3RpdGxlPgogIDxyZWN0IGZpbGw9Im5vbmUiIGlkPSJjYW52YXNfYmFja2dyb3VuZCIgaGVpZ2h0PSIxMiIgd2lkdGg9IjEyIiB5PSItMSIgeD0iLTEiLz4KICA8ZyBkaXNwbGF5PSJub25lIiBvdmVyZmxvdz0idmlzaWJsZSIgeT0iMCIgeD0iMCIgaGVpZ2h0PSIxMDAlIiB3aWR0aD0iMTAwJSIgaWQ9ImNhbnZhc0dyaWQiPgogICA8cmVjdCBmaWxsPSJ1cmwoI2dyaWRwYXR0ZXJuKSIgc3Ryb2tlLXdpZHRoPSIwIiB5PSIwIiB4PSIwIiBoZWlnaHQ9IjEwMCUiIHdpZHRoPSIxMDAlIi8+CiAgPC9nPgogPC9nPgogPGc+CiAgPHRpdGxlPkxheWVyIDE8L3RpdGxlPgogIDxsaW5lIGNhbnZhcz0iI2ZmZmZmZiIgY2FudmFzLW9wYWNpdHk9IjEiIHN0cm9rZS1saW5lY2FwPSJ1bmRlZmluZWQiIHN0cm9rZS1saW5lam9pbj0idW5kZWZpbmVkIiBpZD0ic3ZnXzEiIHkyPSItNzAuMTc4NDA3IiB4Mj0iMTI0LjQ2NDA3NSIgeTE9Ii0zOC4zOTI3MzciIHgxPSIxNDQuODIxMjg5IiBzdHJva2Utd2lkdGg9IjEuNSIgc3Ryb2tlPSIjMDAwIiBmaWxsPSJub25lIi8+CiAgPGxpbmUgc3Ryb2tlPSIjNjY2NjY2IiBzdHJva2UtbGluZWNhcD0idW5kZWZpbmVkIiBzdHJva2UtbGluZWpvaW49InVuZGVmaW5lZCIgaWQ9InN2Z181IiB5Mj0iOS4xMDY5NTciIHgyPSIwLjk0NzI0NyIgeTE9Ii0wLjAxODEyOCIgeDE9IjAuOTQ3MjQ3IiBzdHJva2Utd2lkdGg9IjIiIGZpbGw9Im5vbmUiLz4KICA8bGluZSBzdHJva2UtbGluZWNhcD0idW5kZWZpbmVkIiBzdHJva2UtbGluZWpvaW49InVuZGVmaW5lZCIgaWQ9InN2Z183IiB5Mj0iOSIgeDI9IjEwLjA3MzUyOSIgeTE9IjkiIHgxPSItMC42NTU2NCIgc3Ryb2tlLXdpZHRoPSIwIiBzdHJva2U9IiM2NjY2NjYiIGZpbGw9Im5vbmUiLz4KIDwvZz4KPC9zdmc+);\n background-repeat: no-repeat;\n background-position: bottom left;\n background-origin: content-box;\n cursor: sw-resize;\n}\n\n.vue-grid-item.disable-userselect {\n user-select: none;\n}\n</style>\n","<template>\n <div\n ref=\"item\"\n class=\"vue-grid-layout\"\n :style=\"mergedStyle\"\n >\n <slot></slot>\n <grid-item\n ref=\"gridItem\"\n class=\"vue-grid-placeholder\"\n v-show=\"isDragging\"\n :x=\"placeholder.x\"\n :y=\"placeholder.y\"\n :w=\"placeholder.w\"\n :h=\"placeholder.h\"\n :i=\"placeholder.i\"\n ></grid-item>\n </div>\n</template>\n<script setup lang=\"ts\">\nimport elementResizeDetectorMaker from 'element-resize-detector';\nimport mitt from 'mitt';\nimport {\n nextTick,\n onBeforeMount,\n onBeforeUnmount,\n onMounted,\n provide,\n reactive,\n ref,\n watch,\n} from 'vue';\nimport { addWindowEventListener, removeWindowEventListener } from '../helpers/dom';\nimport {\n findOrGenerateResponsiveLayout,\n getBreakpointFromWidth,\n getColsFromBreakpoint,\n} from '../helpers/responsive-utils';\nimport type { Layout } from '../helpers/utils';\nimport {\n bottom,\n cloneLayout,\n compact,\n getAllCollisions,\n getLayoutItem,\n moveElement,\n validateLayout,\n} from '../helpers/utils';\nimport GridItem from './grid-item.vue';\n\ndefineOptions({\n name: 'GridLayout',\n});\n\nconst props = withDefaults(\n defineProps<{\n // If true, the container height swells and contracts to fit contents\n autoSize?: boolean;\n colNum?: number;\n rowHeight?: number;\n maxRows?: number;\n margin?: number[];\n isDraggable?: boolean;\n isResizable?: boolean;\n isMirrored?: boolean;\n useCssTransforms?: boolean;\n verticalCompact?: boolean;\n layout: Layout;\n responsive?: boolean;\n responsiveLayouts?: Record<string, any>;\n breakpoints?: Record<string, number>;\n cols?: Record<string, number>;\n preventCollision?: boolean;\n usePercentages?: boolean;\n }>(),\n {\n autoSize: true,\n colNum: 12,\n rowHeight: 10,\n maxRows: Infinity,\n margin: () => [10, 10],\n isDraggable: false,\n isResizable: false,\n isMirrored: false,\n useCssTransforms: true,\n verticalCompact: true,\n responsive: false,\n responsiveLayouts: () => ({}),\n breakpoints: () => ({ lg: 1200, md: 996, sm: 768, xs: 480, xxs: 0 }),\n cols: () => ({ lg: 12, md: 10, sm: 6, xs: 4, xxs: 2 }),\n preventCollision: false,\n usePercentages: false,\n },\n);\n\nconst emit = defineEmits<{\n (e: 'layout-created', layout: Layout): void;\n (e: 'layout-mounted', layout: Layout): void;\n (e: 'layout-before-mount', layout: Layout): void;\n (e: 'layout-updated', layout: Layout): void;\n (e: 'layout-ready', layout: Layout): void;\n (e: 'update:layout', layout: Layout): void;\n (e: 'breakpoint-changed', breakpoint: string | null, layout: Layout): void;\n}>();\n\nconst eventBus = mitt();\nprovide('eventBus', eventBus);\nprovide('usePercentages', props.usePercentages);\nprovide('layout', props.layout);\n\nconst item = ref<HTMLElement | null>(null);\nconst gridItem = ref(null);\nconst width = ref<number | null>(null);\nconst mergedStyle = ref<Record<string, any>>({});\nconst lastLayoutLength = ref(0);\nconst isDragging = ref(false);\nconst placeholder = reactive({\n x: 0 as string | number,\n y: 0 as string | number,\n w: 0 as string | number,\n h: 0 as string | number,\n i: -1 as string | number,\n});\nconst layouts = ref<Record<string, Layout>>({}); // array to store all layouts from different breakpoints\nconst lastBreakpoint = ref<string | null>(null); // store last active breakpoint\nconst originalLayout = ref<Layout | null>(null); // store original Layout\nconst erd = ref<any>(null);\n\nconst getLayoutEl = () => {\n return item.value;\n};\n\nconst updateHeight = () => {\n mergedStyle.value = {\n height: containerHeight(),\n };\n if (props.usePercentages) {\n mergedStyle.value.width = '100%';\n }\n};\n\nconst onWindowResize = () => {\n if (item.value !== null && item.value !== undefined) {\n width.value = item.value.offsetWidth;\n }\n eventBus.emit('resizeEvent', {});\n};\n\nconst containerHeight = () => {\n if (props.usePercentages) return '100%';\n if (!props.autoSize) return;\n return bottom(props.layout) * (props.rowHeight + props.margin[1]) + props.margin[1] + 'px';\n};\n\nconst dragEvent = (\n eventName: string,\n id: string | number,\n x: number,\n y: number,\n h: number,\n w: number,\n) => {\n let l = getLayoutItem(props.layout, String(id));\n if (l === undefined || l === null) {\n l = { x: 0, y: 0, w: 0, h: 0, i: String(id) };\n }\n if (eventName === 'dragmove' || eventName === 'dragstart') {\n placeholder.i = id;\n placeholder.x = l.x;\n placeholder.y = l.y;\n placeholder.w = w;\n placeholder.h = h;\n nextTick(() => {\n isDragging.value = true;\n });\n eventBus.emit('updateWidth', width.value);\n } else {\n nextTick(() => {\n isDragging.value = false;\n });\n }\n // Move the element to the dragged location.\n moveElement(props.layout, l, x, y, true, props.preventCollision);\n compact(props.layout, props.verticalCompact);\n // needed because vue can't detect changes on array element properties\n eventBus.emit('compact');\n updateHeight();\n if (eventName === 'dragend') emit('layout-updated', props.layout);\n};\n\nconst responsiveGridLayout = () => {\n if (!width.value) return;\n const newBreakpoint = getBreakpointFromWidth(props.breakpoints, width.value);\n const newCols = getColsFromBreakpoint(newBreakpoint, props.cols);\n // save actual layout in layouts\n if (lastBreakpoint.value != null && !layouts.value[lastBreakpoint.value])\n layouts.value[lastBreakpoint.value] = cloneLayout(props.layout);\n // Find or generate a new layout.\n const layout = findOrGenerateResponsiveLayout(\n originalLayout.value!,\n layouts.value,\n props.breakpoints as any,\n newBreakpoint,\n lastBreakpoint.value as any,\n newCols,\n props.verticalCompact,\n );\n // Store the new layout.\n layouts.value[newBreakpoint] = layout;\n if (lastBreakpoint.value !== newBreakpoint) {\n emit('breakpoint-changed', newBreakpoint, layout);\n }\n // new prop sync\n emit('update:layout', layout);\n lastBreakpoint.value = newBreakpoint;\n eventBus.emit('setColNum', getColsFromBreakpoint(newBreakpoint, props.cols));\n};\n\nconst resizeEvent = (\n eventName: string,\n id: string | number,\n x: number,\n y: number,\n h: number,\n w: number,\n) => {\n let l = getLayoutItem(props.layout, String(id));\n if (l === undefined || l === null) {\n l = { h: 0, w: 0, x: 0, y: 0, i: String(id) };\n }\n let hasCollisions = false;\n if (props.preventCollision) {\n const collisions = getAllCollisions(props.layout, { ...l, w, h }).filter(\n layoutItem => layoutItem.i !== l!.i,\n );\n hasCollisions = collisions.length > 0;\n // If we're colliding, we need adjust the placeholder.\n if (hasCollisions) {\n // adjust w && h to maximum allowed space\n let leastX = Infinity;\n let leastY = Infinity;\n collisions.forEach(layoutItem => {\n if (layoutItem.x > l!.x) leastX = Math.min(leastX, layoutItem.x);\n if (layoutItem.y > l!.y) leastY = Math.min(leastY, layoutItem.y);\n });\n if (Number.isFinite(leastX)) l.w = leastX - l.x;\n if (Number.isFinite(leastY)) l.h = leastY - l.y;\n }\n }\n if (!hasCollisions) {\n // Set new width and height.\n l.w = w;\n l.h = h;\n }\n if (eventName === 'resizestart' || eventName === 'resizemove') {\n placeholder.i = id;\n placeholder.x = x;\n placeholder.y = y;\n placeholder.w = l.w;\n placeholder.h = l.h;\n nextTick(() => {\n isDragging.value = true;\n });\n eventBus.emit('updateWidth', width.value);\n } else {\n nextTick(() => {\n isDragging.value = false;\n });\n }\n if (props.responsive) responsiveGridLayout();\n compact(props.layout, props.verticalCompact);\n eventBus.emit('compact');\n updateHeight();\n if (eventName === 'resizeend') emit('layout-updated', props.layout);\n};\n\nconst initResponsiveFeatures = () => {\n layouts.value = Object.assign({}, props.responsiveLayouts);\n};\n\nconst findDifference = (layout: Layout, originalLayout: Layout) => {\n const uniqueResultOne = layout.filter(obj => {\n return !originalLayout.some(obj2 => {\n return obj.i === obj2.i;\n });\n });\n const uniqueResultTwo = originalLayout.filter(obj => {\n return !layout.some(obj2 => {\n return obj.i === obj2.i;\n });\n });\n return uniqueResultOne.concat(uniqueResultTwo);\n};\n\nconst layoutUpdate = () => {\n if (props.layout !== undefined && originalLayout.value !== null) {\n if (props.layout.length !== originalLayout.value.length) {\n const diff = findDifference(props.layout, originalLayout.value);\n if (diff.length > 0) {\n if (props.layout.length > originalLayout.value.length) {\n originalLayout.value = originalLayout.value.concat(diff);\n } else {\n originalLayout.value = originalLayout.value.filter(obj => {\n return !diff.some(obj2 => {\n return obj.i === obj2.i;\n });\n });\n }\n }\n lastLayoutLength.value = props.layout.length;\n initResponsiveFeatures();\n }\n if (props.usePercentages) {\n // Skip correctBounds on layout update to keep original values\n }\n compact(props.layout, props.verticalCompact);\n eventBus.emit('updateWidth', width.value);\n updateHeight();\n emit('layout-updated', props.layout);\n }\n};\n\nconst resizeEventHandler = ({ eventType, i, x, y, h, w }: any) => {\n resizeEvent(eventType, i, x, y, h, w);\n};\nconst dragEventHandler = ({ eventType, i, x, y, h, w }: any) => {\n dragEvent(eventType, i, x, y, h, w);\n};\n\nonBeforeMount(() => {\n emit('layout-before-mount', props.layout);\n});\n\nonMounted(() => {\n eventBus.on('resizeEvent', resizeEventHandler);\n eventBus.on('dragEvent', dragEventHandler);\n emit('layout-created', props.layout);\n\n emit('layout-mounted', props.layout);\n nextTick(() => {\n validateLayout(props.layout);\n originalLayout.value = props.layout;\n if (props.usePercentages) {\n // Skip correctBounds on initialization to keep original values\n }\n nextTick(() => {\n onWindowResize();\n initResponsiveFeatures();\n addWindowEventListener('resize', onWindowResize);\n compact(props.layout, props.verticalCompact);\n emit('layout-updated', props.layout);\n updateHeight();\n nextTick(() => {\n erd.value = elementResizeDetectorMaker({\n strategy: 'scroll',\n callOnAdd: false,\n });\n erd.value.listenTo(item.value, () => {\n onWindowResize();\n });\n });\n });\n });\n});\n\nonBeforeUnmount(() => {\n eventBus.off('resizeEvent', resizeEventHandler);\n eventBus.off('dragEvent', dragEventHandler);\n removeWindowEventListener('resize', onWindowResize);\n if (erd.value && item.value) {\n erd.value.uninstall(item.value);\n }\n});\n\nwatch(width, (_newval, oldval) => {\n nextTick(() => {\n eventBus.emit('updateWidth', width.value);\n if (oldval === null) {\n nextTick(() => {\n emit('layout-ready', props.layout);\n });\n }\n updateHeight();\n });\n});\n\nwatch(\n () => props.layout.length,\n () => {\n layoutUpdate();\n },\n);\n\nwatch(\n () => props.layout,\n () => {\n layoutUpdate();\n },\n);\n\nwatch(\n () => props.colNum,\n val => {\n eventBus.emit('setColNum', val);\n },\n);\n\nwatch(\n () => props.rowHeight,\n () => {\n eventBus.emit('setRowHeight', props.rowHeight);\n },\n);\n\nwatch(\n () => props.isDraggable,\n () => {\n eventBus.emit('setDraggable', props.isDraggable);\n },\n);\n\nwatch(\n () => props.isResizable,\n () => {\n eventBus.emit('setResizable', props.isResizable);\n },\n);\n\nwatch(\n () => props.responsive,\n () => {\n if (!props.responsive) {\n emit('update:layout', originalLayout.value!);\n eventBus.emit('setColNum', props.colNum);\n }\n onWindowResize();\n },\n);\n\nwatch(\n () => props.maxRows,\n () => {\n eventBus.emit('setMaxRows', props.maxRows);\n },\n);\n\nwatch(\n () => props.margin,\n () => {\n updateHeight();\n },\n);\n\ndefineExpose({\n getLayoutEl,\n});\n</script>\n<style>\n.vue-grid-layout {\n position: relative;\n}\n</style>\n","<template>\n <div\n ref=\"item\"\n class=\"vue-grid-layout\"\n :style=\"mergedStyle\"\n >\n <slot></slot>\n <grid-item\n ref=\"gridItem\"\n class=\"vue-grid-placeholder\"\n v-show=\"isDragging\"\n :x=\"placeholder.x\"\n :y=\"placeholder.y\"\n :w=\"placeholder.w\"\n :h=\"placeholder.h\"\n :i=\"placeholder.i\"\n ></grid-item>\n </div>\n</template>\n<script setup lang=\"ts\">\nimport elementResizeDetectorMaker from 'element-resize-detector';\nimport mitt from 'mitt';\nimport {\n nextTick,\n onBeforeMount,\n onBeforeUnmount,\n onMounted,\n provide,\n reactive,\n ref,\n watch,\n} from 'vue';\nimport { addWindowEventListener, removeWindowEventListener } from '../helpers/dom';\nimport {\n findOrGenerateResponsiveLayout,\n getBreakpointFromWidth,\n getColsFromBreakpoint,\n} from '../helpers/responsive-utils';\nimport type { Layout } from '../helpers/utils';\nimport {\n bottom,\n cloneLayout,\n compact,\n getAllCollisions,\n getLayoutItem,\n moveElement,\n validateLayout,\n} from '../helpers/utils';\nimport GridItem from './grid-item.vue';\n\ndefineOptions({\n name: 'GridLayout',\n});\n\nconst props = withDefaults(\n defineProps<{\n // If true, the container height swells and contracts to fit contents\n autoSize?: boolean;\n colNum?: number;\n rowHeight?: number;\n maxRows?: number;\n margin?: number[];\n isDraggable?: boolean;\n isResizable?: boolean;\n isMirrored?: boolean;\n useCssTransforms?: boolean;\n verticalCompact?: boolean;\n layout: Layout;\n responsive?: boolean;\n responsiveLayouts?: Record<string, any>;\n breakpoints?: Record<string, number>;\n cols?: Record<string, number>;\n preventCollision?: boolean;\n usePercentages?: boolean;\n }>(),\n {\n autoSize: true,\n colNum: 12,\n rowHeight: 10,\n maxRows: Infinity,\n margin: () => [10, 10],\n isDraggable: false,\n isResizable: false,\n isMirrored: false,\n useCssTransforms: true,\n verticalCompact: true,\n responsive: false,\n responsiveLayouts: () => ({}),\n breakpoints: () => ({ lg: 1200, md: 996, sm: 768, xs: 480, xxs: 0 }),\n cols: () => ({ lg: 12, md: 10, sm: 6, xs: 4, xxs: 2 }),\n preventCollision: false,\n usePercentages: false,\n },\n);\n\nconst emit = defineEmits<{\n (e: 'layout-created', layout: Layout): void;\n (e: 'layout-mounted', layout: Layout): void;\n (e: 'layout-before-mount', layout: Layout): void;\n (e: 'layout-updated', layout: Layout): void;\n (e: 'layout-ready', layout: Layout): void;\n (e: 'update:layout', layout: Layout): void;\n (e: 'breakpoint-changed', breakpoint: string | null, layout: Layout): void;\n}>();\n\nconst eventBus = mitt();\nprovide('eventBus', eventBus);\nprovide('usePercentages', props.usePercentages);\nprovide('layout', props.layout);\n\nconst item = ref<HTMLElement | null>(null);\nconst gridItem = ref(null);\nconst width = ref<number | null>(null);\nconst mergedStyle = ref<Record<string, any>>({});\nconst lastLayoutLength = ref(0);\nconst isDragging = ref(false);\nconst placeholder = reactive({\n x: 0 as string | number,\n y: 0 as string | number,\n w: 0 as string | number,\n h: 0 as string | number,\n i: -1 as string | number,\n});\nconst layouts = ref<Record<string, Layout>>({}); // array to store all layouts from different breakpoints\nconst lastBreakpoint = ref<string | null>(null); // store last active breakpoint\nconst originalLayout = ref<Layout | null>(null); // store original Layout\nconst erd = ref<any>(null);\n\nconst getLayoutEl = () => {\n return item.value;\n};\n\nconst updateHeight = () => {\n mergedStyle.value = {\n height: containerHeight(),\n };\n if (props.usePercentages) {\n mergedStyle.value.width = '100%';\n }\n};\n\nconst onWindowResize = () => {\n if (item.value !== null && item.value !== undefined) {\n width.value = item.value.offsetWidth;\n }\n eventBus.emit('resizeEvent', {});\n};\n\nconst containerHeight = () => {\n if (props.usePercentages) return '100%';\n if (!props.autoSize) return;\n return bottom(props.layout) * (props.rowHeight + props.margin[1]) + props.margin[1] + 'px';\n};\n\nconst dragEvent = (\n eventName: string,\n id: string | number,\n x: number,\n y: number,\n h: number,\n w: number,\n) => {\n let l = getLayoutItem(props.layout, String(id));\n if (l === undefined || l === null) {\n l = { x: 0, y: 0, w: 0, h: 0, i: String(id) };\n }\n if (eventName === 'dragmove' || eventName === 'dragstart') {\n placeholder.i = id;\n placeholder.x = l.x;\n placeholder.y = l.y;\n placeholder.w = w;\n placeholder.h = h;\n nextTick(() => {\n isDragging.value = true;\n });\n eventBus.emit('updateWidth', width.value);\n } else {\n nextTick(() => {\n isDragging.value = false;\n });\n }\n // Move the element to the dragged location.\n moveElement(props.layout, l, x, y, true, props.preventCollision);\n compact(props.layout, props.verticalCompact);\n // needed because vue can't detect changes on array element properties\n eventBus.emit('compact');\n updateHeight();\n if (eventName === 'dragend') emit('layout-updated', props.layout);\n};\n\nconst responsiveGridLayout = () => {\n if (!width.value) return;\n const newBreakpoint = getBreakpointFromWidth(props.breakpoints, width.value);\n const newCols = getColsFromBreakpoint(newBreakpoint, props.cols);\n // save actual layout in layouts\n if (lastBreakpoint.value != null && !layouts.value[lastBreakpoint.value])\n layouts.value[lastBreakpoint.value] = cloneLayout(props.layout);\n // Find or generate a new layout.\n const layout = findOrGenerateResponsiveLayout(\n originalLayout.value!,\n layouts.value,\n props.breakpoints as any,\n newBreakpoint,\n lastBreakpoint.value as any,\n newCols,\n props.verticalCompact,\n );\n // Store the new layout.\n layouts.value[newBreakpoint] = layout;\n if (lastBreakpoint.value !== newBreakpoint) {\n emit('breakpoint-changed', newBreakpoint, layout);\n }\n // new prop sync\n emit('update:layout', layout);\n lastBreakpoint.value = newBreakpoint;\n eventBus.emit('setColNum', getColsFromBreakpoint(newBreakpoint, props.cols));\n};\n\nconst resizeEvent = (\n eventName: string,\n id: string | number,\n x: number,\n y: number,\n h: number,\n w: number,\n) => {\n let l = getLayoutItem(props.layout, String(id));\n if (l === undefined || l === null) {\n l = { h: 0, w: 0, x: 0, y: 0, i: String(id) };\n }\n let hasCollisions = false;\n if (props.preventCollision) {\n const collisions = getAllCollisions(props.layout, { ...l, w, h }).filter(\n layoutItem => layoutItem.i !== l!.i,\n );\n hasCollisions = collisions.length > 0;\n // If we're colliding, we need adjust the placeholder.\n if (hasCollisions) {\n // adjust w && h to maximum allowed space\n let leastX = Infinity;\n let leastY = Infinity;\n collisions.forEach(layoutItem => {\n if (layoutItem.x > l!.x) leastX = Math.min(leastX, layoutItem.x);\n if (layoutItem.y > l!.y) leastY = Math.min(leastY, layoutItem.y);\n });\n if (Number.isFinite(leastX)) l.w = leastX - l.x;\n if (Number.isFinite(leastY)) l.h = leastY - l.y;\n }\n }\n if (!hasCollisions) {\n // Set new width and height.\n l.w = w;\n l.h = h;\n }\n if (eventName === 'resizestart' || eventName === 'resizemove') {\n placeholder.i = id;\n placeholder.x = x;\n placeholder.y = y;\n placeholder.w = l.w;\n placeholder.h = l.h;\n nextTick(() => {\n isDragging.value = true;\n });\n eventBus.emit('updateWidth', width.value);\n } else {\n nextTick(() => {\n isDragging.value = false;\n });\n }\n if (props.responsive) responsiveGridLayout();\n compact(props.layout, props.verticalCompact);\n eventBus.emit('compact');\n updateHeight();\n if (eventName === 'resizeend') emit('layout-updated', props.layout);\n};\n\nconst initResponsiveFeatures = () => {\n layouts.value = Object.assign({}, props.responsiveLayouts);\n};\n\nconst findDifference = (layout: Layout, originalLayout: Layout) => {\n const uniqueResultOne = layout.filter(obj => {\n return !originalLayout.some(obj2 => {\n return obj.i === obj2.i;\n });\n });\n const uniqueResultTwo = originalLayout.filter(obj => {\n return !layout.some(obj2 => {\n return obj.i === obj2.i;\n });\n });\n return uniqueResultOne.concat(uniqueResultTwo);\n};\n\nconst layoutUpdate = () => {\n if (props.layout !== undefined && originalLayout.value !== null) {\n if (props.layout.length !== originalLayout.value.length) {\n const diff = findDifference(props.layout, originalLayout.value);\n if (diff.length > 0) {\n if (props.layout.length > originalLayout.value.length) {\n originalLayout.value = originalLayout.value.concat(diff);\n } else {\n originalLayout.value = originalLayout.value.filter(obj => {\n return !diff.some(obj2 => {\n return obj.i === obj2.i;\n });\n });\n }\n }\n lastLayoutLength.value = props.layout.length;\n initResponsiveFeatures();\n }\n if (props.usePercentages) {\n // Skip correctBounds on layout update to keep original values\n }\n compact(props.layout, props.verticalCompact);\n eventBus.emit('updateWidth', width.value);\n updateHeight();\n emit('layout-updated', props.layout);\n }\n};\n\nconst resizeEventHandler = ({ eventType, i, x, y, h, w }: any) => {\n resizeEvent(eventType, i, x, y, h, w);\n};\nconst dragEventHandler = ({ eventType, i, x, y, h, w }: any) => {\n dragEvent(eventType, i, x, y, h, w);\n};\n\nonBeforeMount(() => {\n emit('layout-before-mount', props.layout);\n});\n\nonMounted(() => {\n eventBus.on('resizeEvent', resizeEventHandler);\n eventBus.on('dragEvent', dragEventHandler);\n emit('layout-created', props.layout);\n\n emit('layout-mounted', props.layout);\n nextTick(() => {\n validateLayout(props.layout);\n originalLayout.value = props.layout;\n if (props.usePercentages) {\n // Skip correctBounds on initialization to keep original values\n }\n nextTick(() => {\n onWindowResize();\n initResponsiveFeatures();\n addWindowEventListener('resize', onWindowResize);\n compact(props.layout, props.verticalCompact);\n emit('layout-updated', props.layout);\n updateHeight();\n nextTick(() => {\n erd.value = elementResizeDetectorMaker({\n strategy: 'scroll',\n callOnAdd: false,\n });\n erd.value.listenTo(item.value, () => {\n onWindowResize();\n });\n });\n });\n });\n});\n\nonBeforeUnmount(() => {\n eventBus.off('resizeEvent', resizeEventHandler);\n eventBus.off('dragEvent', dragEventHandler);\n removeWindowEventListener('resize', onWindowResize);\n if (erd.value && item.value) {\n erd.value.uninstall(item.value);\n }\n});\n\nwatch(width, (_newval, oldval) => {\n nextTick(() => {\n eventBus.emit('updateWidth', width.value);\n if (oldval === null) {\n nextTick(() => {\n emit('layout-ready', props.layout);\n });\n }\n updateHeight();\n });\n});\n\nwatch(\n () => props.layout.length,\n () => {\n layoutUpdate();\n },\n);\n\nwatch(\n () => props.layout,\n () => {\n layoutUpdate();\n },\n);\n\nwatch(\n () => props.colNum,\n val => {\n eventBus.emit('setColNum', val);\n },\n);\n\nwatch(\n () => props.rowHeight,\n () => {\n eventBus.emit('setRowHeight', props.rowHeight);\n },\n);\n\nwatch(\n () => props.isDraggable,\n () => {\n eventBus.emit('setDraggable', props.isDraggable);\n },\n);\n\nwatch(\n () => props.isResizable,\n () => {\n eventBus.emit('setResizable', props.isResizable);\n },\n);\n\nwatch(\n () => props.responsive,\n () => {\n if (!props.responsive) {\n emit('update:layout', originalLayout.value!);\n eventBus.emit('setColNum', props.colNum);\n }\n onWindowResize();\n },\n);\n\nwatch(\n () => props.maxRows,\n () => {\n eventBus.emit('setMaxRows', props.maxRows);\n },\n);\n\nwatch(\n () => props.margin,\n () => {\n updateHeight();\n },\n);\n\ndefineExpose({\n getLayoutEl,\n});\n</script>\n<style>\n.vue-grid-layout {\n position: relative;\n}\n</style>\n","<template>\n <grid-layout\n v-model:layout=\"layout\"\n :is-draggable=\"config.isDraggable\"\n :is-resizable=\"config.isResizable\"\n :is-mirrored=\"false\"\n :vertical-compact=\"false\"\n use-css-transforms\n :use-percentages=\"true\"\n >\n <grid-item\n v-for=\"item in layout\"\n :x=\"item.x\"\n :y=\"item.y\"\n :w=\"item.w\"\n :h=\"item.h\"\n :i=\"item.i\"\n :key=\"item.i\"\n :dragAllowFrom=\"'span'\"\n :class=\"{ item: true, border: hasBorder }\"\n :style=\"{ padding: config.itemPadding || '0' }\"\n >\n <div class=\"item-content\">\n <template v-if=\"item.config.component\">\n <component\n :is=\"item.config.component\"\n :itemKey=\"item.config.key\"\n v-bind=\"item.config.props || {}\"\n />\n </template>\n <template v-else>\n <span class=\"text\">Layout: {{ item.i }}</span>\n </template>\n </div>\n </grid-item>\n </grid-layout>\n</template>\n<script setup lang=\"ts\">\nimport { GridConfig } from 'liyu-pc-base/typing';\nimport { computed, onMounted } from 'vue';\nimport { GridItem, GridLayout } from '../grid-layout';\n\nconst props = withDefaults(\n defineProps<{\n config: GridConfig;\n }>(),\n {},\n);\n\nconst layout = computed(() => {\n const keyMap = {};\n return props.config.items.map((item, index) => {\n let i = item.key;\n if (!i) {\n i = `index_${index}`;\n }\n if (keyMap[i]) {\n throw new Error('key: ${i}重复');\n }\n\n return {\n ...item.layout,\n i: i,\n config: item,\n };\n });\n});\nconst hasBorder = computed(() => {\n return !!props.config.isBorder;\n});\nonMounted(() => {});\n</script>\n\n<style scoped lang=\"less\">\n.item {\n position: relative;\n}\n.border {\n border: 1px solid #ccc;\n}\n.item-content {\n width: 100%;\n height: 100%;\n background: #fff;\n border-radius: 2px;\n overflow: hidden;\n}\n</style>\n","<template>\n <grid-layout\n v-model:layout=\"layout\"\n :is-draggable=\"config.isDraggable\"\n :is-resizable=\"config.isResizable\"\n :is-mirrored=\"false\"\n :vertical-compact=\"false\"\n use-css-transforms\n :use-percentages=\"true\"\n >\n <grid-item\n v-for=\"item in layout\"\n :x=\"item.x\"\n :y=\"item.y\"\n :w=\"item.w\"\n :h=\"item.h\"\n :i=\"item.i\"\n :key=\"item.i\"\n :dragAllowFrom=\"'span'\"\n :class=\"{ item: true, border: hasBorder }\"\n :style=\"{ padding: config.itemPadding || '0' }\"\n >\n <div class=\"item-content\">\n <template v-if=\"item.config.component\">\n <component\n :is=\"item.config.component\"\n :itemKey=\"item.config.key\"\n v-bind=\"item.config.props || {}\"\n />\n </template>\n <template v-else>\n <span class=\"text\">Layout: {{ item.i }}</span>\n </template>\n </div>\n </grid-item>\n </grid-layout>\n</template>\n<script setup lang=\"ts\">\nimport { GridConfig } from 'liyu-pc-base/typing';\nimport { computed, onMounted } from 'vue';\nimport { GridItem, GridLayout } from '../grid-layout';\n\nconst props = withDefaults(\n defineProps<{\n config: GridConfig;\n }>(),\n {},\n);\n\nconst layout = computed(() => {\n const keyMap = {};\n return props.config.items.map((item, index) => {\n let i = item.key;\n if (!i) {\n i = `index_${index}`;\n }\n if (keyMap[i]) {\n throw new Error('key: ${i}重复');\n }\n\n return {\n ...item.layout,\n i: i,\n config: item,\n };\n });\n});\nconst hasBorder = computed(() => {\n return !!props.config.isBorder;\n});\nonMounted(() => {});\n</script>\n\n<style scoped lang=\"less\">\n.item {\n position: relative;\n}\n.border {\n border: 1px solid #ccc;\n}\n.item-content {\n width: 100%;\n height: 100%;\n background: #fff;\n border-radius: 2px;\n overflow: hidden;\n}\n</style>\n","import { useGlobMap } from 'liyu-pc-base/init-plugin';\nimport type { GridConfig } from 'liyu-pc-base/typing';\nimport { markRaw } from 'vue';\nconst custom_config: { [key: string]: any } = {};\n\nconst get_custom_config = async (key: string) => {\n if (Object.keys(custom_config).length > 0) {\n if (custom_config[key]) {\n const obj = await custom_config[key]();\n return obj.default;\n } else {\n const obj = await custom_config['default']();\n return obj.default;\n }\n }\n const allComponents: any = import.meta.glob('liyu-pc-base/components/gridPage/config/*/*.ts', {\n eager: false,\n });\n const customComponents = useGlobMap('gridPage');\n Object.assign(allComponents, customComponents);\n for (const full_file_name in allComponents) {\n const file_name_list = full_file_name.split('/');\n const file_name = file_name_list[file_name_list.length - 1].replace('.ts', '');\n custom_config[file_name] = allComponents[full_file_name];\n }\n\n if (custom_config[key]) {\n const obj = await custom_config[key]();\n return obj.default;\n } else {\n const obj = await custom_config['default']();\n return obj.default;\n }\n};\nconst process_config = (config: any) => {\n if (config.items) {\n for (const item of config.items) {\n if (item.component) {\n item.component = markRaw(item.component);\n }\n }\n }\n};\nexport const getGridConfig = async (\n key: string,\n { context, eventBus },\n): Promise<{ config: GridConfig }> => {\n const configFunc = await get_custom_config(key);\n const local_config = configFunc({ menu_flag: key, context, eventBus });\n process_config(local_config);\n\n return { config: local_config };\n};\n","<template>\n <fullLayout>\n <div\n class=\"grid-page-wraper\"\n :style=\"{ minWidth: minWidth, minHeight: minHeight }\"\n >\n <div class=\"grid-page-content\">\n <gridView\n v-if=\"config\"\n :config=\"config\"\n ></gridView>\n </div>\n </div>\n </fullLayout>\n</template>\n<script setup lang=\"ts\">\nimport { computed, onMounted, onUnmounted, provide, ref } from 'vue';\nimport fullLayout from '../fullLayout/fullLayout.vue';\nimport gridView from './gridView.vue';\nimport mitt from 'mitt';\nimport type { GridConfig } from 'liyu-pc-base/typing';\nimport { getGridConfig } from './index';\nimport { gridPageStateSymbol, GridPageState } from './utils';\nimport { useRoute } from 'vue-router';\nconst route = useRoute();\nconst config = ref<GridConfig>(null);\nconst context = ref<any>({});\nconst eventBus = mitt();\nconst modelType = ref('');\nconst path_arr = route.path.split('/');\nmodelType.value = path_arr[path_arr.length - 1];\n\nprovide<GridPageState>(gridPageStateSymbol, {\n context: context,\n eventBus,\n});\nonMounted(async () => {\n config.value = (\n await getGridConfig(modelType.value, { context: context.value, eventBus })\n ).config;\n if (config.value.onMounted) {\n await config.value.onMounted(context.value, eventBus);\n }\n});\nonUnmounted(() => {\n if (config.value.onUnmounted) {\n config.value.onUnmounted(context.value, eventBus);\n }\n});\nconst minWidth = computed(() => {\n if (config.value?.minWidth != null) {\n return config.value.minWidth;\n } else {\n return undefined;\n }\n});\nconst minHeight = computed(() => {\n if (config.value?.minHeight != null) {\n return config.value.minHeight;\n } else {\n return undefined;\n }\n});\n</script>\n\n<style lang=\"less\">\n.grid-page-wraper {\n height: 100%;\n width: 100%;\n padding: 5px;\n}\n.grid-page-content {\n height: 100%;\n width: 100%;\n border-radius: 4px;\n}\n</style>\n","<template>\n <fullLayout>\n <div\n class=\"grid-page-wraper\"\n :style=\"{ minWidth: minWidth, minHeight: minHeight }\"\n >\n <div class=\"grid-page-content\">\n <gridView\n v-if=\"config\"\n :config=\"config\"\n ></gridView>\n </div>\n </div>\n </fullLayout>\n</template>\n<script setup lang=\"ts\">\nimport { computed, onMounted, onUnmounted, provide, ref } from 'vue';\nimport fullLayout from '../fullLayout/fullLayout.vue';\nimport gridView from './gridView.vue';\nimport mitt from 'mitt';\nimport type { GridConfig } from 'liyu-pc-base/typing';\nimport { getGridConfig } from './index';\nimport { gridPageStateSymbol, GridPageState } from './utils';\nimport { useRoute } from 'vue-router';\nconst route = useRoute();\nconst config = ref<GridConfig>(null);\nconst context = ref<any>({});\nconst eventBus = mitt();\nconst modelType = ref('');\nconst path_arr = route.path.split('/');\nmodelType.value = path_arr[path_arr.length - 1];\n\nprovide<GridPageState>(gridPageStateSymbol, {\n context: context,\n eventBus,\n});\nonMounted(async () => {\n config.value = (\n await getGridConfig(modelType.value, { context: context.value, eventBus })\n ).config;\n if (config.value.onMounted) {\n await config.value.onMounted(context.value, eventBus);\n }\n});\nonUnmounted(() => {\n if (config.value.onUnmounted) {\n config.value.onUnmounted(context.value, eventBus);\n }\n});\nconst minWidth = computed(() => {\n if (config.value?.minWidth != null) {\n return config.value.minWidth;\n } else {\n return undefined;\n }\n});\nconst minHeight = computed(() => {\n if (config.value?.minHeight != null) {\n return config.value.minHeight;\n } else {\n return undefined;\n }\n});\n</script>\n\n<style lang=\"less\">\n.grid-page-wraper {\n height: 100%;\n width: 100%;\n padding: 5px;\n}\n.grid-page-content {\n height: 100%;\n width: 100%;\n border-radius: 4px;\n}\n</style>\n","<template>\n <fullLayout>\n <div class=\"remote-page-shell\">\n <tablePageHost\n ref=\"hostRef\"\n :app_flag=\"field.app_flag\"\n :modalType=\"field.modalType\"\n ></tablePageHost>\n </div>\n </fullLayout>\n</template>\n<script setup lang=\"ts\">\n// 路由级薄壳:只负责「从路由解析 app_flag/modalType」与「required_condition 写入 store」\n// 这两个页面级副作用;其余壳逻辑(总线/详情抽屉/视图模式/hash/keep-alive 注册)\n// 全部参数化在 tablePageHost.vue 中,与 detailTablePro 共用同一份实现。\nimport fullLayout from 'liyu-pc-base/components/fullLayout/fullLayout.vue';\nimport tablePageHost from './tablePageHost.vue';\nimport { computed, ref, watch, onActivated } from 'vue';\nimport { useRoute } from 'vue-router';\nimport { useRequiredConditionStore } from 'liyu-pc-base/init-plugin';\n\nconst route = useRoute();\nconst requiredConditionStore = useRequiredConditionStore();\nconst path_arr = route.path.split('/');\nconst field = {\n app_flag: path_arr[path_arr.length - 2],\n modalType: path_arr[path_arr.length - 1],\n};\n\nconst hostRef = ref(null);\n// defineExpose 暴露的 ref 经模板引用访问时自动解包\nconst pageConfig = computed(() => hostRef.value?.pageConfig ?? null);\n\nconst syncRequiredCondition = () => {\n if (pageConfig.value?.required_condition) {\n requiredConditionStore.set_required_condition(\n field.modalType,\n pageConfig.value.required_condition,\n );\n }\n};\nwatch(pageConfig, syncRequiredCondition);\nonActivated(syncRequiredCondition);\n</script>\n<style scoped lang=\"less\">\n.remote-page-shell {\n height: 100%;\n}\n</style>\n","<template>\n <fullLayout>\n <div class=\"remote-page-shell\">\n <tablePageHost\n ref=\"hostRef\"\n :app_flag=\"field.app_flag\"\n :modalType=\"field.modalType\"\n ></tablePageHost>\n </div>\n </fullLayout>\n</template>\n<script setup lang=\"ts\">\n// 路由级薄壳:只负责「从路由解析 app_flag/modalType」与「required_condition 写入 store」\n// 这两个页面级副作用;其余壳逻辑(总线/详情抽屉/视图模式/hash/keep-alive 注册)\n// 全部参数化在 tablePageHost.vue 中,与 detailTablePro 共用同一份实现。\nimport fullLayout from 'liyu-pc-base/components/fullLayout/fullLayout.vue';\nimport tablePageHost from './tablePageHost.vue';\nimport { computed, ref, watch, onActivated } from 'vue';\nimport { useRoute } from 'vue-router';\nimport { useRequiredConditionStore } from 'liyu-pc-base/init-plugin';\n\nconst route = useRoute();\nconst requiredConditionStore = useRequiredConditionStore();\nconst path_arr = route.path.split('/');\nconst field = {\n app_flag: path_arr[path_arr.length - 2],\n modalType: path_arr[path_arr.length - 1],\n};\n\nconst hostRef = ref(null);\n// defineExpose 暴露的 ref 经模板引用访问时自动解包\nconst pageConfig = computed(() => hostRef.value?.pageConfig ?? null);\n\nconst syncRequiredCondition = () => {\n if (pageConfig.value?.required_condition) {\n requiredConditionStore.set_required_condition(\n field.modalType,\n pageConfig.value.required_condition,\n );\n }\n};\nwatch(pageConfig, syncRequiredCondition);\nonActivated(syncRequiredCondition);\n</script>\n<style scoped lang=\"less\">\n.remote-page-shell {\n height: 100%;\n}\n</style>\n","<template>\n <div class=\"view-item-container\">\n <div\n class=\"view-item-row\"\n @click=\"handleApplyView(record)\"\n >\n <a-tooltip :title=\"record.name\">\n <div class=\"view-name-container\">\n <span class=\"view-name\">{{ record.name }}</span>\n <a-tag\n v-if=\"record.is_default\"\n color=\"blue\"\n size=\"small\"\n class=\"view-default-tag\"\n >\n {{ $t('默认') }}\n </a-tag>\n </div>\n </a-tooltip>\n\n <span\n class=\"view-num\"\n style=\"float: right\"\n :style=\"currentView?.id === record.id ? { color: '#1890ff', fontWeight: 'bold' } : {}\"\n v-if=\"record.num\"\n >\n <a-tooltip :title=\"record.num\">\n {{ record.num }}\n </a-tooltip>\n </span>\n </div>\n <div\n :class=\"{ 'view-actions': true, current: currentView?.id === record.id }\"\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 </div>\n</template>\n<script setup lang=\"ts\">\nimport { useUserStore } from 'liyu-pc-base/init-plugin';\nimport { message, Modal } from 'ant-design-vue';\nimport { useI18n } from 'vue-i18n';\nconst { t } = useI18n();\nimport { reactive, createVNode } from 'vue';\nimport modalBox from 'liyu-pc-base/components/form-modal/modal-tools';\nimport {\n DeleteOutlined,\n EditOutlined,\n StarOutlined,\n StarFilled,\n ExclamationCircleOutlined,\n} from '@ant-design/icons-vue';\ninterface Props {\n fetchViews: Function;\n record: any;\n currentView: any;\n setCurrentView: Function;\n setViewData: Function;\n}\nconst props = defineProps<Props>();\nimport {\n delete_view_settings,\n update_view_settings,\n set_view_settings_default,\n refresh_view_settings_cache,\n} from 'liyu-pc-base/api/view-model';\n\nconst userStore = useUserStore();\nconst current_org = userStore.currentOrg;\n// ★ v24(决策 24):不做按钮权限校验 —— 不 CHECK_AUTH(VIEW_SYSTEM_EDIT),\n// 系统视图的修改/删除/设默认操作按钮恒展示。\nconst handleApplyView = (view: any) => {\n if (props.currentView?.id === view.id) {\n props.setCurrentView({ id: 'no-view' });\n props.setViewData(null);\n } else {\n props.setCurrentView(view);\n props.setViewData(view.data);\n }\n};\nconst 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 props.fetchViews();\n } catch (e) {\n message.error(t('设置默认失败'));\n }\n};\n\nconst 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 props.fetchViews();\n },\n });\n\n // ★ v24:系统视图选项不再做权限门控,恒展示\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 modalBox(tempModal);\n};\nconst 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 props.fetchViews();\n },\n });\n};\n</script>\n<style scoped lang=\"less\">\n.view-item-row {\n display: flex;\n justify-content: space-between;\n align-items: center;\n width: 100%;\n cursor: pointer;\n\n .view-name-container {\n flex: 1;\n display: flex;\n align-items: center;\n min-width: 0;\n padding: 4px 0;\n\n .view-name {\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-default-tag {\n flex: 0 0 auto;\n margin-left: 4px;\n }\n }\n}\n.view-item-container {\n position: relative;\n .view-actions {\n display: flex;\n gap: 4px;\n opacity: 0;\n transition: opacity 0.2s;\n position: absolute;\n align-items: center;\n top: 0;\n right: 0;\n border-radius: 4px;\n height: 30px;\n background: #f9f9f9;\n &.current {\n background: #b9defd;\n }\n }\n\n &:hover .view-actions {\n opacity: 1;\n }\n}\n</style>\n","<template>\n <div class=\"view-item-container\">\n <div\n class=\"view-item-row\"\n @click=\"handleApplyView(record)\"\n >\n <a-tooltip :title=\"record.name\">\n <div class=\"view-name-container\">\n <span class=\"view-name\">{{ record.name }}</span>\n <a-tag\n v-if=\"record.is_default\"\n color=\"blue\"\n size=\"small\"\n class=\"view-default-tag\"\n >\n {{ $t('默认') }}\n </a-tag>\n </div>\n </a-tooltip>\n\n <span\n class=\"view-num\"\n style=\"float: right\"\n :style=\"currentView?.id === record.id ? { color: '#1890ff', fontWeight: 'bold' } : {}\"\n v-if=\"record.num\"\n >\n <a-tooltip :title=\"record.num\">\n {{ record.num }}\n </a-tooltip>\n </span>\n </div>\n <div\n :class=\"{ 'view-actions': true, current: currentView?.id === record.id }\"\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 </div>\n</template>\n<script setup lang=\"ts\">\nimport { useUserStore } from 'liyu-pc-base/init-plugin';\nimport { message, Modal } from 'ant-design-vue';\nimport { useI18n } from 'vue-i18n';\nconst { t } = useI18n();\nimport { reactive, createVNode } from 'vue';\nimport modalBox from 'liyu-pc-base/components/form-modal/modal-tools';\nimport {\n DeleteOutlined,\n EditOutlined,\n StarOutlined,\n StarFilled,\n ExclamationCircleOutlined,\n} from '@ant-design/icons-vue';\ninterface Props {\n fetchViews: Function;\n record: any;\n currentView: any;\n setCurrentView: Function;\n setViewData: Function;\n}\nconst props = defineProps<Props>();\nimport {\n delete_view_settings,\n update_view_settings,\n set_view_settings_default,\n refresh_view_settings_cache,\n} from 'liyu-pc-base/api/view-model';\n\nconst userStore = useUserStore();\nconst current_org = userStore.currentOrg;\n// ★ v24(决策 24):不做按钮权限校验 —— 不 CHECK_AUTH(VIEW_SYSTEM_EDIT),\n// 系统视图的修改/删除/设默认操作按钮恒展示。\nconst handleApplyView = (view: any) => {\n if (props.currentView?.id === view.id) {\n props.setCurrentView({ id: 'no-view' });\n props.setViewData(null);\n } else {\n props.setCurrentView(view);\n props.setViewData(view.data);\n }\n};\nconst 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 props.fetchViews();\n } catch (e) {\n message.error(t('设置默认失败'));\n }\n};\n\nconst 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 props.fetchViews();\n },\n });\n\n // ★ v24:系统视图选项不再做权限门控,恒展示\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 modalBox(tempModal);\n};\nconst 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 props.fetchViews();\n },\n });\n};\n</script>\n<style scoped lang=\"less\">\n.view-item-row {\n display: flex;\n justify-content: space-between;\n align-items: center;\n width: 100%;\n cursor: pointer;\n\n .view-name-container {\n flex: 1;\n display: flex;\n align-items: center;\n min-width: 0;\n padding: 4px 0;\n\n .view-name {\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-default-tag {\n flex: 0 0 auto;\n margin-left: 4px;\n }\n }\n}\n.view-item-container {\n position: relative;\n .view-actions {\n display: flex;\n gap: 4px;\n opacity: 0;\n transition: opacity 0.2s;\n position: absolute;\n align-items: center;\n top: 0;\n right: 0;\n border-radius: 4px;\n height: 30px;\n background: #f9f9f9;\n &.current {\n background: #b9defd;\n }\n }\n\n &:hover .view-actions {\n opacity: 1;\n }\n}\n</style>\n","<template>\n <a-collapse\n v-model:activeKey=\"activeKey\"\n :bordered=\"false\"\n class=\"collapses\"\n style=\"background: rgb(255, 255, 255)\"\n >\n <template #expandIcon=\"{ isActive }\">\n <caret-right-outlined :rotate=\"isActive ? 90 : 0\" />\n </template>\n <a-collapse-panel\n key=\"personal\"\n :style=\"panelStyle\"\n >\n <template #header>\n <span style=\"font-weight: 700\">{{ $t('个人视图') }}</span>\n </template>\n <template #extra>\n <a-tooltip>\n <template #title>{{ $t('个人视图管理') }}</template>\n <setting-outlined\n style=\"margin-right: 10px\"\n @click.stop=\"handleManageView('personal')\"\n />\n </a-tooltip>\n <a-tooltip>\n <template #title>{{ $t('新建个人视图') }}</template>\n <plus-outlined @click.stop=\"addView('personal')\" />\n </a-tooltip>\n </template>\n <s-table\n v-if=\"personData?.length > 0\"\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 <ViewConfigCell\n :fetchViews=\"fetchViews\"\n :record=\"record\"\n :currentView=\"currentView\"\n :setViewData=\"setViewData\"\n :setCurrentView=\"setCurrentView\"\n />\n </template>\n </template>\n </s-table>\n </a-collapse-panel>\n <a-collapse-panel\n key=\"public\"\n :style=\"panelStyle\"\n >\n <template #header>\n <span style=\"font-weight: 700\">{{ $t('公共视图') }}</span>\n </template>\n <template #extra>\n <a-tooltip>\n <template #title>{{ $t('公共视图管理') }}</template>\n <setting-outlined\n style=\"margin-right: 10px\"\n @click.stop=\"handleManageView('public')\"\n />\n </a-tooltip>\n <a-tooltip>\n <template #title>{{ $t('新建公共视图') }}</template>\n <plus-outlined @click.stop=\"addView('public')\" />\n </a-tooltip>\n </template>\n <s-table\n v-if=\"publicData?.length > 0\"\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 <ViewConfigCell\n :fetchViews=\"fetchViews\"\n :record=\"record\"\n :currentView=\"currentView\"\n :setViewData=\"setViewData\"\n :setCurrentView=\"setCurrentView\"\n />\n </template>\n </template>\n </s-table>\n </a-collapse-panel>\n </a-collapse>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, ref, reactive, onMounted, PropType, watch } from 'vue';\nimport { SettingOutlined, PlusOutlined, CaretRightOutlined } from '@ant-design/icons-vue';\nimport { useI18n } from 'vue-i18n';\nimport { create_view_settings, change_view_settings_sort } from 'liyu-pc-base/api/view-model';\nimport { message } from 'ant-design-vue';\nimport modalBox from 'liyu-pc-base/components/form-modal/modal-tools';\nimport { useUserStore } from 'liyu-pc-base/init-plugin';\nimport ViewConfigCell from './viewConfigCell.vue';\n\nconst props = defineProps({\n view_key: {\n type: String,\n default: '',\n },\n view_flag_name: {\n type: String,\n default: '',\n },\n tableProState: {\n type: Object,\n default: () => null,\n },\n eventBus: {\n type: Object as PropType<any>,\n default: () => null,\n },\n hashPrefix: {\n type: String,\n default: '',\n },\n});\n\nconst activeKey = ref(['personal', 'public']);\nconst panelStyle =\n 'background: #ffffff;border-radius: 4px;margin-bottom: 2px;border: 0;overflow: hidden;';\nconst { t } = useI18n();\nconst userStore = useUserStore();\nconst current_org = userStore.currentOrg;\nconst userid = userStore.userid;\n// ★ v24(决策 24):不做按钮权限校验 —— 不 CHECK_AUTH(VIEW_SYSTEM_EDIT),\n// 系统视图的创建/修改/删除/设默认一律放行。\nconst setViewData = (data: any) => props.tableProState?.setViewData(data);\nconst getViewData = () => props.tableProState?.getViewData();\nconst viewDataList = computed(() => {\n return props.tableProState?.viewDataList || [];\n});\nconst fetchViews = () => props.tableProState?.fetchViews();\nconst currentView = computed({\n get: () => props.tableProState?.currentView,\n set: val => {\n props.tableProState.currentView = val;\n },\n});\nconst setCurrentView = (view: any) => {\n props.tableProState.currentView = view;\n};\n\nconst viewTableColumns = [{ dataIndex: 'name', key: 'name' }];\nconst selectedRowKeys = computed(() => {\n return [currentView.value?.id];\n});\n\nconst personData = computed(() => {\n const list = (viewDataList.value || [])\n .filter((item: any) => !!item.user_id)\n .sort((a, b) => (a.sort == b.sort ? a.id - b.id : a.sort - b.sort));\n return list;\n});\n\nconst publicData = computed(() => {\n const list = (viewDataList.value || [])\n .filter((item: any) => !item.user_id)\n .sort((a, b) => (a.sort == b.sort ? a.id - b.id : a.sort - b.sort));\n return list;\n});\n\nconst addView = (view_type: string) => {\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] }),\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 org_id: current_org.id,\n user_id: type === 'personal' ? userid : null,\n name: data.name,\n view_project__flag: process.env.VITE_APP_VIEW_PROJECT_FLAG,\n view_menu__flag: props.view_key,\n view_menu__name: props.view_flag_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 },\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\n // ★ v24:系统视图选项不再做权限门控,恒展示\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 modalBox(tempModal);\n};\n\nconst 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};\nwatch(\n () => props.tableProState?.currentView,\n newVal => {\n if (newVal) {\n window.location.hash = `${props.hashPrefix}${newVal.uid}`;\n }\n },\n);\nonMounted(() => {\n fetchViews();\n});\n</script>\n\n<style lang=\"less\">\n.collapses .ant-collapse-item .ant-collapse-content .ant-collapse-content-box {\n padding: 0;\n}\n</style>\n","<template>\n <a-collapse\n v-model:activeKey=\"activeKey\"\n :bordered=\"false\"\n class=\"collapses\"\n style=\"background: rgb(255, 255, 255)\"\n >\n <template #expandIcon=\"{ isActive }\">\n <caret-right-outlined :rotate=\"isActive ? 90 : 0\" />\n </template>\n <a-collapse-panel\n key=\"personal\"\n :style=\"panelStyle\"\n >\n <template #header>\n <span style=\"font-weight: 700\">{{ $t('个人视图') }}</span>\n </template>\n <template #extra>\n <a-tooltip>\n <template #title>{{ $t('个人视图管理') }}</template>\n <setting-outlined\n style=\"margin-right: 10px\"\n @click.stop=\"handleManageView('personal')\"\n />\n </a-tooltip>\n <a-tooltip>\n <template #title>{{ $t('新建个人视图') }}</template>\n <plus-outlined @click.stop=\"addView('personal')\" />\n </a-tooltip>\n </template>\n <s-table\n v-if=\"personData?.length > 0\"\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 <ViewConfigCell\n :fetchViews=\"fetchViews\"\n :record=\"record\"\n :currentView=\"currentView\"\n :setViewData=\"setViewData\"\n :setCurrentView=\"setCurrentView\"\n />\n </template>\n </template>\n </s-table>\n </a-collapse-panel>\n <a-collapse-panel\n key=\"public\"\n :style=\"panelStyle\"\n >\n <template #header>\n <span style=\"font-weight: 700\">{{ $t('公共视图') }}</span>\n </template>\n <template #extra>\n <a-tooltip>\n <template #title>{{ $t('公共视图管理') }}</template>\n <setting-outlined\n style=\"margin-right: 10px\"\n @click.stop=\"handleManageView('public')\"\n />\n </a-tooltip>\n <a-tooltip>\n <template #title>{{ $t('新建公共视图') }}</template>\n <plus-outlined @click.stop=\"addView('public')\" />\n </a-tooltip>\n </template>\n <s-table\n v-if=\"publicData?.length > 0\"\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 <ViewConfigCell\n :fetchViews=\"fetchViews\"\n :record=\"record\"\n :currentView=\"currentView\"\n :setViewData=\"setViewData\"\n :setCurrentView=\"setCurrentView\"\n />\n </template>\n </template>\n </s-table>\n </a-collapse-panel>\n </a-collapse>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, ref, reactive, onMounted, PropType, watch } from 'vue';\nimport { SettingOutlined, PlusOutlined, CaretRightOutlined } from '@ant-design/icons-vue';\nimport { useI18n } from 'vue-i18n';\nimport { create_view_settings, change_view_settings_sort } from 'liyu-pc-base/api/view-model';\nimport { message } from 'ant-design-vue';\nimport modalBox from 'liyu-pc-base/components/form-modal/modal-tools';\nimport { useUserStore } from 'liyu-pc-base/init-plugin';\nimport ViewConfigCell from './viewConfigCell.vue';\n\nconst props = defineProps({\n view_key: {\n type: String,\n default: '',\n },\n view_flag_name: {\n type: String,\n default: '',\n },\n tableProState: {\n type: Object,\n default: () => null,\n },\n eventBus: {\n type: Object as PropType<any>,\n default: () => null,\n },\n hashPrefix: {\n type: String,\n default: '',\n },\n});\n\nconst activeKey = ref(['personal', 'public']);\nconst panelStyle =\n 'background: #ffffff;border-radius: 4px;margin-bottom: 2px;border: 0;overflow: hidden;';\nconst { t } = useI18n();\nconst userStore = useUserStore();\nconst current_org = userStore.currentOrg;\nconst userid = userStore.userid;\n// ★ v24(决策 24):不做按钮权限校验 —— 不 CHECK_AUTH(VIEW_SYSTEM_EDIT),\n// 系统视图的创建/修改/删除/设默认一律放行。\nconst setViewData = (data: any) => props.tableProState?.setViewData(data);\nconst getViewData = () => props.tableProState?.getViewData();\nconst viewDataList = computed(() => {\n return props.tableProState?.viewDataList || [];\n});\nconst fetchViews = () => props.tableProState?.fetchViews();\nconst currentView = computed({\n get: () => props.tableProState?.currentView,\n set: val => {\n props.tableProState.currentView = val;\n },\n});\nconst setCurrentView = (view: any) => {\n props.tableProState.currentView = view;\n};\n\nconst viewTableColumns = [{ dataIndex: 'name', key: 'name' }];\nconst selectedRowKeys = computed(() => {\n return [currentView.value?.id];\n});\n\nconst personData = computed(() => {\n const list = (viewDataList.value || [])\n .filter((item: any) => !!item.user_id)\n .sort((a, b) => (a.sort == b.sort ? a.id - b.id : a.sort - b.sort));\n return list;\n});\n\nconst publicData = computed(() => {\n const list = (viewDataList.value || [])\n .filter((item: any) => !item.user_id)\n .sort((a, b) => (a.sort == b.sort ? a.id - b.id : a.sort - b.sort));\n return list;\n});\n\nconst addView = (view_type: string) => {\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] }),\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 org_id: current_org.id,\n user_id: type === 'personal' ? userid : null,\n name: data.name,\n view_project__flag: process.env.VITE_APP_VIEW_PROJECT_FLAG,\n view_menu__flag: props.view_key,\n view_menu__name: props.view_flag_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 },\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\n // ★ v24:系统视图选项不再做权限门控,恒展示\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 modalBox(tempModal);\n};\n\nconst 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};\nwatch(\n () => props.tableProState?.currentView,\n newVal => {\n if (newVal) {\n window.location.hash = `${props.hashPrefix}${newVal.uid}`;\n }\n },\n);\nonMounted(() => {\n fetchViews();\n});\n</script>\n\n<style lang=\"less\">\n.collapses .ant-collapse-item .ant-collapse-content .ant-collapse-content-box {\n padding: 0;\n}\n</style>\n","<template>\n <div\n class=\"config-container\"\n v-if=\"open\"\n >\n <a-tabs v-model:activeKey=\"activeTabKey\">\n <a-tab-pane\n key=\"normal\"\n tab=\"标准\"\n v-if=\"enable_view_types.includes('normal')\"\n >\n <ViewsConfig\n v-if=\"state?.config && tableMode === 'normal'\"\n :view_key=\"view_key\"\n :view_flag_name=\"state.config.title\"\n :tableProState=\"state\"\n :eventBus=\"eventBus\"\n :hashPrefix=\"''\"\n />\n </a-tab-pane>\n <a-tab-pane\n key=\"pivot\"\n tab=\"透视表\"\n v-if=\"enable_view_types.includes('pivot')\"\n >\n <ViewsConfig\n v-if=\"state?.config && tableMode === 'pivot'\"\n :view_key=\"view_key\"\n :view_flag_name=\"state.config.title\"\n :tableProState=\"state\"\n :eventBus=\"eventBus\"\n :hashPrefix=\"'pivot:'\"\n />\n </a-tab-pane>\n <a-tab-pane\n key=\"pivot_charts\"\n tab=\"透视图\"\n v-if=\"enable_view_types.includes('pivot_charts')\"\n >\n <ViewsConfig\n v-if=\"state?.config && tableMode === 'pivot_charts'\"\n :view_key=\"view_key\"\n :view_flag_name=\"state.config.title\"\n :tableProState=\"state\"\n :eventBus=\"eventBus\"\n :hashPrefix=\"'pivotcharts:'\"\n />\n </a-tab-pane>\n </a-tabs>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, inject, watch, PropType } from 'vue';\nimport ViewsConfig from './viewsConfig.vue';\n\nconst props = defineProps({\n open: {\n type: Boolean,\n default: true,\n },\n eventBus: {\n type: Object as PropType<any>,\n default: () => null,\n },\n tableMode: {\n type: String as PropType<string | undefined>,\n default: 'normal',\n },\n pageConfig: {\n type: Object as PropType<any>,\n default: () => null,\n },\n});\n\nconst emit = defineEmits(['update:open', 'columnsChange', 'update:tableMode']);\nconst enable_view_types = computed(() => props.pageConfig?.enable_view_types || []);\nconst tableMode = defineModel('tableMode');\nconst activeTabKey = computed({\n get: () => {\n if (!props.pageConfig?.enable_view_types?.length) {\n return undefined;\n }\n const currentType = props.tableMode || props.pageConfig?.default_view_type || 'normal';\n const isFind = props.pageConfig?.enable_view_types?.includes(currentType);\n if (!isFind) {\n return props.pageConfig?.enable_view_types[0];\n } else {\n return currentType;\n }\n },\n set: val => {\n emit('update:tableMode', val);\n },\n});\n\n// Sync active tab with tableMode\nwatch(\n () => props.tableMode,\n newMode => {\n if (newMode === 'pivot') {\n activeTabKey.value = 'pivot';\n } else if (newMode === 'pivot_charts') {\n activeTabKey.value = 'pivot_charts';\n } else {\n activeTabKey.value = 'normal';\n }\n },\n { immediate: true },\n);\n\nconst state = inject<any>('tableProStateProxy');\n\nconst view_key = computed(() => {\n return `table_pro_${state.value?.config?.key}`;\n});\n</script>\n\n<style scoped lang=\"less\">\n.config-container {\n height: 100%;\n display: flex;\n flex-direction: column;\n background: #fff;\n justify-content: space-between;\n :deep(.ant-tabs) {\n flex: 1;\n min-height: 0;\n display: flex;\n flex-direction: column;\n padding: 0;\n overflow: hidden;\n .ant-tabs-nav {\n padding: 0 10px;\n flex-shrink: 0;\n }\n .ant-tabs-content-holder {\n flex: 1;\n min-height: 0;\n overflow-y: auto;\n overflow-x: hidden;\n }\n .ant-tabs-content-top {\n min-height: 100%;\n }\n }\n}\n.left-extra {\n margin-right: 10px;\n}\n\n:deep(.ant-tabs-nav) {\n margin-bottom: 0;\n}\n</style>\n","<template>\n <div\n class=\"config-container\"\n v-if=\"open\"\n >\n <a-tabs v-model:activeKey=\"activeTabKey\">\n <a-tab-pane\n key=\"normal\"\n tab=\"标准\"\n v-if=\"enable_view_types.includes('normal')\"\n >\n <ViewsConfig\n v-if=\"state?.config && tableMode === 'normal'\"\n :view_key=\"view_key\"\n :view_flag_name=\"state.config.title\"\n :tableProState=\"state\"\n :eventBus=\"eventBus\"\n :hashPrefix=\"''\"\n />\n </a-tab-pane>\n <a-tab-pane\n key=\"pivot\"\n tab=\"透视表\"\n v-if=\"enable_view_types.includes('pivot')\"\n >\n <ViewsConfig\n v-if=\"state?.config && tableMode === 'pivot'\"\n :view_key=\"view_key\"\n :view_flag_name=\"state.config.title\"\n :tableProState=\"state\"\n :eventBus=\"eventBus\"\n :hashPrefix=\"'pivot:'\"\n />\n </a-tab-pane>\n <a-tab-pane\n key=\"pivot_charts\"\n tab=\"透视图\"\n v-if=\"enable_view_types.includes('pivot_charts')\"\n >\n <ViewsConfig\n v-if=\"state?.config && tableMode === 'pivot_charts'\"\n :view_key=\"view_key\"\n :view_flag_name=\"state.config.title\"\n :tableProState=\"state\"\n :eventBus=\"eventBus\"\n :hashPrefix=\"'pivotcharts:'\"\n />\n </a-tab-pane>\n </a-tabs>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, inject, watch, PropType } from 'vue';\nimport ViewsConfig from './viewsConfig.vue';\n\nconst props = defineProps({\n open: {\n type: Boolean,\n default: true,\n },\n eventBus: {\n type: Object as PropType<any>,\n default: () => null,\n },\n tableMode: {\n type: String as PropType<string | undefined>,\n default: 'normal',\n },\n pageConfig: {\n type: Object as PropType<any>,\n default: () => null,\n },\n});\n\nconst emit = defineEmits(['update:open', 'columnsChange', 'update:tableMode']);\nconst enable_view_types = computed(() => props.pageConfig?.enable_view_types || []);\nconst tableMode = defineModel('tableMode');\nconst activeTabKey = computed({\n get: () => {\n if (!props.pageConfig?.enable_view_types?.length) {\n return undefined;\n }\n const currentType = props.tableMode || props.pageConfig?.default_view_type || 'normal';\n const isFind = props.pageConfig?.enable_view_types?.includes(currentType);\n if (!isFind) {\n return props.pageConfig?.enable_view_types[0];\n } else {\n return currentType;\n }\n },\n set: val => {\n emit('update:tableMode', val);\n },\n});\n\n// Sync active tab with tableMode\nwatch(\n () => props.tableMode,\n newMode => {\n if (newMode === 'pivot') {\n activeTabKey.value = 'pivot';\n } else if (newMode === 'pivot_charts') {\n activeTabKey.value = 'pivot_charts';\n } else {\n activeTabKey.value = 'normal';\n }\n },\n { immediate: true },\n);\n\nconst state = inject<any>('tableProStateProxy');\n\nconst view_key = computed(() => {\n return `table_pro_${state.value?.config?.key}`;\n});\n</script>\n\n<style scoped lang=\"less\">\n.config-container {\n height: 100%;\n display: flex;\n flex-direction: column;\n background: #fff;\n justify-content: space-between;\n :deep(.ant-tabs) {\n flex: 1;\n min-height: 0;\n display: flex;\n flex-direction: column;\n padding: 0;\n overflow: hidden;\n .ant-tabs-nav {\n padding: 0 10px;\n flex-shrink: 0;\n }\n .ant-tabs-content-holder {\n flex: 1;\n min-height: 0;\n overflow-y: auto;\n overflow-x: hidden;\n }\n .ant-tabs-content-top {\n min-height: 100%;\n }\n }\n}\n.left-extra {\n margin-right: 10px;\n}\n\n:deep(.ant-tabs-nav) {\n margin-bottom: 0;\n}\n</style>\n","<template>\n <div\n v-if=\"showLoading\"\n class=\"global-filter-loading\"\n >\n <a-spin size=\"large\" />\n <div class=\"global-filter-loading__text\">数据定位中,请稍候……</div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, watch } from 'vue';\n\ninterface Props {\n visible: boolean;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n visible: false,\n});\n\nconst showLoading = ref(false);\nconst startTime = ref(0);\nconst minDisplayTime = 1000; // 至少显示2秒\nlet showTimer = null;\nwatch(\n () => props.visible,\n newVal => {\n if (newVal) {\n // 超过0.5秒才显示\n showTimer = setTimeout(() => {\n showTimer = null;\n startTime.value = Date.now();\n showLoading.value = true;\n }, 500);\n } else {\n // 如果已经显示了loading,至少显示2秒\n if (showTimer) {\n clearTimeout(showTimer);\n }\n if (!showLoading.value) {\n return;\n }\n const elapsed = Date.now() - startTime.value;\n const remaining = minDisplayTime - elapsed;\n if (remaining > 0) {\n setTimeout(() => {\n showLoading.value = false;\n }, remaining);\n } else {\n showLoading.value = false;\n }\n }\n },\n);\n</script>\n\n<style scoped lang=\"less\">\n.global-filter-loading {\n position: fixed;\n inset: 0;\n z-index: 3000;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 16px;\n background: rgba(255, 255, 255, 0.65);\n\n &__text {\n color: #333;\n font-size: 14px;\n }\n}\n</style>\n","<template>\n <div\n v-if=\"showLoading\"\n class=\"global-filter-loading\"\n >\n <a-spin size=\"large\" />\n <div class=\"global-filter-loading__text\">数据定位中,请稍候……</div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, watch } from 'vue';\n\ninterface Props {\n visible: boolean;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n visible: false,\n});\n\nconst showLoading = ref(false);\nconst startTime = ref(0);\nconst minDisplayTime = 1000; // 至少显示2秒\nlet showTimer = null;\nwatch(\n () => props.visible,\n newVal => {\n if (newVal) {\n // 超过0.5秒才显示\n showTimer = setTimeout(() => {\n showTimer = null;\n startTime.value = Date.now();\n showLoading.value = true;\n }, 500);\n } else {\n // 如果已经显示了loading,至少显示2秒\n if (showTimer) {\n clearTimeout(showTimer);\n }\n if (!showLoading.value) {\n return;\n }\n const elapsed = Date.now() - startTime.value;\n const remaining = minDisplayTime - elapsed;\n if (remaining > 0) {\n setTimeout(() => {\n showLoading.value = false;\n }, remaining);\n } else {\n showLoading.value = false;\n }\n }\n },\n);\n</script>\n\n<style scoped lang=\"less\">\n.global-filter-loading {\n position: fixed;\n inset: 0;\n z-index: 3000;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 16px;\n background: rgba(255, 255, 255, 0.65);\n\n &__text {\n color: #333;\n font-size: 14px;\n }\n}\n</style>\n","// ============================================================================\n// sql_db_view TS 配置示例(flag = example,§4.3 ⑤ / §4.4 ④)\n// ----------------------------------------------------------------------------\n// ★ 约定:\n// ① 文件路径 = `sql_db_view/configs/{group}/{flag}.ts`,default 导出签名\n// `(t, { model_app }) => config`(与 remotePages/configs 一致,model_app 恒为 'db_view');\n// ② **只做白名单字段的增量覆盖**(§4.4 ④),运行时 URL / 列(baseColumns)/\n// 高级搜索字段(base_search_condition_config_list)一律不写 —— 它们来自\n// DbView / DbViewColumn(get_page_config 编译返回),DB 是单一真相源;\n// ③ 只支持高级搜索,无 searchConfig / 无增删改 URL / 无权限位(v20/v24);\n// ④ flag 命中规则见 pageConfig.ts:`ts_config_map[view_flag]`(按文件名去 .ts 匹配)。\n// 本示例文件名为 example —— 只有存在 flag=example 的 DbView 时才会生效,否则纯文档。\n// ============================================================================\nexport default (t, { model_app }) => {\n void model_app; // 固定为 'db_view',配置内不需要区分 app\n void t; // 需要多语言时用 t('...') 包按钮/标题文案;纯静态配置可不使用\n return {\n // ---- 页面标题相关(可选)----\n // title 由路由 meta 提供,一般不需要在这里配\n\n // ---- 视图形态(可选,均有后端默认值)----\n // enable_view_types: ['normal', 'pivot', 'pivot_charts'], // 启用的视图类型\n // default_view_type: 'normal', // 默认视图\n // default_hide_view: false, // 默认收起左侧保存视图面板\n // pivot_table_max_records: 10000, // 透视表最大记录数\n\n // ---- 头部按钮(可选;★ v24:不做权限校验,配置了就展示)----\n head_btn_list: [\n // 示例:一个「使用说明」按钮(button 组件形态与 remotePages 的 head_btn_list 相同)\n // {\n // name: t('使用说明'),\n // type: 'button',\n // click: ({ dataSource }) => { console.log(dataSource); },\n // },\n ],\n\n // ---- 行按钮 / 行选择(可选)----\n // btn_list: [],\n // is_selection: false,\n // rowSelection: { type: 'checkbox', checkStrictly: false },\n\n // ---- 分页(可选)----\n // is_pagination: true,\n // pageSize: 50,\n // page_size_options: ['10', '20', '50', '100', '200', '500'],\n\n // ---- 单元格 / 行渲染(可选)----\n // customCell: ({ record, column }) => { ... },\n // customRow: (record, index) => { ... },\n // customHeaderCell: (column) => { ... },\n\n // ---- 高级搜索(可选;字段本体来自 DbViewColumn.is_base_query / is_default_query)----\n // 默认条件组:打开页面时预置的搜索条件(结构与 lybase 高级搜索一致)\n default_search_condition_config_list: [\n // [\n // {\n // field_name: 'is_active',\n // operator: 'eq',\n // value: [true],\n // format: 'input',\n // class_name: 'bool',\n // },\n // ],\n ],\n // 条件分组列表(搜索字段分组展示)\n condition_group_config_list: [],\n // 隐藏查询条件:始终附加、用户不可见(后端 build_where 会一并推进 WHERE)\n advanced_base_conditions: [],\n\n // ---- 其它(可选)----\n // required_condition: [], // 全局切换配置\n // refresh_type: '手动', // '手动' | '5s' | '10s' | '30s'\n // detailConfigs: {}, // 详情抽屉配置(key → { component, width, title })\n // i18n: null, // 多语言覆盖配置\n // default_column_field: [], // 默认展示列\n };\n};\n","// ============================================================================\n// sql_db_view 配置解析脚本(v20 必做项:独立生成,不依赖 remotePages/index.ts)\n// ----------------------------------------------------------------------------\n// 职责:融合「接口数据」+「前端 TS 配置」,产出页面壳 / rightTable 消费的 pageConfig。\n//\n// 与 remotePages getPageConfig 的两点区别(§4.4 ④ 白名单裁剪):\n// ① 默认配置只保留搜索+展示相关白名单项 —— 无增删改(addData/updateData/...)、\n// 无普通搜索(searchConfig)、无权限位(titleList.is_create/...);\n// ② 只支持高级搜索(带运算符),is_show_advantage 恒 true / is_show_normal_search 恒 false。\n//\n// URL 策略(v10/v23):**全部显式声明**,不做 `_list` → `_pivot_table_rust` 字符串替换派生:\n// queryData /db_view/sqlview_query_{flag}_list\n// countData /db_view/sqlview_query_{flag}_count\n// queryConditionGroupData /db_view/sqlview_query_{flag}_group\n// getData /db_view/sqlview_get_{flag}\n// field_search_config /db_view/sqlview_obtain_{flag}_field_search_config\n// pivot_table_url /db_view/sqlview_query_{flag}_pivot_table_rust\n// pivot_charts_url /db_view/sqlview_query_{flag}_pivot_charts_rust\n//\n// ★ v24(决策 24):本组件不做任何按钮权限校验 —— 不实现 getApiPermission、\n// 不派生 is_create/is_update 权限位、按钮可见性完全由白名单配置决定。\n// ============================================================================\nimport { cloneDeep } from 'lodash';\nimport { getApiData } from 'liyu-pc-base/api/api-model';\nimport { useEnv, useGlobMap, useCellComponentMap, useCellFormatExcelValueMap } from 'liyu-pc-base/init-plugin';\nimport { modify_by_i18n_config } from 'liyu-pc-base/components/remotePages/i18n_config';\nimport type { SqlViewPageConfig } from './typing';\n\n/** app_flag 固化为常量(v22):本组件只服务 /db_view/*,不解析、不传参 */\nexport const DB_VIEW_APP_FLAG = 'db_view';\n\n/** §4.4 ④ 白名单:默认配置/接口数据只保留这些键(搜索+展示) */\nconst CONFIG_WHITELIST = [\n 'btn_list',\n 'head_btn_list',\n 'is_selection',\n 'rowSelection',\n 'is_pagination',\n 'pageSize',\n 'page_size_options',\n 'customCell',\n 'customRow',\n 'customHeaderCell',\n 'isView',\n 'default_hide_view',\n 'enable_view_types',\n 'default_view_type',\n 'pivot_table_max_records',\n 'advanced_base_conditions',\n 'default_search_condition_config_list',\n 'condition_group_config_list',\n 'base_search_condition_config_list',\n 'baseColumns',\n 'rowKey', // ★ v29.24:行唯一键(单主键 → 列名;0 个或 ≥2 个主键 → '_id',v29.40),透传给 tablePro\n 'default_column_field',\n 'required_condition',\n 'refresh_type',\n 'i18n',\n 'detailConfigs',\n] as const;\n\n/** 从任意配置对象中摘出白名单键(白名单外的键一律丢弃) */\nconst pickWhitelist = (source: any): Record<string, any> => {\n const out: Record<string, any> = {};\n if (!source) return out;\n for (const key of CONFIG_WHITELIST) {\n if (source[key] !== undefined) {\n out[key] = source[key];\n }\n }\n return out;\n};\n\n// ---------------- TS 配置加载(configs/{group}/{flag}.ts,仅增量覆盖、不重复写列) ----------------\n\nconst ts_config_map: { [key: string]: any } = {};\nconst init_ts_config = () => {\n if (Object.keys(ts_config_map).length > 0) {\n return;\n }\n const allTsConfigs: any = import.meta.glob('liyu-pc-base/components/sql_db_view/configs/*/*.ts', {\n eager: true,\n });\n const customTsConfigs: any = useGlobMap('sql_db_view');\n Object.assign(allTsConfigs, customTsConfigs);\n Object.keys(allTsConfigs).forEach(full_file_name => {\n const file_name_list = full_file_name.split('/');\n const file_name = file_name_list[file_name_list.length - 1].replace('.ts', '');\n if (file_name.endsWith('-config')) {\n return;\n }\n ts_config_map[file_name] = allTsConfigs[full_file_name].default;\n });\n};\n\n// ---------------- 列/按钮合并(与 remotePages/index.ts 同机制) ----------------\n\nconst mergeBtnList = (config: any[], customConfig: any[]) => {\n if (!customConfig) return config;\n const result = cloneDeep(config || []);\n const btnMap = new Map();\n result.forEach((btn, index) => {\n delete btn._key;\n btnMap.set(btn.name, index);\n });\n let last_order = 0;\n customConfig.forEach((customBtn: any) => {\n if (!customBtn.order) {\n customBtn.order = last_order + 1;\n }\n last_order = customBtn.order;\n customBtn._key = `custom_${customBtn.name}_${Math.random()}`;\n const existingIndex = btnMap.get(customBtn.name);\n if (existingIndex !== undefined) {\n const existingBtn = result[existingIndex];\n if (customBtn.children && existingBtn.children) {\n existingBtn.children = mergeBtnList(existingBtn.children, customBtn.children);\n }\n const temp = cloneDeep(customBtn);\n delete temp.children;\n Object.assign(existingBtn, temp);\n } else {\n const temp = cloneDeep(customBtn);\n result.push(temp);\n if (temp.children) {\n temp.children = mergeBtnList([], temp.children);\n }\n }\n });\n return result;\n};\n\nconst mergeDataFunc: Record<string, Function> = {\n btn_list: mergeBtnList,\n head_btn_list: mergeBtnList,\n};\n\nconst mergeData = (config: any, customConfig: any) => {\n const res = cloneDeep(config);\n Object.keys(customConfig).forEach(key => {\n if (mergeDataFunc[key]) {\n res[key] = mergeDataFunc[key](config[key], customConfig[key]);\n } else {\n res[key] = customConfig[key];\n }\n });\n Object.assign(config, res);\n};\n\n// ---------------- 列后处理(cellComponent → 导出格式映射,与 remotePages 同机制) ----------------\n\nconst processBaseColumns = (config: any) => {\n if (!config || !Array.isArray(config)) {\n return config;\n }\n const cellComponentMap = useCellComponentMap();\n const cellFormatExcelValueMap = useCellFormatExcelValueMap();\n for (const item of config) {\n if (item.cellComponent && !item.formatExcelValue) {\n const cellComponentData = cellComponentMap[item.cellComponent];\n if (cellComponentData) {\n const defaultExcelFormat = cellComponentData.defaultExcelFormat;\n const cellFormatExcelValue = cellFormatExcelValueMap[defaultExcelFormat];\n if (cellFormatExcelValue) {\n item.formatExcelValue = cellFormatExcelValue.flag;\n }\n }\n }\n }\n return config;\n};\n\nconst processDataFunc: Record<string, Function> = {\n baseColumns: processBaseColumns,\n};\n\nconst processData = (config: any) => {\n Object.keys(config).forEach(key => {\n if (processDataFunc[key]) {\n config[key] = processDataFunc[key](config[key]);\n }\n });\n};\n\n// ---------------- 运行时 URL(v10/v23:显式声明,不做字符串替换派生) ----------------\n\nexport interface SqlViewRuntimeUrls {\n queryData: string;\n countData: string;\n queryConditionGroupData: string;\n getData: string;\n fieldSearchConfigUrl: string;\n obtainColumnDataUrl: string;\n pivotTableUrl: string;\n pivotChartsUrl: string;\n}\n\nexport const buildRuntimeUrls = (view_flag: string): SqlViewRuntimeUrls => ({\n queryData: `/${DB_VIEW_APP_FLAG}/sqlview_query_${view_flag}_list`,\n countData: `/${DB_VIEW_APP_FLAG}/sqlview_query_${view_flag}_count`,\n queryConditionGroupData: `/${DB_VIEW_APP_FLAG}/sqlview_query_${view_flag}_group`,\n getData: `/${DB_VIEW_APP_FLAG}/sqlview_get_${view_flag}`,\n fieldSearchConfigUrl: `/${DB_VIEW_APP_FLAG}/sqlview_obtain_${view_flag}_field_search_config`,\n obtainColumnDataUrl: `/${DB_VIEW_APP_FLAG}/sqlview_obtain_${view_flag}_column_data`,\n pivotTableUrl: `/${DB_VIEW_APP_FLAG}/sqlview_query_${view_flag}_pivot_table_rust`,\n pivotChartsUrl: `/${DB_VIEW_APP_FLAG}/sqlview_query_${view_flag}_pivot_charts_rust`,\n});\n\n// ---------------- 取数 + 配置融合主入口(v26:合一,async) ----------------\n\nexport const getSqlDbViewPageConfig = async (\n modalType: string, // 形如 `db_view-{flag}`\n org_id: string | number,\n t: any,\n options?: {\n to_i18n?: boolean;\n },\n): Promise<SqlViewPageConfig> => {\n const { to_i18n = true } = options || {};\n init_ts_config();\n const view_flag = modalType.split('-')[1];\n const env = useEnv();\n\n // ★ 取数(v26 并入;v25 起两路并行):baseColumns / base_search_condition_config_list\n // 完全以 DbViewColumn(get_page_config 编译返回)为单一真相源。\n // 列级覆盖接口 override_column_config 已于 v29.22 随后端一并删除(新通用组件不做列级覆盖)。\n const [defaultRes, serverRes] = await Promise.all([\n getApiData({ org_id, flag: view_flag }, `/${DB_VIEW_APP_FLAG}/get_page_config`, false, {\n skip_error: true,\n }),\n getApiData(\n { org_id, flag: `${DB_VIEW_APP_FLAG}-${view_flag}_config` },\n '/sys/get_global_custom_data_by_flag_without_org_id',\n ),\n ]);\n\n // ① 白名单默认值(v20/v27:默认值只含 §4.4 ④ 白名单字段,无增删改 URL、\n // 无 searchConfig、无权限位、无 query_params/get_db_alias 等通用页字段)\n const defaultConfig: SqlViewPageConfig = {\n is_selection: false,\n rowSelection: { type: 'checkbox', checkStrictly: false },\n is_pagination: true,\n pageSize: 50,\n page_size_options: ['10', '20', '50', '100', '200', '500', '1000', '3000', '10000'],\n customCell: null,\n customRow: null,\n customHeaderCell: null,\n isView: true,\n default_hide_view: false,\n enable_view_types: ['normal', 'pivot', 'pivot_charts'],\n default_view_type: 'normal',\n pivot_table_max_records: 10000,\n advanced_base_conditions: [],\n default_search_condition_config_list: null,\n condition_group_config_list: null,\n base_search_condition_config_list: null,\n baseColumns: null,\n rowKey: 'id', // ★ v29.24:兜底与 tablePro 默认一致;接口下发时被覆盖(主键列名 / '_id')\n default_column_field: [],\n required_condition: [],\n refresh_type: '手动',\n i18n: null,\n detailConfigs: {},\n btn_list: null,\n head_btn_list: null,\n };\n\n // ② 接口 defaultConfig(get_page_config:baseColumns + 高级搜索 + 白名单 meta)——只摘白名单\n Object.assign(defaultConfig, pickWhitelist(defaultRes || {}));\n\n // ③ serverConfig(全局自定义配置)——同样只摘白名单\n Object.assign(defaultConfig, pickWhitelist(serverRes || {}));\n\n const mergedConfig = cloneDeep(defaultConfig);\n\n // ④ 前端 TS 配置(configs/{group}/{flag}.ts)——增量覆盖;★ 列不在这里写(DB 单一真相源)\n const ts_config = ts_config_map[view_flag] || ts_config_map[modalType];\n if (ts_config) {\n const ts_config_data = pickWhitelist(cloneDeep(ts_config(t, { model_app: DB_VIEW_APP_FLAG })));\n mergeData(mergedConfig, ts_config_data);\n }\n\n // ⑤ 列后处理(cellComponent → formatExcelValue)\n // ★ v27:运行时 URL **不进 PageConfig**(类型只含白名单字段)——\n // rightTable 用 buildRuntimeUrls(view_flag) 自行派生 8 条 sqlview_* URL。\n processData(mergedConfig);\n\n let result: any = mergedConfig;\n if (to_i18n && env.VITE_APP_ENABLE_ZH_EN) {\n // modify_by_i18n_config 就地处理 mergedConfig(i18n 在白名单内),返回值即同一对象\n result = modify_by_i18n_config(mergedConfig, t, modalType);\n }\n return result as SqlViewPageConfig;\n};\n","<template>\n <div class=\"table-wrapper\">\n <!--\n keep-alive 缓存三种表格模式(标准 / 透视表 / 透视图)的组件实例。\n 左侧切换 tab 时,被隐藏的组件不会被销毁,其已加载的数据与视图状态\n 保留在内存中,再次切回时可以瞬间渲染,无需重新拉取数据。\n 注意:三个组件各自绑定独立的 config,避免共用同一份 config 导致\n 缓存实例在重新激活时被错误 prop 覆盖。\n -->\n <keep-alive>\n <template v-if=\"normalConfig && tableMode === 'normal'\">\n <a-alert\n v-if=\"filter_id_key\"\n type=\"warning\"\n closable\n show-icon\n @close=\"onClearFilterIdkey\"\n >\n <template #message>\n <div class=\"filter-message\">\n <span\n v-for=\"item in filterList\"\n :key=\"item.label\"\n >\n {{ item.label }}:\n <a-tag>{{ item.value }}</a-tag>\n </span>\n <span>\n 值字段:\n <a-tag>{{ matchValueLabel }}</a-tag>\n </span>\n </div>\n <div>\n 当前数据已通过透视表定位,此功能为临时过滤,不会被视图记录。关闭可恢复原始数据。\n </div>\n </template>\n </a-alert>\n\n <tablePro\n :config=\"normalConfig\"\n ref=\"tableProRef\"\n :eventBus=\"eventBus\"\n >\n <template #header_bar_before_title>\n <div v-if=\"pageConfig.isView\">\n <div\n class=\"toggle-button\"\n @click=\"toggleOpen\"\n >\n <MenuFoldOutlined v-if=\"leftOpen\" />\n <MenuUnfoldOutlined v-else />\n </div>\n </div>\n </template>\n </tablePro>\n </template>\n <pivotTable\n v-else-if=\"pivotConfig && tableMode === 'pivot'\"\n :config=\"pivotConfig\"\n ref=\"pivotTableRef\"\n :eventBus=\"eventBus\"\n @filter-for-id-key-start=\"handleFilterForIdKeyStart\"\n @filterForIdKey=\"handleFilterForIdKey\"\n >\n <template #header_bar_before_title>\n <div v-if=\"pageConfig.isView\">\n <div\n class=\"toggle-button\"\n @click=\"toggleOpen\"\n >\n <MenuFoldOutlined v-if=\"leftOpen\" />\n <MenuUnfoldOutlined v-else />\n </div>\n </div>\n </template>\n </pivotTable>\n <pivotCharts\n v-else-if=\"pivotChartsConfig && tableMode === 'pivot_charts'\"\n :config=\"pivotChartsConfig\"\n ref=\"pivotChartsRef\"\n :eventBus=\"eventBus\"\n >\n <template #header_bar_before_title>\n <div v-if=\"pageConfig.isView\">\n <div\n class=\"toggle-button\"\n @click=\"toggleOpen\"\n >\n <MenuFoldOutlined v-if=\"leftOpen\" />\n <MenuUnfoldOutlined v-else />\n </div>\n </div>\n </template>\n </pivotCharts>\n </keep-alive>\n\n <!-- 透视表双击定位时的全局 loading 遮罩:接口可能耗时较久,覆盖整页防止误操作 -->\n <FilterLoading :visible=\"filterLoading\" />\n </div>\n</template>\n<script setup lang=\"ts\">\n// ============================================================================\n// sql_db_view 右侧容器(蓝本:remotePages/v2/rightTable.vue,按 §4.1 裁剪)\n// 与蓝本的差异:\n// ① 去掉 btnAdd / 增删改(只读页);\n// ② 去掉 AI 助手页面能力注册(ai-view-helper / ai-view-ability-schemas / 快速操作);\n// ③ ★ v24(决策 24):去掉全部按钮权限校验 —— 不 CHECK_AUTH(VIEW_SYSTEM_EDIT)、\n// 无 is_view_system_edit_auth,保存视图的系统视图操作一律放行;\n// ④ ★ v10/v23:pivot / field_search_config URL 显式声明(pageConfig 已由 pageConfig.ts\n// 按 flag 拼好),不做 `_list` → `_pivot_table_rust` 字符串替换派生;\n// ⑤ v20:只支持高级搜索(is_show_advantage 恒 true)。\n// ============================================================================\nimport tablePro from 'liyu-pc-base/components/tablePro/tablePro.vue';\nimport pivotTable from 'liyu-pc-base/components/tablePro/pivotTable.vue';\nimport pivotCharts from 'liyu-pc-base/components/tablePro/pivotCharts.vue';\nimport { computed, onMounted, ref, watch, nextTick } from 'vue';\nimport type { SqlViewPageConfig } from './typing';\nimport type {\n SearchGroupItem,\n Table,\n SearchConfig,\n RefreshType,\n RowSelectionType,\n} from 'liyu-pc-base/components/tablePro/typing';\nimport FilterLoading from './FilterLoading.vue';\nimport { MenuFoldOutlined, MenuUnfoldOutlined } from '@ant-design/icons-vue';\nimport { useRoute } from 'vue-router';\nimport { genID } from 'liyu-pc-base/utils/function';\nimport { useUserStore } from 'liyu-pc-base/init-plugin';\nimport { useI18n } from 'vue-i18n';\nimport { message } from 'ant-design-vue';\nimport { buildRuntimeUrls } from './pageConfig';\n\n// 三种表格模式各自独立的 config:\n// keep-alive 缓存隐藏的组件实例,若共用同一个 config,重新激活时 prop 会\n// 被其它模式的 config 覆盖。拆分为三个后才能保证缓存实例数据不被污染。\nconst normalConfig = ref<Table>(null);\nconst pivotConfig = ref<Table>(null);\nconst pivotChartsConfig = ref<Table>(null);\n\ninterface Props {\n eventBus: any;\n pageConfig: SqlViewPageConfig;\n modalType: string;\n tableMode?: 'normal' | 'pivot' | 'pivot_charts';\n setting_drawer_width: number;\n}\nconst props = withDefaults(defineProps<Props>(), {\n eventBus: null,\n pageConfig: null,\n tableMode: 'normal',\n});\nconst emit = defineEmits(['changeMode']);\nconst userStore = useUserStore();\nconst { t } = useI18n();\nconst route = useRoute();\nconst tableProRef = ref(null);\nconst pivotTableRef = ref(null);\nconst pivotChartsRef = ref(null);\nconst filter_id_key = ref('');\nconst filterList = ref<{ label: string; value: string }[]>([]);\nconst matchValueLabel = ref('');\n// 透视表双击定位时的全局 loading 遮罩:filterForIdKeyStart 打开,filterForIdKey 关闭\nconst filterLoading = ref(false);\nconst activeTableRef = computed(() => {\n if (props.tableMode === 'pivot') return pivotTableRef.value;\n if (props.tableMode === 'pivot_charts') return pivotChartsRef.value;\n return tableProRef.value;\n});\nconst leftOpen = defineModel('leftOpen', {\n default: true,\n});\n\n// 三种表格模式在挂载时一次性构建各自的 config。\n// 切换 tableMode 不再销毁/重建组件,而是由 keep-alive 缓存隐藏实例,\n// 已加载的数据随实例保留,切回时即时显示,无需重新拉取。\nonMounted(() => {\n normalConfig.value = getConfig('normal');\n pivotConfig.value = getConfig('pivot');\n pivotChartsConfig.value = getConfig('pivot_charts');\n});\n\n// 切换左侧 tab 时同步更新 URL hash:\n// keep-alive 下被隐藏的组件实例被缓存,其 currentView 不再变化,\n// 左侧视图组件(viewsConfig)的 hash 更新 watch 不会再触发,\n// 因此这里在每次切换模式时显式把「模式前缀 + 当前视图 uid」写入 hash,\n// 保证刷新页面后能根据 hash 前缀恢复正确的表格模式。\nwatch(\n () => props.tableMode,\n async newMode => {\n await nextTick();\n const prefix =\n newMode === 'pivot' ? 'pivot:' : newMode === 'pivot_charts' ? 'pivotcharts:' : '';\n const uid = activeTableRef.value?.currentView?.uid || '';\n window.location.hash = `${prefix}${uid}`;\n },\n);\nconst toggleOpen = () => {\n leftOpen.value = !leftOpen.value;\n};\n\n// 展平高级搜索分组(v20:只支持高级搜索,无普通搜索分支)\nconst getSearchConfigList = (): SearchConfig[] => {\n const search_config_list: SearchConfig[] = [];\n for (const group of props.pageConfig.base_search_condition_config_list || []) {\n for (const item of group.group || []) {\n search_config_list.push({ ...item, group_name: group.name });\n }\n }\n return search_config_list;\n};\nconst getRouteParams = () => {\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 const del_keys = [\n 't',\n 'query_json',\n 'is_router',\n 'is_global',\n 'is_fuzzy_search',\n 'customerTitle',\n ];\n for (const key of del_keys) {\n delete routeQueryParams[key];\n }\n if (routeQueryParams?.ext_search_keys) {\n let ext_search_keys = routeQueryParams.ext_search_keys;\n ext_search_keys = ext_search_keys.split(',').map(item => item.trim());\n const _ext_search = {};\n ext_search_keys.forEach((key: string) => {\n _ext_search[key] = routeQueryParams[key];\n });\n return _ext_search;\n } else {\n return routeQueryParams;\n }\n};\nconst getConfig = (mode: 'normal' | 'pivot' | 'pivot_charts'): any => {\n const isNormal = mode === 'normal';\n const isPivot = mode === 'pivot';\n const isPivotCharts = mode === 'pivot_charts';\n let keyPrefix = '';\n let hashPrefix = '';\n if (isPivot) {\n keyPrefix = 'pivot-';\n hashPrefix = 'pivot:';\n } else if (isPivotCharts) {\n keyPrefix = 'pivotcharts-';\n hashPrefix = 'pivotcharts:';\n }\n // ★ v20:只支持高级搜索\n const search_config_list = getSearchConfigList();\n const default_advanced_search_multigroups: SearchGroupItem[] = [];\n\n for (const group of props.pageConfig.default_search_condition_config_list || []) {\n const defaultItem: SearchGroupItem = {\n id: genID(),\n conditions: [],\n viewSearchConfig: {},\n };\n for (const item of search_config_list) {\n defaultItem.viewSearchConfig[item.field_name] = {\n checked: false,\n order: 9999,\n };\n }\n let order = 0;\n for (const item of group || []) {\n defaultItem.conditions.push(item);\n defaultItem.viewSearchConfig[item.field_name] = {\n checked: true,\n order: order,\n };\n order++;\n }\n default_advanced_search_multigroups.push(defaultItem);\n }\n let hash = '';\n if (window.location.hash) {\n hash = window.location.hash.substring(1); // 去掉 # 符号\n // Filter hash by mode: pivot hash starts with 'pivot:', pivotcharts hash starts with 'pivotcharts:'\n if (hashPrefix) {\n if (hash.startsWith(hashPrefix)) {\n hash = hash.substring(hashPrefix.length);\n } else {\n hash = '';\n }\n } else {\n // normal mode: ignore pivot: and pivotcharts: hashes\n if (hash.startsWith('pivot:') || hash.startsWith('pivotcharts:')) {\n hash = '';\n }\n }\n }\n let base_conditions = null;\n // ★ v27:query_params 不在白名单,PageConfig 不携带;仅透视定位临时过滤会写入 filter_id_key\n let query_params: any = {};\n // ★ v10/v23:路由参数统一按高级搜索条件(field_name/operator/value)下发\n const route_base_conditions = [];\n Object.entries(getRouteParams()).forEach(([key, value]) => {\n if (!Array.isArray(value)) {\n value = [value];\n }\n route_base_conditions.push({\n field_name: key,\n operator: 'in',\n value: value,\n format: 'input',\n class_name: 'str',\n });\n });\n if (\n Array.isArray(props.pageConfig.advanced_base_conditions) &&\n props.pageConfig.advanced_base_conditions.length > 0 &&\n route_base_conditions.length > 0\n ) {\n base_conditions = [\n { op: 'and', children: props.pageConfig.advanced_base_conditions },\n { op: 'and', children: route_base_conditions },\n ];\n } else if (props.pageConfig.advanced_base_conditions?.length > 0) {\n base_conditions = props.pageConfig.advanced_base_conditions;\n } else if (route_base_conditions.length > 0) {\n base_conditions = route_base_conditions;\n }\n if (filter_id_key.value) {\n query_params.filter_id_key = filter_id_key.value;\n }\n // ★ v29.14:width 为 null 必须剥掉——@surely-vue/table 列宽计算只防 undefined/number,\n // null 会直接进 o.match(/^(.*)px$/) 抛 TypeError(页面白屏级报错,真机已复现)\n const columns = (props.pageConfig.baseColumns || [])\n .filter(item => item.dataIndex !== 'action')\n .map(item => {\n if (item.width == null) {\n const { width: _ignored, ...rest } = item;\n return rest;\n }\n return item;\n });\n if (userStore.HAS_ACTION_BTN(props.pageConfig)) {\n columns.push({\n title: t('操作'),\n width: 50,\n dataIndex: 'action',\n checked: true,\n fixed: 'right',\n cellComponent: 'action',\n });\n }\n // ★ v10/v23/v27:URL 全部由 buildRuntimeUrls(view_flag) 显式拼装(pageConfig.ts 导出),\n // 不做 queryData.replace('_list', '_pivot_table_rust') 式字符串替换派生\n const urls = buildRuntimeUrls(props.modalType.split('-')[1]);\n return {\n key: `${keyPrefix}sql_db_view-${props.modalType}`,\n title: (route.query?.customTitle as string) || (route.meta.title as string) || '',\n tableSize: 'small',\n search_display_type: 'hide',\n search_type: 'advanced',\n is_selection: props.pageConfig.is_selection,\n is_pagination: props.pageConfig.is_pagination,\n list_url: urls.queryData,\n setting_mode: 'drawer',\n setting_drawer_width: props.setting_drawer_width,\n pivot_charts_url: urls.pivotChartsUrl,\n pivot_table_url: urls.pivotTableUrl,\n pivot_table_max_records: props.pageConfig.pivot_table_max_records,\n search_config: search_config_list,\n columns: columns,\n // ★ v29.24(用户定案)/ ★ v29.40 三态:tablePro 用的 S-Table 必须有唯一行键。SQL 视图的\n // 行身份由后端 get_page_config 下发 —— 恰好 1 个主键列 → 该列名;0 个或 ≥2 个主键列 →\n // '_id'(列表接口为每行注入的稳定隐含主键:0 列是整行内容 hash,≥2 列是各主键值用 '|' 拼接,\n // 翻页/排序/裁剪列后都不变)。前端只透传,不做分支。\n rowKey: props.pageConfig.rowKey || 'id',\n show_current_view: true,\n enable_custom_filter: true,\n query_field_search_config_url: urls.fieldSearchConfigUrl,\n enable_advanced_search_multigroups: true,\n default_advanced_search_multigroups: default_advanced_search_multigroups,\n condition_group_config_list: props.pageConfig.condition_group_config_list || [],\n query_group_url: urls.queryConditionGroupData,\n refreshType: props.pageConfig.refresh_type as RefreshType,\n pageSize: props.pageConfig.pageSize,\n pageSizeOptions: props.pageConfig.page_size_options,\n view_uid: hash,\n base_conditions: base_conditions,\n query_params: query_params,\n btn_list: props.pageConfig.btn_list || [],\n head_btn_list: props.pageConfig.head_btn_list || [],\n batch_update_list: [],\n required_condition: props.pageConfig.required_condition,\n count_url: isNormal ? urls.countData : undefined,\n customRow: props.pageConfig.customRow || undefined,\n customHeaderCell: props.pageConfig.customHeaderCell || undefined,\n customCell: props.pageConfig.customCell || undefined,\n rowSelectionType: (props.pageConfig.rowSelection?.type || 'checkbox') as RowSelectionType,\n rowSelectionCheckStrictly: props.pageConfig.rowSelection?.checkStrictly || false,\n hide_index_column: false,\n // ★ v27:get_db_alias 不在白名单(数据源由后端 DbDataSource 决定),不传\n disabledShowSearchGroupName: true,\n cellComponentExt: {\n // ★ v24:无 titleList 权限位;api_fields(lybase 编辑表单字典)不在白名单,一期不提供\n titleList: null,\n api_fields: null,\n modalType: props.modalType,\n app_flag: 'db_view',\n getData: urls.getData,\n pageConfig: props.pageConfig,\n },\n };\n};\nconst handleFilterForIdKeyStart = () => {\n // 透视表双击定位:开始向后端请求(接口可能耗时较久),先展示全局 loading 遮罩\n filterLoading.value = true;\n};\nconst handleFilterForIdKey = (params: {\n filter_id_key: string;\n filterList: { label: string; value: string }[];\n matchValueLabel: string;\n}) => {\n // 后端接口已完成(成功或失败),先关闭全局 loading 遮罩,再进行后续 tab 页跳转\n filterLoading.value = false;\n if (params) {\n filter_id_key.value = params.filter_id_key;\n filterList.value = params.filterList;\n matchValueLabel.value = params.matchValueLabel;\n normalConfig.value = getConfig('normal');\n emit('changeMode', 'normal');\n nextTick(() => {\n tableProRef.value.currentView = { id: 'no-view' };\n tableProRef.value.setViewData(null);\n });\n } else {\n // 定位失败(pivotTable 在接口异常时回传 null),给出明确反馈\n message.error('数据定位失败,请重试');\n }\n};\nconst onClearFilterIdkey = () => {\n filter_id_key.value = '';\n normalConfig.value = getConfig('normal');\n};\n\n// defineExpose 在 setup 末尾调用:它同步读取引用的变量,必须在所有 const 定义之后,\n// 否则会触发 TDZ(Cannot access 'X' before initialization)。\ndefineExpose({\n tableProRef,\n pivotTableRef,\n pivotChartsRef,\n activeTableRef,\n});\n</script>\n\n<style scoped lang=\"less\">\n.table-wrapper {\n flex: 1;\n overflow: hidden;\n height: 100%;\n display: flex;\n flex-direction: column;\n}\n\n.toggle-button {\n cursor: pointer;\n height: 46px;\n line-height: 33px;\n font-size: 20px;\n &:hover {\n color: #1890ff;\n filter: drop-shadow(2px 2px 2px #bddfff);\n }\n}\n.filter-message {\n display: flex;\n gap: 14px;\n}\n</style>\n","<template>\n <div class=\"table-wrapper\">\n <!--\n keep-alive 缓存三种表格模式(标准 / 透视表 / 透视图)的组件实例。\n 左侧切换 tab 时,被隐藏的组件不会被销毁,其已加载的数据与视图状态\n 保留在内存中,再次切回时可以瞬间渲染,无需重新拉取数据。\n 注意:三个组件各自绑定独立的 config,避免共用同一份 config 导致\n 缓存实例在重新激活时被错误 prop 覆盖。\n -->\n <keep-alive>\n <template v-if=\"normalConfig && tableMode === 'normal'\">\n <a-alert\n v-if=\"filter_id_key\"\n type=\"warning\"\n closable\n show-icon\n @close=\"onClearFilterIdkey\"\n >\n <template #message>\n <div class=\"filter-message\">\n <span\n v-for=\"item in filterList\"\n :key=\"item.label\"\n >\n {{ item.label }}:\n <a-tag>{{ item.value }}</a-tag>\n </span>\n <span>\n 值字段:\n <a-tag>{{ matchValueLabel }}</a-tag>\n </span>\n </div>\n <div>\n 当前数据已通过透视表定位,此功能为临时过滤,不会被视图记录。关闭可恢复原始数据。\n </div>\n </template>\n </a-alert>\n\n <tablePro\n :config=\"normalConfig\"\n ref=\"tableProRef\"\n :eventBus=\"eventBus\"\n >\n <template #header_bar_before_title>\n <div v-if=\"pageConfig.isView\">\n <div\n class=\"toggle-button\"\n @click=\"toggleOpen\"\n >\n <MenuFoldOutlined v-if=\"leftOpen\" />\n <MenuUnfoldOutlined v-else />\n </div>\n </div>\n </template>\n </tablePro>\n </template>\n <pivotTable\n v-else-if=\"pivotConfig && tableMode === 'pivot'\"\n :config=\"pivotConfig\"\n ref=\"pivotTableRef\"\n :eventBus=\"eventBus\"\n @filter-for-id-key-start=\"handleFilterForIdKeyStart\"\n @filterForIdKey=\"handleFilterForIdKey\"\n >\n <template #header_bar_before_title>\n <div v-if=\"pageConfig.isView\">\n <div\n class=\"toggle-button\"\n @click=\"toggleOpen\"\n >\n <MenuFoldOutlined v-if=\"leftOpen\" />\n <MenuUnfoldOutlined v-else />\n </div>\n </div>\n </template>\n </pivotTable>\n <pivotCharts\n v-else-if=\"pivotChartsConfig && tableMode === 'pivot_charts'\"\n :config=\"pivotChartsConfig\"\n ref=\"pivotChartsRef\"\n :eventBus=\"eventBus\"\n >\n <template #header_bar_before_title>\n <div v-if=\"pageConfig.isView\">\n <div\n class=\"toggle-button\"\n @click=\"toggleOpen\"\n >\n <MenuFoldOutlined v-if=\"leftOpen\" />\n <MenuUnfoldOutlined v-else />\n </div>\n </div>\n </template>\n </pivotCharts>\n </keep-alive>\n\n <!-- 透视表双击定位时的全局 loading 遮罩:接口可能耗时较久,覆盖整页防止误操作 -->\n <FilterLoading :visible=\"filterLoading\" />\n </div>\n</template>\n<script setup lang=\"ts\">\n// ============================================================================\n// sql_db_view 右侧容器(蓝本:remotePages/v2/rightTable.vue,按 §4.1 裁剪)\n// 与蓝本的差异:\n// ① 去掉 btnAdd / 增删改(只读页);\n// ② 去掉 AI 助手页面能力注册(ai-view-helper / ai-view-ability-schemas / 快速操作);\n// ③ ★ v24(决策 24):去掉全部按钮权限校验 —— 不 CHECK_AUTH(VIEW_SYSTEM_EDIT)、\n// 无 is_view_system_edit_auth,保存视图的系统视图操作一律放行;\n// ④ ★ v10/v23:pivot / field_search_config URL 显式声明(pageConfig 已由 pageConfig.ts\n// 按 flag 拼好),不做 `_list` → `_pivot_table_rust` 字符串替换派生;\n// ⑤ v20:只支持高级搜索(is_show_advantage 恒 true)。\n// ============================================================================\nimport tablePro from 'liyu-pc-base/components/tablePro/tablePro.vue';\nimport pivotTable from 'liyu-pc-base/components/tablePro/pivotTable.vue';\nimport pivotCharts from 'liyu-pc-base/components/tablePro/pivotCharts.vue';\nimport { computed, onMounted, ref, watch, nextTick } from 'vue';\nimport type { SqlViewPageConfig } from './typing';\nimport type {\n SearchGroupItem,\n Table,\n SearchConfig,\n RefreshType,\n RowSelectionType,\n} from 'liyu-pc-base/components/tablePro/typing';\nimport FilterLoading from './FilterLoading.vue';\nimport { MenuFoldOutlined, MenuUnfoldOutlined } from '@ant-design/icons-vue';\nimport { useRoute } from 'vue-router';\nimport { genID } from 'liyu-pc-base/utils/function';\nimport { useUserStore } from 'liyu-pc-base/init-plugin';\nimport { useI18n } from 'vue-i18n';\nimport { message } from 'ant-design-vue';\nimport { buildRuntimeUrls } from './pageConfig';\n\n// 三种表格模式各自独立的 config:\n// keep-alive 缓存隐藏的组件实例,若共用同一个 config,重新激活时 prop 会\n// 被其它模式的 config 覆盖。拆分为三个后才能保证缓存实例数据不被污染。\nconst normalConfig = ref<Table>(null);\nconst pivotConfig = ref<Table>(null);\nconst pivotChartsConfig = ref<Table>(null);\n\ninterface Props {\n eventBus: any;\n pageConfig: SqlViewPageConfig;\n modalType: string;\n tableMode?: 'normal' | 'pivot' | 'pivot_charts';\n setting_drawer_width: number;\n}\nconst props = withDefaults(defineProps<Props>(), {\n eventBus: null,\n pageConfig: null,\n tableMode: 'normal',\n});\nconst emit = defineEmits(['changeMode']);\nconst userStore = useUserStore();\nconst { t } = useI18n();\nconst route = useRoute();\nconst tableProRef = ref(null);\nconst pivotTableRef = ref(null);\nconst pivotChartsRef = ref(null);\nconst filter_id_key = ref('');\nconst filterList = ref<{ label: string; value: string }[]>([]);\nconst matchValueLabel = ref('');\n// 透视表双击定位时的全局 loading 遮罩:filterForIdKeyStart 打开,filterForIdKey 关闭\nconst filterLoading = ref(false);\nconst activeTableRef = computed(() => {\n if (props.tableMode === 'pivot') return pivotTableRef.value;\n if (props.tableMode === 'pivot_charts') return pivotChartsRef.value;\n return tableProRef.value;\n});\nconst leftOpen = defineModel('leftOpen', {\n default: true,\n});\n\n// 三种表格模式在挂载时一次性构建各自的 config。\n// 切换 tableMode 不再销毁/重建组件,而是由 keep-alive 缓存隐藏实例,\n// 已加载的数据随实例保留,切回时即时显示,无需重新拉取。\nonMounted(() => {\n normalConfig.value = getConfig('normal');\n pivotConfig.value = getConfig('pivot');\n pivotChartsConfig.value = getConfig('pivot_charts');\n});\n\n// 切换左侧 tab 时同步更新 URL hash:\n// keep-alive 下被隐藏的组件实例被缓存,其 currentView 不再变化,\n// 左侧视图组件(viewsConfig)的 hash 更新 watch 不会再触发,\n// 因此这里在每次切换模式时显式把「模式前缀 + 当前视图 uid」写入 hash,\n// 保证刷新页面后能根据 hash 前缀恢复正确的表格模式。\nwatch(\n () => props.tableMode,\n async newMode => {\n await nextTick();\n const prefix =\n newMode === 'pivot' ? 'pivot:' : newMode === 'pivot_charts' ? 'pivotcharts:' : '';\n const uid = activeTableRef.value?.currentView?.uid || '';\n window.location.hash = `${prefix}${uid}`;\n },\n);\nconst toggleOpen = () => {\n leftOpen.value = !leftOpen.value;\n};\n\n// 展平高级搜索分组(v20:只支持高级搜索,无普通搜索分支)\nconst getSearchConfigList = (): SearchConfig[] => {\n const search_config_list: SearchConfig[] = [];\n for (const group of props.pageConfig.base_search_condition_config_list || []) {\n for (const item of group.group || []) {\n search_config_list.push({ ...item, group_name: group.name });\n }\n }\n return search_config_list;\n};\nconst getRouteParams = () => {\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 const del_keys = [\n 't',\n 'query_json',\n 'is_router',\n 'is_global',\n 'is_fuzzy_search',\n 'customerTitle',\n ];\n for (const key of del_keys) {\n delete routeQueryParams[key];\n }\n if (routeQueryParams?.ext_search_keys) {\n let ext_search_keys = routeQueryParams.ext_search_keys;\n ext_search_keys = ext_search_keys.split(',').map(item => item.trim());\n const _ext_search = {};\n ext_search_keys.forEach((key: string) => {\n _ext_search[key] = routeQueryParams[key];\n });\n return _ext_search;\n } else {\n return routeQueryParams;\n }\n};\nconst getConfig = (mode: 'normal' | 'pivot' | 'pivot_charts'): any => {\n const isNormal = mode === 'normal';\n const isPivot = mode === 'pivot';\n const isPivotCharts = mode === 'pivot_charts';\n let keyPrefix = '';\n let hashPrefix = '';\n if (isPivot) {\n keyPrefix = 'pivot-';\n hashPrefix = 'pivot:';\n } else if (isPivotCharts) {\n keyPrefix = 'pivotcharts-';\n hashPrefix = 'pivotcharts:';\n }\n // ★ v20:只支持高级搜索\n const search_config_list = getSearchConfigList();\n const default_advanced_search_multigroups: SearchGroupItem[] = [];\n\n for (const group of props.pageConfig.default_search_condition_config_list || []) {\n const defaultItem: SearchGroupItem = {\n id: genID(),\n conditions: [],\n viewSearchConfig: {},\n };\n for (const item of search_config_list) {\n defaultItem.viewSearchConfig[item.field_name] = {\n checked: false,\n order: 9999,\n };\n }\n let order = 0;\n for (const item of group || []) {\n defaultItem.conditions.push(item);\n defaultItem.viewSearchConfig[item.field_name] = {\n checked: true,\n order: order,\n };\n order++;\n }\n default_advanced_search_multigroups.push(defaultItem);\n }\n let hash = '';\n if (window.location.hash) {\n hash = window.location.hash.substring(1); // 去掉 # 符号\n // Filter hash by mode: pivot hash starts with 'pivot:', pivotcharts hash starts with 'pivotcharts:'\n if (hashPrefix) {\n if (hash.startsWith(hashPrefix)) {\n hash = hash.substring(hashPrefix.length);\n } else {\n hash = '';\n }\n } else {\n // normal mode: ignore pivot: and pivotcharts: hashes\n if (hash.startsWith('pivot:') || hash.startsWith('pivotcharts:')) {\n hash = '';\n }\n }\n }\n let base_conditions = null;\n // ★ v27:query_params 不在白名单,PageConfig 不携带;仅透视定位临时过滤会写入 filter_id_key\n let query_params: any = {};\n // ★ v10/v23:路由参数统一按高级搜索条件(field_name/operator/value)下发\n const route_base_conditions = [];\n Object.entries(getRouteParams()).forEach(([key, value]) => {\n if (!Array.isArray(value)) {\n value = [value];\n }\n route_base_conditions.push({\n field_name: key,\n operator: 'in',\n value: value,\n format: 'input',\n class_name: 'str',\n });\n });\n if (\n Array.isArray(props.pageConfig.advanced_base_conditions) &&\n props.pageConfig.advanced_base_conditions.length > 0 &&\n route_base_conditions.length > 0\n ) {\n base_conditions = [\n { op: 'and', children: props.pageConfig.advanced_base_conditions },\n { op: 'and', children: route_base_conditions },\n ];\n } else if (props.pageConfig.advanced_base_conditions?.length > 0) {\n base_conditions = props.pageConfig.advanced_base_conditions;\n } else if (route_base_conditions.length > 0) {\n base_conditions = route_base_conditions;\n }\n if (filter_id_key.value) {\n query_params.filter_id_key = filter_id_key.value;\n }\n // ★ v29.14:width 为 null 必须剥掉——@surely-vue/table 列宽计算只防 undefined/number,\n // null 会直接进 o.match(/^(.*)px$/) 抛 TypeError(页面白屏级报错,真机已复现)\n const columns = (props.pageConfig.baseColumns || [])\n .filter(item => item.dataIndex !== 'action')\n .map(item => {\n if (item.width == null) {\n const { width: _ignored, ...rest } = item;\n return rest;\n }\n return item;\n });\n if (userStore.HAS_ACTION_BTN(props.pageConfig)) {\n columns.push({\n title: t('操作'),\n width: 50,\n dataIndex: 'action',\n checked: true,\n fixed: 'right',\n cellComponent: 'action',\n });\n }\n // ★ v10/v23/v27:URL 全部由 buildRuntimeUrls(view_flag) 显式拼装(pageConfig.ts 导出),\n // 不做 queryData.replace('_list', '_pivot_table_rust') 式字符串替换派生\n const urls = buildRuntimeUrls(props.modalType.split('-')[1]);\n return {\n key: `${keyPrefix}sql_db_view-${props.modalType}`,\n title: (route.query?.customTitle as string) || (route.meta.title as string) || '',\n tableSize: 'small',\n search_display_type: 'hide',\n search_type: 'advanced',\n is_selection: props.pageConfig.is_selection,\n is_pagination: props.pageConfig.is_pagination,\n list_url: urls.queryData,\n setting_mode: 'drawer',\n setting_drawer_width: props.setting_drawer_width,\n pivot_charts_url: urls.pivotChartsUrl,\n pivot_table_url: urls.pivotTableUrl,\n pivot_table_max_records: props.pageConfig.pivot_table_max_records,\n search_config: search_config_list,\n columns: columns,\n // ★ v29.24(用户定案)/ ★ v29.40 三态:tablePro 用的 S-Table 必须有唯一行键。SQL 视图的\n // 行身份由后端 get_page_config 下发 —— 恰好 1 个主键列 → 该列名;0 个或 ≥2 个主键列 →\n // '_id'(列表接口为每行注入的稳定隐含主键:0 列是整行内容 hash,≥2 列是各主键值用 '|' 拼接,\n // 翻页/排序/裁剪列后都不变)。前端只透传,不做分支。\n rowKey: props.pageConfig.rowKey || 'id',\n show_current_view: true,\n enable_custom_filter: true,\n query_field_search_config_url: urls.fieldSearchConfigUrl,\n enable_advanced_search_multigroups: true,\n default_advanced_search_multigroups: default_advanced_search_multigroups,\n condition_group_config_list: props.pageConfig.condition_group_config_list || [],\n query_group_url: urls.queryConditionGroupData,\n refreshType: props.pageConfig.refresh_type as RefreshType,\n pageSize: props.pageConfig.pageSize,\n pageSizeOptions: props.pageConfig.page_size_options,\n view_uid: hash,\n base_conditions: base_conditions,\n query_params: query_params,\n btn_list: props.pageConfig.btn_list || [],\n head_btn_list: props.pageConfig.head_btn_list || [],\n batch_update_list: [],\n required_condition: props.pageConfig.required_condition,\n count_url: isNormal ? urls.countData : undefined,\n customRow: props.pageConfig.customRow || undefined,\n customHeaderCell: props.pageConfig.customHeaderCell || undefined,\n customCell: props.pageConfig.customCell || undefined,\n rowSelectionType: (props.pageConfig.rowSelection?.type || 'checkbox') as RowSelectionType,\n rowSelectionCheckStrictly: props.pageConfig.rowSelection?.checkStrictly || false,\n hide_index_column: false,\n // ★ v27:get_db_alias 不在白名单(数据源由后端 DbDataSource 决定),不传\n disabledShowSearchGroupName: true,\n cellComponentExt: {\n // ★ v24:无 titleList 权限位;api_fields(lybase 编辑表单字典)不在白名单,一期不提供\n titleList: null,\n api_fields: null,\n modalType: props.modalType,\n app_flag: 'db_view',\n getData: urls.getData,\n pageConfig: props.pageConfig,\n },\n };\n};\nconst handleFilterForIdKeyStart = () => {\n // 透视表双击定位:开始向后端请求(接口可能耗时较久),先展示全局 loading 遮罩\n filterLoading.value = true;\n};\nconst handleFilterForIdKey = (params: {\n filter_id_key: string;\n filterList: { label: string; value: string }[];\n matchValueLabel: string;\n}) => {\n // 后端接口已完成(成功或失败),先关闭全局 loading 遮罩,再进行后续 tab 页跳转\n filterLoading.value = false;\n if (params) {\n filter_id_key.value = params.filter_id_key;\n filterList.value = params.filterList;\n matchValueLabel.value = params.matchValueLabel;\n normalConfig.value = getConfig('normal');\n emit('changeMode', 'normal');\n nextTick(() => {\n tableProRef.value.currentView = { id: 'no-view' };\n tableProRef.value.setViewData(null);\n });\n } else {\n // 定位失败(pivotTable 在接口异常时回传 null),给出明确反馈\n message.error('数据定位失败,请重试');\n }\n};\nconst onClearFilterIdkey = () => {\n filter_id_key.value = '';\n normalConfig.value = getConfig('normal');\n};\n\n// defineExpose 在 setup 末尾调用:它同步读取引用的变量,必须在所有 const 定义之后,\n// 否则会触发 TDZ(Cannot access 'X' before initialization)。\ndefineExpose({\n tableProRef,\n pivotTableRef,\n pivotChartsRef,\n activeTableRef,\n});\n</script>\n\n<style scoped lang=\"less\">\n.table-wrapper {\n flex: 1;\n overflow: hidden;\n height: 100%;\n display: flex;\n flex-direction: column;\n}\n\n.toggle-button {\n cursor: pointer;\n height: 46px;\n line-height: 33px;\n font-size: 20px;\n &:hover {\n color: #1890ff;\n filter: drop-shadow(2px 2px 2px #bddfff);\n }\n}\n.filter-message {\n display: flex;\n gap: 14px;\n}\n</style>\n","<template>\n <fullLayout>\n <div\n class=\"pri-page\"\n v-if=\"inited\"\n >\n <div class=\"pri-wrapper\">\n <transition name=\"left-slide\">\n <div\n class=\"left-slide-outer\"\n v-if=\"leftOpen\"\n >\n <div class=\"left-wrapper\">\n <leftLayout\n :pageConfig=\"pageConfig\"\n v-model:open=\"leftOpen\"\n :eventBus=\"eventBus\"\n v-model:tableMode=\"tableMode\"\n ></leftLayout>\n </div>\n </div>\n </transition>\n <div\n class=\"right-wrapper\"\n ref=\"rightWrapperRef\"\n >\n <div\n :class=\"['left-space', { 'setting-open': settingOpen }]\"\n :style=\"{\n '--x': `${right_wrapper_left}px`,\n '--drawer_width': `${setting_drawer_width}px`,\n }\"\n ></div>\n <rightTable\n :pageConfig=\"pageConfig\"\n :modalType=\"field.modalType\"\n ref=\"rightTableRef\"\n :eventBus=\"eventBus\"\n v-model:leftOpen=\"leftOpen\"\n :setting_drawer_width=\"setting_drawer_width\"\n :tableMode=\"tableMode\"\n @changeMode=\"tableMode = $event\"\n ></rightTable>\n <div\n :class=\"['right-space', { 'detail-open': detailState.open }]\"\n :style=\"{\n '--detail_width': `${detailState.width}px`,\n }\"\n ></div>\n </div>\n </div>\n </div>\n </fullLayout>\n <a-drawer\n :title=\"detailState.title\"\n :width=\"detailState.width\"\n placement=\"right\"\n v-model:open=\"detailState.open\"\n :mask=\"false\"\n :push=\"false\"\n v-if=\"detailState.open\"\n >\n <component\n :is=\"detailState.component\"\n :cmpObj=\"detailState.cmpObj\"\n :extra=\"detailState.extra\"\n ></component>\n </a-drawer>\n</template>\n<script setup lang=\"ts\">\n// ============================================================================\n// sql_db_view 页面壳(v15 路径 / v20 配置裁剪 / v22 app_flag 常量 / v24 无按钮权限校验)\n// 与 remotePages/v2/index.vue 的差异:\n// ① app_flag 固化为常量 'db_view',不从路由解析、不向子组件传递(v22);\n// ② 配置获取走本目录 pageConfig.ts 的 getDbViewConfig(get_page_config,\n// 入参 { org_id, flag })+ getSqlDbViewPageConfig(白名单融合),不复用\n// getDefaultAndServerConfig / getPageConfig(v10:那套会打到 lybase 通用页);\n// ③ 只支持高级搜索(v20);\n// ④ 无按钮权限校验(v24 决策 24):不 import CHECK_AUTH、无权限位。\n// ============================================================================\nimport fullLayout from 'liyu-pc-base/components/fullLayout/fullLayout.vue';\nimport {\n onMounted,\n ref,\n reactive,\n provide,\n computed,\n onUnmounted,\n onActivated,\n onDeactivated,\n nextTick,\n watch,\n} from 'vue';\nimport leftLayout from './leftLayout.vue';\nimport rightTable from './rightTable.vue';\nimport mitt from 'mitt';\nimport { useRoute } from 'vue-router';\nimport { event_obj } from 'liyu-pc-base/init-plugin';\nimport { useUserStore, useRequiredConditionStore, useInjectMenuState } from 'liyu-pc-base/init-plugin';\nimport { useI18n } from 'vue-i18n';\nimport { getSqlDbViewPageConfig } from './pageConfig';\nimport type { SqlViewPageConfig } from './typing';\n\nconst leftOpen = ref(true);\nconst inited = ref(false);\nconst rightTableRef = ref(null);\nconst eventBus = mitt();\nconst tableMode = ref<'normal' | 'pivot' | 'pivot_charts'>('normal');\nconst userStore = useUserStore();\nconst pageConfig = ref<SqlViewPageConfig | null>(null);\nconst { t } = useI18n();\nconst setting_drawer_width = ref(1000);\nconst rightWrapperRef = ref(null);\nconst right_wrapper_left = ref(0);\nconst injectMenuState = useInjectMenuState();\nconst { collapsed } = injectMenuState();\nconst detailState = reactive({\n open: false,\n component: null,\n width: 0,\n title: '详情',\n cmpObj: null,\n extra: null,\n lastLeftOpen: true,\n lastMenuCollapsed: true,\n});\n\nconst calcRightWrapperLeft = () => {\n if (rightWrapperRef.value) {\n const rect = (rightWrapperRef.value as HTMLElement).getBoundingClientRect();\n right_wrapper_left.value = rect.left;\n }\n};\n\nconst route = useRoute();\nconst requiredConditionStore = useRequiredConditionStore();\n// 路由形态:/db_view/db_view-{flag}(§4.3)。modalType = 末段;view_flag = modalType 第二段。\n// app_flag 是 URL 第一段且固定为 'db_view',不再解析、不再传递(v22)。\nconst field = {\n modalType: route.path.split('/').pop() || '',\n modalName: '',\n};\n// view_flag(= modalType 第二段)由 getSqlDbViewPageConfig 内部解析,页面壳不再单独持有\n\nconst tableProState = computed(() => {\n return rightTableRef.value?.activeTableRef;\n});\nconst settingOpen = computed(() => {\n return tableProState.value?.settingOpen;\n});\n\nprovide('tableProStateProxy', tableProState);\n\nconst init = async () => {\n // v26:取数 + 白名单融合合一为 async getSqlDbViewPageConfig(内部两路并行取数)\n pageConfig.value = await getSqlDbViewPageConfig(field.modalType, userStore.currentOrg.id, t, {\n to_i18n: true,\n });\n if (!pageConfig.value?.isView) {\n leftOpen.value = false;\n } else if (pageConfig.value?.default_hide_view) {\n leftOpen.value = false;\n } else {\n leftOpen.value = true;\n }\n if (pageConfig.value?.required_condition) {\n requiredConditionStore.set_required_condition(\n field.modalType,\n pageConfig.value.required_condition,\n );\n }\n // URL hash 恢复初始表格模式(#pivot:uid / #pivotcharts:uid / #uid)\n const hash = window.location.hash.substring(1);\n let tmpModel = undefined;\n if (hash) {\n if (hash.startsWith('pivotcharts:')) {\n tmpModel = 'pivot_charts';\n } else if (hash.startsWith('pivot:')) {\n tmpModel = 'pivot';\n } else {\n tmpModel = 'normal';\n }\n }\n if (!pageConfig.value?.enable_view_types?.length) {\n tmpModel = undefined;\n } else {\n tmpModel = tmpModel || pageConfig.value?.default_view_type || 'normal';\n const isFind = pageConfig.value?.enable_view_types?.includes(tmpModel);\n if (!isFind) {\n tmpModel = pageConfig.value?.enable_view_types[0];\n }\n }\n tableMode.value = tmpModel;\n};\n\nconst event_obj_reinit = () => {\n init();\n tableProState.value?.init();\n};\nconst event_obj_refresh = () => {\n tableProState.value?.refresh();\n};\nconst handleShowDetail = ({ key, cmpObj }) => {\n const detailConfigItem = pageConfig?.value?.detailConfigs?.[key];\n if (detailConfigItem) {\n detailState.component = detailConfigItem.component;\n detailState.width = detailConfigItem.width || 500;\n detailState.title = detailConfigItem.title || '详情';\n detailState.cmpObj = cmpObj;\n // extra:详情组件的私有配置(配置期常量),原样透传给详情组件\n detailState.extra = detailConfigItem.extra ?? null;\n if (!detailState.open) {\n detailState.open = true;\n detailState.lastLeftOpen = leftOpen.value;\n detailState.lastMenuCollapsed = collapsed.value;\n leftOpen.value = false;\n collapsed.value = true;\n }\n } else {\n console.warn(`detailConfigItem not found, key: ${key}`);\n }\n};\n\nconst event_obj_local_refresh = () => {\n eventBus.emit('local_refresh');\n};\nonMounted(async () => {\n event_obj()?.on('refresh', event_obj_refresh);\n event_obj()?.on('reset_and_reload', event_obj_reinit);\n event_obj()?.on('local_refresh', event_obj_local_refresh);\n // ★ show_detail 走页面实例总线,避免嵌套详情串扰;\n // 保留全局监听作为兼容入口(旧版 lib / 外部仍可能向全局单例发 show_detail)\n eventBus.on('show_detail', handleShowDetail);\n event_obj()?.on('show_detail', handleShowDetail);\n await init();\n inited.value = true;\n nextTick(() => {\n calcRightWrapperLeft();\n });\n});\nonUnmounted(() => {\n event_obj()?.off('refresh', event_obj_refresh);\n event_obj()?.off('reset_and_reload', event_obj_reinit);\n event_obj()?.off('local_refresh', event_obj_local_refresh);\n eventBus.off('show_detail', handleShowDetail);\n event_obj()?.off('show_detail', handleShowDetail);\n});\nonActivated(() => {\n if (pageConfig.value?.required_condition) {\n requiredConditionStore.set_required_condition(\n field.modalType,\n pageConfig.value.required_condition,\n );\n }\n event_obj()?.off('refresh', event_obj_refresh);\n event_obj()?.off('reset_and_reload', event_obj_reinit);\n event_obj()?.off('local_refresh', event_obj_local_refresh);\n eventBus.off('show_detail', handleShowDetail);\n event_obj()?.off('show_detail', handleShowDetail);\n\n event_obj()?.on('refresh', event_obj_refresh);\n event_obj()?.on('reset_and_reload', event_obj_reinit);\n event_obj()?.on('local_refresh', event_obj_local_refresh);\n eventBus.on('show_detail', handleShowDetail);\n event_obj()?.on('show_detail', handleShowDetail);\n});\nonDeactivated(() => {\n event_obj()?.off('refresh', event_obj_refresh);\n event_obj()?.off('reset_and_reload', event_obj_reinit);\n event_obj()?.off('local_refresh', event_obj_local_refresh);\n eventBus.off('show_detail', handleShowDetail);\n event_obj()?.off('show_detail', handleShowDetail);\n});\nwatch(\n () => detailState.open,\n (newVal, oldVal) => {\n if (newVal != oldVal && !newVal) {\n leftOpen.value = detailState.lastLeftOpen;\n collapsed.value = detailState.lastMenuCollapsed;\n }\n },\n);\n</script>\n<style scoped lang=\"less\">\n.pri-page {\n height: 100%;\n padding-left: 4px;\n padding-right: 4px;\n padding-top: 4px;\n}\n.pri-wrapper {\n height: 100%;\n display: flex;\n flex-direction: row;\n justify-content: space-between;\n overflow: hidden;\n gap: 4px;\n}\n.left-slide-outer {\n height: 100%;\n overflow: hidden;\n width: 220px;\n background-color: white;\n}\n.left-wrapper {\n height: 100%;\n overflow: hidden;\n width: 220px;\n background-color: white;\n padding-left: 4px;\n padding-right: 4px;\n}\n.left-slide-enter-active {\n transition: width 0.3s ease, opacity 0.3s ease;\n overflow: hidden;\n}\n.left-slide-leave-active {\n transition: width 0.3s ease, opacity 0.3s ease;\n overflow: hidden;\n}\n.left-slide-enter-from,\n.left-slide-leave-to {\n width: 0;\n opacity: 0;\n}\n.left-slide-leave-from,\n.left-slide-enter-to {\n width: 220px;\n opacity: 1;\n}\n.right-wrapper {\n display: flex;\n flex: 1;\n height: 100%;\n overflow: hidden;\n background-color: white;\n flex-direction: row;\n justify-content: space-between;\n}\n.left-space {\n width: 0;\n transition: width 0.2s ease;\n &.setting-open {\n width: calc(var(--drawer_width) - var(--x));\n }\n}\n.right-space {\n width: 0;\n transition: width 0.2s ease;\n &.detail-open {\n width: calc(var(--detail_width));\n }\n}\n</style>\n","<template>\n <fullLayout>\n <div\n class=\"pri-page\"\n v-if=\"inited\"\n >\n <div class=\"pri-wrapper\">\n <transition name=\"left-slide\">\n <div\n class=\"left-slide-outer\"\n v-if=\"leftOpen\"\n >\n <div class=\"left-wrapper\">\n <leftLayout\n :pageConfig=\"pageConfig\"\n v-model:open=\"leftOpen\"\n :eventBus=\"eventBus\"\n v-model:tableMode=\"tableMode\"\n ></leftLayout>\n </div>\n </div>\n </transition>\n <div\n class=\"right-wrapper\"\n ref=\"rightWrapperRef\"\n >\n <div\n :class=\"['left-space', { 'setting-open': settingOpen }]\"\n :style=\"{\n '--x': `${right_wrapper_left}px`,\n '--drawer_width': `${setting_drawer_width}px`,\n }\"\n ></div>\n <rightTable\n :pageConfig=\"pageConfig\"\n :modalType=\"field.modalType\"\n ref=\"rightTableRef\"\n :eventBus=\"eventBus\"\n v-model:leftOpen=\"leftOpen\"\n :setting_drawer_width=\"setting_drawer_width\"\n :tableMode=\"tableMode\"\n @changeMode=\"tableMode = $event\"\n ></rightTable>\n <div\n :class=\"['right-space', { 'detail-open': detailState.open }]\"\n :style=\"{\n '--detail_width': `${detailState.width}px`,\n }\"\n ></div>\n </div>\n </div>\n </div>\n </fullLayout>\n <a-drawer\n :title=\"detailState.title\"\n :width=\"detailState.width\"\n placement=\"right\"\n v-model:open=\"detailState.open\"\n :mask=\"false\"\n :push=\"false\"\n v-if=\"detailState.open\"\n >\n <component\n :is=\"detailState.component\"\n :cmpObj=\"detailState.cmpObj\"\n :extra=\"detailState.extra\"\n ></component>\n </a-drawer>\n</template>\n<script setup lang=\"ts\">\n// ============================================================================\n// sql_db_view 页面壳(v15 路径 / v20 配置裁剪 / v22 app_flag 常量 / v24 无按钮权限校验)\n// 与 remotePages/v2/index.vue 的差异:\n// ① app_flag 固化为常量 'db_view',不从路由解析、不向子组件传递(v22);\n// ② 配置获取走本目录 pageConfig.ts 的 getDbViewConfig(get_page_config,\n// 入参 { org_id, flag })+ getSqlDbViewPageConfig(白名单融合),不复用\n// getDefaultAndServerConfig / getPageConfig(v10:那套会打到 lybase 通用页);\n// ③ 只支持高级搜索(v20);\n// ④ 无按钮权限校验(v24 决策 24):不 import CHECK_AUTH、无权限位。\n// ============================================================================\nimport fullLayout from 'liyu-pc-base/components/fullLayout/fullLayout.vue';\nimport {\n onMounted,\n ref,\n reactive,\n provide,\n computed,\n onUnmounted,\n onActivated,\n onDeactivated,\n nextTick,\n watch,\n} from 'vue';\nimport leftLayout from './leftLayout.vue';\nimport rightTable from './rightTable.vue';\nimport mitt from 'mitt';\nimport { useRoute } from 'vue-router';\nimport { event_obj } from 'liyu-pc-base/init-plugin';\nimport { useUserStore, useRequiredConditionStore, useInjectMenuState } from 'liyu-pc-base/init-plugin';\nimport { useI18n } from 'vue-i18n';\nimport { getSqlDbViewPageConfig } from './pageConfig';\nimport type { SqlViewPageConfig } from './typing';\n\nconst leftOpen = ref(true);\nconst inited = ref(false);\nconst rightTableRef = ref(null);\nconst eventBus = mitt();\nconst tableMode = ref<'normal' | 'pivot' | 'pivot_charts'>('normal');\nconst userStore = useUserStore();\nconst pageConfig = ref<SqlViewPageConfig | null>(null);\nconst { t } = useI18n();\nconst setting_drawer_width = ref(1000);\nconst rightWrapperRef = ref(null);\nconst right_wrapper_left = ref(0);\nconst injectMenuState = useInjectMenuState();\nconst { collapsed } = injectMenuState();\nconst detailState = reactive({\n open: false,\n component: null,\n width: 0,\n title: '详情',\n cmpObj: null,\n extra: null,\n lastLeftOpen: true,\n lastMenuCollapsed: true,\n});\n\nconst calcRightWrapperLeft = () => {\n if (rightWrapperRef.value) {\n const rect = (rightWrapperRef.value as HTMLElement).getBoundingClientRect();\n right_wrapper_left.value = rect.left;\n }\n};\n\nconst route = useRoute();\nconst requiredConditionStore = useRequiredConditionStore();\n// 路由形态:/db_view/db_view-{flag}(§4.3)。modalType = 末段;view_flag = modalType 第二段。\n// app_flag 是 URL 第一段且固定为 'db_view',不再解析、不再传递(v22)。\nconst field = {\n modalType: route.path.split('/').pop() || '',\n modalName: '',\n};\n// view_flag(= modalType 第二段)由 getSqlDbViewPageConfig 内部解析,页面壳不再单独持有\n\nconst tableProState = computed(() => {\n return rightTableRef.value?.activeTableRef;\n});\nconst settingOpen = computed(() => {\n return tableProState.value?.settingOpen;\n});\n\nprovide('tableProStateProxy', tableProState);\n\nconst init = async () => {\n // v26:取数 + 白名单融合合一为 async getSqlDbViewPageConfig(内部两路并行取数)\n pageConfig.value = await getSqlDbViewPageConfig(field.modalType, userStore.currentOrg.id, t, {\n to_i18n: true,\n });\n if (!pageConfig.value?.isView) {\n leftOpen.value = false;\n } else if (pageConfig.value?.default_hide_view) {\n leftOpen.value = false;\n } else {\n leftOpen.value = true;\n }\n if (pageConfig.value?.required_condition) {\n requiredConditionStore.set_required_condition(\n field.modalType,\n pageConfig.value.required_condition,\n );\n }\n // URL hash 恢复初始表格模式(#pivot:uid / #pivotcharts:uid / #uid)\n const hash = window.location.hash.substring(1);\n let tmpModel = undefined;\n if (hash) {\n if (hash.startsWith('pivotcharts:')) {\n tmpModel = 'pivot_charts';\n } else if (hash.startsWith('pivot:')) {\n tmpModel = 'pivot';\n } else {\n tmpModel = 'normal';\n }\n }\n if (!pageConfig.value?.enable_view_types?.length) {\n tmpModel = undefined;\n } else {\n tmpModel = tmpModel || pageConfig.value?.default_view_type || 'normal';\n const isFind = pageConfig.value?.enable_view_types?.includes(tmpModel);\n if (!isFind) {\n tmpModel = pageConfig.value?.enable_view_types[0];\n }\n }\n tableMode.value = tmpModel;\n};\n\nconst event_obj_reinit = () => {\n init();\n tableProState.value?.init();\n};\nconst event_obj_refresh = () => {\n tableProState.value?.refresh();\n};\nconst handleShowDetail = ({ key, cmpObj }) => {\n const detailConfigItem = pageConfig?.value?.detailConfigs?.[key];\n if (detailConfigItem) {\n detailState.component = detailConfigItem.component;\n detailState.width = detailConfigItem.width || 500;\n detailState.title = detailConfigItem.title || '详情';\n detailState.cmpObj = cmpObj;\n // extra:详情组件的私有配置(配置期常量),原样透传给详情组件\n detailState.extra = detailConfigItem.extra ?? null;\n if (!detailState.open) {\n detailState.open = true;\n detailState.lastLeftOpen = leftOpen.value;\n detailState.lastMenuCollapsed = collapsed.value;\n leftOpen.value = false;\n collapsed.value = true;\n }\n } else {\n console.warn(`detailConfigItem not found, key: ${key}`);\n }\n};\n\nconst event_obj_local_refresh = () => {\n eventBus.emit('local_refresh');\n};\nonMounted(async () => {\n event_obj()?.on('refresh', event_obj_refresh);\n event_obj()?.on('reset_and_reload', event_obj_reinit);\n event_obj()?.on('local_refresh', event_obj_local_refresh);\n // ★ show_detail 走页面实例总线,避免嵌套详情串扰;\n // 保留全局监听作为兼容入口(旧版 lib / 外部仍可能向全局单例发 show_detail)\n eventBus.on('show_detail', handleShowDetail);\n event_obj()?.on('show_detail', handleShowDetail);\n await init();\n inited.value = true;\n nextTick(() => {\n calcRightWrapperLeft();\n });\n});\nonUnmounted(() => {\n event_obj()?.off('refresh', event_obj_refresh);\n event_obj()?.off('reset_and_reload', event_obj_reinit);\n event_obj()?.off('local_refresh', event_obj_local_refresh);\n eventBus.off('show_detail', handleShowDetail);\n event_obj()?.off('show_detail', handleShowDetail);\n});\nonActivated(() => {\n if (pageConfig.value?.required_condition) {\n requiredConditionStore.set_required_condition(\n field.modalType,\n pageConfig.value.required_condition,\n );\n }\n event_obj()?.off('refresh', event_obj_refresh);\n event_obj()?.off('reset_and_reload', event_obj_reinit);\n event_obj()?.off('local_refresh', event_obj_local_refresh);\n eventBus.off('show_detail', handleShowDetail);\n event_obj()?.off('show_detail', handleShowDetail);\n\n event_obj()?.on('refresh', event_obj_refresh);\n event_obj()?.on('reset_and_reload', event_obj_reinit);\n event_obj()?.on('local_refresh', event_obj_local_refresh);\n eventBus.on('show_detail', handleShowDetail);\n event_obj()?.on('show_detail', handleShowDetail);\n});\nonDeactivated(() => {\n event_obj()?.off('refresh', event_obj_refresh);\n event_obj()?.off('reset_and_reload', event_obj_reinit);\n event_obj()?.off('local_refresh', event_obj_local_refresh);\n eventBus.off('show_detail', handleShowDetail);\n event_obj()?.off('show_detail', handleShowDetail);\n});\nwatch(\n () => detailState.open,\n (newVal, oldVal) => {\n if (newVal != oldVal && !newVal) {\n leftOpen.value = detailState.lastLeftOpen;\n collapsed.value = detailState.lastMenuCollapsed;\n }\n },\n);\n</script>\n<style scoped lang=\"less\">\n.pri-page {\n height: 100%;\n padding-left: 4px;\n padding-right: 4px;\n padding-top: 4px;\n}\n.pri-wrapper {\n height: 100%;\n display: flex;\n flex-direction: row;\n justify-content: space-between;\n overflow: hidden;\n gap: 4px;\n}\n.left-slide-outer {\n height: 100%;\n overflow: hidden;\n width: 220px;\n background-color: white;\n}\n.left-wrapper {\n height: 100%;\n overflow: hidden;\n width: 220px;\n background-color: white;\n padding-left: 4px;\n padding-right: 4px;\n}\n.left-slide-enter-active {\n transition: width 0.3s ease, opacity 0.3s ease;\n overflow: hidden;\n}\n.left-slide-leave-active {\n transition: width 0.3s ease, opacity 0.3s ease;\n overflow: hidden;\n}\n.left-slide-enter-from,\n.left-slide-leave-to {\n width: 0;\n opacity: 0;\n}\n.left-slide-leave-from,\n.left-slide-enter-to {\n width: 220px;\n opacity: 1;\n}\n.right-wrapper {\n display: flex;\n flex: 1;\n height: 100%;\n overflow: hidden;\n background-color: white;\n flex-direction: row;\n justify-content: space-between;\n}\n.left-space {\n width: 0;\n transition: width 0.2s ease;\n &.setting-open {\n width: calc(var(--drawer_width) - var(--x));\n }\n}\n.right-space {\n width: 0;\n transition: width 0.2s ease;\n &.detail-open {\n width: calc(var(--detail_width));\n }\n}\n</style>\n"],"mappings":"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"}
|