lyflowchart 1.0.135 → 1.0.139

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.
Files changed (42) hide show
  1. package/dist/{ApprovalEditorModal-suKPJ-vN.js → ApprovalEditorModal-19j5zbe2.js} +1 -1
  2. package/dist/{Cell_click_approve-DoemsGnY.js → Cell_click_approve-BGDZUzTS.js} +1 -1
  3. package/dist/{approval-BaVHder3.js → approval-BaD4Bmw6.js} +1 -1
  4. package/dist/components/approval/utils.d.ts +1 -0
  5. package/dist/{core-BOc9ch_5.js → core-Cv0Erg9E.js} +10 -11
  6. package/dist/index.js +2 -2
  7. package/dist/lyflowchart.css +1 -1
  8. package/package.json +1 -1
  9. package/dist/ActionsConfig-BuvSvRbv.js.map +0 -1
  10. package/dist/ApprovalEditorModal-suKPJ-vN.js.map +0 -1
  11. package/dist/CancelModal-BUi3ieI8.js.map +0 -1
  12. package/dist/Cell_click_approve-DoemsGnY.js.map +0 -1
  13. package/dist/JsonTags-BbWLqghI.js.map +0 -1
  14. package/dist/MyProcess-FWGEwQcv.js.map +0 -1
  15. package/dist/approval-BW2WjPxY.js.map +0 -1
  16. package/dist/approval-BaVHder3.js.map +0 -1
  17. package/dist/approvalHistory-B2gpQbFC.js.map +0 -1
  18. package/dist/approvalHistoryViewModal-DgLpv2ot.js.map +0 -1
  19. package/dist/approvalPageConfig-D0zPXOUf.js.map +0 -1
  20. package/dist/approveLeftConfig-BOU_UgHp.js.map +0 -1
  21. package/dist/codeHistoryViewModal-BfSjIbEU.js.map +0 -1
  22. package/dist/columnTables-DLwtgcC7.js.map +0 -1
  23. package/dist/core-BOc9ch_5.js.map +0 -1
  24. package/dist/dataStoreSettingHistoryViewModal-D_so-KLp.js.map +0 -1
  25. package/dist/debugCode-Cm9-WiUG.js.map +0 -1
  26. package/dist/debugCode-dD1YnQSD.js.map +0 -1
  27. package/dist/default-VdDMlY4e.js.map +0 -1
  28. package/dist/example_code-C_xF8RRG.js.map +0 -1
  29. package/dist/flowHistoryViewModal-D8DJP7Te.js.map +0 -1
  30. package/dist/index.js.map +0 -1
  31. package/dist/init-plugin-fQTSQzui.js.map +0 -1
  32. package/dist/leftColumn-CsPjufue.js.map +0 -1
  33. package/dist/middleColumn-C7M6-eVo.js.map +0 -1
  34. package/dist/recordActions-BgFlNsGU.js.map +0 -1
  35. package/dist/settingsState-CI81PG-i.js.map +0 -1
  36. package/dist/tableConfig-uLXue-BS.js.map +0 -1
  37. package/dist/tableModal-BcYfVL02.js.map +0 -1
  38. package/dist/useApprovalRecordActions-BQ6MgV2L.js.map +0 -1
  39. package/dist/utils-CLet2gLV.js.map +0 -1
  40. package/dist/v0001-OaBeBCXI.js.map +0 -1
  41. package/dist/viewer-Dv3kQsMf.js.map +0 -1
  42. package/dist/vue-print-next-HRweUmNi.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"tableModal-BcYfVL02.js","names":[],"sources":["../src/components/approval/components/tableModal.vue","../src/components/approval/components/tableModal.vue"],"sourcesContent":["<template>\n <a-modal\n v-model:open=\"open\"\n :title=\"title\"\n width=\"80%\"\n wrap-class-name=\"approve-table-full-modal\"\n @cancel=\"cancel\"\n >\n <columnTables\n v-if=\"open\"\n :columnConfig=\"columnConfig\"\n :height=\"height\"\n :eventBus=\"eventBus\"\n :modelType=\"modelType\"\n :approvalConfig=\"approvalConfig\"\n :filterTables=\"tables\"\n :hideAllButtons=\"hideAllButtons\"\n @selected-counts-change=\"handleSelectedCountsChange\"\n ></columnTables>\n <!-- 自定义 footer:左侧固定位置放校验错误(不满足选择数量时不关闭弹窗),右侧为确定/取消 -->\n <template #footer>\n <div class=\"table-modal-footer\">\n <span\n v-if=\"errorText\"\n class=\"footer-error\"\n >\n {{ errorText }}\n </span>\n <div class=\"footer-actions\">\n <a-space :size=\"8\">\n <a-button @click=\"cancel\">取消</a-button>\n <a-button\n type=\"primary\"\n @click=\"ok\"\n >\n 确定\n </a-button>\n </a-space>\n </div>\n </div>\n </template>\n </a-modal>\n</template>\n<script setup lang=\"ts\">\nimport { computed, PropType, ref, watch } from 'vue';\nimport { message } from 'ant-design-vue';\nimport columnTables from './columnTables.vue';\nimport { ApprovalSetting } from '../typing';\nimport { useContextStore } from '@/components/approval/store/context';\nimport { validateTableSelectCounts } from '../utils';\nconst props = defineProps({\n columnConfig: {\n type: Object,\n required: true,\n },\n height: {\n type: Number,\n required: true,\n },\n eventBus: {\n type: Object,\n required: true,\n },\n modelType: {\n type: String,\n required: true,\n },\n approvalConfig: {\n type: Object as PropType<ApprovalSetting>,\n required: true,\n },\n tables: {\n type: Array,\n required: true,\n },\n title: {\n type: String,\n required: true,\n },\n hideAllButtons: {\n type: Boolean,\n required: true,\n },\n});\nconst emit = defineEmits(['ok', 'cancel']);\nconst contextStore = useContextStore();\n\nconst current_context = contextStore.contexts?.[props.modelType] || ({} as any);\nconst open = defineModel<boolean>('open');\n\n/** 表 id → 已选条数,由 columnTables 汇总各表(ApprovalTable)上报的条数 */\nconst selectedCounts = ref<Record<string, number>>({});\n/** 弹窗底部红字:只在点过「确定」之后才出现,用户改对了自动消失 */\nconst errorText = ref('');\nlet validateAttempted = false;\n\n/**\n * 参与校验的表 = showTables 入参 tables ∩ 页面配置里**真实渲染出来**的表。\n * 入参里写了页面上不存在的表 id 时必须剔除:否则用户根本勾不到那张表,\n * 配了 min_count 就会让弹窗永远关不掉。\n */\nconst validateTables = computed<any[]>(() => {\n const configMap: Record<string, any> = {};\n for (const item of (props.columnConfig as any)?.tables || []) {\n configMap[item.id] = item;\n }\n return ((props.tables || []) as any[])\n .filter(item => configMap[item.id])\n .map(item => ({ ...item, title: item.title || configMap[item.id].title }));\n});\n\nconst collectError = () => validateTableSelectCounts(validateTables.value, selectedCounts.value);\nconst resetError = () => {\n validateAttempted = false;\n errorText.value = '';\n};\nconst handleSelectedCountsChange = (counts: Record<string, number>) => {\n selectedCounts.value = counts || {};\n};\n\nconst ok = async () => {\n validateAttempted = true;\n const err = collectError();\n errorText.value = err;\n if (err) {\n // 拦截确定:不 emit ok(父级收到 ok 后才会移除弹窗),保持弹窗打开让用户补选\n message.warning(err);\n return;\n }\n emit('ok', { context: JSON.parse(JSON.stringify(current_context)) });\n};\nconst cancel = () => {\n resetError();\n emit('cancel');\n};\n\n// 校验失败后,选择变化时实时刷新底部提示(改对了自动消失)\nwatch(selectedCounts, () => {\n if (!validateAttempted) {\n return;\n }\n errorText.value = collectError();\n});\nwatch(open, value => {\n if (!value) {\n resetError();\n }\n});\n</script>\n<style>\n.approve-table-full-modal {\n .ant-layout-header {\n background-color: #fff;\n }\n .ant-layout-sider {\n background-color: #fff;\n }\n .ant-modal {\n top: 0;\n margin: 0 auto;\n padding-bottom: 0;\n }\n .ant-modal-content {\n display: flex;\n flex-direction: column;\n height: calc(100vh);\n }\n .ant-modal-body {\n flex: 1;\n padding: 0;\n overflow: hidden;\n }\n .ant-modal-footer {\n padding: 0;\n }\n .table-modal-footer {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 8px 16px;\n border-top: 1px solid #e8e8e8;\n .footer-error {\n flex: 1 1 auto;\n min-width: 0;\n text-align: left;\n font-size: 13px;\n line-height: 1.5;\n color: #ff4d4f;\n }\n .footer-actions {\n flex: 0 0 auto;\n margin-left: auto;\n }\n }\n}\n</style>\n","<template>\n <a-modal\n v-model:open=\"open\"\n :title=\"title\"\n width=\"80%\"\n wrap-class-name=\"approve-table-full-modal\"\n @cancel=\"cancel\"\n >\n <columnTables\n v-if=\"open\"\n :columnConfig=\"columnConfig\"\n :height=\"height\"\n :eventBus=\"eventBus\"\n :modelType=\"modelType\"\n :approvalConfig=\"approvalConfig\"\n :filterTables=\"tables\"\n :hideAllButtons=\"hideAllButtons\"\n @selected-counts-change=\"handleSelectedCountsChange\"\n ></columnTables>\n <!-- 自定义 footer:左侧固定位置放校验错误(不满足选择数量时不关闭弹窗),右侧为确定/取消 -->\n <template #footer>\n <div class=\"table-modal-footer\">\n <span\n v-if=\"errorText\"\n class=\"footer-error\"\n >\n {{ errorText }}\n </span>\n <div class=\"footer-actions\">\n <a-space :size=\"8\">\n <a-button @click=\"cancel\">取消</a-button>\n <a-button\n type=\"primary\"\n @click=\"ok\"\n >\n 确定\n </a-button>\n </a-space>\n </div>\n </div>\n </template>\n </a-modal>\n</template>\n<script setup lang=\"ts\">\nimport { computed, PropType, ref, watch } from 'vue';\nimport { message } from 'ant-design-vue';\nimport columnTables from './columnTables.vue';\nimport { ApprovalSetting } from '../typing';\nimport { useContextStore } from '@/components/approval/store/context';\nimport { validateTableSelectCounts } from '../utils';\nconst props = defineProps({\n columnConfig: {\n type: Object,\n required: true,\n },\n height: {\n type: Number,\n required: true,\n },\n eventBus: {\n type: Object,\n required: true,\n },\n modelType: {\n type: String,\n required: true,\n },\n approvalConfig: {\n type: Object as PropType<ApprovalSetting>,\n required: true,\n },\n tables: {\n type: Array,\n required: true,\n },\n title: {\n type: String,\n required: true,\n },\n hideAllButtons: {\n type: Boolean,\n required: true,\n },\n});\nconst emit = defineEmits(['ok', 'cancel']);\nconst contextStore = useContextStore();\n\nconst current_context = contextStore.contexts?.[props.modelType] || ({} as any);\nconst open = defineModel<boolean>('open');\n\n/** 表 id → 已选条数,由 columnTables 汇总各表(ApprovalTable)上报的条数 */\nconst selectedCounts = ref<Record<string, number>>({});\n/** 弹窗底部红字:只在点过「确定」之后才出现,用户改对了自动消失 */\nconst errorText = ref('');\nlet validateAttempted = false;\n\n/**\n * 参与校验的表 = showTables 入参 tables ∩ 页面配置里**真实渲染出来**的表。\n * 入参里写了页面上不存在的表 id 时必须剔除:否则用户根本勾不到那张表,\n * 配了 min_count 就会让弹窗永远关不掉。\n */\nconst validateTables = computed<any[]>(() => {\n const configMap: Record<string, any> = {};\n for (const item of (props.columnConfig as any)?.tables || []) {\n configMap[item.id] = item;\n }\n return ((props.tables || []) as any[])\n .filter(item => configMap[item.id])\n .map(item => ({ ...item, title: item.title || configMap[item.id].title }));\n});\n\nconst collectError = () => validateTableSelectCounts(validateTables.value, selectedCounts.value);\nconst resetError = () => {\n validateAttempted = false;\n errorText.value = '';\n};\nconst handleSelectedCountsChange = (counts: Record<string, number>) => {\n selectedCounts.value = counts || {};\n};\n\nconst ok = async () => {\n validateAttempted = true;\n const err = collectError();\n errorText.value = err;\n if (err) {\n // 拦截确定:不 emit ok(父级收到 ok 后才会移除弹窗),保持弹窗打开让用户补选\n message.warning(err);\n return;\n }\n emit('ok', { context: JSON.parse(JSON.stringify(current_context)) });\n};\nconst cancel = () => {\n resetError();\n emit('cancel');\n};\n\n// 校验失败后,选择变化时实时刷新底部提示(改对了自动消失)\nwatch(selectedCounts, () => {\n if (!validateAttempted) {\n return;\n }\n errorText.value = collectError();\n});\nwatch(open, value => {\n if (!value) {\n resetError();\n }\n});\n</script>\n<style>\n.approve-table-full-modal {\n .ant-layout-header {\n background-color: #fff;\n }\n .ant-layout-sider {\n background-color: #fff;\n }\n .ant-modal {\n top: 0;\n margin: 0 auto;\n padding-bottom: 0;\n }\n .ant-modal-content {\n display: flex;\n flex-direction: column;\n height: calc(100vh);\n }\n .ant-modal-body {\n flex: 1;\n padding: 0;\n overflow: hidden;\n }\n .ant-modal-footer {\n padding: 0;\n }\n .table-modal-footer {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 8px 16px;\n border-top: 1px solid #e8e8e8;\n .footer-error {\n flex: 1 1 auto;\n min-width: 0;\n text-align: left;\n font-size: 13px;\n line-height: 1.5;\n color: #ff4d4f;\n }\n .footer-actions {\n flex: 0 0 auto;\n margin-left: auto;\n }\n }\n}\n</style>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAkDA,IAAM,IAAQ,GAkCR,IAAO,GAGP,IAFe,GAAiB,CAED,WAAW,EAAM,cAAe,EAAE,EACjE,IAAO,EAAoB,GAAC,OAAO,EAGnC,IAAiB,EAA4B,EAAE,CAAC,EAEhD,IAAY,EAAI,GAAG,EACrB,IAAoB,IAOlB,IAAiB,QAAsB;GAC3C,IAAM,IAAiC,EAAE;AACzC,QAAK,IAAM,KAAS,EAAM,cAAsB,UAAU,EAAE,CAC1D,GAAU,EAAK,MAAM;AAEvB,WAAS,EAAM,UAAU,EAAE,EACxB,QAAO,MAAQ,EAAU,EAAK,IAAG,CACjC,KAAI,OAAS;IAAE,GAAG;IAAM,OAAO,EAAK,SAAS,EAAU,EAAK,IAAI;IAAO,EAAE;IAC5E,EAEI,UAAqB,EAA0B,EAAe,OAAO,EAAe,MAAM,EAC1F,UAAmB;AAEvB,GADA,IAAoB,IACpB,EAAU,QAAQ;KAEd,KAA8B,MAAmC;AACrE,KAAe,QAAQ,KAAU,EAAE;KAG/B,IAAK,YAAY;AACrB,OAAoB;GACpB,IAAM,IAAM,GAAc;AAE1B,OADA,EAAU,QAAQ,GACd,GAAK;AAEP,MAAQ,QAAQ,EAAI;AACpB;;AAEF,KAAK,MAAM,EAAE,SAAS,KAAK,MAAM,KAAK,UAAU,EAAgB,CAAC,EAAE,CAAC;KAEhE,UAAe;AAEnB,GADA,GAAY,EACZ,EAAK,SAAS;;SAIhB,EAAM,SAAsB;AACrB,SAGL,EAAU,QAAQ,GAAc;IAChC,EACF,EAAM,IAAM,MAAS;AACnB,GAAK,KACH,GAAY;IAEd;;eAlJA,EAwCU,GAAA;IAvCA,MAAM,EAAA;uCAAI,QAAA;IACjB,OAAO,EAAA;IACR,OAAM;IACN,mBAAgB;IACf,UAAQ;;IAcE,QAAM,QAmBT,CAlBN,EAkBM,OAlBN,GAkBM,CAhBI,EAAA,SAAA,GAAA,EADR,EAKO,QALP,GAKO,EADF,EAAA,MAAS,EAAA,EAAA,IAAA,EAAA,IAAA,GAAA,EAEd,EAUM,OAVN,GAUM,CATJ,EAQU,GAAA,EARA,MAAM,GAAC,EAAA;sBACwB,CAAvC,EAAuC,GAAA,EAA5B,SAAO,GAAM,EAAA;uBAAI,CAAA,GAAA,AAAA,EAAA,OAAA,CAAA,EAAF,MAAE,GAAA,CAAA,CAAA,CAAA;;SAC5B,EAKW,GAAA;MAJT,MAAK;MACJ,SAAO;;uBAGV,CAAA,GAAA,AAAA,EAAA,OAAA,CAAA,EAFC,QAED,GAAA,CAAA,CAAA,CAAA;;;;;qBAlBQ,CATR,EAAA,SAAA,GAAA,EADR,EAUgB,GAAA;;KARb,cAAc,EAAA;KACd,QAAQ,EAAA;KACR,UAAU,EAAA;KACV,WAAW,EAAA;KACX,gBAAgB,EAAA;KAChB,cAAc,EAAA;KACd,gBAAgB,EAAA;KAChB,wBAAwB"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"useApprovalRecordActions-BQ6MgV2L.js","names":[],"sources":["../src/components/approval_for_details.vue","../src/components/approval_for_details.vue","../src/components/approval/useApprovalRecordActions.ts"],"sourcesContent":["<template>\n <div class=\"form-container\">\n <!--\n 本组件只负责**展示**审批详情(头部 / 基本信息 / 表单渲染 / 流程图 / 审批记录表)。\n 修改 / 删除 / 打印按钮不在这里 —— 由外壳自己渲染(位置随外壳挑),\n 是否显示与点击行为统一走 useApprovalRecordActions(参照 Cell_click_approve 的抽屉 #extra、\n Cell_click_data_source 的 tabs #rightExtra)。\n -->\n <div class=\"header-container\">\n <div class=\"serial-number\">流程编码:{{ record?.number }}</div>\n <div class=\"article-title\">{{ approval_obj?.context }}({{ approval_obj?.flow_name }})</div>\n <div\n v-if=\"approval_obj?.modify_status\"\n class=\"modify-status\"\n >\n <a-tag :color=\"getModifyStatusColor(approval_obj.modify_status)\">\n {{ approval_obj.modify_status }}\n </a-tag>\n </div>\n </div>\n <div\n class=\"form-body descriptions\"\n style=\"padding-bottom: 10px\"\n >\n <div\n class=\"xinxi-title\"\n style=\"margin-top: 0\"\n >\n 基本信息\n </div>\n <a-descriptions bordered>\n <a-descriptions-item label=\"发起人\">\n {{ approval_obj?.send_person__realname }}\n </a-descriptions-item>\n <a-descriptions-item label=\"切换组织\">\n {{ approval_obj?.form_data?.globalData?.cost_company?.name }}\n </a-descriptions-item>\n <a-descriptions-item label=\"切换部门\">\n {{ approval_obj?.form_data?.globalData?.cost_department?.name }}\n </a-descriptions-item>\n <a-descriptions-item label=\"员工职位\">\n {{ approval_obj?.form_data?.globalData?.person_position?.name }}\n </a-descriptions-item>\n <a-descriptions-item label=\"员工组织\">\n {{ approval_obj?.form_data?.globalData?.person_cost_company?.name }}\n </a-descriptions-item>\n <a-descriptions-item label=\"员工部门\">\n {{ approval_obj?.form_data?.globalData?.person_department?.name }}\n </a-descriptions-item>\n <a-descriptions-item label=\"发起时间\">\n {{ getDate(approval_obj?.start_time) }}\n </a-descriptions-item>\n <a-descriptions-item\n :span=\"2\"\n label=\"结束时间\"\n >\n {{ getDate(approval_obj?.finish_time) }}\n </a-descriptions-item>\n <a-descriptions-item label=\"流程主题\">{{ approval_obj?.context }}</a-descriptions-item>\n <a-descriptions-item\n v-if=\"approval_obj?.modify_source__number\"\n label=\"修改来源流水号\"\n >\n {{ approval_obj?.modify_source__number }}\n </a-descriptions-item>\n </a-descriptions>\n <template\n v-for=\"(item, i) in data\"\n :key=\"i\"\n >\n <div class=\"xinxi-title\">\n {{ item?.group_name ? item.group_name : '审批信息' + (i + 1) }}\n </div>\n <a-descriptions\n bordered\n :column=\"item?.column ? item?.column : 3\"\n >\n <template\n v-for=\"(obj, j) in item.children\"\n :key=\"j\"\n >\n <template v-if=\"obj.type !== 'remotetablepro' && obj.type !== 'formtemplate'\">\n <template v-if=\"obj.type === 'textarea'\">\n <a-descriptions-item :label=\"obj.label\">\n <p style=\"white-space: pre-line; margin: 0; color: #909399\">{{ obj.value }}</p>\n </a-descriptions-item>\n </template>\n <template v-else-if=\"obj.type === 'upload'\">\n <a-descriptions-item :label=\"obj.label\">\n <template v-if=\"obj.value && obj.value?.length > 0\">\n <template\n v-for=\"(uploadItem, m) in obj.value\"\n :key=\"m\"\n >\n <br v-if=\"m > 0\" />\n <a-button\n type=\"link\"\n @click=\"look(uploadItem.url)\"\n >\n {{ uploadItem.name }}\n </a-button>\n </template>\n </template>\n </a-descriptions-item>\n </template>\n <template v-else>\n <a-descriptions-item\n :label=\"obj.label\"\n :span=\"1\"\n >\n {{ obj.value }}\n </a-descriptions-item>\n </template>\n </template>\n </template>\n </a-descriptions>\n <a-descriptions\n bordered\n :column=\"item?.column ? item?.column : 3\"\n >\n <template\n v-for=\"(obj, j) in item.children\"\n :key=\"j\"\n >\n <template v-if=\"obj.type === 'remotetablepro'\">\n <a-descriptions-item\n :label=\"obj.label\"\n :span=\"3\"\n >\n <s-table\n :columns=\"getColumns(obj.children)\"\n :data-source=\"getDataSource(obj.children)\"\n :pagination=\"false\"\n :rangeSelection=\"false\"\n :row-key=\"'index'\"\n bordered\n size=\"small\"\n stripe\n >\n <template #bodyCell=\"{ record, column, text, index }\">\n <template v-if=\"column.dataIndex.includes('upload')\">\n <template v-if=\"text && text?.length > 0\">\n <template\n v-for=\"(uploadItem, m) in text\"\n :key=\"m\"\n >\n <br v-if=\"m > 0\" />\n <a-button\n :title=\"uploadItem.name\"\n style=\"padding-left: 1px; width: 100%\"\n type=\"link\"\n @click=\"look(uploadItem.url)\"\n >\n <span\n style=\"\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n width: 100%;\n user-select: text;\n text-align: left;\n \"\n >\n {{ uploadItem.name }}\n </span>\n </a-button>\n </template>\n </template>\n </template>\n <template v-else>{{ text }}</template>\n </template>\n </s-table>\n </a-descriptions-item>\n </template>\n <template v-if=\"obj.type === 'formtemplate'\">\n <a-descriptions-item\n :label=\"obj.label\"\n :span=\"3\"\n >\n <template\n v-for=\"(obj1, k) in obj.children\"\n :key=\"k\"\n >\n <a-descriptions\n bordered\n :column=\"obj?.column ? obj?.column : 3\"\n >\n <template\n v-for=\"(obj2, l) in obj1\"\n :key=\"l\"\n >\n <template\n v-if=\"obj2.type !== 'remotetablepro' && obj2.type !== 'formtemplate'\"\n >\n <template v-if=\"obj2.type === 'textarea' && !obj2.is_hide\">\n <a-descriptions-item :label=\"obj2.label\">\n <p style=\"white-space: pre-line; margin: 0; color: #909399\">\n {{ obj2.value }}\n </p>\n </a-descriptions-item>\n </template>\n <template v-else-if=\"obj2.type === 'upload' && !obj2.is_hide\">\n <a-descriptions-item :label=\"obj2.label\">\n <template v-if=\"obj2.value && obj2.value?.length > 0\">\n <template\n v-for=\"(uploadItem, m) in obj2.value\"\n :key=\"m\"\n >\n <br v-if=\"m > 0\" />\n <a-button\n type=\"link\"\n @click=\"look(uploadItem.url)\"\n >\n {{ uploadItem.name }}\n </a-button>\n </template>\n </template>\n </a-descriptions-item>\n </template>\n <template v-else>\n <a-descriptions-item\n v-if=\"!obj2.is_hide\"\n :label=\"obj2.label\"\n >\n {{ obj2.value }}\n </a-descriptions-item>\n </template>\n </template>\n </template>\n </a-descriptions>\n <a-descriptions\n bordered\n :column=\"obj?.column ? obj?.column : 3\"\n >\n <template\n v-for=\"(obj2, l) in obj1\"\n :key=\"l\"\n >\n <template v-if=\"obj2.type === 'remotetablepro' && !obj2.is_hide\">\n <a-descriptions-item\n :label=\"obj2.label\"\n :span=\"3\"\n >\n <s-table\n :columns=\"getColumns(obj2.children)\"\n :data-source=\"getDataSource(obj2.children)\"\n :pagination=\"false\"\n :rangeSelection=\"false\"\n :row-key=\"'index'\"\n bordered\n size=\"small\"\n stripe\n >\n <template #bodyCell=\"{ record, column, text, index }\">\n <template v-if=\"column.dataIndex.includes('upload')\">\n <template v-if=\"text && text?.length > 0\">\n <template\n v-for=\"(uploadItem, m) in text\"\n :key=\"m\"\n >\n <br v-if=\"m > 0\" />\n <a-button\n :title=\"uploadItem.name\"\n style=\"padding-left: 1px; width: 100%\"\n type=\"link\"\n @click=\"look(uploadItem.url)\"\n >\n <span\n style=\"\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n width: 100%;\n user-select: text;\n text-align: left;\n \"\n >\n {{ uploadItem.name }}\n </span>\n </a-button>\n </template>\n </template>\n </template>\n <template v-else>{{ text }}</template>\n </template>\n </s-table>\n </a-descriptions-item>\n </template>\n <template v-if=\"obj2.type === 'formtemplate' && !obj2.is_hide\">\n <a-descriptions-item\n :label=\"obj2.label\"\n :span=\"3\"\n >\n <template\n v-for=\"(obj3, k) in obj2.children\"\n :key=\"k\"\n >\n <a-descriptions\n bordered\n :column=\"obj2?.column ? obj2?.column : 3\"\n >\n <template\n v-for=\"(obj4, l) in obj3\"\n :key=\"l\"\n >\n <template\n v-if=\"\n obj4.type !== 'remotetablepro' && obj4.type !== 'formtemplate'\n \"\n >\n <template v-if=\"obj4.type === 'textarea' && !obj4.is_hide\">\n <a-descriptions-item :label=\"obj4.label\">\n <p style=\"white-space: pre-line; margin: 0; color: #909399\">\n {{ obj4.value }}\n </p>\n </a-descriptions-item>\n </template>\n <template v-else-if=\"obj4.type === 'upload' && !obj4.is_hide\">\n <a-descriptions-item :label=\"obj4.label\">\n <template v-if=\"obj4.value && obj4.value?.length > 0\">\n <template\n v-for=\"(uploadItem, m) in obj4.value\"\n :key=\"m\"\n >\n <br v-if=\"m > 0\" />\n <a-button\n type=\"link\"\n @click=\"look(uploadItem.url)\"\n >\n {{ uploadItem.name }}\n </a-button>\n </template>\n </template>\n </a-descriptions-item>\n </template>\n <template v-else>\n <a-descriptions-item\n v-if=\"!obj4.is_hide\"\n :label=\"obj4.label\"\n >\n {{ obj4.value }}\n </a-descriptions-item>\n </template>\n </template>\n </template>\n </a-descriptions>\n <a-descriptions\n bordered\n :column=\"obj2?.column ? obj2?.column : 3\"\n >\n <template\n v-for=\"(obj4, l) in obj3\"\n :key=\"l\"\n >\n <template v-if=\"obj4.type === 'remotetablepro'\">\n <a-descriptions-item\n :label=\"obj4.label\"\n :span=\"3\"\n >\n <s-table\n :columns=\"getColumns(obj4.children)\"\n :data-source=\"getDataSource(obj4.children)\"\n :pagination=\"false\"\n :rangeSelection=\"false\"\n :row-key=\"'index'\"\n bordered\n size=\"small\"\n stripe\n >\n <template #bodyCell=\"{ record, column, text, index }\">\n <template v-if=\"column.dataIndex.includes('upload')\">\n <template v-if=\"text && text?.length > 0\">\n <template\n v-for=\"(uploadItem, m) in text\"\n :key=\"m\"\n >\n <br v-if=\"m > 0\" />\n <a-button\n :title=\"uploadItem.name\"\n style=\"padding-left: 1px; width: 100%\"\n type=\"link\"\n @click=\"look(uploadItem.url)\"\n >\n <span\n style=\"\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n width: 100%;\n user-select: text;\n text-align: left;\n \"\n >\n {{ uploadItem.name }}\n </span>\n </a-button>\n </template>\n </template>\n </template>\n <template v-else>{{ text }}</template>\n </template>\n </s-table>\n </a-descriptions-item>\n </template>\n <template v-if=\"obj4.type === 'formtemplate'\">\n <a-descriptions-item\n :label=\"obj4.label\"\n :span=\"3\"\n >\n <template\n v-for=\"(obj5, k) in obj4.children\"\n :key=\"k\"\n >\n <a-descriptions\n bordered\n :column=\"obj4?.column ? obj4?.column : 3\"\n >\n <template\n v-for=\"(obj6, l) in obj5\"\n :key=\"l\"\n >\n <template\n v-if=\"\n obj6.type !== 'remotetablepro' &&\n obj6.type !== 'formtemplate'\n \"\n >\n <template\n v-if=\"obj6.type === 'textarea' && !obj6.is_hide\"\n >\n <a-descriptions-item :label=\"obj6.label\">\n <p\n style=\"\n white-space: pre-line;\n margin: 0;\n color: #909399;\n \"\n >\n {{ obj6.value }}\n </p>\n </a-descriptions-item>\n </template>\n <template\n v-else-if=\"obj6.type === 'upload' && !obj6.is_hide\"\n >\n <a-descriptions-item :label=\"obj6.label\">\n <template\n v-if=\"obj6.value && obj6.value?.length > 0\"\n >\n <template\n v-for=\"(uploadItem, m) in obj6.value\"\n :key=\"m\"\n >\n <br v-if=\"m > 0\" />\n <a-button\n type=\"link\"\n @click=\"look(uploadItem.url)\"\n >\n {{ uploadItem.name }}\n </a-button>\n </template>\n </template>\n </a-descriptions-item>\n </template>\n <template v-else>\n <a-descriptions-item\n v-if=\"!obj6.is_hide\"\n :label=\"obj6.label\"\n >\n {{ obj6.value }}\n </a-descriptions-item>\n </template>\n </template>\n </template>\n </a-descriptions>\n <a-descriptions\n bordered\n :column=\"obj4?.column ? obj4?.column : 3\"\n >\n <template\n v-for=\"(obj6, l) in obj5\"\n :key=\"l\"\n >\n <template v-if=\"obj6.type === 'remotetablepro'\">\n <a-descriptions-item\n :label=\"obj6.label\"\n :span=\"3\"\n >\n <s-table\n :columns=\"getColumns(obj6.children)\"\n :data-source=\"getDataSource(obj6.children)\"\n :pagination=\"false\"\n :rangeSelection=\"false\"\n :row-key=\"'index'\"\n bordered\n size=\"small\"\n stripe\n >\n <template\n #bodyCell=\"{ record, column, text, index }\"\n >\n <template\n v-if=\"column.dataIndex.includes('upload')\"\n >\n <template v-if=\"text && text?.length > 0\">\n <template\n v-for=\"(uploadItem, m) in text\"\n :key=\"m\"\n >\n <br v-if=\"m > 0\" />\n <a-button\n :title=\"uploadItem.name\"\n style=\"padding-left: 1px; width: 100%\"\n type=\"link\"\n @click=\"look(uploadItem.url)\"\n >\n <span\n style=\"\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n width: 100%;\n user-select: text;\n text-align: left;\n \"\n >\n {{ uploadItem.name }}\n </span>\n </a-button>\n </template>\n </template>\n </template>\n <template v-else>{{ text }}</template>\n </template>\n </s-table>\n </a-descriptions-item>\n </template>\n </template>\n </a-descriptions>\n </template>\n </a-descriptions-item>\n </template>\n </template>\n </a-descriptions>\n </template>\n </a-descriptions-item>\n </template>\n </template>\n </a-descriptions>\n </template>\n </a-descriptions-item>\n </template>\n </template>\n </a-descriptions>\n </template>\n <template v-if=\"task_data.length > 0\">\n <div class=\"xinxi-title\">审批记录</div>\n <s-table\n :columns=\"task_columns\"\n :data-source=\"task_data\"\n :pagination=\"false\"\n :rangeSelection=\"false\"\n :scroll=\"{ y: 400 }\"\n :rowKey=\"'id'\"\n bordered\n size=\"small\"\n stripe\n >\n <template #bodyCell=\"{ column, index, text, record }\">\n <template v-if=\"column.dataIndex == 'index'\">\n {{ index + 1 }}\n </template>\n <template v-else>\n {{ text }}\n </template>\n </template>\n </s-table>\n </template>\n <template v-if=\"person_approve.length > 0\">\n <div class=\"xinxi-title\">步骤审批人信息</div>\n <s-table\n :columns=\"person_columns\"\n :data-source=\"person_approve\"\n :pagination=\"false\"\n :rangeSelection=\"false\"\n :scroll=\"{ y: 400 }\"\n :rowKey=\"'id'\"\n bordered\n size=\"small\"\n stripe\n >\n <template #bodyCell=\"{ column, index, text, record }\">\n <template v-if=\"column.dataIndex == 'index'\">\n {{ index + 1 }}\n </template>\n <template v-else-if=\"column.dataIndex == 'jue_se'\">\n <a-tag\n v-if=\"record?.jue_se\"\n color=\"blue\"\n >\n {{ record?.jue_se || '' }}\n </a-tag>\n </template>\n <template v-else-if=\"column.dataIndex == 'list'\">\n <a-tag\n v-for=\"(obj, index) in record.list\"\n :key=\"index\"\n color=\"green\"\n >\n {{ obj.realname }}\n </a-tag>\n </template>\n <template v-else>\n {{ text }}\n </template>\n </template>\n </s-table>\n </template>\n <div style=\"height: 400px; margin-top: 10px\">\n <my-process-viewer\n :flowData=\"flowData\"\n :height=\"400\"\n />\n </div>\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { onMounted, reactive, ref, watch } from 'vue';\nimport { useGetApiData } from '../init-plugin';\nimport MyProcessViewer from './Process/viewer/index.vue';\n\ndefineOptions({\n name: 'ApprovalForDetails',\n});\n\nconst getApiData = useGetApiData();\n\nconst props = defineProps<{\n /** 审批记录(至少要有 id;权威字段由组件内部再取一次) */\n record: Record<string, any>;\n}>();\n\nconst data = ref([]);\nconst approval_obj: any = reactive({});\nconst flowData = ref({});\nconst task_columns = [\n {\n title: '序号',\n dataIndex: 'index',\n width: 50,\n ellipsis: true,\n fixed: 'left',\n },\n {\n title: '审批步骤',\n dataIndex: 'name',\n minWidth: 150,\n ellipsis: true,\n resizable: true,\n },\n {\n title: '职位',\n dataIndex: 'approval_position__name',\n minWidth: 150,\n ellipsis: true,\n resizable: true,\n },\n {\n title: '审批人',\n dataIndex: 'assignee__realname',\n minWidth: 150,\n ellipsis: true,\n resizable: true,\n },\n {\n title: '操作',\n dataIndex: 'approval_result',\n minWidth: 150,\n ellipsis: true,\n resizable: true,\n },\n {\n title: '审批意见',\n dataIndex: 'comment',\n minWidth: 150,\n ellipsis: true,\n resizable: true,\n },\n {\n title: '时间',\n dataIndex: 'end_time',\n minWidth: 150,\n ellipsis: true,\n resizable: true,\n },\n];\nconst person_columns = [\n {\n title: '序号',\n dataIndex: 'index',\n width: 50,\n ellipsis: true,\n fixed: 'left',\n },\n {\n title: '审批步骤',\n dataIndex: 'name',\n width: 150,\n ellipsis: true,\n resizable: true,\n },\n {\n title: '职位',\n dataIndex: 'jue_se',\n width: 150,\n ellipsis: true,\n resizable: true,\n },\n {\n title: '步骤审批人',\n dataIndex: 'list',\n minWidth: 150,\n ellipsis: true,\n resizable: true,\n },\n];\nconst task_data = ref([]);\nconst isNotEmpty = value => {\n return value !== null && value !== undefined && value !== '';\n};\nconst getData = (list, loaddata, options) => {\n const displayList = [];\n // 递归处理 formtemplate 的子字段\n const processFormTemplate = (formTemplate, formData, formOptions) => {\n if (!formTemplate?.form?.dynamicFieldList) return [];\n return formTemplate.form.dynamicFieldList.flatMap(fieldGroup =>\n fieldGroup.children.map(child => {\n const childObj: any = {\n label: child.label,\n type: child.type,\n value: '',\n column: child?.column || 3,\n is_hide:\n formTemplate?.showType == 'table'\n ? child?.is_table_hide_column || false\n : child?.is_hide || false,\n };\n // 处理不同类型的字段\n if (child.type === 'formtemplate') {\n // 递归处理嵌套的 formtemplate\n if (formData?.[child.name]?.length > 0) {\n childObj.children = [];\n formData[child.name].forEach(item => {\n childObj.children.push(processFormTemplate(child, item, child.form.options));\n });\n }\n } else if (child.type === 'select' || child.type === 'radio') {\n if (isNotEmpty(formData?.[child.name])) {\n const option = formOptions?.[child.name]?.find(\n item => item.value == formData[child.name],\n );\n childObj.value = option?.name || '';\n }\n } else if (child.type === 'checkbox') {\n if (isNotEmpty(formData?.[child.name])) {\n const names = formOptions?.[child.name]\n ?.filter(item => formData[child.name].includes(item.value))\n ?.map(item => item.name)\n ?.filter(Boolean);\n childObj.value = names?.join(',') || '';\n }\n } else if (child.type === 'remoteselectpro') {\n if (isNotEmpty(formData?.[child.name + '.label'])) {\n childObj.value = formData[child.name + '.label'];\n }\n } else if (child.type === 'remotetablepro') {\n childObj.children = [];\n if (formData?.[child.name]?.length > 0) {\n formData[child.name].forEach(tableData => {\n const remotetableproList = [];\n if (child?.children?.length > 0) {\n child.children.forEach(child1 => {\n if (child1?.children?.length > 0) {\n child1.children.forEach(child2 => {\n const remotetableproObj = {\n label: child2.label,\n type: child2.type,\n value: '',\n };\n if (\n child2.type === 'select' ||\n child2.type === 'radio' ||\n child2.type === 'checkbox' ||\n child2.type === 'remoteselectpro'\n ) {\n remotetableproObj.value = tableData?.[child2.name2] || '';\n } else {\n remotetableproObj.value = tableData?.[child2.name] || '';\n }\n remotetableproList.push(remotetableproObj);\n });\n }\n });\n }\n childObj.children.push(remotetableproList);\n });\n }\n } else {\n childObj.value = formData?.[child.name] || '';\n }\n return childObj;\n }),\n );\n };\n\n list.forEach(item => {\n if (item?.children?.length > 0) {\n const obj = {\n group_name: item?.group_name || '',\n children: [],\n column: item?.column || 3,\n };\n\n item.children.forEach(child => {\n const childObj: any = {\n label: child.label,\n type: child.type,\n column: child?.column || 3,\n value: '',\n };\n\n // 处理不同类型的字段\n if (child.type === 'remoteselectpro') {\n if (isNotEmpty(loaddata?.[child.name + '.label'])) {\n childObj.value = loaddata?.[child.name + '.label'];\n }\n } else if (child.type === 'select' || child.type === 'radio') {\n if (isNotEmpty(loaddata?.[child.name])) {\n const option = options?.[child.name]?.find(item => item.value == loaddata[child.name]);\n childObj.value = option?.name || '';\n }\n } else if (child.type === 'checkbox') {\n if (isNotEmpty(loaddata?.[child.name])) {\n const names = options?.[child.name]\n ?.filter(item => loaddata[child.name].includes(item.value))\n ?.map(item => item.name)\n ?.filter(Boolean);\n childObj.value = names?.join(',') || '';\n }\n } else if (child.type === 'remotetablepro') {\n childObj.children = [];\n if (loaddata?.[child.name]?.length > 0) {\n loaddata[child.name].forEach(tableData => {\n const remotetableproList = [];\n if (child?.children?.length > 0) {\n child.children.forEach(child1 => {\n if (child1?.children?.length > 0) {\n child1.children.forEach(child2 => {\n const remotetableproObj = {\n label: child2.label,\n type: child2.type,\n value: '',\n };\n if (\n child2.type === 'select' ||\n child2.type === 'radio' ||\n child2.type === 'checkbox' ||\n child2.type === 'remoteselectpro'\n ) {\n remotetableproObj.value = tableData?.[child2.name2] || '';\n } else {\n remotetableproObj.value = tableData?.[child2.name] || '';\n }\n remotetableproList.push(remotetableproObj);\n });\n }\n });\n }\n childObj.children.push(remotetableproList);\n });\n }\n } else if (child.type === 'formtemplate') {\n // 处理 formtemplate 类型\n if (loaddata?.[child.name]?.length > 0) {\n childObj.children = [];\n loaddata[child.name].forEach(item => {\n childObj.children.push(processFormTemplate(child, item, child.form.options));\n });\n }\n } else {\n childObj.value = loaddata?.[child.name] || '';\n }\n obj.children.push(childObj);\n });\n displayList.push(obj);\n }\n });\n return displayList;\n};\nconst parseBpmnUserTask = (xmlStr: any) => {\n // 1. 创建DOMParser解析XML\n const parser = new DOMParser();\n const xmlDoc = parser.parseFromString(xmlStr, 'text/xml');\n\n // 2. 获取所有userTask标签(处理命名空间)\n const userTasks = xmlDoc.getElementsByTagName('userTask');\n const result = [];\n\n // 3. 遍历每个userTask\n for (const task of userTasks) {\n // 提取name\n const name = task.getAttribute('name') || '';\n // 提取审批类型 userType\n const userType = task.getAttribute('flowable:userType') || '';\n // 根据类型提取对应的值\n let value = '';\n if (userType === 'candidateGroups') {\n value = task.getAttribute('flowable:candidateGroups') || '';\n }\n if (userType === 'assignee') {\n value = task.getAttribute('flowable:assignee') || '';\n }\n if (userType === 'candidateUsers') {\n value = task.getAttribute('flowable:candidateUsers') || '';\n }\n // 组装结果\n result.push({\n name: name,\n type: userType,\n value: value,\n });\n }\n return result;\n};\nconst person_approve = ref([]);\n/**\n * 拉取 / 刷新审批详情。\n *\n * 被两处调用:挂载时,以及「修改保存 / 作废成功」后的 onChange。\n * 所以有两件事必须做:\n * 1. 累积型数组(task_data / person_approve)每次**先清空**,否则重复追加;\n * 2. 用请求序号丢弃过期响应 —— 用户连点刷新时旧请求可能后到,把新数据覆盖掉。\n */\nlet load_seq = 0;\nconst loadDetail = async () => {\n const seq = ++load_seq;\n const approve_record_id = props.record?.id;\n if (!approve_record_id) {\n return;\n }\n task_data.value = [];\n person_approve.value = [];\n data.value = [];\n const res: any = await getApiData(\n { approve_record_id },\n '/approve/get_approve_record_info',\n );\n if (seq !== load_seq) {\n return;\n }\n data.value = getData(\n res.form_definition__data.dynamicFieldList,\n res.form_data,\n res.form_definition__data.options,\n );\n flowData.value = { xmlData: res.xml_data, nodeData: res.node_data };\n const person_list: any = await getApiData(\n {\n is_active: true,\n },\n '/sys/query_person_detail_list',\n );\n const approval_position_list: any = await getApiData(\n {\n is_active: true,\n column_fields: ['approvers_m2m_json', 'name'],\n },\n '/lyapprove/query_approval_position_list',\n );\n person_approve.value = parseBpmnUserTask(res.xml_data);\n person_approve.value = person_approve.value.map((item: any, index: number) => {\n return {\n ...item,\n id: index,\n value: item.value ? item.value.split(',').filter(Boolean).map(Number) : null,\n };\n });\n person_approve.value.forEach((item: any) => {\n if (item.value && item.value.length > 0) {\n item.list = [];\n if (item.type == 'assignee' || item.type == 'candidateUsers') {\n item.value.forEach((item2: any) => {\n person_list.data.forEach((item3: any) => {\n if (item2 == item3.id) {\n item.list.push({\n realname: item3.realname,\n });\n }\n });\n });\n }\n if (item.type == 'candidateGroups') {\n item.value.forEach((item2: any) => {\n approval_position_list.data.forEach((item3: any) => {\n if (item2 == item3.id) {\n item.jue_se = item3.name;\n item.list = item3.approvers_m2m_json;\n }\n });\n });\n }\n }\n });\n Object.assign(approval_obj, res);\n if (res.process_instance_id) {\n task_data.value.push({\n name: '开始',\n id: 0,\n approval_position__name: approval_obj?.form_data?.globalData?.person_position?.name\n ? approval_obj.form_data.globalData.person_position.name\n : '',\n assignee__realname: res.send_person__realname,\n approval_result: '发起',\n comment: '',\n end_time: res.start_time,\n });\n getApiData(\n {\n process_instance_id: res.process_instance_id,\n },\n '/lyapprove/query_task_list',\n ).then((task: any) => {\n if (task && task.data && task.data.length > 0) {\n task.data\n .sort((a: any, b: any) => {\n return a.id - b.id;\n })\n .forEach((item: any) => {\n if (item.status == '完成') {\n task_data.value.push({\n ...item,\n approval_result:\n item.approval_result === 'agree'\n ? '通过'\n : item.approval_result === 'refuse'\n ? '拒绝'\n : '',\n });\n }\n });\n }\n task_data.value = [].concat(task_data.value);\n });\n }\n};\nonMounted(() => {\n loadDetail();\n});\n// 记录 id 变化时重拉(Cell_click_approve 的 cmpObj.record 可能被表格替换)\nwatch(\n () => props.record?.id,\n () => {\n loadDetail();\n },\n);\ndefineExpose({\n /** 供外层在操作完成后刷新详情 */\n reload: loadDetail,\n});\nconst uniqueByTitle = (arr: any) => {\n const seen = new Set();\n return arr.filter(item => !seen.has(item.title) && seen.add(item.title));\n};\nconst getColumns = (list: any) => {\n const columns = [];\n if (list && list.length > 0) {\n list[0].forEach((item: any, index: any) => {\n if (item.type === 'upload') {\n columns.push({\n title: item.label,\n dataIndex: 'upload_' + index,\n minWidth: 150,\n resizable: true,\n autoHeight: true,\n });\n } else {\n columns.push({\n title: item.label,\n dataIndex: 'value_' + index,\n resizable: true,\n autoHeight: true,\n });\n }\n });\n }\n return uniqueByTitle(columns);\n};\nconst getDataSource = (list: any) => {\n const data = [];\n if (list && list.length > 0) {\n list.forEach((item: any, index1: any) => {\n const obj: any = {};\n item.forEach((item1: any, index: any) => {\n if (item1.type === 'upload') {\n obj['upload_' + index] = item1.value;\n } else {\n obj['value_' + index] = item1.value;\n }\n });\n data.push({ ...obj, index: index1 });\n });\n }\n return data;\n};\nconst getDate = time => {\n if (time) {\n time = time.substring(0, 10);\n }\n return time;\n};\nconst getModifyStatusColor = (status: string) => {\n const colorMap: Record<string, string> = {\n 正常: 'green',\n 已修改: 'orange',\n 已删除: 'red',\n };\n return colorMap[status] || 'default';\n};\nconst look = (url: any) => {\n window.open(encodeURI(url), '_blank');\n};\n</script>\n<style lang=\"scss\" scoped>\n.flip-90 {\n transform: rotateY(90deg); /* 绕Y轴旋转90度,元素会垂直倒立 */\n}\n\n.form-container {\n display: flex;\n flex-direction: column;\n justify-content: space-between;\n height: 100%;\n padding: 4px;\n\n .form-header {\n display: flex;\n flex: 0 0 auto;\n flex-direction: row;\n justify-content: space-between;\n align-items: center;\n padding: 4px;\n margin-right: 26px;\n\n .form-title {\n font-size: 15px;\n }\n\n .form-header-right {\n display: flex;\n flex-direction: column;\n }\n\n .right-item {\n padding: 4px;\n // border-left: 1px solid;\n // border-top: 1px solid;\n }\n\n .right-item:first {\n border-top: none;\n }\n }\n\n .form-body {\n flex: 1 1 auto;\n overflow: auto;\n overflow-x: hidden;\n padding: 4px;\n }\n\n .form-footer {\n flex: 0 0 auto;\n padding: 8px;\n border-top: 1px solid #e8e8e8;\n display: flex;\n justify-content: flex-end;\n }\n}\n\n.header-container {\n width: 100%;\n position: relative;\n min-height: 70px; /* 增加最小高度保证布局稳定性 */\n padding: 1px 0; /* 增加上下内边距 */\n}\n\n.serial-number {\n position: absolute;\n left: 0;\n top: 19px;\n transform: translateY(-50%); /* 垂直居中 */\n}\n\n.modify-status {\n position: absolute;\n right: 0;\n top: 19px;\n transform: translateY(-50%); /* 垂直居中 */\n z-index: 1;\n}\n\n.article-title {\n width: 100%;\n padding: 0 200px; /* 左右保留40px距离 */\n box-sizing: border-box; /* 盒模型计算包含内边距 */\n text-align: center; /* 文本整体居中 */\n font-weight: bold;\n font-size: 24px;\n word-wrap: break-word; /* 允许长单词换行 */\n line-height: 1.5; /* 增加行高提高可读性 */\n}\n\n.xinxi-title {\n width: 100%;\n background-color: #dcdcdc;\n padding: 10px 0 10px 20px;\n font-weight: bold;\n border-radius: 3px;\n color: #313131;\n margin: 8px 0 2px 0;\n}\n\n.descriptions {\n :deep(.ant-descriptions .ant-descriptions-row > td) {\n padding: 8px;\n }\n\n :deep(.ant-descriptions .ant-descriptions-row > th) {\n padding: 8px;\n width: 100px;\n }\n}\n</style>\n","<template>\n <div class=\"form-container\">\n <!--\n 本组件只负责**展示**审批详情(头部 / 基本信息 / 表单渲染 / 流程图 / 审批记录表)。\n 修改 / 删除 / 打印按钮不在这里 —— 由外壳自己渲染(位置随外壳挑),\n 是否显示与点击行为统一走 useApprovalRecordActions(参照 Cell_click_approve 的抽屉 #extra、\n Cell_click_data_source 的 tabs #rightExtra)。\n -->\n <div class=\"header-container\">\n <div class=\"serial-number\">流程编码:{{ record?.number }}</div>\n <div class=\"article-title\">{{ approval_obj?.context }}({{ approval_obj?.flow_name }})</div>\n <div\n v-if=\"approval_obj?.modify_status\"\n class=\"modify-status\"\n >\n <a-tag :color=\"getModifyStatusColor(approval_obj.modify_status)\">\n {{ approval_obj.modify_status }}\n </a-tag>\n </div>\n </div>\n <div\n class=\"form-body descriptions\"\n style=\"padding-bottom: 10px\"\n >\n <div\n class=\"xinxi-title\"\n style=\"margin-top: 0\"\n >\n 基本信息\n </div>\n <a-descriptions bordered>\n <a-descriptions-item label=\"发起人\">\n {{ approval_obj?.send_person__realname }}\n </a-descriptions-item>\n <a-descriptions-item label=\"切换组织\">\n {{ approval_obj?.form_data?.globalData?.cost_company?.name }}\n </a-descriptions-item>\n <a-descriptions-item label=\"切换部门\">\n {{ approval_obj?.form_data?.globalData?.cost_department?.name }}\n </a-descriptions-item>\n <a-descriptions-item label=\"员工职位\">\n {{ approval_obj?.form_data?.globalData?.person_position?.name }}\n </a-descriptions-item>\n <a-descriptions-item label=\"员工组织\">\n {{ approval_obj?.form_data?.globalData?.person_cost_company?.name }}\n </a-descriptions-item>\n <a-descriptions-item label=\"员工部门\">\n {{ approval_obj?.form_data?.globalData?.person_department?.name }}\n </a-descriptions-item>\n <a-descriptions-item label=\"发起时间\">\n {{ getDate(approval_obj?.start_time) }}\n </a-descriptions-item>\n <a-descriptions-item\n :span=\"2\"\n label=\"结束时间\"\n >\n {{ getDate(approval_obj?.finish_time) }}\n </a-descriptions-item>\n <a-descriptions-item label=\"流程主题\">{{ approval_obj?.context }}</a-descriptions-item>\n <a-descriptions-item\n v-if=\"approval_obj?.modify_source__number\"\n label=\"修改来源流水号\"\n >\n {{ approval_obj?.modify_source__number }}\n </a-descriptions-item>\n </a-descriptions>\n <template\n v-for=\"(item, i) in data\"\n :key=\"i\"\n >\n <div class=\"xinxi-title\">\n {{ item?.group_name ? item.group_name : '审批信息' + (i + 1) }}\n </div>\n <a-descriptions\n bordered\n :column=\"item?.column ? item?.column : 3\"\n >\n <template\n v-for=\"(obj, j) in item.children\"\n :key=\"j\"\n >\n <template v-if=\"obj.type !== 'remotetablepro' && obj.type !== 'formtemplate'\">\n <template v-if=\"obj.type === 'textarea'\">\n <a-descriptions-item :label=\"obj.label\">\n <p style=\"white-space: pre-line; margin: 0; color: #909399\">{{ obj.value }}</p>\n </a-descriptions-item>\n </template>\n <template v-else-if=\"obj.type === 'upload'\">\n <a-descriptions-item :label=\"obj.label\">\n <template v-if=\"obj.value && obj.value?.length > 0\">\n <template\n v-for=\"(uploadItem, m) in obj.value\"\n :key=\"m\"\n >\n <br v-if=\"m > 0\" />\n <a-button\n type=\"link\"\n @click=\"look(uploadItem.url)\"\n >\n {{ uploadItem.name }}\n </a-button>\n </template>\n </template>\n </a-descriptions-item>\n </template>\n <template v-else>\n <a-descriptions-item\n :label=\"obj.label\"\n :span=\"1\"\n >\n {{ obj.value }}\n </a-descriptions-item>\n </template>\n </template>\n </template>\n </a-descriptions>\n <a-descriptions\n bordered\n :column=\"item?.column ? item?.column : 3\"\n >\n <template\n v-for=\"(obj, j) in item.children\"\n :key=\"j\"\n >\n <template v-if=\"obj.type === 'remotetablepro'\">\n <a-descriptions-item\n :label=\"obj.label\"\n :span=\"3\"\n >\n <s-table\n :columns=\"getColumns(obj.children)\"\n :data-source=\"getDataSource(obj.children)\"\n :pagination=\"false\"\n :rangeSelection=\"false\"\n :row-key=\"'index'\"\n bordered\n size=\"small\"\n stripe\n >\n <template #bodyCell=\"{ record, column, text, index }\">\n <template v-if=\"column.dataIndex.includes('upload')\">\n <template v-if=\"text && text?.length > 0\">\n <template\n v-for=\"(uploadItem, m) in text\"\n :key=\"m\"\n >\n <br v-if=\"m > 0\" />\n <a-button\n :title=\"uploadItem.name\"\n style=\"padding-left: 1px; width: 100%\"\n type=\"link\"\n @click=\"look(uploadItem.url)\"\n >\n <span\n style=\"\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n width: 100%;\n user-select: text;\n text-align: left;\n \"\n >\n {{ uploadItem.name }}\n </span>\n </a-button>\n </template>\n </template>\n </template>\n <template v-else>{{ text }}</template>\n </template>\n </s-table>\n </a-descriptions-item>\n </template>\n <template v-if=\"obj.type === 'formtemplate'\">\n <a-descriptions-item\n :label=\"obj.label\"\n :span=\"3\"\n >\n <template\n v-for=\"(obj1, k) in obj.children\"\n :key=\"k\"\n >\n <a-descriptions\n bordered\n :column=\"obj?.column ? obj?.column : 3\"\n >\n <template\n v-for=\"(obj2, l) in obj1\"\n :key=\"l\"\n >\n <template\n v-if=\"obj2.type !== 'remotetablepro' && obj2.type !== 'formtemplate'\"\n >\n <template v-if=\"obj2.type === 'textarea' && !obj2.is_hide\">\n <a-descriptions-item :label=\"obj2.label\">\n <p style=\"white-space: pre-line; margin: 0; color: #909399\">\n {{ obj2.value }}\n </p>\n </a-descriptions-item>\n </template>\n <template v-else-if=\"obj2.type === 'upload' && !obj2.is_hide\">\n <a-descriptions-item :label=\"obj2.label\">\n <template v-if=\"obj2.value && obj2.value?.length > 0\">\n <template\n v-for=\"(uploadItem, m) in obj2.value\"\n :key=\"m\"\n >\n <br v-if=\"m > 0\" />\n <a-button\n type=\"link\"\n @click=\"look(uploadItem.url)\"\n >\n {{ uploadItem.name }}\n </a-button>\n </template>\n </template>\n </a-descriptions-item>\n </template>\n <template v-else>\n <a-descriptions-item\n v-if=\"!obj2.is_hide\"\n :label=\"obj2.label\"\n >\n {{ obj2.value }}\n </a-descriptions-item>\n </template>\n </template>\n </template>\n </a-descriptions>\n <a-descriptions\n bordered\n :column=\"obj?.column ? obj?.column : 3\"\n >\n <template\n v-for=\"(obj2, l) in obj1\"\n :key=\"l\"\n >\n <template v-if=\"obj2.type === 'remotetablepro' && !obj2.is_hide\">\n <a-descriptions-item\n :label=\"obj2.label\"\n :span=\"3\"\n >\n <s-table\n :columns=\"getColumns(obj2.children)\"\n :data-source=\"getDataSource(obj2.children)\"\n :pagination=\"false\"\n :rangeSelection=\"false\"\n :row-key=\"'index'\"\n bordered\n size=\"small\"\n stripe\n >\n <template #bodyCell=\"{ record, column, text, index }\">\n <template v-if=\"column.dataIndex.includes('upload')\">\n <template v-if=\"text && text?.length > 0\">\n <template\n v-for=\"(uploadItem, m) in text\"\n :key=\"m\"\n >\n <br v-if=\"m > 0\" />\n <a-button\n :title=\"uploadItem.name\"\n style=\"padding-left: 1px; width: 100%\"\n type=\"link\"\n @click=\"look(uploadItem.url)\"\n >\n <span\n style=\"\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n width: 100%;\n user-select: text;\n text-align: left;\n \"\n >\n {{ uploadItem.name }}\n </span>\n </a-button>\n </template>\n </template>\n </template>\n <template v-else>{{ text }}</template>\n </template>\n </s-table>\n </a-descriptions-item>\n </template>\n <template v-if=\"obj2.type === 'formtemplate' && !obj2.is_hide\">\n <a-descriptions-item\n :label=\"obj2.label\"\n :span=\"3\"\n >\n <template\n v-for=\"(obj3, k) in obj2.children\"\n :key=\"k\"\n >\n <a-descriptions\n bordered\n :column=\"obj2?.column ? obj2?.column : 3\"\n >\n <template\n v-for=\"(obj4, l) in obj3\"\n :key=\"l\"\n >\n <template\n v-if=\"\n obj4.type !== 'remotetablepro' && obj4.type !== 'formtemplate'\n \"\n >\n <template v-if=\"obj4.type === 'textarea' && !obj4.is_hide\">\n <a-descriptions-item :label=\"obj4.label\">\n <p style=\"white-space: pre-line; margin: 0; color: #909399\">\n {{ obj4.value }}\n </p>\n </a-descriptions-item>\n </template>\n <template v-else-if=\"obj4.type === 'upload' && !obj4.is_hide\">\n <a-descriptions-item :label=\"obj4.label\">\n <template v-if=\"obj4.value && obj4.value?.length > 0\">\n <template\n v-for=\"(uploadItem, m) in obj4.value\"\n :key=\"m\"\n >\n <br v-if=\"m > 0\" />\n <a-button\n type=\"link\"\n @click=\"look(uploadItem.url)\"\n >\n {{ uploadItem.name }}\n </a-button>\n </template>\n </template>\n </a-descriptions-item>\n </template>\n <template v-else>\n <a-descriptions-item\n v-if=\"!obj4.is_hide\"\n :label=\"obj4.label\"\n >\n {{ obj4.value }}\n </a-descriptions-item>\n </template>\n </template>\n </template>\n </a-descriptions>\n <a-descriptions\n bordered\n :column=\"obj2?.column ? obj2?.column : 3\"\n >\n <template\n v-for=\"(obj4, l) in obj3\"\n :key=\"l\"\n >\n <template v-if=\"obj4.type === 'remotetablepro'\">\n <a-descriptions-item\n :label=\"obj4.label\"\n :span=\"3\"\n >\n <s-table\n :columns=\"getColumns(obj4.children)\"\n :data-source=\"getDataSource(obj4.children)\"\n :pagination=\"false\"\n :rangeSelection=\"false\"\n :row-key=\"'index'\"\n bordered\n size=\"small\"\n stripe\n >\n <template #bodyCell=\"{ record, column, text, index }\">\n <template v-if=\"column.dataIndex.includes('upload')\">\n <template v-if=\"text && text?.length > 0\">\n <template\n v-for=\"(uploadItem, m) in text\"\n :key=\"m\"\n >\n <br v-if=\"m > 0\" />\n <a-button\n :title=\"uploadItem.name\"\n style=\"padding-left: 1px; width: 100%\"\n type=\"link\"\n @click=\"look(uploadItem.url)\"\n >\n <span\n style=\"\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n width: 100%;\n user-select: text;\n text-align: left;\n \"\n >\n {{ uploadItem.name }}\n </span>\n </a-button>\n </template>\n </template>\n </template>\n <template v-else>{{ text }}</template>\n </template>\n </s-table>\n </a-descriptions-item>\n </template>\n <template v-if=\"obj4.type === 'formtemplate'\">\n <a-descriptions-item\n :label=\"obj4.label\"\n :span=\"3\"\n >\n <template\n v-for=\"(obj5, k) in obj4.children\"\n :key=\"k\"\n >\n <a-descriptions\n bordered\n :column=\"obj4?.column ? obj4?.column : 3\"\n >\n <template\n v-for=\"(obj6, l) in obj5\"\n :key=\"l\"\n >\n <template\n v-if=\"\n obj6.type !== 'remotetablepro' &&\n obj6.type !== 'formtemplate'\n \"\n >\n <template\n v-if=\"obj6.type === 'textarea' && !obj6.is_hide\"\n >\n <a-descriptions-item :label=\"obj6.label\">\n <p\n style=\"\n white-space: pre-line;\n margin: 0;\n color: #909399;\n \"\n >\n {{ obj6.value }}\n </p>\n </a-descriptions-item>\n </template>\n <template\n v-else-if=\"obj6.type === 'upload' && !obj6.is_hide\"\n >\n <a-descriptions-item :label=\"obj6.label\">\n <template\n v-if=\"obj6.value && obj6.value?.length > 0\"\n >\n <template\n v-for=\"(uploadItem, m) in obj6.value\"\n :key=\"m\"\n >\n <br v-if=\"m > 0\" />\n <a-button\n type=\"link\"\n @click=\"look(uploadItem.url)\"\n >\n {{ uploadItem.name }}\n </a-button>\n </template>\n </template>\n </a-descriptions-item>\n </template>\n <template v-else>\n <a-descriptions-item\n v-if=\"!obj6.is_hide\"\n :label=\"obj6.label\"\n >\n {{ obj6.value }}\n </a-descriptions-item>\n </template>\n </template>\n </template>\n </a-descriptions>\n <a-descriptions\n bordered\n :column=\"obj4?.column ? obj4?.column : 3\"\n >\n <template\n v-for=\"(obj6, l) in obj5\"\n :key=\"l\"\n >\n <template v-if=\"obj6.type === 'remotetablepro'\">\n <a-descriptions-item\n :label=\"obj6.label\"\n :span=\"3\"\n >\n <s-table\n :columns=\"getColumns(obj6.children)\"\n :data-source=\"getDataSource(obj6.children)\"\n :pagination=\"false\"\n :rangeSelection=\"false\"\n :row-key=\"'index'\"\n bordered\n size=\"small\"\n stripe\n >\n <template\n #bodyCell=\"{ record, column, text, index }\"\n >\n <template\n v-if=\"column.dataIndex.includes('upload')\"\n >\n <template v-if=\"text && text?.length > 0\">\n <template\n v-for=\"(uploadItem, m) in text\"\n :key=\"m\"\n >\n <br v-if=\"m > 0\" />\n <a-button\n :title=\"uploadItem.name\"\n style=\"padding-left: 1px; width: 100%\"\n type=\"link\"\n @click=\"look(uploadItem.url)\"\n >\n <span\n style=\"\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n width: 100%;\n user-select: text;\n text-align: left;\n \"\n >\n {{ uploadItem.name }}\n </span>\n </a-button>\n </template>\n </template>\n </template>\n <template v-else>{{ text }}</template>\n </template>\n </s-table>\n </a-descriptions-item>\n </template>\n </template>\n </a-descriptions>\n </template>\n </a-descriptions-item>\n </template>\n </template>\n </a-descriptions>\n </template>\n </a-descriptions-item>\n </template>\n </template>\n </a-descriptions>\n </template>\n </a-descriptions-item>\n </template>\n </template>\n </a-descriptions>\n </template>\n <template v-if=\"task_data.length > 0\">\n <div class=\"xinxi-title\">审批记录</div>\n <s-table\n :columns=\"task_columns\"\n :data-source=\"task_data\"\n :pagination=\"false\"\n :rangeSelection=\"false\"\n :scroll=\"{ y: 400 }\"\n :rowKey=\"'id'\"\n bordered\n size=\"small\"\n stripe\n >\n <template #bodyCell=\"{ column, index, text, record }\">\n <template v-if=\"column.dataIndex == 'index'\">\n {{ index + 1 }}\n </template>\n <template v-else>\n {{ text }}\n </template>\n </template>\n </s-table>\n </template>\n <template v-if=\"person_approve.length > 0\">\n <div class=\"xinxi-title\">步骤审批人信息</div>\n <s-table\n :columns=\"person_columns\"\n :data-source=\"person_approve\"\n :pagination=\"false\"\n :rangeSelection=\"false\"\n :scroll=\"{ y: 400 }\"\n :rowKey=\"'id'\"\n bordered\n size=\"small\"\n stripe\n >\n <template #bodyCell=\"{ column, index, text, record }\">\n <template v-if=\"column.dataIndex == 'index'\">\n {{ index + 1 }}\n </template>\n <template v-else-if=\"column.dataIndex == 'jue_se'\">\n <a-tag\n v-if=\"record?.jue_se\"\n color=\"blue\"\n >\n {{ record?.jue_se || '' }}\n </a-tag>\n </template>\n <template v-else-if=\"column.dataIndex == 'list'\">\n <a-tag\n v-for=\"(obj, index) in record.list\"\n :key=\"index\"\n color=\"green\"\n >\n {{ obj.realname }}\n </a-tag>\n </template>\n <template v-else>\n {{ text }}\n </template>\n </template>\n </s-table>\n </template>\n <div style=\"height: 400px; margin-top: 10px\">\n <my-process-viewer\n :flowData=\"flowData\"\n :height=\"400\"\n />\n </div>\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { onMounted, reactive, ref, watch } from 'vue';\nimport { useGetApiData } from '../init-plugin';\nimport MyProcessViewer from './Process/viewer/index.vue';\n\ndefineOptions({\n name: 'ApprovalForDetails',\n});\n\nconst getApiData = useGetApiData();\n\nconst props = defineProps<{\n /** 审批记录(至少要有 id;权威字段由组件内部再取一次) */\n record: Record<string, any>;\n}>();\n\nconst data = ref([]);\nconst approval_obj: any = reactive({});\nconst flowData = ref({});\nconst task_columns = [\n {\n title: '序号',\n dataIndex: 'index',\n width: 50,\n ellipsis: true,\n fixed: 'left',\n },\n {\n title: '审批步骤',\n dataIndex: 'name',\n minWidth: 150,\n ellipsis: true,\n resizable: true,\n },\n {\n title: '职位',\n dataIndex: 'approval_position__name',\n minWidth: 150,\n ellipsis: true,\n resizable: true,\n },\n {\n title: '审批人',\n dataIndex: 'assignee__realname',\n minWidth: 150,\n ellipsis: true,\n resizable: true,\n },\n {\n title: '操作',\n dataIndex: 'approval_result',\n minWidth: 150,\n ellipsis: true,\n resizable: true,\n },\n {\n title: '审批意见',\n dataIndex: 'comment',\n minWidth: 150,\n ellipsis: true,\n resizable: true,\n },\n {\n title: '时间',\n dataIndex: 'end_time',\n minWidth: 150,\n ellipsis: true,\n resizable: true,\n },\n];\nconst person_columns = [\n {\n title: '序号',\n dataIndex: 'index',\n width: 50,\n ellipsis: true,\n fixed: 'left',\n },\n {\n title: '审批步骤',\n dataIndex: 'name',\n width: 150,\n ellipsis: true,\n resizable: true,\n },\n {\n title: '职位',\n dataIndex: 'jue_se',\n width: 150,\n ellipsis: true,\n resizable: true,\n },\n {\n title: '步骤审批人',\n dataIndex: 'list',\n minWidth: 150,\n ellipsis: true,\n resizable: true,\n },\n];\nconst task_data = ref([]);\nconst isNotEmpty = value => {\n return value !== null && value !== undefined && value !== '';\n};\nconst getData = (list, loaddata, options) => {\n const displayList = [];\n // 递归处理 formtemplate 的子字段\n const processFormTemplate = (formTemplate, formData, formOptions) => {\n if (!formTemplate?.form?.dynamicFieldList) return [];\n return formTemplate.form.dynamicFieldList.flatMap(fieldGroup =>\n fieldGroup.children.map(child => {\n const childObj: any = {\n label: child.label,\n type: child.type,\n value: '',\n column: child?.column || 3,\n is_hide:\n formTemplate?.showType == 'table'\n ? child?.is_table_hide_column || false\n : child?.is_hide || false,\n };\n // 处理不同类型的字段\n if (child.type === 'formtemplate') {\n // 递归处理嵌套的 formtemplate\n if (formData?.[child.name]?.length > 0) {\n childObj.children = [];\n formData[child.name].forEach(item => {\n childObj.children.push(processFormTemplate(child, item, child.form.options));\n });\n }\n } else if (child.type === 'select' || child.type === 'radio') {\n if (isNotEmpty(formData?.[child.name])) {\n const option = formOptions?.[child.name]?.find(\n item => item.value == formData[child.name],\n );\n childObj.value = option?.name || '';\n }\n } else if (child.type === 'checkbox') {\n if (isNotEmpty(formData?.[child.name])) {\n const names = formOptions?.[child.name]\n ?.filter(item => formData[child.name].includes(item.value))\n ?.map(item => item.name)\n ?.filter(Boolean);\n childObj.value = names?.join(',') || '';\n }\n } else if (child.type === 'remoteselectpro') {\n if (isNotEmpty(formData?.[child.name + '.label'])) {\n childObj.value = formData[child.name + '.label'];\n }\n } else if (child.type === 'remotetablepro') {\n childObj.children = [];\n if (formData?.[child.name]?.length > 0) {\n formData[child.name].forEach(tableData => {\n const remotetableproList = [];\n if (child?.children?.length > 0) {\n child.children.forEach(child1 => {\n if (child1?.children?.length > 0) {\n child1.children.forEach(child2 => {\n const remotetableproObj = {\n label: child2.label,\n type: child2.type,\n value: '',\n };\n if (\n child2.type === 'select' ||\n child2.type === 'radio' ||\n child2.type === 'checkbox' ||\n child2.type === 'remoteselectpro'\n ) {\n remotetableproObj.value = tableData?.[child2.name2] || '';\n } else {\n remotetableproObj.value = tableData?.[child2.name] || '';\n }\n remotetableproList.push(remotetableproObj);\n });\n }\n });\n }\n childObj.children.push(remotetableproList);\n });\n }\n } else {\n childObj.value = formData?.[child.name] || '';\n }\n return childObj;\n }),\n );\n };\n\n list.forEach(item => {\n if (item?.children?.length > 0) {\n const obj = {\n group_name: item?.group_name || '',\n children: [],\n column: item?.column || 3,\n };\n\n item.children.forEach(child => {\n const childObj: any = {\n label: child.label,\n type: child.type,\n column: child?.column || 3,\n value: '',\n };\n\n // 处理不同类型的字段\n if (child.type === 'remoteselectpro') {\n if (isNotEmpty(loaddata?.[child.name + '.label'])) {\n childObj.value = loaddata?.[child.name + '.label'];\n }\n } else if (child.type === 'select' || child.type === 'radio') {\n if (isNotEmpty(loaddata?.[child.name])) {\n const option = options?.[child.name]?.find(item => item.value == loaddata[child.name]);\n childObj.value = option?.name || '';\n }\n } else if (child.type === 'checkbox') {\n if (isNotEmpty(loaddata?.[child.name])) {\n const names = options?.[child.name]\n ?.filter(item => loaddata[child.name].includes(item.value))\n ?.map(item => item.name)\n ?.filter(Boolean);\n childObj.value = names?.join(',') || '';\n }\n } else if (child.type === 'remotetablepro') {\n childObj.children = [];\n if (loaddata?.[child.name]?.length > 0) {\n loaddata[child.name].forEach(tableData => {\n const remotetableproList = [];\n if (child?.children?.length > 0) {\n child.children.forEach(child1 => {\n if (child1?.children?.length > 0) {\n child1.children.forEach(child2 => {\n const remotetableproObj = {\n label: child2.label,\n type: child2.type,\n value: '',\n };\n if (\n child2.type === 'select' ||\n child2.type === 'radio' ||\n child2.type === 'checkbox' ||\n child2.type === 'remoteselectpro'\n ) {\n remotetableproObj.value = tableData?.[child2.name2] || '';\n } else {\n remotetableproObj.value = tableData?.[child2.name] || '';\n }\n remotetableproList.push(remotetableproObj);\n });\n }\n });\n }\n childObj.children.push(remotetableproList);\n });\n }\n } else if (child.type === 'formtemplate') {\n // 处理 formtemplate 类型\n if (loaddata?.[child.name]?.length > 0) {\n childObj.children = [];\n loaddata[child.name].forEach(item => {\n childObj.children.push(processFormTemplate(child, item, child.form.options));\n });\n }\n } else {\n childObj.value = loaddata?.[child.name] || '';\n }\n obj.children.push(childObj);\n });\n displayList.push(obj);\n }\n });\n return displayList;\n};\nconst parseBpmnUserTask = (xmlStr: any) => {\n // 1. 创建DOMParser解析XML\n const parser = new DOMParser();\n const xmlDoc = parser.parseFromString(xmlStr, 'text/xml');\n\n // 2. 获取所有userTask标签(处理命名空间)\n const userTasks = xmlDoc.getElementsByTagName('userTask');\n const result = [];\n\n // 3. 遍历每个userTask\n for (const task of userTasks) {\n // 提取name\n const name = task.getAttribute('name') || '';\n // 提取审批类型 userType\n const userType = task.getAttribute('flowable:userType') || '';\n // 根据类型提取对应的值\n let value = '';\n if (userType === 'candidateGroups') {\n value = task.getAttribute('flowable:candidateGroups') || '';\n }\n if (userType === 'assignee') {\n value = task.getAttribute('flowable:assignee') || '';\n }\n if (userType === 'candidateUsers') {\n value = task.getAttribute('flowable:candidateUsers') || '';\n }\n // 组装结果\n result.push({\n name: name,\n type: userType,\n value: value,\n });\n }\n return result;\n};\nconst person_approve = ref([]);\n/**\n * 拉取 / 刷新审批详情。\n *\n * 被两处调用:挂载时,以及「修改保存 / 作废成功」后的 onChange。\n * 所以有两件事必须做:\n * 1. 累积型数组(task_data / person_approve)每次**先清空**,否则重复追加;\n * 2. 用请求序号丢弃过期响应 —— 用户连点刷新时旧请求可能后到,把新数据覆盖掉。\n */\nlet load_seq = 0;\nconst loadDetail = async () => {\n const seq = ++load_seq;\n const approve_record_id = props.record?.id;\n if (!approve_record_id) {\n return;\n }\n task_data.value = [];\n person_approve.value = [];\n data.value = [];\n const res: any = await getApiData(\n { approve_record_id },\n '/approve/get_approve_record_info',\n );\n if (seq !== load_seq) {\n return;\n }\n data.value = getData(\n res.form_definition__data.dynamicFieldList,\n res.form_data,\n res.form_definition__data.options,\n );\n flowData.value = { xmlData: res.xml_data, nodeData: res.node_data };\n const person_list: any = await getApiData(\n {\n is_active: true,\n },\n '/sys/query_person_detail_list',\n );\n const approval_position_list: any = await getApiData(\n {\n is_active: true,\n column_fields: ['approvers_m2m_json', 'name'],\n },\n '/lyapprove/query_approval_position_list',\n );\n person_approve.value = parseBpmnUserTask(res.xml_data);\n person_approve.value = person_approve.value.map((item: any, index: number) => {\n return {\n ...item,\n id: index,\n value: item.value ? item.value.split(',').filter(Boolean).map(Number) : null,\n };\n });\n person_approve.value.forEach((item: any) => {\n if (item.value && item.value.length > 0) {\n item.list = [];\n if (item.type == 'assignee' || item.type == 'candidateUsers') {\n item.value.forEach((item2: any) => {\n person_list.data.forEach((item3: any) => {\n if (item2 == item3.id) {\n item.list.push({\n realname: item3.realname,\n });\n }\n });\n });\n }\n if (item.type == 'candidateGroups') {\n item.value.forEach((item2: any) => {\n approval_position_list.data.forEach((item3: any) => {\n if (item2 == item3.id) {\n item.jue_se = item3.name;\n item.list = item3.approvers_m2m_json;\n }\n });\n });\n }\n }\n });\n Object.assign(approval_obj, res);\n if (res.process_instance_id) {\n task_data.value.push({\n name: '开始',\n id: 0,\n approval_position__name: approval_obj?.form_data?.globalData?.person_position?.name\n ? approval_obj.form_data.globalData.person_position.name\n : '',\n assignee__realname: res.send_person__realname,\n approval_result: '发起',\n comment: '',\n end_time: res.start_time,\n });\n getApiData(\n {\n process_instance_id: res.process_instance_id,\n },\n '/lyapprove/query_task_list',\n ).then((task: any) => {\n if (task && task.data && task.data.length > 0) {\n task.data\n .sort((a: any, b: any) => {\n return a.id - b.id;\n })\n .forEach((item: any) => {\n if (item.status == '完成') {\n task_data.value.push({\n ...item,\n approval_result:\n item.approval_result === 'agree'\n ? '通过'\n : item.approval_result === 'refuse'\n ? '拒绝'\n : '',\n });\n }\n });\n }\n task_data.value = [].concat(task_data.value);\n });\n }\n};\nonMounted(() => {\n loadDetail();\n});\n// 记录 id 变化时重拉(Cell_click_approve 的 cmpObj.record 可能被表格替换)\nwatch(\n () => props.record?.id,\n () => {\n loadDetail();\n },\n);\ndefineExpose({\n /** 供外层在操作完成后刷新详情 */\n reload: loadDetail,\n});\nconst uniqueByTitle = (arr: any) => {\n const seen = new Set();\n return arr.filter(item => !seen.has(item.title) && seen.add(item.title));\n};\nconst getColumns = (list: any) => {\n const columns = [];\n if (list && list.length > 0) {\n list[0].forEach((item: any, index: any) => {\n if (item.type === 'upload') {\n columns.push({\n title: item.label,\n dataIndex: 'upload_' + index,\n minWidth: 150,\n resizable: true,\n autoHeight: true,\n });\n } else {\n columns.push({\n title: item.label,\n dataIndex: 'value_' + index,\n resizable: true,\n autoHeight: true,\n });\n }\n });\n }\n return uniqueByTitle(columns);\n};\nconst getDataSource = (list: any) => {\n const data = [];\n if (list && list.length > 0) {\n list.forEach((item: any, index1: any) => {\n const obj: any = {};\n item.forEach((item1: any, index: any) => {\n if (item1.type === 'upload') {\n obj['upload_' + index] = item1.value;\n } else {\n obj['value_' + index] = item1.value;\n }\n });\n data.push({ ...obj, index: index1 });\n });\n }\n return data;\n};\nconst getDate = time => {\n if (time) {\n time = time.substring(0, 10);\n }\n return time;\n};\nconst getModifyStatusColor = (status: string) => {\n const colorMap: Record<string, string> = {\n 正常: 'green',\n 已修改: 'orange',\n 已删除: 'red',\n };\n return colorMap[status] || 'default';\n};\nconst look = (url: any) => {\n window.open(encodeURI(url), '_blank');\n};\n</script>\n<style lang=\"scss\" scoped>\n.flip-90 {\n transform: rotateY(90deg); /* 绕Y轴旋转90度,元素会垂直倒立 */\n}\n\n.form-container {\n display: flex;\n flex-direction: column;\n justify-content: space-between;\n height: 100%;\n padding: 4px;\n\n .form-header {\n display: flex;\n flex: 0 0 auto;\n flex-direction: row;\n justify-content: space-between;\n align-items: center;\n padding: 4px;\n margin-right: 26px;\n\n .form-title {\n font-size: 15px;\n }\n\n .form-header-right {\n display: flex;\n flex-direction: column;\n }\n\n .right-item {\n padding: 4px;\n // border-left: 1px solid;\n // border-top: 1px solid;\n }\n\n .right-item:first {\n border-top: none;\n }\n }\n\n .form-body {\n flex: 1 1 auto;\n overflow: auto;\n overflow-x: hidden;\n padding: 4px;\n }\n\n .form-footer {\n flex: 0 0 auto;\n padding: 8px;\n border-top: 1px solid #e8e8e8;\n display: flex;\n justify-content: flex-end;\n }\n}\n\n.header-container {\n width: 100%;\n position: relative;\n min-height: 70px; /* 增加最小高度保证布局稳定性 */\n padding: 1px 0; /* 增加上下内边距 */\n}\n\n.serial-number {\n position: absolute;\n left: 0;\n top: 19px;\n transform: translateY(-50%); /* 垂直居中 */\n}\n\n.modify-status {\n position: absolute;\n right: 0;\n top: 19px;\n transform: translateY(-50%); /* 垂直居中 */\n z-index: 1;\n}\n\n.article-title {\n width: 100%;\n padding: 0 200px; /* 左右保留40px距离 */\n box-sizing: border-box; /* 盒模型计算包含内边距 */\n text-align: center; /* 文本整体居中 */\n font-weight: bold;\n font-size: 24px;\n word-wrap: break-word; /* 允许长单词换行 */\n line-height: 1.5; /* 增加行高提高可读性 */\n}\n\n.xinxi-title {\n width: 100%;\n background-color: #dcdcdc;\n padding: 10px 0 10px 20px;\n font-weight: bold;\n border-radius: 3px;\n color: #313131;\n margin: 8px 0 2px 0;\n}\n\n.descriptions {\n :deep(.ant-descriptions .ant-descriptions-row > td) {\n padding: 8px;\n }\n\n :deep(.ant-descriptions .ant-descriptions-row > th) {\n padding: 8px;\n width: 100px;\n }\n}\n</style>\n","import { computed, ref, watch } from 'vue';\nimport type { Ref } from 'vue';\nimport { message } from 'ant-design-vue';\nimport { executeScriptInWorker, getApiData } from '@/init-plugin';\nimport { Action } from './typing';\nimport { getApproveRecordActions } from './configs/approval/recordActions';\n// 只引类型(编译期擦除,不会把 vue-print-next 拖进静态闭包;运行时那 37.5KB 走动态 import)\nimport type { PrintAreaOption } from 'vue-print-next';\n\n/**\n * 审批记录在**详情场景**下的两个操作 + 打印。\n *\n * 为什么要有这个 composable:详情按钮的消费方有两个(`Cell_click_approve` 的抽屉 #extra、\n * `Cell_click_data_source` 的 tabs #rightExtra —— 按钮都渲染在外壳上,`approval_for_details`\n * 本体只负责展示),如果各自写一遍「能不能显示」和「点了做什么」,\n * 迟早和列表页行按钮的行为漂移。这里把两件事统一收口:\n *\n * 1. **是否可用的判断**(`canShow`)—— 复用 `default.ts` 里 `row_actions` 的\n * `showCode` / `disableCode`(经 `recordActions.ts` 抽出),与列表页 `actionsBar.vue`\n * 跑的是**同一份代码**、同一个 `executeScriptInWorker` 通道;\n * 2. **点击后的行为**(`runAction`)—— 跑 action 自身的 `code` 取数,再分发:\n * `edit_approve` → 打开全屏编辑模态框;`cancel_agree_approve` → 打开作废(删除)模态框;\n * `print` → 打印详情区域。\n *\n * ── 与列表页 `actionsBar` 的唯一差别(有意为之,别\"对齐\"掉)──\n * 列表页:`showCode` 控**显示**、`disableCode` 控**禁用置灰**(按钮还在,只是点不动)。\n * 详情页:两者合起来控**显示/隐藏** —— 不可用就直接不渲染按钮。这是产品要求\n * (详情页按钮少,摆一排灰色的反而更难用),所以 `canShow()` 返回 false 时外壳应当 `v-if` 掉。\n *\n * ── 为什么必须重新拉一遍记录 ──\n * 详情入口拿到的 `record` 往往是**列表行数据**或 `/approve/get_approve_record_info` 的结果,\n * 它们都**没有** `is_modifiable`(和 `menu_flag`)。少了 `is_modifiable`,\n * `approved && pass && is_modifiable === true` 这一支永远为假 —— 「已通过但可修改」的审批\n * 在详情页会**错误地看不到「修改」按钮**。所以这里统一走 lybase 公共 detail 接口\n * `/approve/get_approve_record`(= `get_basemodel`)取权威记录。\n */\n\n/** 详情页支持的操作键。`print` 不是页面配置里的 action,用同一个入口只是为了外壳写法统一 */\nexport type ApproveDetailActionKey = 'edit_approve' | 'cancel_agree_approve' | 'print';\n\n/** 详情页支持的操作键清单(按展示顺序) */\nexport const APPROVE_DETAIL_ACTION_KEYS: ApproveDetailActionKey[] = [\n 'edit_approve',\n 'cancel_agree_approve',\n 'print',\n];\n\nexport interface UseApproveRecordActionsOptions {\n /** 审批记录 id getter。允许异步到达(详情数据后到时会自动重新判定) */\n recordId: () => number | null | undefined;\n /** 菜单标识 getter。不传则用权威记录里的 `menu_flag` */\n modelType?: () => string | null | undefined;\n /** 覆盖默认 action 配置;不传则用库内 `configs/approval/recordActions.ts` 的那份 */\n actions?: () =>\n | Partial<Record<'edit_approve' | 'cancel_agree_approve', Action>>\n | null\n | undefined;\n /** 打印目标元素 getter。**不传则没有打印**(`canShow('print')` 恒为 false) */\n getPrintElement?: () => HTMLElement | null | undefined;\n /** 打印页眉标题 */\n printTitle?: string;\n /**\n * 打印参数覆盖(合并进 `new VuePrintNext({...})`)。\n * 例:外壳的打印区域若包含按钮所在元素,可用 `{ noPrintSelector: '<按钮容器类名>' }`\n * 把它们从打印内容里剔掉(按钮通常渲染在打印区域之外,多数场景不需要传)。\n */\n printOptions?: () => Partial<PrintAreaOption> | null | undefined;\n /** 保存 / 作废成功后的回调:外壳据此刷新详情与列表 */\n onChange?: () => void;\n}\n\n/** 详情场景下跑 action 代码时的 `context` 形状(与列表页对齐,但没有真实表格实例) */\nconst createDetailContext = () => ({\n tables: {\n // action 代码里常写 `tables['approve-approve_record']` 再解构(见 default.ts 的注释示例),\n // 这里给一份空壳,避免用户把那段示例取消注释后直接 TypeError。\n 'approve-approve_record': {\n searchConditions: [],\n selectedRowKeys: [],\n selectedRecord: [],\n datasource: [],\n },\n },\n formModel: null,\n isEdit: false,\n});\n\nexport const useApproveRecordActions = (options: UseApproveRecordActionsOptions) => {\n const record: Ref<Record<string, any> | null> = ref(null);\n const loading = ref(false);\n /** 权威记录就绪前不留按钮(否则会先闪一下「修改」再消失) */\n const ready = ref(false);\n const availability = ref<Record<ApproveDetailActionKey, boolean>>({\n edit_approve: false,\n cancel_agree_approve: false,\n print: false,\n });\n\n const editorOpen = ref(false);\n const editorRecordId: Ref<number | null> = ref(null);\n const removeOpen = ref(false);\n const removeRecordId: Ref<number | null> = ref(null);\n\n const actions = computed<Partial<Record<string, Action>>>(() => {\n const override = options.actions?.();\n return { ...getApproveRecordActions(), ...(override || {}) };\n });\n const modelType = computed(\n () => options.modelType?.() || record.value?.menu_flag || '',\n );\n\n /** 跑 action 代码(`code` / `showCode` / `disableCode`)的统一入口 */\n const runCode = (code: string, action: Action, target: Record<string, any>) =>\n executeScriptInWorker(code, {\n // table_id 与 default.ts 里 data_list 的表标识保持一致:详情页没有真实表格,\n // 但如果用户自定义了读取 `tables[table_id]` 的代码,至少能命中 createDetailContext 的空壳\n table_id: 'approve-approve_record',\n record: target,\n context: createDetailContext(),\n settings: action.settings || {},\n });\n\n /**\n * 判定单个 action 是否可用。\n * `showCode` 与 `disableCode` 都是「可选脚本」:没配(或 enable 为假)就不参与判定。\n * 任一脚本判定为「不可用」即整体不可用(详情页表现为隐藏)。\n */\n const judgeAvailable = async (action: Action | undefined): Promise<boolean> => {\n if (!action || !record.value) return false;\n try {\n if (action.showCode?.enable && action.showCode?.code) {\n const show = await runCode(action.showCode.code, action, record.value);\n if (!show) return false;\n }\n if (action.disableCode?.enable && action.disableCode?.code) {\n const disabled = await runCode(action.disableCode.code, action, record.value);\n if (disabled) return false;\n }\n return true;\n } catch (e) {\n // 判定脚本自己出错时按「不可用」处理并留日志:详情页不该因为一段自定义脚本异常就把\n // 用户挡在外面,但也不能默认放开(可能误删数据)\n console.error('[useApproveRecordActions] 可用性判定脚本执行失败,按不可用处理', e);\n return false;\n }\n };\n\n /** 拉权威记录 + 重新判定全部按钮的可用性 */\n const reload = async () => {\n const id = options.recordId();\n if (!id) {\n record.value = null;\n ready.value = false;\n availability.value = {\n edit_approve: false,\n cancel_agree_approve: false,\n print: false,\n };\n return;\n }\n loading.value = true;\n try {\n record.value = await getApiData({ approve_record_id: id }, '/approve/get_approve_record');\n ready.value = true;\n const [editAvailable, deleteAvailable] = await Promise.all([\n judgeAvailable(actions.value.edit_approve),\n judgeAvailable(actions.value.cancel_agree_approve),\n ]);\n availability.value = {\n edit_approve: editAvailable,\n cancel_agree_approve: deleteAvailable,\n // 打印只要「有目标元素 + 有记录」就可用,不依赖页面配置(页面配置里也没有打印 action)\n print: !!(options.getPrintElement && record.value),\n };\n } finally {\n // 记录加载失败时不把按钮留在「loading 中」的中间态\n if (!record.value) ready.value = false;\n loading.value = false;\n }\n };\n\n /** 打印:动态 import vue-print-next,避免把它(37.5KB)拖进静态闭包 */\n const print = async () => {\n const el = options.getPrintElement?.();\n if (!el) {\n message.error('未找到可打印的内容区域');\n return;\n }\n const { VuePrintNext } = await import('vue-print-next');\n new VuePrintNext({\n el,\n popTitle: options.printTitle || '审批信息',\n // @page margin 置 0 后浏览器不再渲染页眉(标题)/页脚(网址),用 body padding 补回边距。\n // 与改前 PSM_ApproveSystemPC/src/components/cellComponent/Cell_click_approve.vue 的打印参数一致。\n extraHead:\n '<style>@page { margin: 0mm; } body { padding: 10mm !important; box-sizing: border-box; }</style>',\n ...(options.printOptions?.() || {}),\n });\n };\n\n /**\n * 统一点击入口。外壳只需要 `@click=\"runAction('edit_approve')\"`,不用关心取数与分发。\n *\n * 这里会**再判一次**记录是否就绪:调用方一般已经用 `canShow` 把按钮 `v-if` 掉了,\n * 但兜底一次可以避免程序化调用绕过 UI 直接执行不可用的操作。\n */\n const runAction = async (key: ApproveDetailActionKey) => {\n if (key === 'print') {\n await print();\n return;\n }\n const action = actions.value[key];\n if (!action?.code) {\n message.error(`未配置 ${key} 的执行代码`);\n return;\n }\n if (!record.value) {\n message.error('未获取到审批记录');\n return;\n }\n let res: any;\n try {\n res = await runCode(action.code, action, record.value);\n } catch (e: any) {\n // action 代码里的业务校验都是 throw new Error('...'),原样透出给用户\n message.error(e?.message || '操作失败');\n return;\n }\n if (key === 'edit_approve') {\n const { id } = res || {};\n if (!id) {\n message.error('代码未返回id');\n return;\n }\n editorRecordId.value = id;\n editorOpen.value = true;\n } else if (key === 'cancel_agree_approve') {\n const ids = res?.ids;\n if (!ids?.length) {\n message.error('代码未返回ids');\n return;\n }\n if (ids.length !== 1) {\n message.error('每次仅能作废一个审批单');\n return;\n }\n removeRecordId.value = ids[0];\n removeOpen.value = true;\n }\n };\n\n /** 是否可用(= 详情页应当显示) */\n const canShow = (key: ApproveDetailActionKey): boolean => !!availability.value[key];\n\n /** 编辑模态框的绑定参数:外壳 `<ApprovalEditorModal v-model:open=\"editorOpen\" v-bind=\"editorProps\" />` */\n const editorProps = computed(() => ({\n modelType: modelType.value,\n approveRecordId: editorRecordId.value,\n onSaved: async () => {\n await reload();\n options.onChange?.();\n // ⛔ 保存成功后**不要**关模态框(2026-09-21 用户定案):保存(save_approve)只是\n // 「暂存为待提交」,用户还要在右侧继续操作「提交」;要关闭时点右上角的关闭按钮\n // (a-modal 自带 closable)。也不用担心编辑态残留 —— 外壳的 `v-if=\"open\"`\n // 让每次打开都重新挂载 core.vue,编辑态由记录字段重新派生。\n // 历史:曾经「修改保存成功后自动关闭」(用户是从详情页进来的)——已按上述定案移除。\n },\n }));\n\n /** 作废(删除)模态框的绑定参数 */\n const removeProps = computed(() => ({\n id: removeRecordId.value,\n onDone: async () => {\n await reload();\n options.onChange?.();\n },\n }));\n\n watch(\n () => options.recordId(),\n () => {\n reload();\n },\n { immediate: true },\n );\n\n return {\n // 数据\n record,\n ready,\n loading,\n modelType,\n // 可用性判断(统一的「是否显示」函数)\n availability,\n canShow,\n // 统一点击入口\n runAction,\n // 模态框状态(外壳只负责渲染,参数与回调都在这里封好)\n editorOpen,\n editorProps,\n removeOpen,\n removeProps,\n reload,\n };\n};\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"utils-CLet2gLV.js","names":[],"sources":["../src/utils/function.ts","../src/components/approval/utils.ts"],"sourcesContent":["/**\n * 纯函数本地实现。\n *\n * 这些函数原本 import 自 liyu-pc-base / liyu-pc-lib,但它们不依赖宿主的任何实例或状态,\n * 属于纯逻辑,因此直接移植到 lyflowchart 内部,不再让公共库反向依赖宿主库(详见 src/init-plugin.ts 说明)。\n *\n * 对应关系:\n * - isEmpty / isNotEmpty / copyValue / get_operator_type_map <- liyu-pc-base/utils/function.ts\n * - removeNestedDuplicates <- liyu-pc-lib/components/form-modal/FormDesignModal/utils.ts\n *\n * 注意:get_operator_type_map 依赖宿主的操作符文案映射(ConditionOperatorMap),\n * 该常量由宿主注入,通过 useConditionOperatorMap() 读取。\n */\nimport { message } from 'ant-design-vue';\nimport { useConditionOperatorMap } from '@/init-plugin';\n\nexport const isNotEmpty = (value: any) => {\n return value !== null && value !== undefined && value !== '';\n};\n\nexport const isEmpty = (value: any) => {\n return value === null || value == undefined || value === '';\n};\n\n/** 复制文本到剪贴板并提示。val 允许传 { val, message } 形式自定义提示文案。 */\nexport const copyValue = (val: any) => {\n let str = '';\n let messages = '复制成功';\n if (val?.message) {\n str = val.val;\n messages = val.message;\n } else {\n str = val;\n }\n const textarea = document.createElement('textarea');\n textarea.setAttribute('readonly', 'readonly');\n textarea.value = str;\n document.body.appendChild(textarea);\n textarea.select();\n if (document.execCommand('copy')) {\n message.info(messages);\n }\n document.body.removeChild(textarea);\n};\n\n/** 操作符 -> 展示文案,format 为 input 且操作符为 in 时固定展示「等于」 */\nexport const get_operator_type_map = (format: string, operator: string) => {\n const operator_type_map = useConditionOperatorMap();\n if (format == 'input' && operator == 'in') {\n return '等于';\n }\n return operator_type_map[operator];\n};\n\n/** 按 name 去重(保留先出现的节点,同时保留其子树) */\nexport function removeNestedDuplicates(\n nodes: any[],\n seenIds: Set<any> = new Set(),\n parentPath: any[] = [],\n): any[] {\n const result: any[] = [];\n\n nodes.forEach((node, index) => {\n const currentPath = [...parentPath, index]; // 记录当前节点的路径\n const nodeId = node.name;\n\n if (!seenIds.has(nodeId)) {\n seenIds.add(nodeId);\n const newNode = { ...node };\n\n if (newNode.children && Array.isArray(newNode.children)) {\n newNode.children = removeNestedDuplicates(newNode.children, seenIds, currentPath);\n }\n\n result.push(newNode);\n } else {\n // 如果需要处理子对象(即使父对象被忽略了),则递归调用\n if (node.children && Array.isArray(node.children)) {\n // 注意:这里我们不将子对象添加到结果数组中,只是处理它们以避免丢失新的 id\n removeNestedDuplicates(node.children, seenIds, currentPath);\n }\n }\n });\n\n return result;\n}\n","import { isEmpty, removeNestedDuplicates } from '@/utils/function';\nimport { getApiData, useConditionOperatorMap, useOperatorParamsCount } from '@/init-plugin';\nimport { cloneDeep } from 'lodash';\n\n/** 操作符 -> 展示文案(值来自宿主注入的 ConditionOperatorMap) */\nexport const useOperatorTypeMap = () => useConditionOperatorMap();\n\nexport const options_for_date_eq = [\n { value: '上月', label: '上月' },\n { value: '本月', label: '本月' },\n { value: '今日', label: '今日' },\n { value: '昨日', label: '昨日' },\n { value: '期初', label: '期初' },\n];\n\nexport const getParamsCount = (operator, configItem) => {\n return useOperatorParamsCount()[operator];\n};\n\nexport const filterConditions = conditions => {\n if (!conditions) {\n return [];\n }\n const res = conditions.filter(item => {\n return (\n item.value instanceof Array &&\n item.value.length > 0 &&\n !item.value.some(item => isEmpty(item))\n );\n });\n return res;\n};\n\n/**\n * 查询值里的参数占位符,例如 {{menu_flag}}。\n *\n * 页面配置只存占位符,实际值由「执行查询的地方」注入(见 getQueryConditionParams)。\n * 这样同一份页面配置就不含任何与节点绑定的具体值,可以原样同步到其他节点,\n * 不必在同步时按节点改写配置内容。\n */\nconst PARAM_TOKEN_RE = /\\{\\{\\s*([^{}]+?)\\s*\\}\\}/g;\nconst PARAM_TOKEN_FULL_RE = /^\\{\\{\\s*([^{}]+?)\\s*\\}\\}$/;\n\nconst getParamValue = (key: string, params: Record<string, any>) => {\n const value = params ? params[key] : undefined;\n if (value === undefined || value === null || value === '') {\n // 缺参数时若把占位符原样带下去,filterConditions 会认为「有值」照常下发,结果是查不到数据;\n // 若直接丢条件,又会把过滤整体放开。两种都是静默的错误结果,所以这里直接报错,\n // 由调用方决定怎么提示。\n throw new Error(`查询条件参数 {{${key}}} 未提供,请检查调用方是否传入了该参数`);\n }\n return value;\n};\n\n/**\n * 解析条件值里的 {{xxx}} 占位符:\n * - 整串就是一个占位符('{{menu_flag}}')→ 返回参数原值,保留类型(true / 数字 / 数组等)\n * - 占位符嵌在字符串中间('{{prefix}}-{{id}}')→ 按字符串拼接\n * - 不含占位符 → 原样返回\n * 值为数组时逐个元素解析(兼容 eq / in 这类多值条件)。\n */\nexport const resolveParamValue = (value: any, params: Record<string, any>): any => {\n if (Array.isArray(value)) {\n return value.map(item => resolveParamValue(item, params));\n }\n if (typeof value !== 'string' || !value.includes('{{')) {\n return value;\n }\n const full = value.match(PARAM_TOKEN_FULL_RE);\n if (full) {\n return getParamValue(full[1], params);\n }\n return value.replace(PARAM_TOKEN_RE, (_match, key) => String(getParamValue(key, params)));\n};\n\n/**\n * 查询参数的实际值来源 —— 页面配置里 {{xxx}} 占位符的唯一取值出处。\n * menu_flag 即当前审批页对应的菜单标识(组件上的 modelType)。\n */\nexport const getQueryConditionParams = (modelType?: string): Record<string, any> => ({\n menu_flag: modelType,\n});\n\nconst processColumnDataSource = (res_data: any, name_map: object) => {\n res_data.forEach((item: any) => {\n name_map[item.name] = item.verbose_name;\n if (item.children) {\n processColumnDataSource(item.children, name_map);\n }\n });\n};\n\nexport const getColumnNameList = async (modelType: string): Promise<any[]> => {\n if (!modelType) {\n return [];\n }\n const url = modelType.split('-')[0] + '/obtain_' + modelType.split('-')[1] + '_column_data';\n const res = await getApiData({}, url, false, { skip_error: true });\n const name_map = {};\n let res_data = removeNestedDuplicates(res || []);\n processColumnDataSource(res_data, name_map);\n if (!('id' in name_map)) {\n name_map['id'] = 'ID';\n }\n return Object.keys(name_map).map((item: any) => ({\n value: item,\n label: name_map[item],\n }));\n};\n\nexport const actionTypes = [\n {\n label: '把(新建/修改)表单暂时保存,审批处于待提交状态(save_approve)',\n value: 'save_approve',\n },\n {\n label: '选择待提交/已通过(可修改)的审批进行编辑(edit_approve)',\n value: 'edit_approve',\n },\n {\n label: '将处于待提交状态的审批提交(commit_approve)',\n value: 'commit_approve',\n },\n {\n label: '删除处于待提交状态的审批(delete_approve)',\n value: 'delete_approve',\n },\n {\n label: '撤销审批(cancel_approve)',\n value: 'cancel_approve',\n },\n {\n label: '作废已经通过的审批(cancel_agree_approve)',\n value: 'cancel_agree_approve',\n },\n {\n label: '催办(send_reminder)',\n value: 'send_reminder',\n },\n {\n label: '清空表单内容(clear_form)',\n value: 'clear_form',\n },\n {\n label: '数据处理(process)',\n value: 'process',\n },\n {\n label: '复制为新审批(copy_approve)',\n value: 'copy_approve',\n },\n];\nexport const globalOptions = [\n {\n key: 'form_code',\n label: '单据编号',\n children: [\n {\n key: 'code',\n label: '单据编号',\n },\n ],\n },\n {\n key: 'create_date',\n label: '制单日期',\n children: [\n {\n key: 'date',\n label: 'YYYY-MM-DD',\n },\n {\n key: 'date_ch',\n label: 'YYYY年MM月DD日',\n },\n {\n key: 'date_short',\n label: 'YYYYMMDD',\n },\n ],\n },\n {\n key: 'cost_company',\n label: '切换组织',\n children: [\n {\n key: 'name',\n label: '切换组织',\n },\n {\n key: 'id',\n label: 'ID',\n },\n {\n key: 'area',\n label: '地区',\n },\n {\n key: 'code',\n label: '组织编码',\n },\n ],\n },\n {\n key: 'cost_department',\n label: '切换部门',\n children: [\n {\n key: 'name',\n label: '切换部门',\n },\n {\n key: 'id',\n label: 'ID',\n },\n {\n key: 'kind',\n label: '是否核算部门',\n },\n {\n key: 'bz',\n label: '备注',\n },\n {\n key: 'start_date',\n label: '启用时间',\n },\n {\n key: 'end_date',\n label: '关闭时间',\n },\n ],\n },\n {\n key: 'create_by',\n label: '制单人',\n children: [\n {\n key: 'name',\n label: '制单人',\n },\n {\n key: 'id',\n label: 'ID',\n },\n {\n key: 'code',\n label: '人员编号',\n },\n {\n key: 'id_str',\n label: '身份证号',\n },\n {\n key: 'bz',\n label: '备注',\n },\n ],\n },\n\n {\n key: 'person_cost_company',\n label: '员工组织',\n children: [\n {\n key: 'name',\n label: '员工组织',\n },\n {\n key: 'id',\n label: 'ID',\n },\n {\n key: 'area',\n label: '地区',\n },\n {\n key: 'code',\n label: '组织编码',\n },\n ],\n },\n {\n key: 'person_department',\n label: '员工部门',\n children: [\n {\n key: 'name',\n label: '员工部门',\n },\n {\n key: 'id',\n label: 'ID',\n },\n {\n key: 'kind',\n label: '是否核算部门',\n },\n {\n key: 'bz',\n label: '备注',\n },\n {\n key: 'start_date',\n label: '启用时间',\n },\n {\n key: 'end_date',\n label: '关闭时间',\n },\n ],\n },\n {\n key: 'person_position',\n label: '员工职位',\n children: [\n {\n key: 'name',\n label: '员工职位',\n },\n {\n key: 'id',\n label: 'ID',\n },\n {\n key: 'bz',\n label: '备注',\n },\n {\n key: 'start_date',\n label: '启用时间',\n },\n {\n key: '启用时间',\n label: '关闭时间',\n },\n ],\n },\n {\n key: 'flow_org',\n label: '流程组织',\n children: [\n {\n key: 'name',\n label: '流程组织',\n },\n {\n key: 'id',\n label: '流程组织ID',\n },\n ],\n },\n {\n key: 'context',\n label: '流程主题',\n children: [\n {\n key: 'context',\n label: '流程主题',\n },\n ],\n },\n];\n/**\n * 取页面配置中表单(type === 'form')的动态字段列表 dynamicFieldList\n */\nexport const getFormDynamicFieldList = (approvalConfig: any): any[] => {\n for (const column of approvalConfig?.columns || []) {\n if (column.type === 'form') {\n return column.form?.dynamicFieldList || [];\n }\n }\n return [];\n};\n\n/**\n * 清空表单数据中「只读动态值」(type === 'dynamicvaluefield') 字段的值。\n *\n * 复制为新审批时必须清空:这类字段多为序号、覆盖ID 等,\n * computeDynamicValue 的「已有值不重复分配」守卫(守卫1)会让旧值一直保留,\n * 导致新审批沿用源单据的序号/覆盖ID。\n * 清空后由 DynamicValueField(单字段)与 FormTemplate.syncDynamicValues(子表批量)\n * 重新向后端取号/计算,与 Excel 导入行的处理方式一致。\n *\n * 子表(formtemplate / remotetablepro)的模型是该字段名下的行数组或对象,\n * 需要递归进每一行处理。\n *\n * @param model 表单数据(会被就地修改)\n * @param dynamicFieldList 字段列表(表单 root 或子表自己的)\n */\nexport const clearDynamicValueFields = (model: any, dynamicFieldList: any[]): any => {\n if (!model || !(dynamicFieldList instanceof Array)) {\n return model;\n }\n for (const group of dynamicFieldList) {\n if (!(group?.children instanceof Array)) {\n continue;\n }\n for (const field of group.children) {\n if (!field?.name) {\n continue;\n }\n if (field.type === 'dynamicvaluefield') {\n delete model[field.name];\n } else if (field.type === 'formtemplate' || field.type === 'remotetablepro') {\n const sub_dynamic_field_list = field.form?.dynamicFieldList || field.children || [];\n const value = model[field.name];\n if (value instanceof Array) {\n for (const row of value) {\n clearDynamicValueFields(row, sub_dynamic_field_list);\n }\n } else if (value && typeof value === 'object') {\n clearDynamicValueFields(value, sub_dynamic_field_list);\n }\n }\n }\n }\n return model;\n};\n\nexport const genID = (): string => {\n const array = new Uint8Array(16); // 16 字节 = 128 位\n window.crypto.getRandomValues(array);\n return Array.from(array, byte => byte.toString(16).padStart(2, '0')).join('');\n};\n\n/**\n * 「规则更新」在 rule.fields[] 上落的临时标记字段。它们只用于「点完规则更新」后,\n * 在**当次会话内**提示哪些列变了、哪些列的数据源配置被清空需要重配,**不属于配置数据**:\n * - 读取(get_data_store_setting / 导入配置文件 / 应用历史版本)时必须过滤掉,否则重新进入\n * 页面会把上一次的「新增/变更」标记当成当前状态渲染出来 —— 灰色「变更」尤其顽固:它代表\n * 「仅属性变更、原配置已保留、无需操作」的列,用户没有理由去编辑它,标记永远清不掉。\n * - 保存(set_data_store_setting / 导出配置文件)时必须剥掉,不再落库。\n * 写入方:components/dataStoreConfig/dataStoreConfig.vue(updateRules);\n * 读取方:components/dataStoreConfig/dataStoreConfigItem.vue(# 列提示标签)。\n * ⚠️ 增删/改名这些标记字段时,上面两处需同步。\n */\nexport const CONFIG_HINT_KEYS = ['config_hint', 'config_hint_cleared', 'config_hint_detail'];\n\n/** 就地剥离数据存储配置里所有临时标记字段(原地修改并返回,便于链式使用) */\nexport const stripDataStoreConfigHints = (config: any): any => {\n if (!Array.isArray(config)) {\n return config;\n }\n for (const rule of config) {\n for (const field of rule?.fields || []) {\n if (!field) {\n continue;\n }\n for (const key of CONFIG_HINT_KEYS) {\n if (key in field) {\n delete field[key];\n }\n }\n }\n }\n return config;\n};\n\nexport interface CreateModifyApproveParams {\n source_approve_record_id: any;\n data: any;\n page_setting_history_id?: any;\n}\n\n/**\n * 修改模式保存:调用后端 create_modify_approve,\n * 新建一条待提交审批记录(关联源记录),源记录置「已修改」。\n * org_id 由后端装饰器从请求上下文解析,无需前端传参。\n */\nexport const createModifyApprove = (params: CreateModifyApproveParams) => {\n return getApiData(params, '/approve/create_modify_approve');\n};\n\n/**\n * ────────── showTables「数据选择」弹窗:按表限制选择数量 ──────────\n *\n * 契约:`showTables({ title, tables })` 的 tables[i] 支持两个**可选**配置:\n * - `min_count`:最少选择条数\n * - `max_count`:最多选择条数\n * 字段名与表单设计端「最小数量/最大数量」(liyu-pc-base FormTemplate 的 min_count/max_count)保持一致。\n *\n * 规则(务必保持):\n * 1. **两个都没配 → 不校验、不提示**,行为与历史版本完全一致(对外只增不减)。\n * 2. `<= 0`、非数字、空值一律视为「未配置」,不产生提示也不参与校验。\n * 3. 校验粒度是**每张表各自校验**(多表弹窗互不影响);配了 `min_count` 的表等同「必选」。\n * 4. 只在点「确定」时拦截,不限制勾选动作本身(勾多了给提示,由用户改回来)。\n * 5. `min_count > max_count` 属非法配置:忽略该表的校验并告警,**不锁死用户**(否则弹窗永远关不掉)。\n *\n * 消费方:components/columnTables.vue(表头提示)、components/tableModal.vue(确定前校验 + 底部红字)。\n */\nexport interface TableSelectLimit {\n min: number | null;\n max: number | null;\n}\n\n/** 归一化单个数量配置:非数字 / 空值 / <= 0 一律视为「未配置」 */\nexport const normalizeSelectCount = (value: any): number | null => {\n const num = typeof value === 'string' ? Number(value) : value;\n if (typeof num !== 'number' || !Number.isFinite(num)) {\n return null;\n }\n const int = Math.floor(num);\n return int > 0 ? int : null;\n};\n\n/**\n * 解析某张表的选择数量限制;未配置(或配置非法)时返回 null,表示「不校验、不提示」。\n */\nexport const getTableSelectLimit = (tableConfig: any): TableSelectLimit | null => {\n if (!tableConfig) {\n return null;\n }\n const min = normalizeSelectCount(tableConfig.min_count);\n const max = normalizeSelectCount(tableConfig.max_count);\n if (min === null && max === null) {\n return null;\n }\n if (min !== null && max !== null && min > max) {\n console.warn(\n `[showTables] 表 ${tableConfig.id} 的 min_count(${min}) 大于 max_count(${max}),该表的选择数量校验已忽略`,\n tableConfig,\n );\n return null;\n }\n return { min, max };\n};\n\n/** 规则文案:`最少 1 条,最多 3 条`(单边配置只出对应半边) */\nexport const getTableSelectLimitText = (limit: TableSelectLimit | null): string => {\n if (!limit) {\n return '';\n }\n const { min, max } = limit;\n if (min !== null && max !== null) {\n return `最少 ${min} 条,最多 ${max} 条`;\n }\n if (min !== null) {\n return `最少 ${min} 条`;\n }\n return `最多 ${max} 条`;\n};\n\n/** 已选条数是否越界(未配置限制时恒为 false) */\nexport const isTableSelectCountInvalid = (\n limit: TableSelectLimit | null,\n count: number,\n): boolean => {\n if (!limit) {\n return false;\n }\n const num = Number(count) || 0;\n if (limit.min !== null && num < limit.min) {\n return true;\n }\n if (limit.max !== null && num > limit.max) {\n return true;\n }\n return false;\n};\n\n/**\n * 逐表校验已选条数,返回错误文案(全部通过返回空字符串)。\n * @param tables 参与校验的表配置(调用方需先按「实际渲染出来的表」过滤,避免配了不存在的表 id 把用户锁死)\n * @param counts 表 id → 已选条数(缺失按 0 计)\n */\nexport const validateTableSelectCounts = (\n tables: any[],\n counts: Record<string, number> | null | undefined,\n): string => {\n const errors: string[] = [];\n for (const table of tables || []) {\n const limit = getTableSelectLimit(table);\n if (!limit) {\n continue;\n }\n const count = Number(counts?.[table.id]) || 0;\n if (!isTableSelectCountInvalid(limit, count)) {\n continue;\n }\n const name = table.title || table.id;\n errors.push(`「${name}」${getTableSelectLimitText(limit)},当前已选 ${count} 条`);\n }\n return errors.length > 0 ? `选择数量不符合要求:${errors.join(';')}` : '';\n};\n\n/**\n * ============================ 配置同步 ============================\n *\n * approvalPageConfig 的「配置同步」tab 把**当前节点的某一张表**上勾选的配置块\n * 同步到其它流程节点,走 /approve/sync_page_setting(服务端合并逻辑见\n * PSMSystem2/approve/page_sync.py)。\n *\n * 为什么不能直接把服务器上保存的配置发过去:\n * 页面配置里按钮存的只是 action_code_id,真正的代码按 menu_flag 存在 ActionCodeSetting 里。\n * 若把 action_code_id 一起同步过去,目标节点就会共用同一份代码配置,改一处等于改所有节点。\n * 因此同步走的是「前端处理过的配置」——**保留内联 code、剥离 action_code_id**,\n * 目标节点重新加载时会各自分配新的 action_code_id,各节点代码互相独立。\n * 处理规则与 index.vue::exportConfig 走的\n * processData(data, null, { clear_code: false, clear_action_code_id: true }) 完全一致。\n */\n\n/**\n * 可勾选的基础配置:描述「这张表是什么」。按勾选写入,**不是固定随附**——\n * 有时只想同步列配置、不想覆盖目标节点的名称/查询参数。\n * 表格标识 `id` 不在这里:它只是「在目标节点定位这张表」的键(type + table_id),\n * 不作为同步内容发送。\n */\nexport const SYNC_BASE_FIELDS = [\n 'title',\n 'is_normal_model',\n 'list_url',\n 'modelType',\n 'query_params',\n];\n\n/** 界面上可勾选的配置块(顺序即界面顺序:列 → 查询 → 基础查询条件 → 行按钮 → 底部按钮) */\nexport const SYNC_OPTION_FIELDS = [\n 'columns',\n 'search_config',\n 'base_conditions',\n 'row_actions',\n 'actions',\n];\n\n/** 同步类型 */\nexport type SyncMode = 'standard' | 'append';\n\nexport const SYNC_MODE_TITLES: Record<SyncMode, string> = {\n standard: '标准同步',\n append: '自动追加配置',\n};\n\nexport const SYNC_OPTION_FIELD_TITLES: Record<string, string> = {\n actions: '底部按钮配置',\n base_conditions: '基础查询条件',\n columns: '列配置',\n row_actions: '行按钮配置',\n search_config: '查询配置',\n};\n\nexport const SYNC_BASE_FIELD_TITLES: Record<string, string> = {\n title: '名称',\n is_normal_model: '是否为标准模型查询',\n list_url: '列表URL',\n modelType: '模型',\n query_params: '查询参数',\n};\n\n/** 剥离按钮上的 action_code_id(保留内联的 action / code) */\nconst stripActionCodeId = (actionItem: any) => {\n if (!actionItem) {\n return;\n }\n if (actionItem.action_code_id) {\n delete actionItem.action_code_id;\n }\n if (actionItem.showCode?.enable && actionItem.showCode.action_code_id) {\n delete actionItem.showCode.action_code_id;\n }\n if (actionItem.disableCode?.enable && actionItem.disableCode.action_code_id) {\n delete actionItem.disableCode.action_code_id;\n }\n};\n\nexport const stripActionCodeIds = (actions: any) => {\n for (const actionItem of actions || []) {\n stripActionCodeId(actionItem);\n }\n};\n\n/**\n * 抽取「要同步的表格配置」:\n * - 在副本上操作,不污染页面上的表格对象;\n * - `selectedFields` 是界面勾选的全部同步内容(基础配置 + 配置块混在一起),\n * 基础配置不再固定随附,全按勾选来;\n * - `id`(表格标识)永远不进 data——它只是定位键(table_id 单独传);\n * - append(自动追加配置)模式下,目标节点找不到该表时要**整表完整写入**,\n * 因此 data 带上当前表格全部存在的配置块(不受勾选限制),\n * `fields` 仍回勾选项——目标已存在该表时后端只按勾选合并;\n * - `fields` 返回真正会写入的配置项;`skipped` 是勾选了但当前表格里不存在的\n * (例如老配置没有 row_actions),调用方据此提示用户,避免「勾了却没同步」的静默失败。\n */\nexport const buildSyncTableData = (\n table: any,\n selectedFields: string[] = [],\n syncMode: SyncMode = 'standard',\n): { data: Record<string, any>; fields: string[]; skipped: string[] } => {\n const data: Record<string, any> = {};\n const fields: string[] = [];\n const skipped: string[] = [];\n if (!table) {\n return { data, fields, skipped: [...selectedFields] };\n }\n const cloned = cloneDeep(table);\n stripActionCodeIds(cloned.actions);\n stripActionCodeIds(cloned.row_actions);\n const includeKeys = syncMode === 'append' ? [...SYNC_BASE_FIELDS, ...SYNC_OPTION_FIELDS] : selectedFields;\n for (const key of includeKeys) {\n if (cloned[key] === undefined) {\n continue;\n }\n data[key] = cloned[key];\n if (selectedFields.includes(key)) {\n fields.push(key);\n }\n }\n for (const key of selectedFields) {\n if (cloned[key] === undefined) {\n skipped.push(key);\n }\n }\n return { data, fields, skipped };\n};\n"],"mappings":";;;;AAgBA,IAAa,KAAc,MAClB,KAAU,QAA+B,MAAU,IAG/C,KAAW,MACf,MAAU,QAAQ,KAAS,QAAa,MAAU,IAI9C,KAAa,MAAa;CACrC,IAAI,IAAM,IACN,IAAW;AACf,CAAI,GAAK,WACP,IAAM,EAAI,KACV,IAAW,EAAI,WAEf,IAAM;CAER,IAAM,IAAW,SAAS,cAAc,WAAW;AAQnD,CAPA,EAAS,aAAa,YAAY,WAAW,EAC7C,EAAS,QAAQ,GACjB,SAAS,KAAK,YAAY,EAAS,EACnC,EAAS,QAAQ,EACb,SAAS,YAAY,OAAO,IAC9B,EAAQ,KAAK,EAAS,EAExB,SAAS,KAAK,YAAY,EAAS;GAIxB,KAAyB,GAAgB,MAAqB;CACzE,IAAM,IAAoB,GAAyB;AAInD,QAHI,KAAU,WAAW,KAAY,OAC5B,OAEF,EAAkB;;AAI3B,SAAgB,EACd,GACA,oBAAoB,IAAI,KAAK,EAC7B,IAAoB,EAAE,EACf;CACP,IAAM,IAAgB,EAAE;AAwBxB,QAtBA,EAAM,SAAS,GAAM,MAAU;EAC7B,IAAM,IAAc,CAAC,GAAG,GAAY,EAAM,EACpC,IAAS,EAAK;AAEpB,MAAK,EAAQ,IAAI,EAAO,EAWlB,EAAK,YAAY,MAAM,QAAQ,EAAK,SAAS,IAE/C,EAAuB,EAAK,UAAU,GAAS,EAAY;OAbrC;AACxB,KAAQ,IAAI,EAAO;GACnB,IAAM,IAAU,EAAE,GAAG,GAAM;AAM3B,GAJI,EAAQ,YAAY,MAAM,QAAQ,EAAQ,SAAS,KACrD,EAAQ,WAAW,EAAuB,EAAQ,UAAU,GAAS,EAAY,GAGnF,EAAO,KAAK,EAAQ;;GAQtB,EAEK;;;;AC/ET,IAAa,UAA2B,GAAyB,EAEpD,IAAsB;CACjC;EAAE,OAAO;EAAM,OAAO;EAAM;CAC5B;EAAE,OAAO;EAAM,OAAO;EAAM;CAC5B;EAAE,OAAO;EAAM,OAAO;EAAM;CAC5B;EAAE,OAAO;EAAM,OAAO;EAAM;CAC5B;EAAE,OAAO;EAAM,OAAO;EAAM;CAC7B,EAEY,KAAkB,GAAU,MAChC,GAAwB,CAAC,IAGrB,KAAmB,MACzB,IAGO,EAAW,QAAO,MAE1B,EAAK,iBAAiB,SACtB,EAAK,MAAM,SAAS,KACpB,CAAC,EAAK,MAAM,MAAK,MAAQ,EAAQ,EAAK,CAAC,CAEzC,GARO,EAAE,EAmBP,IAAiB,4BACjB,IAAsB,6BAEtB,KAAiB,GAAa,MAAgC;CAClE,IAAM,IAAQ,IAAS,EAAO,KAAO,KAAA;AACrC,KAAI,KAAiC,QAAQ,MAAU,GAIrD,OAAU,MAAM,YAAY,EAAI,uBAAuB;AAEzD,QAAO;GAUI,KAAqB,GAAY,MAAqC;AACjF,KAAI,MAAM,QAAQ,EAAM,CACtB,QAAO,EAAM,KAAI,MAAQ,EAAkB,GAAM,EAAO,CAAC;AAE3D,KAAI,OAAO,KAAU,YAAY,CAAC,EAAM,SAAS,KAAK,CACpD,QAAO;CAET,IAAM,IAAO,EAAM,MAAM,EAAoB;AAI7C,QAHI,IACK,EAAc,EAAK,IAAI,EAAO,GAEhC,EAAM,QAAQ,IAAiB,GAAQ,MAAQ,OAAO,EAAc,GAAK,EAAO,CAAC,CAAC;GAO9E,KAA2B,OAA6C,EACnF,WAAW,GACZ,GAEK,KAA2B,GAAe,MAAqB;AACnE,GAAS,SAAS,MAAc;AAE9B,EADA,EAAS,EAAK,QAAQ,EAAK,cACvB,EAAK,YACP,EAAwB,EAAK,UAAU,EAAS;GAElD;GAGS,IAAoB,OAAO,MAAsC;AAC5E,KAAI,CAAC,EACH,QAAO,EAAE;CAGX,IAAM,IAAM,MAAM,EAAW,EAAE,EADnB,EAAU,MAAM,IAAI,CAAC,KAAK,aAAa,EAAU,MAAM,IAAI,CAAC,KAAK,gBACvC,IAAO,EAAE,YAAY,IAAM,CAAC,EAC5D,IAAW,EAAE;AAMnB,QAJA,EADe,EAAuB,KAAO,EAAE,CAAC,EACd,EAAS,EACrC,QAAQ,MACZ,EAAS,KAAQ,OAEZ,OAAO,KAAK,EAAS,CAAC,KAAK,OAAe;EAC/C,OAAO;EACP,OAAO,EAAS;EACjB,EAAE;GAGQ,IAAc;CACzB;EACE,OAAO;EACP,OAAO;EACR;CACD;EACE,OAAO;EACP,OAAO;EACR;CACD;EACE,OAAO;EACP,OAAO;EACR;CACD;EACE,OAAO;EACP,OAAO;EACR;CACD;EACE,OAAO;EACP,OAAO;EACR;CACD;EACE,OAAO;EACP,OAAO;EACR;CACD;EACE,OAAO;EACP,OAAO;EACR;CACD;EACE,OAAO;EACP,OAAO;EACR;CACD;EACE,OAAO;EACP,OAAO;EACR;CACD;EACE,OAAO;EACP,OAAO;EACR;CACF,EACY,IAAgB;CAC3B;EACE,KAAK;EACL,OAAO;EACP,UAAU,CACR;GACE,KAAK;GACL,OAAO;GACR,CACF;EACF;CACD;EACE,KAAK;EACL,OAAO;EACP,UAAU;GACR;IACE,KAAK;IACL,OAAO;IACR;GACD;IACE,KAAK;IACL,OAAO;IACR;GACD;IACE,KAAK;IACL,OAAO;IACR;GACF;EACF;CACD;EACE,KAAK;EACL,OAAO;EACP,UAAU;GACR;IACE,KAAK;IACL,OAAO;IACR;GACD;IACE,KAAK;IACL,OAAO;IACR;GACD;IACE,KAAK;IACL,OAAO;IACR;GACD;IACE,KAAK;IACL,OAAO;IACR;GACF;EACF;CACD;EACE,KAAK;EACL,OAAO;EACP,UAAU;GACR;IACE,KAAK;IACL,OAAO;IACR;GACD;IACE,KAAK;IACL,OAAO;IACR;GACD;IACE,KAAK;IACL,OAAO;IACR;GACD;IACE,KAAK;IACL,OAAO;IACR;GACD;IACE,KAAK;IACL,OAAO;IACR;GACD;IACE,KAAK;IACL,OAAO;IACR;GACF;EACF;CACD;EACE,KAAK;EACL,OAAO;EACP,UAAU;GACR;IACE,KAAK;IACL,OAAO;IACR;GACD;IACE,KAAK;IACL,OAAO;IACR;GACD;IACE,KAAK;IACL,OAAO;IACR;GACD;IACE,KAAK;IACL,OAAO;IACR;GACD;IACE,KAAK;IACL,OAAO;IACR;GACF;EACF;CAED;EACE,KAAK;EACL,OAAO;EACP,UAAU;GACR;IACE,KAAK;IACL,OAAO;IACR;GACD;IACE,KAAK;IACL,OAAO;IACR;GACD;IACE,KAAK;IACL,OAAO;IACR;GACD;IACE,KAAK;IACL,OAAO;IACR;GACF;EACF;CACD;EACE,KAAK;EACL,OAAO;EACP,UAAU;GACR;IACE,KAAK;IACL,OAAO;IACR;GACD;IACE,KAAK;IACL,OAAO;IACR;GACD;IACE,KAAK;IACL,OAAO;IACR;GACD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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"v0001-OaBeBCXI.js","names":[],"sources":["../src/components/approval/migrate/v0001.ts"],"sourcesContent":["export default data => {\n return data;\n};\n"],"mappings":";AAAA,IAAA,KAAe,MACN"}