@longhongguo/form-create-ant-design-vue 3.2.76 → 3.2.78
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/form-create.css +5 -0
- package/dist/form-create.esm.css +5 -0
- package/dist/form-create.esm.js +2 -2
- package/dist/form-create.esm.js.map +1 -1
- package/dist/form-create.js +2 -2
- package/dist/form-create.js.map +1 -1
- package/package.json +1 -1
- package/src/parsers/div.js +60 -0
- package/src/parsers/flex.js +22 -0
- package/src/parsers/index.js +3 -1
- package/src/parsers/space.js +22 -0
- package/src/style/index.css +5 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"form-create.esm.js","sources":["../src/components/icon/QuestionCircleOutlined.vue","../src/components/icon/QuestionCircleOutlined.vue?vue&type=template&id=72badc20&lang.js","../src/components/CusSelect/index.vue","../src/components/CusSelect/index.vue?vue&type=template&id=228f8426&lang.js","../src/components/CusStoreSelect/index.vue","../src/components/CusStoreSelect/index.vue?vue&type=template&id=00ba930b&lang.js","../src/components/CusUserSelect/index.vue","../src/components/CusUserSelect/index.vue?vue&type=template&id=54621955&lang.js","../src/components/tableForm/TableForm.vue","../src/components/tableForm/TableForm.vue?vue&type=template&id=7d8ce230&lang.js","../src/components/tableForm/TableFormView.vue","../src/components/tableForm/TableFormView.vue?vue&type=template&id=13cd901b&lang.js","../src/components/tableForm/TableFormColumnView.vue","../src/components/tableForm/TableFormColumnView.vue?vue&type=template&id=4a2dbc30&lang.js","../src/components/index.js","../src/parsers/checkbox.js","../src/parsers/radio.js","../src/parsers/select.js","../src/parsers/cascader.js","../src/parsers/datePicker.js","../src/parsers/hidden.js","../src/parsers/text.js","../src/parsers/input.js","../src/parsers/timePicker.js","../src/parsers/tree.js","../src/parsers/row.js","../src/parsers/timeRangePicker.js","../src/parsers/index.js","../src/parsers/rangePicker.js","../src/parsers/cusStoreSelect.js","../src/parsers/cusUserSelect.js","../src/parsers/flex.js","../src/parsers/space.js","../src/parsers/spin.js","../src/core/alias.js","../src/core/manager.js","../src/core/config.js","../src/core/maker.js","../src/core/test.js","../src/core/api.js","../src/core/modelFields.js","../src/core/provider.js","../src/core/index.js","../src/index.js"],"sourcesContent":["<template>\n <span class=\"anticon\">\n <svg height=\"1em\" width=\"1em\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 1024 1024\">\n <path\n d=\"M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448s448-200.6 448-448S759.4 64 512 64zm0 820c-205.4 0-372-166.6-372-372s166.6-372 372-372s372 166.6 372 372s-166.6 372-372 372z\"\n fill=\"currentColor\"></path>\n <path\n d=\"M623.6 316.7C593.6 290.4 554 276 512 276s-81.6 14.5-111.6 40.7C369.2 344 352 380.7 352 420v7.6c0 4.4 3.6 8 8 8h48c4.4 0 8-3.6 8-8V420c0-44.1 43.1-80 96-80s96 35.9 96 80c0 31.1-22 59.6-56.1 72.7c-21.2 8.1-39.2 22.3-52.1 40.9c-13.1 19-19.9 41.8-19.9 64.9V620c0 4.4 3.6 8 8 8h48c4.4 0 8-3.6 8-8v-22.7a48.3 48.3 0 0 1 30.9-44.8c59-22.7 97.1-74.7 97.1-132.5c.1-39.3-17.1-76-48.3-103.3zM472 732a40 40 0 1 0 80 0a40 40 0 1 0-80 0z\"\n fill=\"currentColor\"></path>\n </svg>\n </span>\n</template>\n\n<script>\nexport default {\n name: 'QuestionCircleOutlined'\n}\n</script>\n","<template>\n <span class=\"anticon\">\n <svg height=\"1em\" width=\"1em\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 1024 1024\">\n <path\n d=\"M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448s448-200.6 448-448S759.4 64 512 64zm0 820c-205.4 0-372-166.6-372-372s166.6-372 372-372s372 166.6 372 372s-166.6 372-372 372z\"\n fill=\"currentColor\"></path>\n <path\n d=\"M623.6 316.7C593.6 290.4 554 276 512 276s-81.6 14.5-111.6 40.7C369.2 344 352 380.7 352 420v7.6c0 4.4 3.6 8 8 8h48c4.4 0 8-3.6 8-8V420c0-44.1 43.1-80 96-80s96 35.9 96 80c0 31.1-22 59.6-56.1 72.7c-21.2 8.1-39.2 22.3-52.1 40.9c-13.1 19-19.9 41.8-19.9 64.9V620c0 4.4 3.6 8 8 8h48c4.4 0 8-3.6 8-8v-22.7a48.3 48.3 0 0 1 30.9-44.8c59-22.7 97.1-74.7 97.1-132.5c.1-39.3-17.1-76-48.3-103.3zM472 732a40 40 0 1 0 80 0a40 40 0 1 0-80 0z\"\n fill=\"currentColor\"></path>\n </svg>\n </span>\n</template>\n\n<script>\nexport default {\n name: 'QuestionCircleOutlined'\n}\n</script>\n","<template>\r\n <!-- 单个展示模式 -->\r\n <div\r\n v-if=\"!multiple\"\r\n class=\"fc-cus-select fc-cus-select-single\"\r\n :class=\"{\r\n 'fc-cus-select-disabled': disabled\r\n }\"\r\n :style=\"style\"\r\n :tabindex=\"disabled ? -1 : 0\"\r\n >\r\n <div\r\n class=\"fc-cus-select-selector\"\r\n :class=\"{\r\n 'fc-cus-select-selector-borderless': !bordered\r\n }\"\r\n >\r\n <span\r\n v-if=\"displayValue\"\r\n class=\"fc-cus-select-selection-item\"\r\n :title=\"displayLabel\"\r\n >\r\n {{ displayLabel }}\r\n </span>\r\n <span v-else class=\"fc-cus-select-selection-placeholder\">\r\n {{ placeholder || '请选择' }}\r\n </span>\r\n <span v-if=\"showClear\" class=\"fc-cus-select-clear\" @click=\"clearValue\">\r\n <span\r\n role=\"img\"\r\n aria-label=\"close-circle\"\r\n class=\"anticon anticon-close-circle\"\r\n >\r\n <svg\r\n focusable=\"false\"\r\n data-icon=\"close-circle\"\r\n width=\"1em\"\r\n height=\"1em\"\r\n fill=\"currentColor\"\r\n aria-hidden=\"true\"\r\n fill-rule=\"evenodd\"\r\n viewBox=\"64 64 896 896\"\r\n >\r\n <path\r\n d=\"M512 64c247.4 0 448 200.6 448 448S759.4 960 512 960 64 759.4 64 512 264.6 64 512 64zm127.98 274.82h-.04l-.08.06L512 466.75 384.14 338.88c-.04-.05-.06-.06-.08-.06a.12.12 0 00-.07 0c-.03 0-.05.01-.09.05l-45.02 45.02a.2.2 0 00-.05.09.12.12 0 000 .07v.02a.27.27 0 00.06.06L466.75 512 338.88 639.86c-.05.04-.06.06-.06.08a.12.12 0 000 .07c0 .03.01.05.05.09l45.02 45.02a.2.2 0 00.09.05.12.12 0 00.07 0c.02 0 .04-.01.08-.05L512 557.25l127.86 127.87c.04.04.06.05.08.05a.12.12 0 00.07 0c.03 0 .05-.01.09-.05l45.02-45.02a.2.2 0 00.05-.09.12.12 0 000-.07v-.02a.27.27 0 00-.05-.06L557.25 512l127.87-127.86c.04-.04.05-.06.05-.08a.12.12 0 000-.07c0-.03-.01-.05-.05-.09l-45.02-45.02a.2.2 0 00-.09-.05.12.12 0 00-.07 0z\"\r\n ></path>\r\n </svg>\r\n </span>\r\n </span>\r\n <span v-else class=\"fc-cus-select-arrow\">\r\n <span role=\"img\" aria-label=\"down\" class=\"anticon anticon-down\">\r\n <svg\r\n focusable=\"false\"\r\n data-icon=\"down\"\r\n width=\"1em\"\r\n height=\"1em\"\r\n fill=\"currentColor\"\r\n aria-hidden=\"true\"\r\n viewBox=\"64 64 896 896\"\r\n >\r\n <path\r\n d=\"M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z\"\r\n ></path>\r\n </svg>\r\n </span>\r\n </span>\r\n </div>\r\n </div>\r\n\r\n <!-- 多个展示模式 -->\r\n <div\r\n v-else\r\n class=\"fc-cus-select fc-cus-select-multiple\"\r\n :class=\"{\r\n 'fc-cus-select-disabled': disabled\r\n }\"\r\n :style=\"style\"\r\n :tabindex=\"disabled ? -1 : 0\"\r\n >\r\n <div\r\n class=\"fc-cus-select-selector\"\r\n :class=\"{\r\n 'fc-cus-select-selector-borderless': !bordered\r\n }\"\r\n >\r\n <div class=\"fc-cus-select-selection-overflow\">\r\n <!-- 显示的 tags -->\r\n <div\r\n v-for=\"(item, index) in displayItems\"\r\n :key=\"index\"\r\n class=\"fc-cus-select-selection-overflow-item\"\r\n style=\"opacity: 1\"\r\n >\r\n <span class=\"fc-cus-select-selection-item\" :title=\"item.label\">\r\n <span class=\"fc-cus-select-selection-item-content\">{{\r\n item.label\r\n }}</span>\r\n <span\r\n class=\"fc-cus-select-selection-item-remove\"\r\n @click=\"removeItem(item.value, $event)\"\r\n >\r\n <span role=\"img\" aria-label=\"close\" class=\"anticon anticon-close\">\r\n <svg\r\n focusable=\"false\"\r\n data-icon=\"close\"\r\n width=\"1em\"\r\n height=\"1em\"\r\n fill=\"currentColor\"\r\n aria-hidden=\"true\"\r\n fill-rule=\"evenodd\"\r\n viewBox=\"64 64 896 896\"\r\n >\r\n <path\r\n d=\"M799.86 166.31c.02 0 .04.02.08.06l57.69 57.7c.04.03.05.05.06.08a.12.12 0 010 .06c0 .03-.02.05-.06.09L569.93 512l287.7 287.7c.04.04.05.06.06.09a.12.12 0 010 .07c0 .02-.02.04-.06.08l-57.7 57.69c-.03.04-.05.05-.07.06a.12.12 0 01-.07 0c-.03 0-.05-.02-.09-.06L512 569.93l-287.7 287.7c-.04.04-.06.05-.09.06a.12.12 0 01-.07 0c-.02 0-.04-.02-.08-.06l-57.69-57.7c-.04-.03-.05-.05-.06-.07a.12.12 0 010-.07c0-.03.02-.05.06-.09L454.07 512l-287.7-287.7c-.04-.04-.05-.06-.06-.09a.12.12 0 010-.07c0-.02.02-.04.06-.08l57.7-57.69c.03-.04.05-.05.07-.06a.12.12 0 01.07 0c.03 0 .05.02.09.06L512 454.07l287.7-287.7c.04-.04.06-.05.09-.06a.12.12 0 01.07 0z\"\r\n ></path>\r\n </svg>\r\n </span>\r\n </span>\r\n </span>\r\n </div>\r\n\r\n <!-- 折叠提示 -->\r\n <div\r\n v-if=\"remainingCount > 0\"\r\n class=\"fc-cus-select-selection-overflow-item\"\r\n style=\"opacity: 1\"\r\n >\r\n <span class=\"fc-cus-select-selection-item\">\r\n <span class=\"fc-cus-select-selection-item-content\">\r\n +{{ remainingCount }}\r\n </span>\r\n </span>\r\n </div>\r\n\r\n <!-- 空值占位符 -->\r\n <span v-if=\"!hasValue\" class=\"fc-cus-select-selection-placeholder\">\r\n {{ placeholder || '请选择' }}\r\n </span>\r\n </div>\r\n <span v-if=\"showClear\" class=\"fc-cus-select-clear\" @click=\"clearValue\">\r\n <span\r\n role=\"img\"\r\n aria-label=\"close-circle\"\r\n class=\"anticon anticon-close-circle\"\r\n >\r\n <svg\r\n focusable=\"false\"\r\n data-icon=\"close-circle\"\r\n width=\"1em\"\r\n height=\"1em\"\r\n fill=\"currentColor\"\r\n aria-hidden=\"true\"\r\n fill-rule=\"evenodd\"\r\n viewBox=\"64 64 896 896\"\r\n >\r\n <path\r\n d=\"M512 64c247.4 0 448 200.6 448 448S759.4 960 512 960 64 759.4 64 512 264.6 64 512 64zm127.98 274.82h-.04l-.08.06L512 466.75 384.14 338.88c-.04-.05-.06-.06-.08-.06a.12.12 0 00-.07 0c-.03 0-.05.01-.09.05l-45.02 45.02a.2.2 0 00-.05.09.12.12 0 000 .07v.02a.27.27 0 00.06.06L466.75 512 338.88 639.86c-.05.04-.06.06-.06.08a.12.12 0 000 .07c0 .03.01.05.05.09l45.02 45.02a.2.2 0 00.09.05.12.12 0 00.07 0c.02 0 .04-.01.08-.05L512 557.25l127.86 127.87c.04.04.06.05.08.05a.12.12 0 00.07 0c.03 0 .05-.01.09-.05l45.02-45.02a.2.2 0 00.05-.09.12.12 0 000-.07v-.02a.27.27 0 00-.05-.06L557.25 512l127.87-127.86c.04-.04.05-.06.05-.08a.12.12 0 000-.07c0-.03-.01-.05-.05-.09l-45.02-45.02a.2.2 0 00-.09-.05.12.12 0 00-.07 0z\"\r\n ></path>\r\n </svg>\r\n </span>\r\n </span>\r\n <span v-else class=\"fc-cus-select-arrow\">\r\n <span role=\"img\" aria-label=\"down\" class=\"anticon anticon-down\">\r\n <svg\r\n focusable=\"false\"\r\n data-icon=\"down\"\r\n width=\"1em\"\r\n height=\"1em\"\r\n fill=\"currentColor\"\r\n aria-hidden=\"true\"\r\n viewBox=\"64 64 896 896\"\r\n >\r\n <path\r\n d=\"M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z\"\r\n ></path>\r\n </svg>\r\n </span>\r\n </span>\r\n </div>\r\n </div>\r\n</template>\r\n\r\n<script>\r\nimport { defineComponent } from 'vue'\r\n\r\nexport default defineComponent({\r\n name: 'CusSelect',\r\n props: {\r\n // 当前值:统一使用对象数组格式(支持 v-model)\r\n // 单选时:[{value: '1001', label: '门店1'}] 或 []\r\n // 多选时:[{value: '1001', label: '门店1'}, {value: '1002', label: '门店2'}] 或 []\r\n modelValue: {\r\n type: Array,\r\n default: () => []\r\n },\r\n // 选项列表\r\n options: {\r\n type: Array,\r\n default: () => []\r\n },\r\n // 源选项列表\r\n sourceItems: {\r\n type: Array,\r\n default: () => []\r\n },\r\n // 是否多选\r\n multiple: {\r\n type: Boolean,\r\n default: false\r\n },\r\n // 最多显示的 tag 数量(多选模式下有效)\r\n maxTagCount: {\r\n type: Number,\r\n default: undefined // 不限制时显示所有\r\n },\r\n // 占位符\r\n placeholder: {\r\n type: String,\r\n default: ''\r\n },\r\n // 是否禁用样式\r\n disabled: {\r\n type: Boolean,\r\n default: false\r\n },\r\n // 自定义样式\r\n style: {\r\n type: [String, Object],\r\n default: () => ({ width: '100%' })\r\n },\r\n // 选项的 value 字段名\r\n valueKey: {\r\n type: String,\r\n default: 'value'\r\n },\r\n // 选项的 label 字段名\r\n labelKey: {\r\n type: String,\r\n default: 'label'\r\n },\r\n // 是否允许清除\r\n allowClear: {\r\n type: Boolean,\r\n default: false\r\n },\r\n // 是否有边框\r\n bordered: {\r\n type: Boolean,\r\n default: true\r\n }\r\n },\r\n emits: ['update:modelValue', 'update:sourceItems', 'change'],\r\n computed: {\r\n // 统一处理值(支持 v-model),确保始终是对象数组格式\r\n currentValue: {\r\n get() {\r\n // 确保返回对象数组格式\r\n if (!Array.isArray(this.modelValue)) {\r\n // 如果是 null、undefined 或空字符串,返回空数组\r\n if (\r\n this.modelValue === null ||\r\n this.modelValue === undefined ||\r\n this.modelValue === ''\r\n ) {\r\n return []\r\n }\r\n // 如果是单个对象,转换为数组\r\n if (typeof this.modelValue === 'object') {\r\n return [this.modelValue]\r\n }\r\n // 如果是单个值,转换为对象数组格式\r\n return [\r\n { value: this.modelValue, label: this.getLabel(this.modelValue) }\r\n ]\r\n }\r\n // 确保数组中的每个元素都是对象格式\r\n return this.modelValue.map((item) => {\r\n if (\r\n typeof item === 'object' &&\r\n item !== null &&\r\n (item.value !== undefined || item[this.valueKey] !== undefined)\r\n ) {\r\n // 已经是对象格式\r\n return item\r\n }\r\n // 如果是单个值,转换为对象格式\r\n return {\r\n [this.valueKey]: item,\r\n [this.labelKey]: this.getLabel(item)\r\n }\r\n })\r\n },\r\n set(val) {\r\n // 确保设置的值是对象数组格式\r\n let arrayValue = []\r\n if (val !== null && val !== undefined) {\r\n if (Array.isArray(val)) {\r\n // 确保数组中的每个元素都是对象格式\r\n arrayValue = val.map((item) => {\r\n if (\r\n typeof item === 'object' &&\r\n item !== null &&\r\n (item.value !== undefined || item[this.valueKey] !== undefined)\r\n ) {\r\n return item\r\n }\r\n // 单个值转换为对象格式\r\n return {\r\n [this.valueKey]: item,\r\n [this.labelKey]: this.getLabel(item)\r\n }\r\n })\r\n } else if (typeof val === 'object' && val !== null) {\r\n // 单个对象转换为数组\r\n arrayValue = [val]\r\n } else {\r\n // 单个值转换为对象数组格式\r\n arrayValue = [\r\n { [this.valueKey]: val, [this.labelKey]: this.getLabel(val) }\r\n ]\r\n }\r\n }\r\n // 触发 update:modelValue 事件以支持 v-model\r\n this.$emit('update:modelValue', arrayValue)\r\n this.$emit('change', arrayValue)\r\n }\r\n },\r\n // 是否有值(统一判断数组长度)\r\n hasValue() {\r\n const val = this.currentValue\r\n return Array.isArray(val) && val.length > 0\r\n },\r\n // 单个模式:显示的值对象(从数组中取第一个)\r\n displayValue() {\r\n if (!this.hasValue) return null\r\n return this.currentValue[0]\r\n },\r\n // 单个模式:显示的标签\r\n displayLabel() {\r\n if (!this.displayValue) return ''\r\n const item = this.displayValue\r\n // 如果是对象格式,直接取 label\r\n if (typeof item === 'object' && item !== null) {\r\n return (\r\n item[this.labelKey] ||\r\n item.label ||\r\n String(item[this.valueKey] || item.value || '')\r\n )\r\n }\r\n // 如果不是对象,使用 getLabel 方法查找\r\n return this.getLabel(item)\r\n },\r\n // 多个模式:所有选中的项(直接使用对象数组)\r\n allSelectedItems() {\r\n const val = this.currentValue\r\n if (!Array.isArray(val) || val.length === 0) {\r\n return []\r\n }\r\n // 直接返回对象数组,确保格式统一\r\n return val.map((item) => {\r\n if (typeof item === 'object' && item !== null) {\r\n return {\r\n value: item[this.valueKey] || item.value,\r\n label:\r\n item[this.labelKey] ||\r\n item.label ||\r\n String(item[this.valueKey] || item.value || '')\r\n }\r\n }\r\n // 如果不是对象,转换为对象格式\r\n return {\r\n value: item,\r\n label: this.getLabel(item)\r\n }\r\n })\r\n },\r\n // 多个模式:显示的项(根据 maxTagCount 限制)\r\n displayItems() {\r\n const items = this.allSelectedItems\r\n if (this.maxTagCount === undefined || this.maxTagCount === null) {\r\n return items\r\n }\r\n return items.slice(0, this.maxTagCount)\r\n },\r\n // 多个模式:剩余未显示的项数量\r\n remainingCount() {\r\n if (this.maxTagCount === undefined || this.maxTagCount === null) {\r\n return 0\r\n }\r\n const total = this.allSelectedItems.length\r\n return Math.max(0, total - this.maxTagCount)\r\n },\r\n // 是否显示清除图标\r\n showClear() {\r\n return this.allowClear && this.hasValue && !this.disabled\r\n }\r\n },\r\n methods: {\r\n // 根据 value 查找对应的 option\r\n findOptionByValue(val) {\r\n if (!this.options || this.options.length === 0) {\r\n return null\r\n }\r\n return this.options.find((opt) => {\r\n const optValue = typeof opt === 'object' ? opt[this.valueKey] : opt\r\n return optValue === val || String(optValue) === String(val)\r\n })\r\n },\r\n // 获取显示的 label\r\n getLabel(val) {\r\n const option = this.findOptionByValue(val)\r\n if (option) {\r\n return typeof option === 'object' ? option[this.labelKey] : option\r\n }\r\n // 如果找不到对应的 option,直接显示 value\r\n return String(val)\r\n },\r\n // 删除单个项\r\n removeItem(itemValue, event) {\r\n if (this.disabled) return\r\n event.stopPropagation()\r\n const val = this.currentValue\r\n if (Array.isArray(val)) {\r\n // 根据 value 来过滤,支持对象数组格式\r\n const newValue = val.filter((item) => {\r\n if (typeof item === 'object' && item !== null) {\r\n const currentItemValue = item[this.valueKey] || item.value\r\n return currentItemValue !== itemValue\r\n }\r\n return item !== itemValue\r\n })\r\n const sourceItems = this.sourceItems.filter((item) => {\r\n return !newValue.some((newItem) => {\r\n return newItem[this.valueKey] === item[this.valueKey]\r\n })\r\n })\r\n this.$emit('update:sourceItems', sourceItems)\r\n this.currentValue = newValue\r\n }\r\n },\r\n // 清除所有值\r\n clearValue(event) {\r\n if (this.disabled) return\r\n event.stopPropagation()\r\n // 统一设置为空数组\r\n this.currentValue = []\r\n const sourceItems = this.sourceItems.filter((item) => {\r\n return !this.currentValue.some((newItem) => {\r\n return newItem[this.valueKey] === item[this.valueKey]\r\n })\r\n })\r\n this.$emit('update:sourceItems', sourceItems)\r\n }\r\n }\r\n})\r\n</script>\r\n","<template>\r\n <!-- 单个展示模式 -->\r\n <div\r\n v-if=\"!multiple\"\r\n class=\"fc-cus-select fc-cus-select-single\"\r\n :class=\"{\r\n 'fc-cus-select-disabled': disabled\r\n }\"\r\n :style=\"style\"\r\n :tabindex=\"disabled ? -1 : 0\"\r\n >\r\n <div\r\n class=\"fc-cus-select-selector\"\r\n :class=\"{\r\n 'fc-cus-select-selector-borderless': !bordered\r\n }\"\r\n >\r\n <span\r\n v-if=\"displayValue\"\r\n class=\"fc-cus-select-selection-item\"\r\n :title=\"displayLabel\"\r\n >\r\n {{ displayLabel }}\r\n </span>\r\n <span v-else class=\"fc-cus-select-selection-placeholder\">\r\n {{ placeholder || '请选择' }}\r\n </span>\r\n <span v-if=\"showClear\" class=\"fc-cus-select-clear\" @click=\"clearValue\">\r\n <span\r\n role=\"img\"\r\n aria-label=\"close-circle\"\r\n class=\"anticon anticon-close-circle\"\r\n >\r\n <svg\r\n focusable=\"false\"\r\n data-icon=\"close-circle\"\r\n width=\"1em\"\r\n height=\"1em\"\r\n fill=\"currentColor\"\r\n aria-hidden=\"true\"\r\n fill-rule=\"evenodd\"\r\n viewBox=\"64 64 896 896\"\r\n >\r\n <path\r\n d=\"M512 64c247.4 0 448 200.6 448 448S759.4 960 512 960 64 759.4 64 512 264.6 64 512 64zm127.98 274.82h-.04l-.08.06L512 466.75 384.14 338.88c-.04-.05-.06-.06-.08-.06a.12.12 0 00-.07 0c-.03 0-.05.01-.09.05l-45.02 45.02a.2.2 0 00-.05.09.12.12 0 000 .07v.02a.27.27 0 00.06.06L466.75 512 338.88 639.86c-.05.04-.06.06-.06.08a.12.12 0 000 .07c0 .03.01.05.05.09l45.02 45.02a.2.2 0 00.09.05.12.12 0 00.07 0c.02 0 .04-.01.08-.05L512 557.25l127.86 127.87c.04.04.06.05.08.05a.12.12 0 00.07 0c.03 0 .05-.01.09-.05l45.02-45.02a.2.2 0 00.05-.09.12.12 0 000-.07v-.02a.27.27 0 00-.05-.06L557.25 512l127.87-127.86c.04-.04.05-.06.05-.08a.12.12 0 000-.07c0-.03-.01-.05-.05-.09l-45.02-45.02a.2.2 0 00-.09-.05.12.12 0 00-.07 0z\"\r\n ></path>\r\n </svg>\r\n </span>\r\n </span>\r\n <span v-else class=\"fc-cus-select-arrow\">\r\n <span role=\"img\" aria-label=\"down\" class=\"anticon anticon-down\">\r\n <svg\r\n focusable=\"false\"\r\n data-icon=\"down\"\r\n width=\"1em\"\r\n height=\"1em\"\r\n fill=\"currentColor\"\r\n aria-hidden=\"true\"\r\n viewBox=\"64 64 896 896\"\r\n >\r\n <path\r\n d=\"M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z\"\r\n ></path>\r\n </svg>\r\n </span>\r\n </span>\r\n </div>\r\n </div>\r\n\r\n <!-- 多个展示模式 -->\r\n <div\r\n v-else\r\n class=\"fc-cus-select fc-cus-select-multiple\"\r\n :class=\"{\r\n 'fc-cus-select-disabled': disabled\r\n }\"\r\n :style=\"style\"\r\n :tabindex=\"disabled ? -1 : 0\"\r\n >\r\n <div\r\n class=\"fc-cus-select-selector\"\r\n :class=\"{\r\n 'fc-cus-select-selector-borderless': !bordered\r\n }\"\r\n >\r\n <div class=\"fc-cus-select-selection-overflow\">\r\n <!-- 显示的 tags -->\r\n <div\r\n v-for=\"(item, index) in displayItems\"\r\n :key=\"index\"\r\n class=\"fc-cus-select-selection-overflow-item\"\r\n style=\"opacity: 1\"\r\n >\r\n <span class=\"fc-cus-select-selection-item\" :title=\"item.label\">\r\n <span class=\"fc-cus-select-selection-item-content\">{{\r\n item.label\r\n }}</span>\r\n <span\r\n class=\"fc-cus-select-selection-item-remove\"\r\n @click=\"removeItem(item.value, $event)\"\r\n >\r\n <span role=\"img\" aria-label=\"close\" class=\"anticon anticon-close\">\r\n <svg\r\n focusable=\"false\"\r\n data-icon=\"close\"\r\n width=\"1em\"\r\n height=\"1em\"\r\n fill=\"currentColor\"\r\n aria-hidden=\"true\"\r\n fill-rule=\"evenodd\"\r\n viewBox=\"64 64 896 896\"\r\n >\r\n <path\r\n d=\"M799.86 166.31c.02 0 .04.02.08.06l57.69 57.7c.04.03.05.05.06.08a.12.12 0 010 .06c0 .03-.02.05-.06.09L569.93 512l287.7 287.7c.04.04.05.06.06.09a.12.12 0 010 .07c0 .02-.02.04-.06.08l-57.7 57.69c-.03.04-.05.05-.07.06a.12.12 0 01-.07 0c-.03 0-.05-.02-.09-.06L512 569.93l-287.7 287.7c-.04.04-.06.05-.09.06a.12.12 0 01-.07 0c-.02 0-.04-.02-.08-.06l-57.69-57.7c-.04-.03-.05-.05-.06-.07a.12.12 0 010-.07c0-.03.02-.05.06-.09L454.07 512l-287.7-287.7c-.04-.04-.05-.06-.06-.09a.12.12 0 010-.07c0-.02.02-.04.06-.08l57.7-57.69c.03-.04.05-.05.07-.06a.12.12 0 01.07 0c.03 0 .05.02.09.06L512 454.07l287.7-287.7c.04-.04.06-.05.09-.06a.12.12 0 01.07 0z\"\r\n ></path>\r\n </svg>\r\n </span>\r\n </span>\r\n </span>\r\n </div>\r\n\r\n <!-- 折叠提示 -->\r\n <div\r\n v-if=\"remainingCount > 0\"\r\n class=\"fc-cus-select-selection-overflow-item\"\r\n style=\"opacity: 1\"\r\n >\r\n <span class=\"fc-cus-select-selection-item\">\r\n <span class=\"fc-cus-select-selection-item-content\">\r\n +{{ remainingCount }}\r\n </span>\r\n </span>\r\n </div>\r\n\r\n <!-- 空值占位符 -->\r\n <span v-if=\"!hasValue\" class=\"fc-cus-select-selection-placeholder\">\r\n {{ placeholder || '请选择' }}\r\n </span>\r\n </div>\r\n <span v-if=\"showClear\" class=\"fc-cus-select-clear\" @click=\"clearValue\">\r\n <span\r\n role=\"img\"\r\n aria-label=\"close-circle\"\r\n class=\"anticon anticon-close-circle\"\r\n >\r\n <svg\r\n focusable=\"false\"\r\n data-icon=\"close-circle\"\r\n width=\"1em\"\r\n height=\"1em\"\r\n fill=\"currentColor\"\r\n aria-hidden=\"true\"\r\n fill-rule=\"evenodd\"\r\n viewBox=\"64 64 896 896\"\r\n >\r\n <path\r\n d=\"M512 64c247.4 0 448 200.6 448 448S759.4 960 512 960 64 759.4 64 512 264.6 64 512 64zm127.98 274.82h-.04l-.08.06L512 466.75 384.14 338.88c-.04-.05-.06-.06-.08-.06a.12.12 0 00-.07 0c-.03 0-.05.01-.09.05l-45.02 45.02a.2.2 0 00-.05.09.12.12 0 000 .07v.02a.27.27 0 00.06.06L466.75 512 338.88 639.86c-.05.04-.06.06-.06.08a.12.12 0 000 .07c0 .03.01.05.05.09l45.02 45.02a.2.2 0 00.09.05.12.12 0 00.07 0c.02 0 .04-.01.08-.05L512 557.25l127.86 127.87c.04.04.06.05.08.05a.12.12 0 00.07 0c.03 0 .05-.01.09-.05l45.02-45.02a.2.2 0 00.05-.09.12.12 0 000-.07v-.02a.27.27 0 00-.05-.06L557.25 512l127.87-127.86c.04-.04.05-.06.05-.08a.12.12 0 000-.07c0-.03-.01-.05-.05-.09l-45.02-45.02a.2.2 0 00-.09-.05.12.12 0 00-.07 0z\"\r\n ></path>\r\n </svg>\r\n </span>\r\n </span>\r\n <span v-else class=\"fc-cus-select-arrow\">\r\n <span role=\"img\" aria-label=\"down\" class=\"anticon anticon-down\">\r\n <svg\r\n focusable=\"false\"\r\n data-icon=\"down\"\r\n width=\"1em\"\r\n height=\"1em\"\r\n fill=\"currentColor\"\r\n aria-hidden=\"true\"\r\n viewBox=\"64 64 896 896\"\r\n >\r\n <path\r\n d=\"M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z\"\r\n ></path>\r\n </svg>\r\n </span>\r\n </span>\r\n </div>\r\n </div>\r\n</template>\r\n\r\n<script>\r\nimport { defineComponent } from 'vue'\r\n\r\nexport default defineComponent({\r\n name: 'CusSelect',\r\n props: {\r\n // 当前值:统一使用对象数组格式(支持 v-model)\r\n // 单选时:[{value: '1001', label: '门店1'}] 或 []\r\n // 多选时:[{value: '1001', label: '门店1'}, {value: '1002', label: '门店2'}] 或 []\r\n modelValue: {\r\n type: Array,\r\n default: () => []\r\n },\r\n // 选项列表\r\n options: {\r\n type: Array,\r\n default: () => []\r\n },\r\n // 源选项列表\r\n sourceItems: {\r\n type: Array,\r\n default: () => []\r\n },\r\n // 是否多选\r\n multiple: {\r\n type: Boolean,\r\n default: false\r\n },\r\n // 最多显示的 tag 数量(多选模式下有效)\r\n maxTagCount: {\r\n type: Number,\r\n default: undefined // 不限制时显示所有\r\n },\r\n // 占位符\r\n placeholder: {\r\n type: String,\r\n default: ''\r\n },\r\n // 是否禁用样式\r\n disabled: {\r\n type: Boolean,\r\n default: false\r\n },\r\n // 自定义样式\r\n style: {\r\n type: [String, Object],\r\n default: () => ({ width: '100%' })\r\n },\r\n // 选项的 value 字段名\r\n valueKey: {\r\n type: String,\r\n default: 'value'\r\n },\r\n // 选项的 label 字段名\r\n labelKey: {\r\n type: String,\r\n default: 'label'\r\n },\r\n // 是否允许清除\r\n allowClear: {\r\n type: Boolean,\r\n default: false\r\n },\r\n // 是否有边框\r\n bordered: {\r\n type: Boolean,\r\n default: true\r\n }\r\n },\r\n emits: ['update:modelValue', 'update:sourceItems', 'change'],\r\n computed: {\r\n // 统一处理值(支持 v-model),确保始终是对象数组格式\r\n currentValue: {\r\n get() {\r\n // 确保返回对象数组格式\r\n if (!Array.isArray(this.modelValue)) {\r\n // 如果是 null、undefined 或空字符串,返回空数组\r\n if (\r\n this.modelValue === null ||\r\n this.modelValue === undefined ||\r\n this.modelValue === ''\r\n ) {\r\n return []\r\n }\r\n // 如果是单个对象,转换为数组\r\n if (typeof this.modelValue === 'object') {\r\n return [this.modelValue]\r\n }\r\n // 如果是单个值,转换为对象数组格式\r\n return [\r\n { value: this.modelValue, label: this.getLabel(this.modelValue) }\r\n ]\r\n }\r\n // 确保数组中的每个元素都是对象格式\r\n return this.modelValue.map((item) => {\r\n if (\r\n typeof item === 'object' &&\r\n item !== null &&\r\n (item.value !== undefined || item[this.valueKey] !== undefined)\r\n ) {\r\n // 已经是对象格式\r\n return item\r\n }\r\n // 如果是单个值,转换为对象格式\r\n return {\r\n [this.valueKey]: item,\r\n [this.labelKey]: this.getLabel(item)\r\n }\r\n })\r\n },\r\n set(val) {\r\n // 确保设置的值是对象数组格式\r\n let arrayValue = []\r\n if (val !== null && val !== undefined) {\r\n if (Array.isArray(val)) {\r\n // 确保数组中的每个元素都是对象格式\r\n arrayValue = val.map((item) => {\r\n if (\r\n typeof item === 'object' &&\r\n item !== null &&\r\n (item.value !== undefined || item[this.valueKey] !== undefined)\r\n ) {\r\n return item\r\n }\r\n // 单个值转换为对象格式\r\n return {\r\n [this.valueKey]: item,\r\n [this.labelKey]: this.getLabel(item)\r\n }\r\n })\r\n } else if (typeof val === 'object' && val !== null) {\r\n // 单个对象转换为数组\r\n arrayValue = [val]\r\n } else {\r\n // 单个值转换为对象数组格式\r\n arrayValue = [\r\n { [this.valueKey]: val, [this.labelKey]: this.getLabel(val) }\r\n ]\r\n }\r\n }\r\n // 触发 update:modelValue 事件以支持 v-model\r\n this.$emit('update:modelValue', arrayValue)\r\n this.$emit('change', arrayValue)\r\n }\r\n },\r\n // 是否有值(统一判断数组长度)\r\n hasValue() {\r\n const val = this.currentValue\r\n return Array.isArray(val) && val.length > 0\r\n },\r\n // 单个模式:显示的值对象(从数组中取第一个)\r\n displayValue() {\r\n if (!this.hasValue) return null\r\n return this.currentValue[0]\r\n },\r\n // 单个模式:显示的标签\r\n displayLabel() {\r\n if (!this.displayValue) return ''\r\n const item = this.displayValue\r\n // 如果是对象格式,直接取 label\r\n if (typeof item === 'object' && item !== null) {\r\n return (\r\n item[this.labelKey] ||\r\n item.label ||\r\n String(item[this.valueKey] || item.value || '')\r\n )\r\n }\r\n // 如果不是对象,使用 getLabel 方法查找\r\n return this.getLabel(item)\r\n },\r\n // 多个模式:所有选中的项(直接使用对象数组)\r\n allSelectedItems() {\r\n const val = this.currentValue\r\n if (!Array.isArray(val) || val.length === 0) {\r\n return []\r\n }\r\n // 直接返回对象数组,确保格式统一\r\n return val.map((item) => {\r\n if (typeof item === 'object' && item !== null) {\r\n return {\r\n value: item[this.valueKey] || item.value,\r\n label:\r\n item[this.labelKey] ||\r\n item.label ||\r\n String(item[this.valueKey] || item.value || '')\r\n }\r\n }\r\n // 如果不是对象,转换为对象格式\r\n return {\r\n value: item,\r\n label: this.getLabel(item)\r\n }\r\n })\r\n },\r\n // 多个模式:显示的项(根据 maxTagCount 限制)\r\n displayItems() {\r\n const items = this.allSelectedItems\r\n if (this.maxTagCount === undefined || this.maxTagCount === null) {\r\n return items\r\n }\r\n return items.slice(0, this.maxTagCount)\r\n },\r\n // 多个模式:剩余未显示的项数量\r\n remainingCount() {\r\n if (this.maxTagCount === undefined || this.maxTagCount === null) {\r\n return 0\r\n }\r\n const total = this.allSelectedItems.length\r\n return Math.max(0, total - this.maxTagCount)\r\n },\r\n // 是否显示清除图标\r\n showClear() {\r\n return this.allowClear && this.hasValue && !this.disabled\r\n }\r\n },\r\n methods: {\r\n // 根据 value 查找对应的 option\r\n findOptionByValue(val) {\r\n if (!this.options || this.options.length === 0) {\r\n return null\r\n }\r\n return this.options.find((opt) => {\r\n const optValue = typeof opt === 'object' ? opt[this.valueKey] : opt\r\n return optValue === val || String(optValue) === String(val)\r\n })\r\n },\r\n // 获取显示的 label\r\n getLabel(val) {\r\n const option = this.findOptionByValue(val)\r\n if (option) {\r\n return typeof option === 'object' ? option[this.labelKey] : option\r\n }\r\n // 如果找不到对应的 option,直接显示 value\r\n return String(val)\r\n },\r\n // 删除单个项\r\n removeItem(itemValue, event) {\r\n if (this.disabled) return\r\n event.stopPropagation()\r\n const val = this.currentValue\r\n if (Array.isArray(val)) {\r\n // 根据 value 来过滤,支持对象数组格式\r\n const newValue = val.filter((item) => {\r\n if (typeof item === 'object' && item !== null) {\r\n const currentItemValue = item[this.valueKey] || item.value\r\n return currentItemValue !== itemValue\r\n }\r\n return item !== itemValue\r\n })\r\n const sourceItems = this.sourceItems.filter((item) => {\r\n return !newValue.some((newItem) => {\r\n return newItem[this.valueKey] === item[this.valueKey]\r\n })\r\n })\r\n this.$emit('update:sourceItems', sourceItems)\r\n this.currentValue = newValue\r\n }\r\n },\r\n // 清除所有值\r\n clearValue(event) {\r\n if (this.disabled) return\r\n event.stopPropagation()\r\n // 统一设置为空数组\r\n this.currentValue = []\r\n const sourceItems = this.sourceItems.filter((item) => {\r\n return !this.currentValue.some((newItem) => {\r\n return newItem[this.valueKey] === item[this.valueKey]\r\n })\r\n })\r\n this.$emit('update:sourceItems', sourceItems)\r\n }\r\n }\r\n})\r\n</script>\r\n","<template>\n <div @click=\"handleClick\">\n <CusSelect\n :model-value=\"modelValue\"\n :options=\"mergedOptions\"\n v-model:source-items=\"sourceItems\"\n :multiple=\"multiple\"\n :max-tag-count=\"maxTagCount\"\n :placeholder=\"placeholder\"\n :disabled=\"disabled\"\n :style=\"style\"\n :valueKey=\"valueKey\"\n :labelKey=\"labelKey\"\n :allowClear=\"allowClear\"\n :bordered=\"bordered\"\n @update:model-value=\"handleUpdate\"\n @change=\"handleChange\"\n />\n </div>\n</template>\n\n<script>\nimport { defineComponent } from 'vue'\nimport CusSelect from '../CusSelect/index.vue'\n\nexport default defineComponent({\n name: 'CusStoreSelect',\n components: {\n CusSelect\n },\n props: {\n // form-create 注入的对象,包含 API 等\n formCreateInject: {\n type: Object,\n default: null\n },\n // 当前值:统一使用数组格式(支持 v-model)\n // 单选时:[value] 或 []\n // 多选时:[value1, value2, ...] 或 []\n modelValue: {\n type: Array,\n default: () => []\n },\n // 选项列表\n options: {\n type: Array,\n default: () => []\n },\n // 是否多选\n multiple: {\n type: Boolean,\n default: false\n },\n // 最多显示的 tag 数量(多选模式下有效)\n maxTagCount: {\n type: Number,\n default: undefined // 不限制时显示所有\n },\n // 占位符\n placeholder: {\n type: String,\n default: '请选择'\n },\n // 是否禁用样式\n disabled: {\n type: Boolean,\n default: false\n },\n // 自定义样式\n style: {\n type: [String, Object],\n default: () => ({ width: '100%' })\n },\n // 选项的 value 字段名\n valueKey: {\n type: String,\n default: 'value'\n },\n // 选项的 label 字段名\n labelKey: {\n type: String,\n default: 'label'\n },\n // 是否允许清除\n allowClear: {\n type: Boolean,\n default: false\n },\n // 字段名,用于跨窗口通信时标识字段\n field: {\n type: String,\n default: ''\n },\n // 是否有边框\n bordered: {\n type: Boolean,\n default: true\n },\n // 额外查询参数\n extraQuery: {\n type: Object,\n default: () => ({})\n },\n extraQueryFn: {\n type: Function,\n default: () => {}\n }\n },\n emits: ['update:modelValue', 'change'],\n data() {\n return {\n // 消息ID计数器,用于标识每次请求\n messageId: 0,\n // 存储待处理的回调函数\n pendingCallbacks: {},\n // 内部维护的选项列表(合并父窗口返回的源对象)\n internalOptions: [],\n sourceItems: []\n }\n },\n computed: {\n // 合并内部选项和外部传入的选项\n mergedOptions() {\n // 如果内部有选项,优先使用内部选项\n if (this.internalOptions.length > 0) {\n // 合并去重:根据 valueKey 去重,保留内部选项(后添加的优先)\n const optionMap = new Map()\n // 先添加外部选项\n this.options.forEach((opt) => {\n const value = typeof opt === 'object' ? opt[this.valueKey] : opt\n optionMap.set(value, opt)\n })\n // 再添加内部选项(会覆盖相同 value 的选项)\n this.internalOptions.forEach((opt) => {\n const value = typeof opt === 'object' ? opt[this.valueKey] : opt\n optionMap.set(value, opt)\n })\n return Array.from(optionMap.values())\n }\n return this.options\n }\n },\n watch: {\n // 监听外部 options 变化,初始化内部选项列表\n options: {\n immediate: true,\n handler(newOptions) {\n // 如果内部选项为空,且外部有选项,初始化内部选项\n if (\n this.internalOptions.length === 0 &&\n Array.isArray(newOptions) &&\n newOptions.length > 0\n ) {\n this.internalOptions = [...newOptions]\n }\n }\n }\n },\n mounted() {\n // 监听父窗口返回的消息\n window.addEventListener('message', this.handleMessage)\n },\n beforeUnmount() {\n // 组件销毁时移除事件监听\n window.removeEventListener('message', this.handleMessage)\n },\n methods: {\n // 序列化数据,确保可以被 postMessage 发送\n // postMessage 使用结构化克隆算法,无法克隆 Vue 响应式代理对象\n serializeForPostMessage(data) {\n // 处理 null 和 undefined\n if (data === null || data === undefined) {\n return data\n }\n\n try {\n // 使用 JSON 序列化和反序列化来创建可克隆的副本\n // 这会移除 Vue 响应式代理、函数、Symbol 等不可序列化的内容\n return JSON.parse(JSON.stringify(data))\n } catch (error) {\n console.warn('CusStoreSelect: 数据序列化失败,尝试递归处理', error)\n\n // 如果 JSON 序列化失败(可能是循环引用),尝试递归处理\n if (Array.isArray(data)) {\n // 空数组直接返回\n if (data.length === 0) {\n return []\n }\n // 递归处理数组中的每个元素\n return data.map((item) => this.serializeForPostMessage(item))\n }\n\n if (typeof data === 'object') {\n const result = {}\n for (const key in data) {\n if (Object.prototype.hasOwnProperty.call(data, key)) {\n try {\n result[key] = this.serializeForPostMessage(data[key])\n } catch (e) {\n // 忽略无法序列化的属性,避免整个序列化失败\n console.warn(`CusStoreSelect: 跳过无法序列化的属性: ${key}`, e)\n }\n }\n }\n return result\n }\n\n // 基本类型(string, number, boolean)直接返回\n return data\n }\n },\n handleClick() {\n // 如果禁用,不处理\n if (this.disabled) {\n return\n }\n\n // 生成唯一消息ID\n const msgId = `store-select-${\n this.field || 'default'\n }-${Date.now()}-${++this.messageId}`\n\n // 序列化所有需要传递的数据,确保可以被 postMessage 发送\n // postMessage 无法发送 Vue 响应式代理对象,必须序列化\n // 获取当前值,确保是对象数组格式\n const currentArrayValue = Array.isArray(this.modelValue)\n ? this.modelValue\n : []\n // 从对象数组中提取 value 值,用于发送给父窗口\n // 单选时发送第一个对象的 value,多选时发送所有对象的 value 数组\n let valueToSend = null\n if (currentArrayValue.length > 0) {\n valueToSend = currentArrayValue\n }\n const serializedCurrentValue =\n valueToSend === null || valueToSend === undefined\n ? null\n : this.serializeForPostMessage(valueToSend)\n\n // 发送消息给父窗口,请求打开门店选择弹窗\n const extraQuery = {\n ...this.extraQuery\n }\n if (this.extraQueryFn) {\n Object.assign(extraQuery, this.extraQueryFn())\n }\n const message = {\n type: 'OPEN_STORE_SELECT',\n field: this.field || '',\n multiple: this.multiple,\n currentValue: serializedCurrentValue,\n valueKey: this.valueKey,\n labelKey: this.labelKey,\n extraQuery,\n messageId: msgId\n }\n\n // 发送到父窗口(支持 iframe 场景)\n if (window.parent && window.parent !== window) {\n try {\n window.parent.postMessage(message, '*')\n } catch (error) {\n console.error('CusStoreSelect: 发送消息失败', error)\n }\n } else {\n // 如果不在 iframe 中,也可以发送到当前窗口(用于测试)\n console.warn(\n 'CusStoreSelect: 当前不在 iframe 环境中,无法向父窗口发送消息'\n )\n }\n\n // 存储回调,等待父窗口返回结果\n this.pendingCallbacks[msgId] = (value, sourceItems) => {\n // 优先使用 sourceItems(源对象数组),如果没有则根据 value 和 options 构建\n if (\n sourceItems &&\n Array.isArray(sourceItems) &&\n sourceItems.length > 0\n ) {\n // 合并到内部选项列表\n this.mergeOptions(sourceItems)\n }\n\n this.sourceItems = sourceItems\n this.handleUpdate(value)\n this.handleChange(value)\n }\n },\n handleMessage(event) {\n // 验证消息来源(可选,根据实际需求调整)\n // if (event.origin !== 'expected-origin') return\n\n const data = event.data\n\n // 检查是否是门店选择返回的消息\n if (data && data.type === 'STORE_SELECT_RESULT') {\n const { field, value, sourceItems, messageId } = data\n\n // 验证字段名是否匹配\n if (field !== this.field) {\n return\n }\n\n // 查找对应的回调函数\n const callback = this.pendingCallbacks[messageId]\n if (callback) {\n // 执行回调,更新值并传递源对象\n // sourceItems: 源对象数组,包含完整的选项信息\n // 单选时:[{ value: '1001', label: '门店1', ... }]\n // 多选时:[{ value: '1001', label: '门店1', ... }, { value: '1002', label: '门店2', ... }]\n callback(value, sourceItems)\n // 清理已处理的回调\n delete this.pendingCallbacks[messageId]\n }\n }\n },\n // 合并选项到内部选项列表\n mergeOptions(newItems) {\n if (!Array.isArray(newItems) || newItems.length === 0) {\n return\n }\n\n // 创建选项映射,用于去重\n const optionMap = new Map()\n\n // 先将现有内部选项添加到映射\n this.internalOptions.forEach((opt) => {\n const value = typeof opt === 'object' ? opt[this.valueKey] : opt\n optionMap.set(value, opt)\n })\n\n // 再添加新选项(会覆盖相同 value 的选项)\n newItems.forEach((opt) => {\n const value = typeof opt === 'object' ? opt[this.valueKey] : opt\n optionMap.set(value, opt)\n })\n\n // 更新内部选项列表\n this.internalOptions = Array.from(optionMap.values())\n },\n handleUpdate(value) {\n this.$emit('update:modelValue', value)\n // 值更新后触发校验\n this.triggerValidate()\n },\n handleChange(value) {\n this.$emit(\n 'change',\n value,\n this.sourceItems && this.sourceItems.length > 0\n ? this.multiple\n ? this.sourceItems\n : this.sourceItems[0]\n : this.multiple\n ? []\n : null\n )\n },\n // 触发字段校验\n triggerValidate() {\n // 使用 nextTick 确保值已经更新完成\n this.$nextTick(() => {\n this.$nextTick(() => {\n try {\n // 方式1:通过 formCreateInject 中的 API 触发校验\n if (\n this.formCreateInject &&\n this.formCreateInject.api &&\n this.field\n ) {\n this.formCreateInject.api.validateField(this.field).catch(() => {\n // 校验失败时静默处理,错误会通过 form-item 显示\n })\n return\n }\n\n // 方式2:通过组件实例查找父组件中的 form-create API\n let parent = this.$parent\n while (parent) {\n if (\n parent.$options &&\n parent.$options.name === 'FormCreate' &&\n parent.fapi\n ) {\n if (this.field && parent.fapi.validateField) {\n parent.fapi.validateField(this.field).catch(() => {\n // 校验失败时静默处理\n })\n }\n break\n }\n parent = parent.$parent\n }\n } catch (error) {\n console.warn('CusStoreSelect: 触发校验失败', error)\n }\n })\n })\n }\n }\n})\n</script>\n","<template>\n <div @click=\"handleClick\">\n <CusSelect\n :model-value=\"modelValue\"\n :options=\"mergedOptions\"\n v-model:source-items=\"sourceItems\"\n :multiple=\"multiple\"\n :max-tag-count=\"maxTagCount\"\n :placeholder=\"placeholder\"\n :disabled=\"disabled\"\n :style=\"style\"\n :valueKey=\"valueKey\"\n :labelKey=\"labelKey\"\n :allowClear=\"allowClear\"\n :bordered=\"bordered\"\n @update:model-value=\"handleUpdate\"\n @change=\"handleChange\"\n />\n </div>\n</template>\n\n<script>\nimport { defineComponent } from 'vue'\nimport CusSelect from '../CusSelect/index.vue'\n\nexport default defineComponent({\n name: 'CusStoreSelect',\n components: {\n CusSelect\n },\n props: {\n // form-create 注入的对象,包含 API 等\n formCreateInject: {\n type: Object,\n default: null\n },\n // 当前值:统一使用数组格式(支持 v-model)\n // 单选时:[value] 或 []\n // 多选时:[value1, value2, ...] 或 []\n modelValue: {\n type: Array,\n default: () => []\n },\n // 选项列表\n options: {\n type: Array,\n default: () => []\n },\n // 是否多选\n multiple: {\n type: Boolean,\n default: false\n },\n // 最多显示的 tag 数量(多选模式下有效)\n maxTagCount: {\n type: Number,\n default: undefined // 不限制时显示所有\n },\n // 占位符\n placeholder: {\n type: String,\n default: '请选择'\n },\n // 是否禁用样式\n disabled: {\n type: Boolean,\n default: false\n },\n // 自定义样式\n style: {\n type: [String, Object],\n default: () => ({ width: '100%' })\n },\n // 选项的 value 字段名\n valueKey: {\n type: String,\n default: 'value'\n },\n // 选项的 label 字段名\n labelKey: {\n type: String,\n default: 'label'\n },\n // 是否允许清除\n allowClear: {\n type: Boolean,\n default: false\n },\n // 字段名,用于跨窗口通信时标识字段\n field: {\n type: String,\n default: ''\n },\n // 是否有边框\n bordered: {\n type: Boolean,\n default: true\n },\n // 额外查询参数\n extraQuery: {\n type: Object,\n default: () => ({})\n },\n extraQueryFn: {\n type: Function,\n default: () => {}\n }\n },\n emits: ['update:modelValue', 'change'],\n data() {\n return {\n // 消息ID计数器,用于标识每次请求\n messageId: 0,\n // 存储待处理的回调函数\n pendingCallbacks: {},\n // 内部维护的选项列表(合并父窗口返回的源对象)\n internalOptions: [],\n sourceItems: []\n }\n },\n computed: {\n // 合并内部选项和外部传入的选项\n mergedOptions() {\n // 如果内部有选项,优先使用内部选项\n if (this.internalOptions.length > 0) {\n // 合并去重:根据 valueKey 去重,保留内部选项(后添加的优先)\n const optionMap = new Map()\n // 先添加外部选项\n this.options.forEach((opt) => {\n const value = typeof opt === 'object' ? opt[this.valueKey] : opt\n optionMap.set(value, opt)\n })\n // 再添加内部选项(会覆盖相同 value 的选项)\n this.internalOptions.forEach((opt) => {\n const value = typeof opt === 'object' ? opt[this.valueKey] : opt\n optionMap.set(value, opt)\n })\n return Array.from(optionMap.values())\n }\n return this.options\n }\n },\n watch: {\n // 监听外部 options 变化,初始化内部选项列表\n options: {\n immediate: true,\n handler(newOptions) {\n // 如果内部选项为空,且外部有选项,初始化内部选项\n if (\n this.internalOptions.length === 0 &&\n Array.isArray(newOptions) &&\n newOptions.length > 0\n ) {\n this.internalOptions = [...newOptions]\n }\n }\n }\n },\n mounted() {\n // 监听父窗口返回的消息\n window.addEventListener('message', this.handleMessage)\n },\n beforeUnmount() {\n // 组件销毁时移除事件监听\n window.removeEventListener('message', this.handleMessage)\n },\n methods: {\n // 序列化数据,确保可以被 postMessage 发送\n // postMessage 使用结构化克隆算法,无法克隆 Vue 响应式代理对象\n serializeForPostMessage(data) {\n // 处理 null 和 undefined\n if (data === null || data === undefined) {\n return data\n }\n\n try {\n // 使用 JSON 序列化和反序列化来创建可克隆的副本\n // 这会移除 Vue 响应式代理、函数、Symbol 等不可序列化的内容\n return JSON.parse(JSON.stringify(data))\n } catch (error) {\n console.warn('CusStoreSelect: 数据序列化失败,尝试递归处理', error)\n\n // 如果 JSON 序列化失败(可能是循环引用),尝试递归处理\n if (Array.isArray(data)) {\n // 空数组直接返回\n if (data.length === 0) {\n return []\n }\n // 递归处理数组中的每个元素\n return data.map((item) => this.serializeForPostMessage(item))\n }\n\n if (typeof data === 'object') {\n const result = {}\n for (const key in data) {\n if (Object.prototype.hasOwnProperty.call(data, key)) {\n try {\n result[key] = this.serializeForPostMessage(data[key])\n } catch (e) {\n // 忽略无法序列化的属性,避免整个序列化失败\n console.warn(`CusStoreSelect: 跳过无法序列化的属性: ${key}`, e)\n }\n }\n }\n return result\n }\n\n // 基本类型(string, number, boolean)直接返回\n return data\n }\n },\n handleClick() {\n // 如果禁用,不处理\n if (this.disabled) {\n return\n }\n\n // 生成唯一消息ID\n const msgId = `store-select-${\n this.field || 'default'\n }-${Date.now()}-${++this.messageId}`\n\n // 序列化所有需要传递的数据,确保可以被 postMessage 发送\n // postMessage 无法发送 Vue 响应式代理对象,必须序列化\n // 获取当前值,确保是对象数组格式\n const currentArrayValue = Array.isArray(this.modelValue)\n ? this.modelValue\n : []\n // 从对象数组中提取 value 值,用于发送给父窗口\n // 单选时发送第一个对象的 value,多选时发送所有对象的 value 数组\n let valueToSend = null\n if (currentArrayValue.length > 0) {\n valueToSend = currentArrayValue\n }\n const serializedCurrentValue =\n valueToSend === null || valueToSend === undefined\n ? null\n : this.serializeForPostMessage(valueToSend)\n\n // 发送消息给父窗口,请求打开门店选择弹窗\n const extraQuery = {\n ...this.extraQuery\n }\n if (this.extraQueryFn) {\n Object.assign(extraQuery, this.extraQueryFn())\n }\n const message = {\n type: 'OPEN_STORE_SELECT',\n field: this.field || '',\n multiple: this.multiple,\n currentValue: serializedCurrentValue,\n valueKey: this.valueKey,\n labelKey: this.labelKey,\n extraQuery,\n messageId: msgId\n }\n\n // 发送到父窗口(支持 iframe 场景)\n if (window.parent && window.parent !== window) {\n try {\n window.parent.postMessage(message, '*')\n } catch (error) {\n console.error('CusStoreSelect: 发送消息失败', error)\n }\n } else {\n // 如果不在 iframe 中,也可以发送到当前窗口(用于测试)\n console.warn(\n 'CusStoreSelect: 当前不在 iframe 环境中,无法向父窗口发送消息'\n )\n }\n\n // 存储回调,等待父窗口返回结果\n this.pendingCallbacks[msgId] = (value, sourceItems) => {\n // 优先使用 sourceItems(源对象数组),如果没有则根据 value 和 options 构建\n if (\n sourceItems &&\n Array.isArray(sourceItems) &&\n sourceItems.length > 0\n ) {\n // 合并到内部选项列表\n this.mergeOptions(sourceItems)\n }\n\n this.sourceItems = sourceItems\n this.handleUpdate(value)\n this.handleChange(value)\n }\n },\n handleMessage(event) {\n // 验证消息来源(可选,根据实际需求调整)\n // if (event.origin !== 'expected-origin') return\n\n const data = event.data\n\n // 检查是否是门店选择返回的消息\n if (data && data.type === 'STORE_SELECT_RESULT') {\n const { field, value, sourceItems, messageId } = data\n\n // 验证字段名是否匹配\n if (field !== this.field) {\n return\n }\n\n // 查找对应的回调函数\n const callback = this.pendingCallbacks[messageId]\n if (callback) {\n // 执行回调,更新值并传递源对象\n // sourceItems: 源对象数组,包含完整的选项信息\n // 单选时:[{ value: '1001', label: '门店1', ... }]\n // 多选时:[{ value: '1001', label: '门店1', ... }, { value: '1002', label: '门店2', ... }]\n callback(value, sourceItems)\n // 清理已处理的回调\n delete this.pendingCallbacks[messageId]\n }\n }\n },\n // 合并选项到内部选项列表\n mergeOptions(newItems) {\n if (!Array.isArray(newItems) || newItems.length === 0) {\n return\n }\n\n // 创建选项映射,用于去重\n const optionMap = new Map()\n\n // 先将现有内部选项添加到映射\n this.internalOptions.forEach((opt) => {\n const value = typeof opt === 'object' ? opt[this.valueKey] : opt\n optionMap.set(value, opt)\n })\n\n // 再添加新选项(会覆盖相同 value 的选项)\n newItems.forEach((opt) => {\n const value = typeof opt === 'object' ? opt[this.valueKey] : opt\n optionMap.set(value, opt)\n })\n\n // 更新内部选项列表\n this.internalOptions = Array.from(optionMap.values())\n },\n handleUpdate(value) {\n this.$emit('update:modelValue', value)\n // 值更新后触发校验\n this.triggerValidate()\n },\n handleChange(value) {\n this.$emit(\n 'change',\n value,\n this.sourceItems && this.sourceItems.length > 0\n ? this.multiple\n ? this.sourceItems\n : this.sourceItems[0]\n : this.multiple\n ? []\n : null\n )\n },\n // 触发字段校验\n triggerValidate() {\n // 使用 nextTick 确保值已经更新完成\n this.$nextTick(() => {\n this.$nextTick(() => {\n try {\n // 方式1:通过 formCreateInject 中的 API 触发校验\n if (\n this.formCreateInject &&\n this.formCreateInject.api &&\n this.field\n ) {\n this.formCreateInject.api.validateField(this.field).catch(() => {\n // 校验失败时静默处理,错误会通过 form-item 显示\n })\n return\n }\n\n // 方式2:通过组件实例查找父组件中的 form-create API\n let parent = this.$parent\n while (parent) {\n if (\n parent.$options &&\n parent.$options.name === 'FormCreate' &&\n parent.fapi\n ) {\n if (this.field && parent.fapi.validateField) {\n parent.fapi.validateField(this.field).catch(() => {\n // 校验失败时静默处理\n })\n }\n break\n }\n parent = parent.$parent\n }\n } catch (error) {\n console.warn('CusStoreSelect: 触发校验失败', error)\n }\n })\n })\n }\n }\n})\n</script>\n","<template>\r\n <div @click=\"handleClick\">\r\n <CusSelect\r\n :model-value=\"modelValue\"\r\n :options=\"mergedOptions\"\r\n v-model:source-items=\"sourceItems\"\r\n :multiple=\"multiple\"\r\n :max-tag-count=\"maxTagCount\"\r\n :placeholder=\"placeholder\"\r\n :disabled=\"disabled\"\r\n :style=\"style\"\r\n :valueKey=\"valueKey\"\r\n :labelKey=\"labelKey\"\r\n :allowClear=\"allowClear\"\r\n :bordered=\"bordered\"\r\n @update:model-value=\"handleUpdate\"\r\n @change=\"handleChange\"\r\n />\r\n </div>\r\n</template>\r\n\r\n<script>\r\nimport { defineComponent } from 'vue'\r\nimport CusSelect from '../CusSelect/index.vue'\r\n\r\nexport default defineComponent({\r\n name: 'CusUserSelect',\r\n components: {\r\n CusSelect\r\n },\r\n props: {\r\n // form-create 注入的对象,包含 API 等\r\n formCreateInject: {\r\n type: Object,\r\n default: null\r\n },\r\n // 当前值:统一使用数组格式(支持 v-model)\r\n // 单选时:[value] 或 []\r\n // 多选时:[value1, value2, ...] 或 []\r\n modelValue: {\r\n type: Array,\r\n default: () => []\r\n },\r\n // 选项列表\r\n options: {\r\n type: Array,\r\n default: () => []\r\n },\r\n // 是否多选\r\n multiple: {\r\n type: Boolean,\r\n default: false\r\n },\r\n // 最多显示的 tag 数量(多选模式下有效)\r\n maxTagCount: {\r\n type: Number,\r\n default: undefined // 不限制时显示所有\r\n },\r\n // 占位符\r\n placeholder: {\r\n type: String,\r\n default: '请选择'\r\n },\r\n // 是否禁用样式\r\n disabled: {\r\n type: Boolean,\r\n default: false\r\n },\r\n // 自定义样式\r\n style: {\r\n type: [String, Object],\r\n default: () => ({ width: '100%' })\r\n },\r\n // 选项的 value 字段名\r\n valueKey: {\r\n type: String,\r\n default: 'value'\r\n },\r\n // 选项的 label 字段名\r\n labelKey: {\r\n type: String,\r\n default: 'label'\r\n },\r\n // 是否允许清除\r\n allowClear: {\r\n type: Boolean,\r\n default: false\r\n },\r\n // 字段名,用于跨窗口通信时标识字段\r\n field: {\r\n type: String,\r\n default: ''\r\n },\r\n // 是否有边框\r\n bordered: {\r\n type: Boolean,\r\n default: true\r\n },\r\n selectType: {\r\n type: [String, Number],\r\n default: null\r\n },\r\n extraQuery: {\r\n type: Object,\r\n default: () => ({})\r\n },\r\n extraQueryFn: {\r\n type: Function,\r\n default: () => {}\r\n }\r\n },\r\n emits: ['update:modelValue', 'change'],\r\n data() {\r\n return {\r\n // 消息ID计数器,用于标识每次请求\r\n messageId: 0,\r\n // 存储待处理的回调函数\r\n pendingCallbacks: {},\r\n // 内部维护的选项列表(合并父窗口返回的源对象)\r\n internalOptions: [],\r\n sourceItems: []\r\n }\r\n },\r\n computed: {\r\n // 合并内部选项和外部传入的选项\r\n mergedOptions() {\r\n // 如果内部有选项,优先使用内部选项\r\n if (this.internalOptions.length > 0) {\r\n // 合并去重:根据 valueKey 去重,保留内部选项(后添加的优先)\r\n const optionMap = new Map()\r\n // 先添加外部选项\r\n this.options.forEach((opt) => {\r\n const value = typeof opt === 'object' ? opt[this.valueKey] : opt\r\n optionMap.set(value, opt)\r\n })\r\n // 再添加内部选项(会覆盖相同 value 的选项)\r\n this.internalOptions.forEach((opt) => {\r\n const value = typeof opt === 'object' ? opt[this.valueKey] : opt\r\n optionMap.set(value, opt)\r\n })\r\n return Array.from(optionMap.values())\r\n }\r\n return this.options\r\n }\r\n },\r\n watch: {\r\n // 监听外部 options 变化,初始化内部选项列表\r\n options: {\r\n immediate: true,\r\n handler(newOptions) {\r\n // 如果内部选项为空,且外部有选项,初始化内部选项\r\n if (\r\n this.internalOptions.length === 0 &&\r\n Array.isArray(newOptions) &&\r\n newOptions.length > 0\r\n ) {\r\n this.internalOptions = [...newOptions]\r\n }\r\n }\r\n }\r\n },\r\n mounted() {\r\n // 监听父窗口返回的消息\r\n window.addEventListener('message', this.handleMessage)\r\n },\r\n beforeUnmount() {\r\n // 组件销毁时移除事件监听\r\n window.removeEventListener('message', this.handleMessage)\r\n },\r\n methods: {\r\n // 序列化数据,确保可以被 postMessage 发送\r\n // postMessage 使用结构化克隆算法,无法克隆 Vue 响应式代理对象\r\n serializeForPostMessage(data) {\r\n // 处理 null 和 undefined\r\n if (data === null || data === undefined) {\r\n return data\r\n }\r\n\r\n try {\r\n // 使用 JSON 序列化和反序列化来创建可克隆的副本\r\n // 这会移除 Vue 响应式代理、函数、Symbol 等不可序列化的内容\r\n return JSON.parse(JSON.stringify(data))\r\n } catch (error) {\r\n console.warn('CusUserSelect: 数据序列化失败,尝试递归处理', error)\r\n\r\n // 如果 JSON 序列化失败(可能是循环引用),尝试递归处理\r\n if (Array.isArray(data)) {\r\n // 空数组直接返回\r\n if (data.length === 0) {\r\n return []\r\n }\r\n // 递归处理数组中的每个元素\r\n return data.map((item) => this.serializeForPostMessage(item))\r\n }\r\n\r\n if (typeof data === 'object') {\r\n const result = {}\r\n for (const key in data) {\r\n if (Object.prototype.hasOwnProperty.call(data, key)) {\r\n try {\r\n result[key] = this.serializeForPostMessage(data[key])\r\n } catch (e) {\r\n // 忽略无法序列化的属性,避免整个序列化失败\r\n console.warn(`CusUserSelect: 跳过无法序列化的属性: ${key}`, e)\r\n }\r\n }\r\n }\r\n return result\r\n }\r\n\r\n // 基本类型(string, number, boolean)直接返回\r\n return data\r\n }\r\n },\r\n handleClick() {\r\n // 如果禁用,不处理\r\n if (this.disabled) {\r\n return\r\n }\r\n\r\n // 生成唯一消息ID\r\n const msgId = `user-select-${\r\n this.field || 'default'\r\n }-${Date.now()}-${++this.messageId}`\r\n\r\n // 序列化所有需要传递的数据,确保可以被 postMessage 发送\r\n // postMessage 无法发送 Vue 响应式代理对象,必须序列化\r\n // 获取当前值,确保是对象数组格式\r\n const currentArrayValue = Array.isArray(this.modelValue)\r\n ? this.modelValue\r\n : []\r\n // 从对象数组中提取 value 值,用于发送给父窗口\r\n // 单选时发送第一个对象的 value,多选时发送所有对象的 value 数组\r\n let valueToSend = null\r\n if (currentArrayValue.length > 0) {\r\n valueToSend = currentArrayValue\r\n }\r\n const serializedCurrentValue =\r\n valueToSend === null || valueToSend === undefined\r\n ? null\r\n : this.serializeForPostMessage(valueToSend)\r\n\r\n // 发送消息给父窗口,请求打开用户选择弹窗\r\n const extraQuery = {\r\n ...this.extraQuery\r\n }\r\n if (this.extraQueryFn) {\r\n Object.assign(extraQuery, this.extraQueryFn())\r\n }\r\n\r\n const message = {\r\n type: 'OPEN_USER_SELECT',\r\n field: this.field || '',\r\n multiple: this.multiple,\r\n currentValue: serializedCurrentValue,\r\n valueKey: this.valueKey,\r\n labelKey: this.labelKey,\r\n selectType: this.selectType,\r\n extraQuery,\r\n messageId: msgId\r\n }\r\n\r\n // 发送到父窗口(支持 iframe 场景)\r\n if (window.parent && window.parent !== window) {\r\n try {\r\n window.parent.postMessage(message, '*')\r\n } catch (error) {\r\n console.error('CusUserSelect: 发送消息失败', error)\r\n }\r\n } else {\r\n // 如果不在 iframe 中,也可以发送到当前窗口(用于测试)\r\n console.warn(\r\n 'CusUserSelect: 当前不在 iframe 环境中,无法向父窗口发送消息'\r\n )\r\n }\r\n\r\n // 存储回调,等待父窗口返回结果\r\n this.pendingCallbacks[msgId] = (value, sourceItems) => {\r\n // 优先使用 sourceItems(源对象数组),如果没有则根据 value 和 options 构建\r\n if (\r\n sourceItems &&\r\n Array.isArray(sourceItems) &&\r\n sourceItems.length > 0\r\n ) {\r\n // 合并到内部选项列表\r\n this.mergeOptions(sourceItems)\r\n }\r\n\r\n this.sourceItems = sourceItems\r\n\r\n this.handleUpdate(value)\r\n this.handleChange(value)\r\n }\r\n },\r\n handleMessage(event) {\r\n // 验证消息来源(可选,根据实际需求调整)\r\n // if (event.origin !== 'expected-origin') return\r\n\r\n const data = event.data\r\n\r\n // 检查是否是用户选择返回的消息\r\n if (data && data.type === 'USER_SELECT_RESULT') {\r\n const { field, value, sourceItems, messageId } = data\r\n\r\n // 验证字段名是否匹配\r\n if (field !== this.field) {\r\n return\r\n }\r\n\r\n // 查找对应的回调函数\r\n const callback = this.pendingCallbacks[messageId]\r\n if (callback) {\r\n // 执行回调,更新值并传递源对象\r\n // sourceItems: 源对象数组,包含完整的选项信息\r\n // 单选时:[{ value: '1001', label: '用户1', ... }]\r\n // 多选时:[{ value: '1001', label: '用户1', ... }, { value: '1002', label: '用户2', ... }]\r\n callback(value, sourceItems)\r\n // 清理已处理的回调\r\n delete this.pendingCallbacks[messageId]\r\n }\r\n }\r\n },\r\n // 合并选项到内部选项列表\r\n mergeOptions(newItems) {\r\n if (!Array.isArray(newItems) || newItems.length === 0) {\r\n return\r\n }\r\n\r\n // 创建选项映射,用于去重\r\n const optionMap = new Map()\r\n\r\n // 先将现有内部选项添加到映射\r\n this.internalOptions.forEach((opt) => {\r\n const value = typeof opt === 'object' ? opt[this.valueKey] : opt\r\n optionMap.set(value, opt)\r\n })\r\n\r\n // 再添加新选项(会覆盖相同 value 的选项)\r\n newItems.forEach((opt) => {\r\n const value = typeof opt === 'object' ? opt[this.valueKey] : opt\r\n optionMap.set(value, opt)\r\n })\r\n\r\n // 更新内部选项列表\r\n this.internalOptions = Array.from(optionMap.values())\r\n },\r\n handleUpdate(value) {\r\n this.$emit('update:modelValue', value)\r\n // 值更新后触发校验\r\n this.triggerValidate()\r\n },\r\n handleChange(value) {\r\n this.$emit(\r\n 'change',\r\n value,\r\n this.sourceItems && this.sourceItems.length > 0\r\n ? this.multiple\r\n ? this.sourceItems\r\n : this.sourceItems[0]\r\n : this.multiple\r\n ? []\r\n : null\r\n )\r\n },\r\n // 触发字段校验\r\n triggerValidate() {\r\n // 使用 nextTick 确保值已经更新完成\r\n this.$nextTick(() => {\r\n this.$nextTick(() => {\r\n try {\r\n // 方式1:通过 formCreateInject 中的 API 触发校验\r\n if (\r\n this.formCreateInject &&\r\n this.formCreateInject.api &&\r\n this.field\r\n ) {\r\n this.formCreateInject.api.validateField(this.field).catch(() => {\r\n // 校验失败时静默处理,错误会通过 form-item 显示\r\n })\r\n return\r\n }\r\n\r\n // 方式2:通过组件实例查找父组件中的 form-create API\r\n let parent = this.$parent\r\n while (parent) {\r\n if (\r\n parent.$options &&\r\n parent.$options.name === 'FormCreate' &&\r\n parent.fapi\r\n ) {\r\n if (this.field && parent.fapi.validateField) {\r\n parent.fapi.validateField(this.field).catch(() => {\r\n // 校验失败时静默处理\r\n })\r\n }\r\n break\r\n }\r\n parent = parent.$parent\r\n }\r\n } catch (error) {\r\n console.warn('CusUserSelect: 触发校验失败', error)\r\n }\r\n })\r\n })\r\n }\r\n }\r\n})\r\n</script>\r\n","<template>\r\n <div @click=\"handleClick\">\r\n <CusSelect\r\n :model-value=\"modelValue\"\r\n :options=\"mergedOptions\"\r\n v-model:source-items=\"sourceItems\"\r\n :multiple=\"multiple\"\r\n :max-tag-count=\"maxTagCount\"\r\n :placeholder=\"placeholder\"\r\n :disabled=\"disabled\"\r\n :style=\"style\"\r\n :valueKey=\"valueKey\"\r\n :labelKey=\"labelKey\"\r\n :allowClear=\"allowClear\"\r\n :bordered=\"bordered\"\r\n @update:model-value=\"handleUpdate\"\r\n @change=\"handleChange\"\r\n />\r\n </div>\r\n</template>\r\n\r\n<script>\r\nimport { defineComponent } from 'vue'\r\nimport CusSelect from '../CusSelect/index.vue'\r\n\r\nexport default defineComponent({\r\n name: 'CusUserSelect',\r\n components: {\r\n CusSelect\r\n },\r\n props: {\r\n // form-create 注入的对象,包含 API 等\r\n formCreateInject: {\r\n type: Object,\r\n default: null\r\n },\r\n // 当前值:统一使用数组格式(支持 v-model)\r\n // 单选时:[value] 或 []\r\n // 多选时:[value1, value2, ...] 或 []\r\n modelValue: {\r\n type: Array,\r\n default: () => []\r\n },\r\n // 选项列表\r\n options: {\r\n type: Array,\r\n default: () => []\r\n },\r\n // 是否多选\r\n multiple: {\r\n type: Boolean,\r\n default: false\r\n },\r\n // 最多显示的 tag 数量(多选模式下有效)\r\n maxTagCount: {\r\n type: Number,\r\n default: undefined // 不限制时显示所有\r\n },\r\n // 占位符\r\n placeholder: {\r\n type: String,\r\n default: '请选择'\r\n },\r\n // 是否禁用样式\r\n disabled: {\r\n type: Boolean,\r\n default: false\r\n },\r\n // 自定义样式\r\n style: {\r\n type: [String, Object],\r\n default: () => ({ width: '100%' })\r\n },\r\n // 选项的 value 字段名\r\n valueKey: {\r\n type: String,\r\n default: 'value'\r\n },\r\n // 选项的 label 字段名\r\n labelKey: {\r\n type: String,\r\n default: 'label'\r\n },\r\n // 是否允许清除\r\n allowClear: {\r\n type: Boolean,\r\n default: false\r\n },\r\n // 字段名,用于跨窗口通信时标识字段\r\n field: {\r\n type: String,\r\n default: ''\r\n },\r\n // 是否有边框\r\n bordered: {\r\n type: Boolean,\r\n default: true\r\n },\r\n selectType: {\r\n type: [String, Number],\r\n default: null\r\n },\r\n extraQuery: {\r\n type: Object,\r\n default: () => ({})\r\n },\r\n extraQueryFn: {\r\n type: Function,\r\n default: () => {}\r\n }\r\n },\r\n emits: ['update:modelValue', 'change'],\r\n data() {\r\n return {\r\n // 消息ID计数器,用于标识每次请求\r\n messageId: 0,\r\n // 存储待处理的回调函数\r\n pendingCallbacks: {},\r\n // 内部维护的选项列表(合并父窗口返回的源对象)\r\n internalOptions: [],\r\n sourceItems: []\r\n }\r\n },\r\n computed: {\r\n // 合并内部选项和外部传入的选项\r\n mergedOptions() {\r\n // 如果内部有选项,优先使用内部选项\r\n if (this.internalOptions.length > 0) {\r\n // 合并去重:根据 valueKey 去重,保留内部选项(后添加的优先)\r\n const optionMap = new Map()\r\n // 先添加外部选项\r\n this.options.forEach((opt) => {\r\n const value = typeof opt === 'object' ? opt[this.valueKey] : opt\r\n optionMap.set(value, opt)\r\n })\r\n // 再添加内部选项(会覆盖相同 value 的选项)\r\n this.internalOptions.forEach((opt) => {\r\n const value = typeof opt === 'object' ? opt[this.valueKey] : opt\r\n optionMap.set(value, opt)\r\n })\r\n return Array.from(optionMap.values())\r\n }\r\n return this.options\r\n }\r\n },\r\n watch: {\r\n // 监听外部 options 变化,初始化内部选项列表\r\n options: {\r\n immediate: true,\r\n handler(newOptions) {\r\n // 如果内部选项为空,且外部有选项,初始化内部选项\r\n if (\r\n this.internalOptions.length === 0 &&\r\n Array.isArray(newOptions) &&\r\n newOptions.length > 0\r\n ) {\r\n this.internalOptions = [...newOptions]\r\n }\r\n }\r\n }\r\n },\r\n mounted() {\r\n // 监听父窗口返回的消息\r\n window.addEventListener('message', this.handleMessage)\r\n },\r\n beforeUnmount() {\r\n // 组件销毁时移除事件监听\r\n window.removeEventListener('message', this.handleMessage)\r\n },\r\n methods: {\r\n // 序列化数据,确保可以被 postMessage 发送\r\n // postMessage 使用结构化克隆算法,无法克隆 Vue 响应式代理对象\r\n serializeForPostMessage(data) {\r\n // 处理 null 和 undefined\r\n if (data === null || data === undefined) {\r\n return data\r\n }\r\n\r\n try {\r\n // 使用 JSON 序列化和反序列化来创建可克隆的副本\r\n // 这会移除 Vue 响应式代理、函数、Symbol 等不可序列化的内容\r\n return JSON.parse(JSON.stringify(data))\r\n } catch (error) {\r\n console.warn('CusUserSelect: 数据序列化失败,尝试递归处理', error)\r\n\r\n // 如果 JSON 序列化失败(可能是循环引用),尝试递归处理\r\n if (Array.isArray(data)) {\r\n // 空数组直接返回\r\n if (data.length === 0) {\r\n return []\r\n }\r\n // 递归处理数组中的每个元素\r\n return data.map((item) => this.serializeForPostMessage(item))\r\n }\r\n\r\n if (typeof data === 'object') {\r\n const result = {}\r\n for (const key in data) {\r\n if (Object.prototype.hasOwnProperty.call(data, key)) {\r\n try {\r\n result[key] = this.serializeForPostMessage(data[key])\r\n } catch (e) {\r\n // 忽略无法序列化的属性,避免整个序列化失败\r\n console.warn(`CusUserSelect: 跳过无法序列化的属性: ${key}`, e)\r\n }\r\n }\r\n }\r\n return result\r\n }\r\n\r\n // 基本类型(string, number, boolean)直接返回\r\n return data\r\n }\r\n },\r\n handleClick() {\r\n // 如果禁用,不处理\r\n if (this.disabled) {\r\n return\r\n }\r\n\r\n // 生成唯一消息ID\r\n const msgId = `user-select-${\r\n this.field || 'default'\r\n }-${Date.now()}-${++this.messageId}`\r\n\r\n // 序列化所有需要传递的数据,确保可以被 postMessage 发送\r\n // postMessage 无法发送 Vue 响应式代理对象,必须序列化\r\n // 获取当前值,确保是对象数组格式\r\n const currentArrayValue = Array.isArray(this.modelValue)\r\n ? this.modelValue\r\n : []\r\n // 从对象数组中提取 value 值,用于发送给父窗口\r\n // 单选时发送第一个对象的 value,多选时发送所有对象的 value 数组\r\n let valueToSend = null\r\n if (currentArrayValue.length > 0) {\r\n valueToSend = currentArrayValue\r\n }\r\n const serializedCurrentValue =\r\n valueToSend === null || valueToSend === undefined\r\n ? null\r\n : this.serializeForPostMessage(valueToSend)\r\n\r\n // 发送消息给父窗口,请求打开用户选择弹窗\r\n const extraQuery = {\r\n ...this.extraQuery\r\n }\r\n if (this.extraQueryFn) {\r\n Object.assign(extraQuery, this.extraQueryFn())\r\n }\r\n\r\n const message = {\r\n type: 'OPEN_USER_SELECT',\r\n field: this.field || '',\r\n multiple: this.multiple,\r\n currentValue: serializedCurrentValue,\r\n valueKey: this.valueKey,\r\n labelKey: this.labelKey,\r\n selectType: this.selectType,\r\n extraQuery,\r\n messageId: msgId\r\n }\r\n\r\n // 发送到父窗口(支持 iframe 场景)\r\n if (window.parent && window.parent !== window) {\r\n try {\r\n window.parent.postMessage(message, '*')\r\n } catch (error) {\r\n console.error('CusUserSelect: 发送消息失败', error)\r\n }\r\n } else {\r\n // 如果不在 iframe 中,也可以发送到当前窗口(用于测试)\r\n console.warn(\r\n 'CusUserSelect: 当前不在 iframe 环境中,无法向父窗口发送消息'\r\n )\r\n }\r\n\r\n // 存储回调,等待父窗口返回结果\r\n this.pendingCallbacks[msgId] = (value, sourceItems) => {\r\n // 优先使用 sourceItems(源对象数组),如果没有则根据 value 和 options 构建\r\n if (\r\n sourceItems &&\r\n Array.isArray(sourceItems) &&\r\n sourceItems.length > 0\r\n ) {\r\n // 合并到内部选项列表\r\n this.mergeOptions(sourceItems)\r\n }\r\n\r\n this.sourceItems = sourceItems\r\n\r\n this.handleUpdate(value)\r\n this.handleChange(value)\r\n }\r\n },\r\n handleMessage(event) {\r\n // 验证消息来源(可选,根据实际需求调整)\r\n // if (event.origin !== 'expected-origin') return\r\n\r\n const data = event.data\r\n\r\n // 检查是否是用户选择返回的消息\r\n if (data && data.type === 'USER_SELECT_RESULT') {\r\n const { field, value, sourceItems, messageId } = data\r\n\r\n // 验证字段名是否匹配\r\n if (field !== this.field) {\r\n return\r\n }\r\n\r\n // 查找对应的回调函数\r\n const callback = this.pendingCallbacks[messageId]\r\n if (callback) {\r\n // 执行回调,更新值并传递源对象\r\n // sourceItems: 源对象数组,包含完整的选项信息\r\n // 单选时:[{ value: '1001', label: '用户1', ... }]\r\n // 多选时:[{ value: '1001', label: '用户1', ... }, { value: '1002', label: '用户2', ... }]\r\n callback(value, sourceItems)\r\n // 清理已处理的回调\r\n delete this.pendingCallbacks[messageId]\r\n }\r\n }\r\n },\r\n // 合并选项到内部选项列表\r\n mergeOptions(newItems) {\r\n if (!Array.isArray(newItems) || newItems.length === 0) {\r\n return\r\n }\r\n\r\n // 创建选项映射,用于去重\r\n const optionMap = new Map()\r\n\r\n // 先将现有内部选项添加到映射\r\n this.internalOptions.forEach((opt) => {\r\n const value = typeof opt === 'object' ? opt[this.valueKey] : opt\r\n optionMap.set(value, opt)\r\n })\r\n\r\n // 再添加新选项(会覆盖相同 value 的选项)\r\n newItems.forEach((opt) => {\r\n const value = typeof opt === 'object' ? opt[this.valueKey] : opt\r\n optionMap.set(value, opt)\r\n })\r\n\r\n // 更新内部选项列表\r\n this.internalOptions = Array.from(optionMap.values())\r\n },\r\n handleUpdate(value) {\r\n this.$emit('update:modelValue', value)\r\n // 值更新后触发校验\r\n this.triggerValidate()\r\n },\r\n handleChange(value) {\r\n this.$emit(\r\n 'change',\r\n value,\r\n this.sourceItems && this.sourceItems.length > 0\r\n ? this.multiple\r\n ? this.sourceItems\r\n : this.sourceItems[0]\r\n : this.multiple\r\n ? []\r\n : null\r\n )\r\n },\r\n // 触发字段校验\r\n triggerValidate() {\r\n // 使用 nextTick 确保值已经更新完成\r\n this.$nextTick(() => {\r\n this.$nextTick(() => {\r\n try {\r\n // 方式1:通过 formCreateInject 中的 API 触发校验\r\n if (\r\n this.formCreateInject &&\r\n this.formCreateInject.api &&\r\n this.field\r\n ) {\r\n this.formCreateInject.api.validateField(this.field).catch(() => {\r\n // 校验失败时静默处理,错误会通过 form-item 显示\r\n })\r\n return\r\n }\r\n\r\n // 方式2:通过组件实例查找父组件中的 form-create API\r\n let parent = this.$parent\r\n while (parent) {\r\n if (\r\n parent.$options &&\r\n parent.$options.name === 'FormCreate' &&\r\n parent.fapi\r\n ) {\r\n if (this.field && parent.fapi.validateField) {\r\n parent.fapi.validateField(this.field).catch(() => {\r\n // 校验失败时静默处理\r\n })\r\n }\r\n break\r\n }\r\n parent = parent.$parent\r\n }\r\n } catch (error) {\r\n console.warn('CusUserSelect: 触发校验失败', error)\r\n }\r\n })\r\n })\r\n }\r\n }\r\n})\r\n</script>\r\n","<template>\n <div class=\"_fc-table-form\" :class=\"{ '_fc-disabled': disabled }\">\n <component\n :is=\"Form\"\n :option=\"options\"\n :rule=\"rule\"\n :extendOption=\"true\"\n :disabled=\"disabled\"\n @change=\"formChange\"\n v-model:api=\"fapi\"\n @emit-event=\"$emit\"\n ></component>\n <a-button\n type=\"link\"\n class=\"fc-clock\"\n v-if=\"addable && (!max || max > this.trs.length)\"\n @click=\"addRaw(true)\"\n :disabled=\"disabled\"\n ><i class=\"fc-icon icon-add-circle\" style=\"font-weight: 700\"></i>\n {{ formCreateInject.t('add') || '添加' }}\n </a-button>\n </div>\n</template>\n\n<script>\nimport { markRaw, reactive } from 'vue'\n\nexport default {\n name: 'TableForm',\n emits: ['change', 'add', 'delete', 'update:modelValue'],\n props: {\n formCreateInject: Object,\n modelValue: {\n type: Array,\n default: () => []\n },\n columns: {\n type: Array,\n required: true,\n default: () => []\n },\n filterEmptyColumn: {\n type: Boolean,\n default: true\n },\n deletable: {\n type: Boolean,\n default: true\n },\n addable: {\n type: Boolean,\n default: true\n },\n options: {\n type: Object,\n default: () =>\n reactive({\n submitBtn: false,\n resetBtn: false\n })\n },\n min: Number,\n max: Number,\n disabled: Boolean\n },\n watch: {\n modelValue: {\n handler() {\n this.updateTable()\n },\n deep: true\n },\n 'formCreateInject.preview': function (n) {\n this.emptyRule.children[0].props.colspan =\n this.columns.length + (n ? 1 : 2)\n }\n },\n data() {\n return {\n rule: [],\n trs: [],\n fapi: {},\n Form: markRaw(this.formCreateInject.form.$form()),\n copyTrs: '',\n oldValue: '',\n emptyRule: {\n type: 'tr',\n _isEmpty: true,\n native: true,\n subRule: true,\n children: [\n {\n type: 'td',\n style: {\n textAlign: 'center'\n },\n native: true,\n subRule: true,\n props: {\n colspan:\n this.columns.length + (this.formCreateInject.preview ? 1 : 2)\n },\n children: [this.formCreateInject.t('dataEmpty') || '暂无数据']\n }\n ]\n }\n }\n },\n methods: {\n formChange() {\n this.updateValue()\n },\n updateValue() {\n const value = this.trs\n .map((tr, idx) => {\n return {\n ...(this.modelValue[idx] || {}),\n ...this.fapi.getChildrenFormData(tr)\n }\n })\n .filter((v) => {\n if (!this.filterEmptyColumn) {\n return true\n }\n if (v === undefined || v === null) {\n return false\n }\n let flag = false\n Object.keys(v).forEach((k) => {\n flag = flag || (v[k] !== undefined && v[k] !== '' && v[k] !== null)\n })\n return flag\n })\n const str = JSON.stringify(value)\n if (str !== this.oldValue) {\n this.oldValue = str\n this.$emit('update:modelValue', value)\n this.$emit('change', value)\n }\n },\n setRawData(idx, formData) {\n const raw = this.trs[idx]\n this.fapi.setChildrenFormData(raw, formData, true)\n },\n updateTable() {\n const str = JSON.stringify(this.modelValue)\n if (this.oldValue === str) {\n return\n }\n this.oldValue = str\n this.trs = this.trs.splice(0, this.modelValue.length)\n if (!this.modelValue.length) {\n this.addEmpty()\n } else {\n this.clearEmpty()\n }\n this.modelValue.forEach((data, idx) => {\n if (!this.trs[idx]) {\n this.addRaw()\n }\n this.setRawData(idx, data || {})\n })\n this.rule[0].children[1].children = this.trs\n },\n addEmpty() {\n if (this.trs.length) {\n this.trs.splice(0, this.trs.length)\n }\n this.trs.push(this.emptyRule)\n },\n clearEmpty() {\n if (this.trs[0] && this.trs[0]._isEmpty) {\n this.trs.splice(0, 1)\n }\n },\n delRaw(idx) {\n if (\n this.disabled ||\n !this.deletable ||\n (this.min > 0 && this.trs.length <= this.min)\n ) {\n return\n }\n this.trs.splice(idx, 1)\n this.updateValue()\n if (this.trs.length) {\n this.trs.forEach((tr) => this.updateRaw(tr))\n } else {\n this.addEmpty()\n }\n this.$emit('delete', idx)\n },\n addRaw(flag) {\n if (flag && this.disabled) {\n return\n }\n const tr = this.formCreateInject.form.parseJson(this.copyTrs)[0]\n if (this.trs.length === 1 && this.trs[0]._isEmpty) {\n this.trs.splice(0, 1)\n }\n this.trs.push(tr)\n this.updateRaw(tr)\n if (flag) {\n this.$emit('add', this.trs.length)\n this.updateValue()\n }\n },\n updateRaw(tr) {\n const idx = this.trs.indexOf(tr)\n tr.children[0].props.innerText = idx + 1\n tr.children[tr.children.length - 1].children[0].props.onClick = () => {\n this.delRaw(idx)\n }\n },\n loadRule() {\n const header = [\n {\n type: 'th',\n native: true,\n class: '_fc-tf-head-idx',\n props: {\n innerText: '#'\n }\n }\n ]\n let body = [\n {\n type: 'td',\n class: '_fc-tf-idx',\n native: true,\n props: {\n innerText: '0'\n }\n }\n ]\n this.columns.forEach((column) => {\n header.push({\n type: 'th',\n native: true,\n style: {\n ...(column.style || {}),\n textAlign: column.align || 'center'\n },\n class: column.required ? '_fc-tf-head-required' : '',\n props: {\n innerText: column.label || ''\n }\n })\n body.push({\n type: 'td',\n native: true,\n children: [...(column.rule || [])]\n })\n })\n header.push({\n type: 'th',\n native: true,\n class: '_fc-tf-edit fc-clock',\n props: {\n innerText: this.formCreateInject.t('operation') || '操作'\n }\n })\n body.push({\n type: 'td',\n native: true,\n class: '_fc-tf-btn fc-clock',\n children: [\n {\n type: 'i',\n native: true,\n class: 'fc-icon icon-delete',\n props: {}\n }\n ]\n })\n this.copyTrs = this.formCreateInject.form.toJson([\n {\n type: 'tr',\n native: true,\n subRule: true,\n children: body\n }\n ])\n this.rule = [\n {\n type: 'table',\n native: true,\n class: '_fc-tf-table',\n props: {\n border: '1',\n cellspacing: '0',\n cellpadding: '0'\n },\n children: [\n {\n type: 'thead',\n native: true,\n children: [\n {\n type: 'tr',\n native: true,\n children: header\n }\n ]\n },\n {\n type: 'tbody',\n native: true,\n children: this.trs\n }\n ]\n }\n ]\n }\n },\n created() {\n this.loadRule()\n },\n mounted() {\n this.updateTable()\n }\n}\n</script>\n","<template>\n <div class=\"_fc-table-form\" :class=\"{ '_fc-disabled': disabled }\">\n <component\n :is=\"Form\"\n :option=\"options\"\n :rule=\"rule\"\n :extendOption=\"true\"\n :disabled=\"disabled\"\n @change=\"formChange\"\n v-model:api=\"fapi\"\n @emit-event=\"$emit\"\n ></component>\n <a-button\n type=\"link\"\n class=\"fc-clock\"\n v-if=\"addable && (!max || max > this.trs.length)\"\n @click=\"addRaw(true)\"\n :disabled=\"disabled\"\n ><i class=\"fc-icon icon-add-circle\" style=\"font-weight: 700\"></i>\n {{ formCreateInject.t('add') || '添加' }}\n </a-button>\n </div>\n</template>\n\n<script>\nimport { markRaw, reactive } from 'vue'\n\nexport default {\n name: 'TableForm',\n emits: ['change', 'add', 'delete', 'update:modelValue'],\n props: {\n formCreateInject: Object,\n modelValue: {\n type: Array,\n default: () => []\n },\n columns: {\n type: Array,\n required: true,\n default: () => []\n },\n filterEmptyColumn: {\n type: Boolean,\n default: true\n },\n deletable: {\n type: Boolean,\n default: true\n },\n addable: {\n type: Boolean,\n default: true\n },\n options: {\n type: Object,\n default: () =>\n reactive({\n submitBtn: false,\n resetBtn: false\n })\n },\n min: Number,\n max: Number,\n disabled: Boolean\n },\n watch: {\n modelValue: {\n handler() {\n this.updateTable()\n },\n deep: true\n },\n 'formCreateInject.preview': function (n) {\n this.emptyRule.children[0].props.colspan =\n this.columns.length + (n ? 1 : 2)\n }\n },\n data() {\n return {\n rule: [],\n trs: [],\n fapi: {},\n Form: markRaw(this.formCreateInject.form.$form()),\n copyTrs: '',\n oldValue: '',\n emptyRule: {\n type: 'tr',\n _isEmpty: true,\n native: true,\n subRule: true,\n children: [\n {\n type: 'td',\n style: {\n textAlign: 'center'\n },\n native: true,\n subRule: true,\n props: {\n colspan:\n this.columns.length + (this.formCreateInject.preview ? 1 : 2)\n },\n children: [this.formCreateInject.t('dataEmpty') || '暂无数据']\n }\n ]\n }\n }\n },\n methods: {\n formChange() {\n this.updateValue()\n },\n updateValue() {\n const value = this.trs\n .map((tr, idx) => {\n return {\n ...(this.modelValue[idx] || {}),\n ...this.fapi.getChildrenFormData(tr)\n }\n })\n .filter((v) => {\n if (!this.filterEmptyColumn) {\n return true\n }\n if (v === undefined || v === null) {\n return false\n }\n let flag = false\n Object.keys(v).forEach((k) => {\n flag = flag || (v[k] !== undefined && v[k] !== '' && v[k] !== null)\n })\n return flag\n })\n const str = JSON.stringify(value)\n if (str !== this.oldValue) {\n this.oldValue = str\n this.$emit('update:modelValue', value)\n this.$emit('change', value)\n }\n },\n setRawData(idx, formData) {\n const raw = this.trs[idx]\n this.fapi.setChildrenFormData(raw, formData, true)\n },\n updateTable() {\n const str = JSON.stringify(this.modelValue)\n if (this.oldValue === str) {\n return\n }\n this.oldValue = str\n this.trs = this.trs.splice(0, this.modelValue.length)\n if (!this.modelValue.length) {\n this.addEmpty()\n } else {\n this.clearEmpty()\n }\n this.modelValue.forEach((data, idx) => {\n if (!this.trs[idx]) {\n this.addRaw()\n }\n this.setRawData(idx, data || {})\n })\n this.rule[0].children[1].children = this.trs\n },\n addEmpty() {\n if (this.trs.length) {\n this.trs.splice(0, this.trs.length)\n }\n this.trs.push(this.emptyRule)\n },\n clearEmpty() {\n if (this.trs[0] && this.trs[0]._isEmpty) {\n this.trs.splice(0, 1)\n }\n },\n delRaw(idx) {\n if (\n this.disabled ||\n !this.deletable ||\n (this.min > 0 && this.trs.length <= this.min)\n ) {\n return\n }\n this.trs.splice(idx, 1)\n this.updateValue()\n if (this.trs.length) {\n this.trs.forEach((tr) => this.updateRaw(tr))\n } else {\n this.addEmpty()\n }\n this.$emit('delete', idx)\n },\n addRaw(flag) {\n if (flag && this.disabled) {\n return\n }\n const tr = this.formCreateInject.form.parseJson(this.copyTrs)[0]\n if (this.trs.length === 1 && this.trs[0]._isEmpty) {\n this.trs.splice(0, 1)\n }\n this.trs.push(tr)\n this.updateRaw(tr)\n if (flag) {\n this.$emit('add', this.trs.length)\n this.updateValue()\n }\n },\n updateRaw(tr) {\n const idx = this.trs.indexOf(tr)\n tr.children[0].props.innerText = idx + 1\n tr.children[tr.children.length - 1].children[0].props.onClick = () => {\n this.delRaw(idx)\n }\n },\n loadRule() {\n const header = [\n {\n type: 'th',\n native: true,\n class: '_fc-tf-head-idx',\n props: {\n innerText: '#'\n }\n }\n ]\n let body = [\n {\n type: 'td',\n class: '_fc-tf-idx',\n native: true,\n props: {\n innerText: '0'\n }\n }\n ]\n this.columns.forEach((column) => {\n header.push({\n type: 'th',\n native: true,\n style: {\n ...(column.style || {}),\n textAlign: column.align || 'center'\n },\n class: column.required ? '_fc-tf-head-required' : '',\n props: {\n innerText: column.label || ''\n }\n })\n body.push({\n type: 'td',\n native: true,\n children: [...(column.rule || [])]\n })\n })\n header.push({\n type: 'th',\n native: true,\n class: '_fc-tf-edit fc-clock',\n props: {\n innerText: this.formCreateInject.t('operation') || '操作'\n }\n })\n body.push({\n type: 'td',\n native: true,\n class: '_fc-tf-btn fc-clock',\n children: [\n {\n type: 'i',\n native: true,\n class: 'fc-icon icon-delete',\n props: {}\n }\n ]\n })\n this.copyTrs = this.formCreateInject.form.toJson([\n {\n type: 'tr',\n native: true,\n subRule: true,\n children: body\n }\n ])\n this.rule = [\n {\n type: 'table',\n native: true,\n class: '_fc-tf-table',\n props: {\n border: '1',\n cellspacing: '0',\n cellpadding: '0'\n },\n children: [\n {\n type: 'thead',\n native: true,\n children: [\n {\n type: 'tr',\n native: true,\n children: header\n }\n ]\n },\n {\n type: 'tbody',\n native: true,\n children: this.trs\n }\n ]\n }\n ]\n }\n },\n created() {\n this.loadRule()\n },\n mounted() {\n this.updateTable()\n }\n}\n</script>\n","<template>\n <div class=\"_fd-table-form\">\n <div class=\"_fd-tf-wrap\" v-if=\"$slots.default\">\n <slot></slot>\n </div>\n <div class=\"_fc-child-empty\" v-else></div>\n </div>\n</template>\n\n<script>\nimport { defineComponent } from 'vue'\n\nexport default defineComponent({\n name: 'TableFormView',\n data() {\n return {}\n }\n})\n</script>\n","<template>\n <div class=\"_fd-table-form\">\n <div class=\"_fd-tf-wrap\" v-if=\"$slots.default\">\n <slot></slot>\n </div>\n <div class=\"_fc-child-empty\" v-else></div>\n </div>\n</template>\n\n<script>\nimport { defineComponent } from 'vue'\n\nexport default defineComponent({\n name: 'TableFormView',\n data() {\n return {}\n }\n})\n</script>\n","<template>\n <div class=\"_fd-tf-col\" :style=\"colStyle\">\n <div class=\"_fd-tf-title\" :style=\"{ textAlign: align || 'center' }\">\n <span v-if=\"required\" class=\"_fd-tf-required\">*</span>{{ label || '' }}\n </div>\n <div class=\"_fd-tf-con\">\n <slot></slot>\n </div>\n </div>\n</template>\n\n<script>\nimport is from '@form-create/utils/lib/type'\nimport { defineComponent } from 'vue'\n\nexport default defineComponent({\n name: 'TableFormColumnView',\n props: {\n label: String,\n align: String,\n width: [Number, String],\n color: String,\n required: Boolean\n },\n computed: {\n colStyle() {\n const w = this.width\n const style = {\n width: is.Number(w) ? `${w}px` : !w || w === 'auto' ? '180px' : w\n }\n if (this.color) {\n style.color = this.color\n }\n return style\n }\n },\n data() {\n return {}\n }\n})\n</script>\n","<template>\n <div class=\"_fd-tf-col\" :style=\"colStyle\">\n <div class=\"_fd-tf-title\" :style=\"{ textAlign: align || 'center' }\">\n <span v-if=\"required\" class=\"_fd-tf-required\">*</span>{{ label || '' }}\n </div>\n <div class=\"_fd-tf-con\">\n <slot></slot>\n </div>\n </div>\n</template>\n\n<script>\nimport is from '@form-create/utils/lib/type'\nimport { defineComponent } from 'vue'\n\nexport default defineComponent({\n name: 'TableFormColumnView',\n props: {\n label: String,\n align: String,\n width: [Number, String],\n color: String,\n required: Boolean\n },\n computed: {\n colStyle() {\n const w = this.width\n const style = {\n width: is.Number(w) ? `${w}px` : !w || w === 'auto' ? '180px' : w\n }\n if (this.color) {\n style.color = this.color\n }\n return style\n }\n },\n data() {\n return {}\n }\n})\n</script>\n","import upload from '@longhongguo/component-antdv-upload/src/index'\nimport frame from '@form-create/component-antdv-frame/src/index'\nimport group from '@form-create/component-antdv-group/src/index'\nimport subForm from '@form-create/component-subform/src/index'\nimport QuestionCircleOutlined from './icon/QuestionCircleOutlined.vue'\nimport CusSelect from './CusSelect/index.vue'\nimport CusStoreSelect from './CusStoreSelect/index.vue'\nimport CusUserSelect from './CusUserSelect/index.vue'\nimport TableForm from './tableForm/TableForm.vue'\nimport TableFormView from './tableForm/TableFormView.vue'\nimport TableFormColumnView from './tableForm/TableFormColumnView.vue'\n\nexport default [\n upload,\n frame,\n group,\n subForm,\n QuestionCircleOutlined,\n CusSelect,\n CusStoreSelect,\n CusUserSelect,\n TableForm,\n TableFormView,\n TableFormColumnView\n]\n","import {hasProperty} from '@form-create/utils/lib/type';\r\n\r\nexport default {\r\n name: 'checkbox',\r\n modelField: 'value',\r\n mergeProp(ctx) {\r\n const props = ctx.prop.props;\r\n if (!hasProperty(props, 'options'))\r\n props.options = ctx.prop.options || [];\r\n }\r\n\r\n}\r\n","import checkbox from './checkbox';\n\nexport default {\n ...checkbox, name: 'radio'\n};\n","import checkbox from './checkbox'\nimport { hasProperty } from '@form-create/utils/lib/type'\n\nexport default {\n ...checkbox,\n name: 'select',\n mergeProp(ctx) {\n const props = ctx.prop.props\n if (!hasProperty(props, 'options')) props.options = ctx.prop.options || []\n\n // 检测 loading 状态:从 effectData('fetch') 中获取 loading 状态\n const fetchData = ctx.effectData('fetch')\n const isLoading = fetchData && fetchData.loading === true\n\n // 如果正在加载,设置 disabled 和 loading\n if (isLoading) {\n props.disabled = true\n props.loading = true\n }\n },\n render(children, ctx) {\n // 检测 loading 状态(与 mergeProp 中的逻辑保持一致)\n const fetchData = ctx.effectData('fetch')\n const isLoading = fetchData && fetchData.loading === true\n\n // 如果有 loading 插槽且正在加载,将 loading 插槽传递给组件的 notFoundContent 插槽\n if (isLoading && children.loading) {\n // 将 loading 插槽合并到 children 中,作为 notFoundContent\n const newChildren = { ...children }\n newChildren.notFoundContent = children.loading\n return ctx.$render.defaultRender(ctx, newChildren)\n }\n\n // 调用默认渲染\n return ctx.$render.defaultRender(ctx, children)\n }\n}\n","import { hasProperty } from '@form-create/utils/lib/type'\r\nimport { parseFn } from '@form-create/utils/lib/json'\r\nimport is from '@form-create/utils/lib/type'\r\nimport deepSet from '@form-create/utils/lib/deepset'\r\n\r\nexport default {\r\n name: 'cascader',\r\n mergeProp(ctx) {\r\n const props = ctx.prop.props\r\n if (!hasProperty(props, 'options')) props.options = ctx.prop.options || []\r\n\r\n // 检测 loading 状态:从 effectData('fetch') 中获取 loading 状态\r\n const fetchData = ctx.effectData('fetch')\r\n const isLoading = fetchData && fetchData.loading === true\r\n\r\n // 如果正在加载,设置 disabled 和 loading\r\n if (isLoading) {\r\n props.disabled = true\r\n props.loading = true\r\n }\r\n\r\n // 处理 loadData 函数\r\n if (props.loadData) {\r\n const api = ctx.$handle?.api\r\n const rule = ctx.rule\r\n const ctxRef = ctx\r\n\r\n // 解析函数(如果是字符串)\r\n let parsedFn = is.String(props.loadData)\r\n ? parseFn(props.loadData)\r\n : props.loadData\r\n\r\n // 如果不是函数,尝试包装\r\n if (!is.Function(parsedFn) && is.String(props.loadData)) {\r\n try {\r\n const code = props.loadData.trim()\r\n if (\r\n !code.startsWith('function') &&\r\n !code.startsWith('[[FORM-CREATE-PREFIX-function') &&\r\n !code.startsWith('$FNX:')\r\n ) {\r\n parsedFn = new Function(\r\n 'selectedOptions',\r\n 'options',\r\n 'updateOptions',\r\n 'api',\r\n 'rule',\r\n code\r\n )\r\n }\r\n } catch (e) {\r\n console.error('Failed to parse loadData:', e)\r\n }\r\n }\r\n\r\n if (is.Function(parsedFn)) {\r\n // 包装 loadData 函数\r\n props.loadData = function (selectedOptions) {\r\n if (!selectedOptions || selectedOptions.length === 0) return\r\n\r\n const targetOption = selectedOptions[selectedOptions.length - 1]\r\n\r\n if (targetOption?.isLeaf === true) {\r\n return\r\n }\r\n\r\n const options = props.options || []\r\n\r\n // 创建 updateOptions 函数,完全按照 effect.fetch 的方式\r\n // 关键:effect.fetch 使用 deepSet(inject.getProp(), 'props.options', val) 然后 api.sync(rule)\r\n const updateOptions = () => {\r\n // 关键:创建新数组时,同时创建新对象,确保引用完全改变\r\n // 这样可以触发 Vue 的响应式更新,即使对象属性被修改了\r\n const currentOptions = props.options || []\r\n\r\n // 找到 targetOption 在数组中的索引\r\n let targetIndex = -1\r\n if (targetOption) {\r\n targetIndex = currentOptions.findIndex(\r\n (item) =>\r\n item.value === targetOption.value ||\r\n item.id === targetOption.id ||\r\n item === targetOption\r\n )\r\n }\r\n\r\n const newOptions = currentOptions.map((item, index) => {\r\n // 如果是 targetOption,创建包含所有修改的新对象\r\n if (index === targetIndex && targetOption) {\r\n const newTarget = { ...targetOption }\r\n return newTarget\r\n }\r\n // 其他对象创建新引用(浅拷贝即可)\r\n return { ...item }\r\n })\r\n\r\n // 完全按照 effect.fetch 的方式:使用 deepSet 在响应式对象上设置值\r\n // effect.fetch 使用: deepSet(inject.getProp(), 'props.options', val)\r\n // inject.getProp() 返回 ctx.effectData('fetch')\r\n // 所以我们应该在同一个位置设置:ctxRef.effectData('fetch')\r\n const fetchData = ctxRef.effectData('fetch')\r\n if (fetchData) {\r\n // 关键:在 fetchData 上设置,就像 effect.fetch 那样\r\n deepSet(fetchData, 'props.options', newOptions)\r\n }\r\n\r\n // 同时直接更新 props.options(这是最终传递给组件的值)\r\n props.options = newOptions\r\n\r\n // 同步到 ctx.prop.props.options(确保 mergeRule 能获取到最新值)\r\n if (ctxRef.prop?.props) {\r\n ctxRef.prop.props.options = newOptions\r\n }\r\n\r\n // 同步到 rule.props.options\r\n if (ctxRef.rule?.props) {\r\n ctxRef.rule.props.options = newOptions\r\n }\r\n\r\n // 调用 api.sync 触发更新,就像 effect.fetch 那样\r\n if (api && rule) {\r\n api.sync(rule)\r\n }\r\n\r\n // 刷新组件\r\n if (ctxRef.$handle) {\r\n ctxRef.$handle.refresh()\r\n }\r\n }\r\n\r\n // 关键:在调用用户函数之前,立即设置 loading 并更新\r\n // 这样确保 loading 状态能立即显示\r\n if (targetOption) {\r\n targetOption.loading = true\r\n updateOptions()\r\n }\r\n\r\n // 调用用户函数\r\n const result = parsedFn.call(\r\n this,\r\n selectedOptions,\r\n options,\r\n updateOptions,\r\n api,\r\n rule\r\n )\r\n\r\n // 如果用户函数返回 Promise,等待完成\r\n if (result && typeof result.then === 'function') {\r\n return result.finally(() => {\r\n updateOptions()\r\n })\r\n }\r\n\r\n return result\r\n }\r\n }\r\n }\r\n },\r\n render(children, ctx) {\r\n // 检测 loading 状态(与 mergeProp 中的逻辑保持一致)\r\n const fetchData = ctx.effectData('fetch')\r\n const isLoading = fetchData && fetchData.loading === true\r\n\r\n // 如果有 loading 插槽且正在加载,将 loading 插槽传递给组件的 notFoundContent 插槽\r\n if (isLoading && children.loading) {\r\n // 将 loading 插槽合并到 children 中,作为 notFoundContent\r\n const newChildren = { ...children }\r\n newChildren.notFoundContent = children.loading\r\n return ctx.$render.defaultRender(ctx, newChildren)\r\n }\r\n\r\n // 调用默认渲染\r\n return ctx.$render.defaultRender(ctx, children)\r\n }\r\n}\r\n","import { creatorFactory } from '@longhongguo/form-create-core/src/index'\n\nconst FORMAT_TYPE = {\n date: 'YYYY-MM-DD',\n month: 'YYYY-MM',\n week: 'YYYY-wo',\n quarter: 'YYYY-qQ',\n year: 'YYYY'\n}\n\nconst name = 'datePicker'\n\nexport default {\n name,\n maker: (function () {\n return ['date', 'month', 'week'].reduce(\n (initial, type) => {\n initial[type] = creatorFactory(name, { type })\n return initial\n },\n {\n dateRange: creatorFactory(name, { type: 'range' }),\n datetimeRange: creatorFactory(name, (m) =>\n m.props({ type: 'range', showTime: true })\n )\n }\n )\n })(),\n modelField: 'value',\n mergeProp(ctx) {\n const props = ctx.prop.props\n const type = props.type || props.picker\n if (!props.valueFormat) {\n props.valueFormat =\n (FORMAT_TYPE[type] || FORMAT_TYPE['date']) +\n (props.showTime && (!type || type === 'date') ? ' HH:mm:ss' : '')\n }\n },\n render(children, ctx) {\n return ctx.$render.vNode[\n (ctx.prop.props.range === true ? 'range' : 'date') + 'Picker'\n ](ctx.prop, children)\n }\n}\n","import { creatorFactory } from '@longhongguo/form-create-core/src/index'\n\nconst name = 'hidden'\n\nexport default {\n name,\n maker: {\n [name]: (field, value) => creatorFactory(name)('', field, value)\n },\n render() {\n return []\n }\n}\n","import is from '@form-create/utils/lib/type'\r\nimport { watch, toRef } from 'vue'\r\n\r\nexport default {\r\n name: 'text',\r\n // 设置 loadChildren 为 false,避免 children 被当作子组件处理\r\n // text 的 children 只是简单的文本内容,不需要作为子组件加载\r\n loadChildren: false,\r\n // 组件挂载后,手动触发一次 loadData 更新,确保表单数据准备好后再获取初始值\r\n mounted(ctx) {\r\n // 如果是动态绑定的 Text 组件,在挂载后手动解析模板并更新值\r\n const props = ctx.rule.props || {}\r\n const bindField =\r\n ctx.rule.bindField || props.bindField || ctx.prop.props?.bindField\r\n const template =\r\n ctx.rule.template || props.template || ctx.prop.props?.template\r\n\r\n if (template || bindField) {\r\n // 延迟执行,确保表单数据已经准备好\r\n setTimeout(() => {\r\n if (ctx.$handle && ctx.$handle.api) {\r\n try {\r\n let value = ''\r\n\r\n // 如果是模板模式,手动解析模板字符串\r\n if (template) {\r\n const formData = ctx.$handle.api.formData()\r\n // 使用 loadStrVar 解析模板,传入一个 get 函数来获取表单数据\r\n value = ctx.$handle.loadStrVar(\r\n template,\r\n (field) => {\r\n // 使用 api.getValue 获取表单字段值\r\n const val = ctx.$handle.api.getValue(field)\r\n // 如果 getValue 返回 undefined,尝试从 formData 直接获取\r\n if (\r\n val === undefined &&\r\n formData &&\r\n formData[field] !== undefined\r\n ) {\r\n return formData[field]\r\n }\r\n return val\r\n },\r\n null\r\n )\r\n }\r\n // 如果是字段绑定模式,直接获取字段值\r\n else if (bindField) {\r\n value = ctx.$handle.api.getValue(bindField) || ''\r\n }\r\n\r\n // 更新 rule.children(转换为字符串)\r\n if (value != null) {\r\n if (!ctx.rule.children) {\r\n ctx.rule.children = []\r\n }\r\n ctx.rule.children[0] = String(value)\r\n // 触发同步和刷新\r\n ctx.$handle.api.sync(ctx.rule)\r\n ctx.$handle.refresh()\r\n }\r\n } catch (e) {\r\n // 静默处理错误\r\n }\r\n }\r\n }, 500) // 增加延迟,确保表单数据完全准备好\r\n }\r\n },\r\n // 处理 children 的渲染,将 children 数组转换为可渲染的内容\r\n renderChildren(children, ctx) {\r\n // 使用 computed 确保响应式更新\r\n // 每次 rule.children 变化时,都会重新计算\r\n return {\r\n default: () => {\r\n // 每次都重新从 rule.children 获取最新值(loadData 会更新这个值)\r\n // 不要使用闭包中的 children 参数,因为它可能是旧值\r\n let currentChildren = ctx.rule?.children\r\n\r\n // 如果 rule.children 不存在,才使用传入的 children 参数(初始值)\r\n if (!currentChildren) {\r\n currentChildren = children\r\n }\r\n\r\n // 确保是数组\r\n const childrenArray = Array.isArray(currentChildren)\r\n ? currentChildren\r\n : [currentChildren]\r\n\r\n // 过滤并转换字符串,参考 html parser 的实现\r\n const text = childrenArray\r\n .filter((v) => v !== null && v !== undefined)\r\n .map((v) => {\r\n if (is.String(v)) {\r\n return v\r\n }\r\n // 如果是对象或其他类型,转换为字符串\r\n return String(v)\r\n })\r\n .join('')\r\n\r\n return text || ''\r\n }\r\n }\r\n },\r\n mergeProp(ctx) {\r\n // 确保没有 field 的组件能正常显示\r\n // 如果 prop.native 未设置,默认设置为 false,让组件被 makeWrap 包装(这样可以显示 title)\r\n // 但如果需要直接渲染,可以设置 native: true\r\n\r\n // 支持从多个位置读取配置:\r\n // 1. ctx.rule.bindField / ctx.rule.template(直接在 rule 中)\r\n // 2. ctx.rule.props.bindField / ctx.rule.props.template(在 props 中)\r\n // 3. ctx.prop.props.bindField / ctx.prop.props.template(在 prop.props 中)\r\n const props = ctx.rule.props || {}\r\n const bindField =\r\n ctx.rule.bindField || props.bindField || ctx.prop.props?.bindField\r\n const template =\r\n ctx.rule.template || props.template || ctx.prop.props?.template\r\n let bindMode =\r\n ctx.rule.bindMode || props.bindMode || ctx.prop.props?.bindMode\r\n\r\n // 如果没有设置 bindMode,根据是否有 bindField 或 template 自动判断\r\n if (!bindMode) {\r\n if (template) {\r\n bindMode = 'template'\r\n } else if (bindField) {\r\n bindMode = 'field'\r\n } else {\r\n bindMode = 'static'\r\n }\r\n }\r\n\r\n // 如果配置了 bindField(绑定单个字段),使用 loadData 来实现动态绑定\r\n if (bindMode === 'field' && bindField) {\r\n const loadDataConfig = {\r\n attr: bindField,\r\n to: 'child',\r\n modify: true,\r\n // 增加 debounce 延迟,避免频繁更新导致循环\r\n wait: 300,\r\n // 确保 watch 开启,但通过 debounce 控制频率\r\n watch: true\r\n }\r\n\r\n // 添加到 effect 中(避免重复添加)\r\n if (!ctx.rule.effect) {\r\n ctx.rule.effect = {}\r\n }\r\n if (!ctx.rule.effect.loadData) {\r\n ctx.rule.effect.loadData = []\r\n }\r\n // 检查是否已存在相同的配置,避免重复添加\r\n const exists = ctx.rule.effect.loadData.some(\r\n (item) => item.attr === bindField && item.to === 'child'\r\n )\r\n if (!exists) {\r\n ctx.rule.effect.loadData.push(loadDataConfig)\r\n // 手动触发 effect 来确保 loadData provider 被调用\r\n // 使用 effect 方法,它会正确设置 ctx 和 input\r\n if (ctx.$handle && ctx.$handle.effect) {\r\n ctx.$handle.effect(ctx, 'loaded')\r\n }\r\n }\r\n }\r\n // 如果配置了 template(模板字符串),支持多个字段绑定\r\n else if (bindMode === 'template' && template) {\r\n const loadDataConfig = {\r\n template: template,\r\n to: 'child',\r\n modify: true,\r\n // 增加 debounce 延迟,避免频繁更新导致循环\r\n wait: 300,\r\n // 确保 watch 开启,但通过 debounce 控制频率\r\n watch: true\r\n }\r\n\r\n if (!ctx.rule.effect) {\r\n ctx.rule.effect = {}\r\n }\r\n if (!ctx.rule.effect.loadData) {\r\n ctx.rule.effect.loadData = []\r\n }\r\n // 检查是否已存在相同的配置,避免重复添加\r\n const exists = ctx.rule.effect.loadData.some(\r\n (item) => item.template === template && item.to === 'child'\r\n )\r\n if (!exists) {\r\n ctx.rule.effect.loadData.push(loadDataConfig)\r\n // 手动触发 effect 来确保 loadData provider 被调用\r\n if (ctx.$handle && ctx.$handle.effect) {\r\n ctx.$handle.effect(ctx, 'loaded')\r\n // 同时手动添加 watch,监听 effect.loadData 的变化\r\n // 这样当 effect.loadData 被修改时,也会触发 provider\r\n if (!ctx._textLoadDataWatched) {\r\n ctx._textLoadDataWatched = true\r\n const loadDataRef = toRef(ctx.rule.effect, 'loadData')\r\n ctx.watch.push(\r\n watch(\r\n loadDataRef,\r\n (newVal, oldVal) => {\r\n ctx.$handle.effect(ctx, 'watch', { loadData: newVal })\r\n },\r\n { deep: true }\r\n )\r\n )\r\n }\r\n }\r\n }\r\n }\r\n // 静态模式:使用 formCreateChild 或 children 作为内容\r\n // formCreateChild 会作为 children[0] 渲染,如果已有 children,也会正常渲染\r\n\r\n // 如果配置了 formCreateChild,将其转换为 children\r\n if (ctx.rule.formCreateChild != null && !ctx.rule.children) {\r\n ctx.rule.children = [ctx.rule.formCreateChild]\r\n }\r\n\r\n // 确保 children 存在(如果没有设置,默认为空数组)\r\n if (!ctx.rule.children) {\r\n ctx.rule.children = []\r\n }\r\n\r\n // 对于动态绑定的情况,初始化时设置一个占位符,确保组件能被渲染\r\n // loadData 会在初始化后立即执行一次,更新这个值\r\n if (\r\n (bindMode === 'field' && bindField) ||\r\n (bindMode === 'template' && template)\r\n ) {\r\n // 如果 children 是空数组或未设置,设置为一个非空字符串\r\n // 这样确保组件会被渲染,然后 loadData 会更新内容\r\n if (\r\n !ctx.rule.children ||\r\n (Array.isArray(ctx.rule.children) && ctx.rule.children.length === 0)\r\n ) {\r\n // 对于 template 模式,先不设置占位符,等待 loadData 执行\r\n // 因为如果设置了占位符,可能会覆盖 loadData 的结果\r\n if (bindMode === 'template') {\r\n // template 模式下,等待 loadData 执行后更新\r\n // 但为了确保组件能渲染,至少设置一个空字符串\r\n ctx.rule.children = ['']\r\n } else {\r\n // field 模式下,设置一个空格字符串作为占位符\r\n ctx.rule.children = [' ']\r\n }\r\n }\r\n }\r\n },\r\n render(children, ctx) {\r\n // text 组件使用 div 渲染,内容来自 children\r\n // 使用 children.default() 获取响应式内容,参考 html parser 的实现\r\n\r\n // 获取文本内容(children.default() 会从 renderChildren 返回的响应式函数中获取)\r\n // renderChildren 返回的 default 函数会从 ctx.rule.children 获取最新值\r\n let text = ''\r\n if (children && typeof children.default === 'function') {\r\n try {\r\n text = children.default() || ''\r\n } catch (e) {\r\n text = ''\r\n }\r\n }\r\n\r\n // 确保 text 是字符串\r\n if (text == null || text === undefined) {\r\n text = ''\r\n } else {\r\n text = String(text)\r\n }\r\n\r\n // 复制 prop,避免修改原始对象\r\n const prop = { ...ctx.prop }\r\n if (!prop.props) {\r\n prop.props = {}\r\n }\r\n\r\n // 确保 type 是 'div'\r\n if (prop.type === 'text') {\r\n prop.type = 'div'\r\n }\r\n\r\n delete prop.props.innerHTML\r\n\r\n // 直接使用 vNode.make 渲染 div,文本作为子节点\r\n // 即使 text 为空,也传递 [text] 确保渲染出 div\r\n const vnode = ctx.vNode.make('div', prop, [text])\r\n return vnode\r\n }\r\n}\r\n","import { creatorFactory } from '@longhongguo/form-create-core/src/index'\n\nconst name = 'input'\nexport default {\n name,\n maker: (function () {\n return ['password', 'url', 'email', 'text', 'textarea', 'search'].reduce(\n (maker, type) => {\n maker[type] = creatorFactory(name, { type })\n return maker\n },\n {\n idate: creatorFactory(name, { type: 'date' })\n }\n )\n })(),\n modelField: 'value',\n render(children, ctx) {\n let type = ctx.prop.props.type\n if (['textarea', 'search', 'password'].indexOf(type) === -1) type = 'input'\n\n type =\n {\n textarea: 'aTextarea',\n search: 'aInputSearch',\n password: 'aInputPassword'\n }[type] || 'aInput'\n return ctx.$render.vNode.make(type, ctx.prop, children)\n }\n}\n","export default {\n name: 'timePicker',\n modelField: 'value',\n mergeProp(ctx) {\n const props = ctx.prop.props;\n if (!props.valueFormat) {\n props.valueFormat = 'HH:mm:ss';\n }\n },\n render(children, ctx) {\n return ctx.$render.vNode['time' +( ctx.prop.props.range === true ? 'Range' : '') + 'Picker'](ctx.prop, children);\n }\n\n}\n\n","export default {\n name: 'tree',\n modelField: 'checkedKeys',\n mergeProp(ctx) {\n const props = ctx.prop.props;\n if (!props.fieldNames)\n props.fieldNames = {\n key: 'id'\n };\n else if (!props.fieldNames.key) props.fieldNames.key = 'id';\n props.checkedKeys = ctx.rule.value;\n props.checkable = true;\n },\n\n}\n\n","export default {\n name: 'FcRow',\n render(_, ctx) {\n return ctx.vNode.col({props: {span: 24}}, {\n default: () => [\n ctx.vNode.row(ctx.prop, _)\n ]\n })\n }\n}\n","import timePicker from './timePicker';\n\nconst name = 'timeRangePicker';\n\nexport default {\n ...timePicker,\n name,\n render(children, ctx) {\n return ctx.$render.vNode['timeRangePicker'](ctx.prop, children);\n }\n}\n","import checkbox from './checkbox'\nimport radio from './radio'\nimport select from './select'\nimport cascader from './cascader'\nimport datePicker from './datePicker'\nimport hidden from './hidden'\nimport text from './text' // text parser 必须在 input 之前注册,避免被 input 的 maker.text 覆盖\nimport input from './input'\nimport timePicker from './timePicker'\nimport tree from './tree'\nimport row from './row'\nimport rangePicker from './rangePicker'\nimport timeRangePicker from './timeRangePicker'\nimport cusStoreSelect from './cusStoreSelect'\nimport cusUserSelect from './cusUserSelect'\nimport flex from './flex'\nimport space from './space'\nimport spin from './spin'\n\nexport default [\n checkbox,\n datePicker,\n rangePicker,\n hidden,\n text, // text parser 必须在 input 之前,确保 type: 'text' 时优先匹配 text parser\n input,\n timePicker,\n timeRangePicker,\n tree,\n radio,\n select,\n cascader,\n row,\n cusStoreSelect,\n cusUserSelect,\n flex,\n space,\n spin\n]\n","import datePicker from './datePicker';\n\nconst name = 'rangePicker';\n\nexport default {\n ...datePicker,\n name,\n maker: {},\n render(children, ctx) {\n return ctx.$render.vNode['rangePicker'](ctx.prop, children);\n }\n}\n","import { hasProperty } from '@form-create/utils/lib/type'\r\nimport { nextTick } from 'vue'\r\n\r\nexport default {\r\n name: 'cusStoreSelect',\r\n modelField: 'modelValue',\r\n // 将 form-create 内部的值转换为对象数组格式\r\n toFormValue(value, ctx) {\r\n // 组件内部统一使用对象数组格式 [{value, label, ...}]\r\n if (value === null || value === undefined || value === '') {\r\n return []\r\n }\r\n if (Array.isArray(value)) {\r\n // 确保数组中的每个元素都是对象格式\r\n return value.map((item) => {\r\n if (\r\n typeof item === 'object' &&\r\n item !== null &&\r\n (item.value !== undefined || item.label !== undefined)\r\n ) {\r\n // 已经是对象格式\r\n return item\r\n }\r\n // 如果是单个值,需要转换为对象格式(但此时没有 label,会在组件内部处理)\r\n return item\r\n })\r\n }\r\n // 单个值转换为数组(组件内部会处理对象转换)\r\n return [value]\r\n },\r\n // 将组件返回的数组格式转换为 form-create 内部格式(可选,保持原值)\r\n toValue(formValue, ctx) {\r\n // 保持数组格式,不转换\r\n return formValue\r\n },\r\n mergeProp(ctx) {\r\n const props = ctx.prop.props\r\n // 确保 options 存在\r\n if (!hasProperty(props, 'options')) {\r\n props.options = ctx.prop.options || []\r\n }\r\n // 传递字段名到组件,用于跨窗口通信时标识字段\r\n if (!hasProperty(props, 'field')) {\r\n props.field = ctx.rule.field || ''\r\n }\r\n // 确保初始值转换为数组格式\r\n if (ctx.rule.value !== undefined) {\r\n const currentValue = ctx.rule.value\r\n if (\r\n currentValue === null ||\r\n currentValue === undefined ||\r\n currentValue === ''\r\n ) {\r\n ctx.rule.value = []\r\n } else if (!Array.isArray(currentValue)) {\r\n ctx.rule.value = [currentValue]\r\n }\r\n }\r\n },\r\n render(children, ctx) {\r\n // 使用默认渲染\r\n const vnode = ctx.$render.defaultRender(ctx, children)\r\n\r\n // 添加校验触发逻辑:在值变化时触发校验\r\n if (vnode && vnode.props && vnode.props.on) {\r\n // 保存原始的 update:modelValue 事件处理器(form-create 自动添加的)\r\n const originalUpdateModelValue = vnode.props.on['update:modelValue']\r\n\r\n // 创建校验触发函数\r\n const triggerValidate = () => {\r\n // 延迟触发校验,确保值已经更新完成\r\n // 使用多个 nextTick 确保 form-create 内部的值更新流程完成\r\n nextTick(() => {\r\n nextTick(() => {\r\n try {\r\n // 方式1:通过 field 名称触发校验(推荐)\r\n const fieldName = ctx.rule.field\r\n if (fieldName) {\r\n ctx.$handle.api.validateField(fieldName).catch(() => {\r\n // 校验失败时静默处理,错误会通过 form-item 显示\r\n })\r\n return\r\n }\r\n\r\n // 方式2:通过字段上下文ID触发校验(备用)\r\n const fieldCtx = ctx.$handle.getFieldCtx(ctx.rule.field)\r\n if (fieldCtx && fieldCtx.id) {\r\n ctx.$handle.$manager.validateField(fieldCtx.id).catch(() => {\r\n // 校验失败时静默处理,错误会通过 form-item 显示\r\n })\r\n }\r\n } catch (error) {\r\n // 静默处理错误,避免影响正常流程\r\n console.warn('CusStoreSelect: 触发校验失败', error)\r\n }\r\n })\r\n })\r\n }\r\n\r\n // 包装 update:modelValue 事件,在值更新后触发校验\r\n vnode.props.on['update:modelValue'] = (...args) => {\r\n // 先调用原始的事件处理器(form-create 的 onInput,会更新值和触发其他逻辑)\r\n if (originalUpdateModelValue) {\r\n originalUpdateModelValue(...args)\r\n }\r\n // 触发校验\r\n triggerValidate()\r\n }\r\n\r\n // 同时监听 change 事件,确保所有情况下都能触发校验\r\n const originalChange = vnode.props.on['change']\r\n if (originalChange) {\r\n vnode.props.on['change'] = (...args) => {\r\n // 先调用原始的 change 处理器\r\n originalChange(...args)\r\n // 触发校验\r\n triggerValidate()\r\n }\r\n } else {\r\n // 如果没有原始的 change 处理器,直接添加\r\n vnode.props.on['change'] = triggerValidate\r\n }\r\n }\r\n\r\n return vnode\r\n }\r\n}\r\n","import { hasProperty } from '@form-create/utils/lib/type'\r\nimport { nextTick } from 'vue'\r\n\r\nexport default {\r\n name: 'cusUserSelect',\r\n modelField: 'modelValue',\r\n // 将 form-create 内部的值转换为对象数组格式\r\n toFormValue(value, ctx) {\r\n // 组件内部统一使用对象数组格式 [{value, label, ...}]\r\n if (value === null || value === undefined || value === '') {\r\n return []\r\n }\r\n if (Array.isArray(value)) {\r\n // 确保数组中的每个元素都是对象格式\r\n return value.map((item) => {\r\n if (\r\n typeof item === 'object' &&\r\n item !== null &&\r\n (item.value !== undefined || item.label !== undefined)\r\n ) {\r\n // 已经是对象格式\r\n return item\r\n }\r\n // 如果是单个值,需要转换为对象格式(但此时没有 label,会在组件内部处理)\r\n return item\r\n })\r\n }\r\n // 单个值转换为数组(组件内部会处理对象转换)\r\n return [value]\r\n },\r\n // 将组件返回的数组格式转换为 form-create 内部格式(可选,保持原值)\r\n toValue(formValue, ctx) {\r\n // 保持数组格式,不转换\r\n return formValue\r\n },\r\n mergeProp(ctx) {\r\n const props = ctx.prop.props\r\n // 确保 options 存在\r\n if (!hasProperty(props, 'options')) {\r\n props.options = ctx.prop.options || []\r\n }\r\n // 传递字段名到组件,用于跨窗口通信时标识字段\r\n if (!hasProperty(props, 'field')) {\r\n props.field = ctx.rule.field || ''\r\n }\r\n // 传递 formCreateInject 到组件,用于在组件内部触发校验\r\n if (!hasProperty(props, 'formCreateInject')) {\r\n props.formCreateInject = ctx.inject\r\n }\r\n // 确保初始值转换为数组格式\r\n if (ctx.rule.value !== undefined) {\r\n const currentValue = ctx.rule.value\r\n if (\r\n currentValue === null ||\r\n currentValue === undefined ||\r\n currentValue === ''\r\n ) {\r\n ctx.rule.value = []\r\n } else if (!Array.isArray(currentValue)) {\r\n ctx.rule.value = [currentValue]\r\n }\r\n }\r\n },\r\n render(children, ctx) {\r\n // 使用默认渲染\r\n const vnode = ctx.$render.defaultRender(ctx, children)\r\n\r\n // 添加校验触发逻辑:在值变化时触发校验\r\n if (vnode && vnode.props && vnode.props.on) {\r\n // 保存原始的 update:modelValue 事件处理器(form-create 自动添加的)\r\n const originalUpdateModelValue = vnode.props.on['update:modelValue']\r\n\r\n // 创建校验触发函数\r\n const triggerValidate = () => {\r\n // 延迟触发校验,确保值已经更新完成\r\n // 使用多个 nextTick 确保 form-create 内部的值更新流程完成\r\n nextTick(() => {\r\n nextTick(() => {\r\n try {\r\n // 方式1:通过 field 名称触发校验(推荐)\r\n const fieldName = ctx.rule.field\r\n if (fieldName) {\r\n ctx.$handle.api.validateField(fieldName).catch(() => {\r\n // 校验失败时静默处理,错误会通过 form-item 显示\r\n })\r\n return\r\n }\r\n\r\n // 方式2:通过字段上下文ID触发校验(备用)\r\n const fieldCtx = ctx.$handle.getFieldCtx(ctx.rule.field)\r\n if (fieldCtx && fieldCtx.id) {\r\n ctx.$handle.$manager.validateField(fieldCtx.id).catch(() => {\r\n // 校验失败时静默处理,错误会通过 form-item 显示\r\n })\r\n }\r\n } catch (error) {\r\n // 静默处理错误,避免影响正常流程\r\n console.warn('CusUserSelect: 触发校验失败', error)\r\n }\r\n })\r\n })\r\n }\r\n\r\n // 包装 update:modelValue 事件,在值更新后触发校验\r\n vnode.props.on['update:modelValue'] = (...args) => {\r\n // 先调用原始的事件处理器(form-create 的 onInput,会更新值和触发其他逻辑)\r\n if (originalUpdateModelValue) {\r\n originalUpdateModelValue(...args)\r\n }\r\n // 触发校验\r\n triggerValidate()\r\n }\r\n\r\n // 同时监听 change 事件,确保所有情况下都能触发校验\r\n const originalChange = vnode.props.on['change']\r\n if (originalChange) {\r\n vnode.props.on['change'] = (...args) => {\r\n // 先调用原始的 change 处理器\r\n originalChange(...args)\r\n // 触发校验\r\n triggerValidate()\r\n }\r\n } else {\r\n // 如果没有原始的 change 处理器,直接添加\r\n vnode.props.on['change'] = triggerValidate\r\n }\r\n }\r\n\r\n return vnode\r\n }\r\n}\r\n","export default {\r\n name: 'flex',\r\n mergeProp(ctx) {\r\n // 从 props 中读取 flex 布局配置\r\n const props = ctx.rule.props || {}\r\n const flexDirection = props.flexDirection || ctx.rule.flexDirection || 'row'\r\n const flexWrap = props.flexWrap || ctx.rule.flexWrap || 'nowrap'\r\n const justifyContent =\r\n props.justifyContent || ctx.rule.justifyContent || 'flex-start'\r\n const alignItems = props.alignItems || ctx.rule.alignItems || 'flex-start'\r\n const alignContent =\r\n props.alignContent || ctx.rule.alignContent || 'flex-start'\r\n\r\n // 映射 CSS flexbox 值到 Ant Design Vue Flex 组件的 props\r\n const vertical =\r\n flexDirection === 'column' || flexDirection === 'column-reverse'\r\n const wrap = flexWrap === 'wrap'\r\n\r\n // 映射 justifyContent 到 justify\r\n const justifyMap = {\r\n 'flex-start': 'start',\r\n 'flex-end': 'end',\r\n center: 'center',\r\n 'space-between': 'space-between',\r\n 'space-around': 'space-around',\r\n 'space-evenly': 'space-evenly'\r\n }\r\n const justify = justifyMap[justifyContent] || 'start'\r\n\r\n // 映射 alignItems 到 align\r\n const alignMap = {\r\n 'flex-start': 'start',\r\n 'flex-end': 'end',\r\n center: 'center',\r\n baseline: 'baseline',\r\n stretch: 'stretch'\r\n }\r\n const align = alignMap[alignItems] || 'start'\r\n\r\n // 设置到 prop.props,用于传递给 a-flex 组件\r\n if (!ctx.prop.props) {\r\n ctx.prop.props = {}\r\n }\r\n\r\n // 映射 Ant Design Vue Flex 组件的 props\r\n ctx.prop.props.vertical = vertical\r\n // 注意:不设置 wrap prop,因为 Ant Design Vue 的 Flex 组件的 wrap prop 类型可能不匹配\r\n // 换行功能完全通过 CSS 样式来实现\r\n ctx.prop.props.justify = justify\r\n ctx.prop.props.align = align\r\n\r\n // 如果设置了 gap,也传递\r\n if (props.gap !== undefined) {\r\n ctx.prop.props.gap = props.gap\r\n }\r\n\r\n // 合并样式(不要直接修改 ctx.rule.style,避免响应式循环)\r\n const existingStyle = ctx.rule.style || {}\r\n // 排除已经被 Flex 组件处理的样式\r\n const {\r\n display: userDisplay,\r\n flexDirection: _fd,\r\n flexWrap: _fw,\r\n justifyContent: _jc,\r\n alignItems: _ai,\r\n alignContent: _ac,\r\n ...otherStyles\r\n } = existingStyle\r\n\r\n // 构建样式对象,确保从 props 读取的配置能够应用到样式中\r\n const flexStyles = {\r\n // 保留用户设置的 display,如果没有则设置为 'flex'\r\n display: userDisplay || 'flex',\r\n // 确保 flex 容器占满整行\r\n // 在样式中设置 flexWrap,确保从 props 读取的配置能够生效\r\n // 这是关键的:将 props.flexWrap 的值('wrap' 或 'nowrap')应用到样式中\r\n flexWrap: flexWrap,\r\n // 合并其他用户自定义样式\r\n ...otherStyles\r\n }\r\n\r\n // 如果设置了 alignContent,添加到样式中\r\n if (alignContent && alignContent !== 'flex-start') {\r\n flexStyles.alignContent = alignContent\r\n }\r\n\r\n // 同时设置到 ctx.prop.style 和 ctx.prop.props.style\r\n // form-create 会将 prop.style 应用到组件上,但有时也需要 prop.props.style\r\n // 保留已有的 prop.style 和 prop.props.style,然后合并新的样式\r\n const existingPropStyle = ctx.prop.style || {}\r\n const existingPropsStyle = ctx.prop.props?.style || {}\r\n\r\n // 合并样式到 ctx.prop.style(保留已有样式,新的样式优先)\r\n ctx.prop.style = {\r\n ...existingPropStyle,\r\n ...flexStyles\r\n }\r\n\r\n // 同时也合并到 props.style,确保样式生效\r\n if (!ctx.prop.props) {\r\n ctx.prop.props = {}\r\n }\r\n ctx.prop.props.style = {\r\n ...existingPropsStyle,\r\n ...flexStyles\r\n }\r\n\r\n // 确保 children 存在\r\n if (!ctx.rule.children) {\r\n ctx.rule.children = []\r\n }\r\n\r\n // 为 flex 容器的所有子组件设置 col: false,避免被 a-col 包装\r\n // 这样可以确保子组件直接作为 flex 子项,而不是占满整行\r\n if (ctx.rule.children && Array.isArray(ctx.rule.children)) {\r\n ctx.rule.children.forEach((child) => {\r\n if (\r\n child &&\r\n typeof child === 'object' &&\r\n !child.type === 'DragTool' &&\r\n !child.type === 'DragBox'\r\n ) {\r\n // 只有当 col 未设置或为默认值时才设置\r\n if (child.col === undefined || child.col === null) {\r\n child.col = false\r\n } else if (\r\n child.col &&\r\n typeof child.col === 'object' &&\r\n child.col.show !== false\r\n ) {\r\n child.col.show = false\r\n }\r\n }\r\n })\r\n }\r\n },\r\n render(children, ctx) {\r\n // 使用 Ant Design Vue 的 Flex 组件\r\n const prop = { ...ctx.prop }\r\n\r\n // 将 type 设置为 'a-flex',form-create 会自动识别\r\n if (prop.type === 'flex') {\r\n prop.type = 'a-flex'\r\n }\r\n\r\n // 读取 flexDirection 来判断是否是垂直方向\r\n const props = ctx.rule.props || {}\r\n const flexDirection = props.flexDirection || ctx.rule.flexDirection || 'row'\r\n const isVertical =\r\n flexDirection === 'column' || flexDirection === 'column-reverse'\r\n\r\n // 初始化 prop.props 和 prop.class(如果需要的话)\r\n if (!prop.props) {\r\n prop.props = {}\r\n }\r\n\r\n // 添加自定义 class 的辅助函数\r\n const ensureClass = () => {\r\n if (!prop.class) {\r\n prop.class = []\r\n }\r\n if (!Array.isArray(prop.class)) {\r\n prop.class = [prop.class]\r\n }\r\n }\r\n\r\n // 读取 childFlex 配置\r\n const childFlex = ctx.rule.props?.childFlex ?? ctx.rule.childFlex\r\n if (childFlex !== undefined && childFlex !== null && childFlex !== '') {\r\n ensureClass()\r\n if (!prop.class.includes('_fc-flex-container')) {\r\n prop.class.push('_fc-flex-container')\r\n }\r\n\r\n // 通过 CSS 变量传递 flex 值\r\n const flexValue = String(childFlex).trim()\r\n // 合并到样式中,设置 CSS 变量\r\n if (!prop.props.style) {\r\n prop.props.style = {}\r\n }\r\n prop.props.style['--fc-child-flex'] = flexValue\r\n\r\n // 同时也设置到 prop.style\r\n if (!prop.style) {\r\n prop.style = {}\r\n }\r\n prop.style['--fc-child-flex'] = flexValue\r\n }\r\n\r\n // 如果是垂直方向,读取 childWidth 配置(默认 100%)\r\n if (isVertical) {\r\n const childWidth =\r\n ctx.rule.props?.childWidth ?? ctx.rule.childWidth ?? '100%'\r\n\r\n ensureClass()\r\n if (!prop.class.includes('_fc-flex-container')) {\r\n prop.class.push('_fc-flex-container')\r\n }\r\n if (!prop.class.includes('_fc-flex-vertical')) {\r\n prop.class.push('_fc-flex-vertical')\r\n }\r\n\r\n // 通过 CSS 变量传递宽度值\r\n const widthValue = String(childWidth).trim()\r\n if (!prop.props.style) {\r\n prop.props.style = {}\r\n }\r\n prop.props.style['--fc-child-width'] = widthValue\r\n\r\n if (!prop.style) {\r\n prop.style = {}\r\n }\r\n prop.style['--fc-child-width'] = widthValue\r\n }\r\n\r\n // children 会通过 form-create 的机制自动渲染\r\n const childrenNodes = children || []\r\n\r\n // 将 flex 容器包装在 col 中,确保它占满整行(span: 24)\r\n // 这样 flex 容器才能有足够的宽度,子项才能自适应展示\r\n return ctx.vNode.col(\r\n { props: { span: 24 } },\r\n {\r\n default: () => [ctx.vNode.make('a-flex', prop, childrenNodes)]\r\n }\r\n )\r\n }\r\n}\r\n","export default {\r\n name: 'space',\r\n mergeProp(ctx) {\r\n // 从 props 中读取 Space 组件配置\r\n const props = ctx.rule.props || {}\r\n const direction = props.direction || ctx.rule.direction || 'horizontal'\r\n const size = props.size || ctx.rule.size || 'small'\r\n const align = props.align || ctx.rule.align\r\n const wrap = props.wrap || ctx.rule.wrap || false\r\n\r\n // 设置到 prop.props,用于传递给 a-space 组件\r\n if (!ctx.prop.props) {\r\n ctx.prop.props = {}\r\n }\r\n\r\n // 映射 Ant Design Vue Space 组件的 props\r\n ctx.prop.props.direction = direction\r\n ctx.prop.props.size = size\r\n if (align !== undefined && align !== null && align !== '') {\r\n ctx.prop.props.align = align\r\n }\r\n ctx.prop.props.wrap = wrap\r\n\r\n // 合并样式,确保 Space 容器占满整行\r\n const existingStyle = ctx.rule.style || {}\r\n const spaceStyles = {\r\n width: '100%',\r\n ...existingStyle\r\n }\r\n\r\n // 同时设置到 ctx.prop.style 和 ctx.prop.props.style\r\n if (!ctx.prop.style) {\r\n ctx.prop.style = {}\r\n }\r\n ctx.prop.style = { ...ctx.prop.style, ...spaceStyles }\r\n\r\n if (!ctx.prop.props.style) {\r\n ctx.prop.props.style = {}\r\n }\r\n ctx.prop.props.style = { ...ctx.prop.props.style, ...spaceStyles }\r\n\r\n // 确保 children 存在\r\n if (!ctx.rule.children) {\r\n ctx.rule.children = []\r\n }\r\n\r\n // 为 space 容器的所有子组件设置 col: false,避免被 a-col 包装\r\n // Space 组件会自动处理子项间距,不需要 col 包装\r\n if (ctx.rule.children && Array.isArray(ctx.rule.children)) {\r\n ctx.rule.children.forEach((child) => {\r\n if (\r\n child &&\r\n typeof child === 'object' &&\r\n child.type !== 'DragTool' &&\r\n child.type !== 'DragBox'\r\n ) {\r\n // 只有当 col 未设置或为默认值时才设置\r\n if (child.col === undefined || child.col === null) {\r\n child.col = false\r\n } else if (\r\n child.col &&\r\n typeof child.col === 'object' &&\r\n child.col.show !== false\r\n ) {\r\n child.col.show = false\r\n }\r\n }\r\n })\r\n }\r\n },\r\n render(children, ctx) {\r\n // 使用 Ant Design Vue 的 Space 组件\r\n const prop = { ...ctx.prop }\r\n\r\n // 读取 compact 配置,决定使用 Space 还是 Space.Compact\r\n const props = ctx.rule.props || {}\r\n const compact = props.compact || ctx.rule.compact || false\r\n\r\n // 根据 compact 属性决定使用哪个组件\r\n if (compact) {\r\n // 使用 Space.Compact 紧凑布局\r\n prop.type = 'a-space-compact'\r\n } else {\r\n // 使用普通 Space 组件\r\n if (prop.type === 'space') {\r\n prop.type = 'a-space'\r\n }\r\n }\r\n\r\n // children 会通过 form-create 的机制自动渲染\r\n const childrenNodes = children || []\r\n\r\n // 将 space 容器包装在 col 中,确保它占满整行(span: 24)\r\n // 这样 space 容器才能有足够的宽度\r\n return ctx.vNode.col(\r\n { props: { span: 24 } },\r\n {\r\n default: () => [ctx.vNode.make(prop.type, prop, childrenNodes)]\r\n }\r\n )\r\n }\r\n}\r\n","import { hasProperty } from '@form-create/utils/lib/type'\r\n\r\nexport default {\r\n name: 'spin',\r\n mergeProp(ctx) {\r\n // 确保不显示标题\r\n if (!ctx.rule.wrap) {\r\n ctx.rule.wrap = {}\r\n }\r\n ctx.rule.wrap.title = false\r\n\r\n const props = ctx.prop.props || {}\r\n\r\n // 读取 containerMode 配置\r\n const containerMode =\r\n ctx.rule.containerMode ??\r\n ctx.rule.props?.containerMode ??\r\n ctx.prop.props?.containerMode ??\r\n true\r\n\r\n // 如果不是容器模式,清空 children\r\n if (!containerMode) {\r\n ctx.rule.children = []\r\n }\r\n\r\n if (!hasProperty(props, 'spinning')) {\r\n props.spinning =\r\n ctx.prop.props?.spinning ?? ctx.rule.props?.spinning ?? false\r\n }\r\n\r\n // 如果没有子组件且不是容器模式,spinning 不应该为 true(避免显示空加载状态)\r\n const hasChildren =\r\n ctx.rule.children &&\r\n Array.isArray(ctx.rule.children) &&\r\n ctx.rule.children.length > 0\r\n if (!containerMode && !hasChildren && props.spinning) {\r\n // 独立模式下如果没有内容,不建议显示加载状态\r\n // 但这里不强制修改,让用户自己控制\r\n }\r\n\r\n // 支持从多个位置读取配置\r\n const bindField =\r\n ctx.rule.bindField ||\r\n ctx.rule.props?.bindField ||\r\n ctx.prop.props?.bindField\r\n let bindMode =\r\n ctx.rule.bindMode || ctx.rule.props?.bindMode || ctx.prop.props?.bindMode\r\n\r\n // 如果没有设置 bindMode,根据是否有 bindField 自动判断\r\n if (!bindMode) {\r\n if (bindField) {\r\n bindMode = 'field'\r\n } else {\r\n bindMode = 'static'\r\n }\r\n }\r\n\r\n // 如果配置了 bindField(绑定单个字段),使用 loadData 来实现动态绑定\r\n if (bindMode === 'field' && bindField) {\r\n const loadDataConfig = {\r\n attr: bindField,\r\n to: 'props.spinning',\r\n modify: true,\r\n wait: 300,\r\n watch: true\r\n }\r\n\r\n // 添加到 effect 中(避免重复添加)\r\n if (!ctx.rule.effect) {\r\n ctx.rule.effect = {}\r\n }\r\n if (!ctx.rule.effect.loadData) {\r\n ctx.rule.effect.loadData = []\r\n }\r\n // 检查是否已存在相同的配置,避免重复添加\r\n const exists = ctx.rule.effect.loadData.some(\r\n (item) => item.attr === bindField && item.to === 'props.spinning'\r\n )\r\n if (!exists) {\r\n ctx.rule.effect.loadData.push(loadDataConfig)\r\n // 手动触发 effect 来确保 loadData provider 被调用\r\n if (ctx.$handle && ctx.$handle.effect) {\r\n ctx.$handle.effect(ctx, 'loaded')\r\n }\r\n }\r\n }\r\n\r\n // 只在容器模式下处理 children\r\n if (containerMode) {\r\n // 确保 children 存在\r\n if (!ctx.rule.children) {\r\n ctx.rule.children = []\r\n }\r\n\r\n // 确保子组件不被 a-col 包装\r\n if (ctx.rule.children && Array.isArray(ctx.rule.children)) {\r\n ctx.rule.children.forEach((child) => {\r\n if (\r\n child &&\r\n typeof child === 'object' &&\r\n child.type !== 'DragTool' &&\r\n child.type !== 'DragBox'\r\n ) {\r\n // 只有当 col 未设置或为默认值时才设置\r\n if (child.col === undefined || child.col === null) {\r\n child.col = false\r\n } else if (\r\n child.col &&\r\n typeof child.col === 'object' &&\r\n child.col.show !== false\r\n ) {\r\n child.col.show = false\r\n }\r\n }\r\n })\r\n }\r\n }\r\n },\r\n render(children, ctx) {\r\n // 获取 spinning 状态\r\n const props = ctx.prop.props || {}\r\n const spinning = props.spinning || false\r\n\r\n // 设置组件类型为 a-spin\r\n if (!ctx.prop.props) {\r\n ctx.prop.props = {}\r\n }\r\n\r\n // 映射 props\r\n ctx.prop.props.spinning = spinning\r\n\r\n // 如果有 tip,设置 tip prop\r\n const tip = ctx.rule.tip || ctx.rule.props?.tip || ctx.prop.props?.tip\r\n if (tip) {\r\n ctx.prop.props.tip = tip\r\n }\r\n\r\n // 如果有 delay,设置 delay prop\r\n const delay =\r\n ctx.rule.delay || ctx.rule.props?.delay || ctx.prop.props?.delay\r\n if (delay != null) {\r\n ctx.prop.props.delay = delay\r\n }\r\n\r\n // 如果有 size,设置 size prop\r\n const size = ctx.rule.size || ctx.rule.props?.size || ctx.prop.props?.size\r\n if (size) {\r\n ctx.prop.props.size = size\r\n }\r\n\r\n // 设置类型为 a-spin\r\n if (ctx.prop.type === 'spin') {\r\n ctx.prop.type = 'a-spin'\r\n }\r\n\r\n // 读取 containerMode 配置\r\n const containerMode =\r\n ctx.rule.containerMode ??\r\n ctx.rule.props?.containerMode ??\r\n ctx.prop.props?.containerMode ??\r\n true\r\n\r\n // 如果不是容器模式,不渲染 children,直接使用 defaultRender\r\n if (!containerMode) {\r\n return ctx.$render.defaultRender(ctx, undefined)\r\n }\r\n\r\n // 容器模式:使用传入的 children 参数\r\n // children 参数已经是渲染好的 vnodes,直接传递给 a-spin\r\n const childrenNodes =\r\n children && Array.isArray(children) ? children : children || []\r\n\r\n // 将 spin 容器包装在 col 中,确保它占满整行(span: 24)\r\n // 直接使用 vNode.make 来渲染 a-spin,并传入 childrenNodes(类似 flex 组件的处理方式)\r\n return ctx.vNode.col(\r\n { props: { span: 24 } },\r\n {\r\n default: () => [ctx.vNode.make('a-spin', ctx.prop, childrenNodes)]\r\n }\r\n )\r\n }\r\n}\r\n","const PRE = 'a'\nexport default {\n tooltip: PRE + 'Tooltip',\n popover: PRE + 'Popover',\n button: PRE + 'Button',\n icon: PRE + 'Icon',\n slider: PRE + 'Slider',\n rate: PRE + 'Rate',\n upload: 'fcUpload',\n cascader: PRE + 'Cascader',\n timePicker: PRE + 'TimePicker',\n timeRangePicker: PRE + 'TimeRangePicker',\n datePicker: PRE + 'DatePicker',\n rangePicker: PRE + 'RangePicker',\n switch: PRE + 'Switch',\n select: PRE + 'Select',\n checkbox: PRE + 'CheckboxGroup',\n radio: PRE + 'RadioGroup',\n input: PRE + 'Input',\n inputNumber: PRE + 'InputNumber',\n treeSelect: PRE + 'TreeSelect',\n search: PRE + 'InputSearch',\n inputPassword: PRE + 'InputPassword',\n textarea: PRE + 'Textarea',\n formItem: PRE + 'FormItem',\n form: PRE + 'Form',\n frame: 'fcFrame',\n col: PRE + 'Col',\n row: PRE + 'Row',\n flex: PRE + 'Flex',\n space: PRE + 'Space',\n 'space-compact': PRE + 'SpaceCompact',\n spin: PRE + 'Spin',\n tree: PRE + 'Tree',\n autoComplete: PRE + 'AutoComplete',\n transfer: PRE + 'Transfer',\n group: 'fcGroup',\n array: 'fcGroup',\n subForm: 'fcSubForm',\n object: 'fcSubForm',\n image: PRE + 'Image',\n aImage: PRE + 'Image'\n}\n","import getConfig from './config'\r\nimport mergeProps from '@form-create/utils/lib/mergeprops'\r\nimport is, { hasProperty } from '@form-create/utils/lib/type'\r\nimport extend from '@form-create/utils/lib/extend'\r\n\r\nfunction isTooltip(info) {\r\n return info.type === 'tooltip'\r\n}\r\n\r\nfunction tidy(props, name) {\r\n if (!hasProperty(props, name)) return\r\n if (is.String(props[name])) {\r\n props[name] = { [name]: props[name], show: true }\r\n }\r\n}\r\n\r\nfunction isFalse(val) {\r\n return val === false\r\n}\r\n\r\nfunction tidyBool(opt, name) {\r\n if (hasProperty(opt, name) && !is.Object(opt[name])) {\r\n opt[name] = { show: !!opt[name] }\r\n }\r\n}\r\n\r\nfunction tidyRule(rule) {\r\n const _rule = { ...rule }\r\n delete _rule.children\r\n return _rule\r\n}\r\n\r\nexport default {\r\n validate() {\r\n const form = this.form()\r\n if (form) {\r\n return form.validate()\r\n } else {\r\n return new Promise((v) => v())\r\n }\r\n },\r\n validateField(field) {\r\n const form = this.form()\r\n if (form) {\r\n return form.validateFields(field)\r\n } else {\r\n return new Promise((v) => v())\r\n }\r\n },\r\n clearValidateState(ctx) {\r\n const fItem = this.vm.refs[ctx.wrapRef]\r\n if (fItem) {\r\n fItem.clearValidate()\r\n }\r\n },\r\n tidyOptions(options) {\r\n ;['submitBtn', 'resetBtn', 'row', 'info', 'wrap', 'col', 'title'].forEach(\r\n (name) => {\r\n tidyBool(options, name)\r\n }\r\n )\r\n return options\r\n },\r\n tidyRule({ prop }) {\r\n tidy(prop, 'title')\r\n tidy(prop, 'info')\r\n return prop\r\n },\r\n mergeProp(ctx) {\r\n const def = {\r\n info: {\r\n type: 'popover',\r\n placement: 'topLeft',\r\n icon: 'QuestionCircleOutlined'\r\n },\r\n title: {},\r\n col: { span: 24 },\r\n wrap: {}\r\n }\r\n ;['info', 'wrap', 'col', 'title'].forEach((name) => {\r\n ctx.prop[name] = mergeProps(\r\n [this.options[name] || {}, ctx.prop[name] || {}],\r\n def[name]\r\n )\r\n })\r\n\r\n // 检查父容器是否是 flex 或 space 类型,如果是,自动设置 col: false 避免被 a-col 包装\r\n // 需要在合并完 col 后再检查,确保能覆盖默认值\r\n if (ctx.parent && ctx.parent.rule) {\r\n const parentType = ctx.parent.rule.type\r\n const parentMenu = ctx.parent.rule._menu\r\n if (\r\n parentType === 'flex' ||\r\n parentType === 'a-flex' ||\r\n parentMenu?.name === 'flex' ||\r\n parentType === 'space' ||\r\n parentType === 'a-space' ||\r\n parentMenu?.name === 'space'\r\n ) {\r\n // 如果父容器是 flex 或 space,强制设置 col 为 false,禁用 col 包装\r\n ctx.prop.col = false\r\n // 同时设置 rule.col 以确保在 makeWrap 中也能识别\r\n if (ctx.rule) {\r\n ctx.rule.col = false\r\n }\r\n }\r\n }\r\n\r\n // 为 upload 组件自动添加 onPreview,确保始终向父窗口发送预览通知\r\n if (ctx.rule.type === 'upload' && !ctx.prop.props.onPreview) {\r\n const sendPreviewMessage = function (file) {\r\n if (window.parent && window.parent !== window) {\r\n window.parent.postMessage(\r\n {\r\n type: 'upload-preview',\r\n file: {\r\n url: file.url,\r\n name: file.name,\r\n uid: file.uid,\r\n size: file.size,\r\n type: file.type\r\n },\r\n timestamp: Date.now()\r\n },\r\n '*'\r\n )\r\n }\r\n }\r\n ctx.prop.props.onPreview = function (file) {\r\n sendPreviewMessage(file)\r\n // 不执行默认预览,只发送消息\r\n }\r\n } else if (ctx.rule.type === 'upload' && ctx.prop.props.onPreview) {\r\n // 如果用户已经设置了 onPreview,包装它以确保先发送消息\r\n const originalOnPreview = ctx.prop.props.onPreview\r\n const sendPreviewMessage = function (file) {\r\n if (window.parent && window.parent !== window) {\r\n window.parent.postMessage(\r\n {\r\n type: 'upload-preview',\r\n file: {\r\n url: file.url,\r\n name: file.name,\r\n uid: file.uid,\r\n size: file.size,\r\n type: file.type\r\n },\r\n timestamp: Date.now()\r\n },\r\n '*'\r\n )\r\n }\r\n }\r\n ctx.prop.props.onPreview = function (file) {\r\n sendPreviewMessage(file)\r\n if (originalOnPreview && typeof originalOnPreview === 'function') {\r\n originalOnPreview.apply(this, arguments)\r\n }\r\n }\r\n }\r\n\r\n // 为 aImage 组件自动添加预览拦截,确保始终向父窗口发送预览通知\r\n if (\r\n (ctx.rule.type === 'image' || ctx.rule.type === 'aImage') &&\r\n !ctx.prop.props.preview\r\n ) {\r\n const sendImagePreviewMessage = function (src) {\r\n if (window.parent && window.parent !== window) {\r\n window.parent.postMessage(\r\n {\r\n type: 'upload-preview',\r\n file: {\r\n url: src || ctx.prop.props.src || ''\r\n },\r\n timestamp: Date.now()\r\n },\r\n '*'\r\n )\r\n }\r\n }\r\n\r\n // 拦截 Image 组件的预览,发送消息给父窗口并阻止默认预览\r\n const imageSrc = ctx.prop.props.src || ''\r\n ctx.prop.props.preview = {\r\n visible: false,\r\n src: imageSrc,\r\n onVisibleChange: (visible, prevVisible) => {\r\n if (visible && !prevVisible) {\r\n // 发送预览通知给父窗口\r\n sendImagePreviewMessage(imageSrc)\r\n // 返回 false 阻止默认预览显示\r\n return false\r\n }\r\n }\r\n }\r\n } else if (\r\n (ctx.rule.type === 'image' || ctx.rule.type === 'aImage') &&\r\n ctx.prop.props.preview\r\n ) {\r\n // 如果用户已经设置了 preview,包装它以确保先发送消息\r\n const originalPreview = ctx.prop.props.preview\r\n const sendImagePreviewMessage = function (src) {\r\n if (window.parent && window.parent !== window) {\r\n window.parent.postMessage(\r\n {\r\n type: 'upload-preview',\r\n file: {\r\n url: src || ctx.prop.props.src || ''\r\n },\r\n timestamp: Date.now()\r\n },\r\n '*'\r\n )\r\n }\r\n }\r\n\r\n const imageSrc = ctx.prop.props.src || ''\r\n const originalOnVisibleChange = originalPreview?.onVisibleChange\r\n\r\n ctx.prop.props.preview = {\r\n ...originalPreview,\r\n visible: originalPreview.visible || false,\r\n src: originalPreview.src || imageSrc,\r\n onVisibleChange: (visible, prevVisible) => {\r\n if (visible && !prevVisible) {\r\n // 先发送消息给父窗口\r\n sendImagePreviewMessage(originalPreview.src || imageSrc)\r\n }\r\n // 执行用户自定义的 onVisibleChange\r\n if (\r\n originalOnVisibleChange &&\r\n typeof originalOnVisibleChange === 'function'\r\n ) {\r\n return originalOnVisibleChange.apply(this, arguments)\r\n }\r\n // 默认阻止预览显示\r\n return false\r\n }\r\n }\r\n }\r\n },\r\n getDefaultOptions() {\r\n return getConfig()\r\n },\r\n adapterValidate(validate, validator) {\r\n validate.validator = (rule, value) => {\r\n return new Promise((resolve, reject) => {\r\n const callback = (err) => {\r\n if (err) {\r\n reject(err)\r\n } else {\r\n resolve()\r\n }\r\n }\r\n return validator(value, callback)\r\n })\r\n }\r\n return validate\r\n },\r\n update() {\r\n const form = this.options.form\r\n this.rule = {\r\n props: { ...form },\r\n on: {\r\n submit: (e) => {\r\n e.preventDefault()\r\n }\r\n },\r\n style: form.style,\r\n type: 'form'\r\n }\r\n },\r\n beforeRender() {\r\n const { key, ref, $handle } = this\r\n const form = this.options.form\r\n extend(this.rule, {\r\n key,\r\n ref,\r\n class: [\r\n form.className,\r\n form.class,\r\n 'form-create',\r\n this.$handle.preview ? 'is-preview' : ''\r\n ]\r\n })\r\n extend(this.rule.props, {\r\n model: $handle.formData\r\n })\r\n },\r\n render(children) {\r\n if (children.slotLen() && !this.$handle.preview) {\r\n children.setSlot(undefined, () => this.makeFormBtn())\r\n }\r\n return this.$r(\r\n this.rule,\r\n isFalse(this.options.row.show)\r\n ? children.getSlots()\r\n : [this.makeRow(children)]\r\n )\r\n },\r\n makeWrap(ctx, children) {\r\n const rule = ctx.prop\r\n const uni = `${this.key}${ctx.key}`\r\n const col = rule.col\r\n const isTitle = this.isTitle(rule) && rule.wrap.title !== false\r\n const { layout, col: _col } = this.rule.props\r\n const cls = rule.wrap.class\r\n delete rule.wrap.class\r\n delete rule.wrap.title\r\n\r\n // 检查父容器是否是 flex 或 space 类型,如果是,强制禁用 col 包装\r\n let shouldDisableCol = false\r\n if (ctx.parent && ctx.parent.rule) {\r\n const parentType = ctx.parent.rule.type\r\n const parentMenu = ctx.parent.rule._menu\r\n if (\r\n parentType === 'flex' ||\r\n parentType === 'a-flex' ||\r\n parentMenu?.name === 'flex' ||\r\n parentType === 'space' ||\r\n parentType === 'a-space' ||\r\n parentMenu?.name === 'space'\r\n ) {\r\n shouldDisableCol = true\r\n }\r\n }\r\n\r\n const item = isFalse(rule.wrap.show)\r\n ? children\r\n : this.$r(\r\n mergeProps([\r\n rule.wrap,\r\n {\r\n props: {\r\n ...tidyRule(rule.wrap || {}),\r\n hasFeedback: rule.hasFeedback || false,\r\n name: ctx.id,\r\n rules: ctx.injectValidate(),\r\n ...(layout !== 'horizontal'\r\n ? { labelCol: {}, wrapperCol: {} }\r\n : {})\r\n },\r\n class: this.$render.mergeClass(\r\n cls || rule.className,\r\n 'fc-form-item'\r\n ),\r\n key: `${uni}fi`,\r\n ref: ctx.wrapRef,\r\n type: 'formItem'\r\n }\r\n ]),\r\n {\r\n default: () => children,\r\n ...(isTitle ? { label: () => this.makeInfo(rule, uni, ctx) } : {})\r\n }\r\n )\r\n // 如果父容器是 flex,或者 layout 是 inline,或者 col 被显式禁用,则不使用 col 包装\r\n return layout === 'inline' ||\r\n isFalse(_col) ||\r\n isFalse(col.show) ||\r\n shouldDisableCol\r\n ? item\r\n : this.makeCol(rule, uni, [item])\r\n },\r\n isTitle(rule) {\r\n if (this.options.form.title === false) return false\r\n const title = rule.title\r\n return !((!title.title && !title.native) || isFalse(title.show))\r\n },\r\n makeInfo(rule, uni, ctx) {\r\n const titleProp = { ...rule.title }\r\n const infoProp = { ...rule.info }\r\n if (this.options.form.title === false) return false\r\n if ((!titleProp.title && !titleProp.native) || isFalse(titleProp.show))\r\n return\r\n const isTip = isTooltip(infoProp)\r\n const titleSlot = this.getSlot('title')\r\n const children = [\r\n titleSlot\r\n ? titleSlot({\r\n title: ctx.refRule?.__$title?.value,\r\n rule: ctx.rule,\r\n options: this.options\r\n })\r\n : ctx.refRule?.__$title?.value\r\n ]\r\n\r\n if (\r\n !isFalse(infoProp.show) &&\r\n (infoProp.info || infoProp.native) &&\r\n !isFalse(infoProp.icon)\r\n ) {\r\n const prop = {\r\n type: infoProp.type || 'popover',\r\n props: tidyRule(infoProp),\r\n key: `${uni}pop`\r\n }\r\n\r\n delete prop.props.icon\r\n delete prop.props.show\r\n delete prop.props.info\r\n delete prop.props.align\r\n delete prop.props.native\r\n\r\n const field = isTip ? 'title' : 'content'\r\n if (infoProp.info && !hasProperty(prop.props, field)) {\r\n prop.props[field] = ctx.refRule?.__$info?.value\r\n }\r\n children[infoProp.align !== 'left' ? 'unshift' : 'push'](\r\n this.$r(mergeProps([infoProp, prop]), {\r\n [titleProp.slot || 'default']: () =>\r\n this.$r({\r\n type:\r\n infoProp.icon === true\r\n ? 'QuestionCircleOutlined'\r\n : infoProp.icon || '',\r\n props: {\r\n type:\r\n infoProp.icon === true\r\n ? 'QuestionCircleOutlined'\r\n : infoProp.icon\r\n },\r\n key: `${uni}i`\r\n })\r\n })\r\n )\r\n }\r\n\r\n const _prop = mergeProps([\r\n titleProp,\r\n {\r\n props: tidyRule(titleProp),\r\n key: `${uni}tit`,\r\n class: 'fc-form-title',\r\n type: titleProp.type || 'span'\r\n }\r\n ])\r\n\r\n delete _prop.props.show\r\n delete _prop.props.title\r\n delete _prop.props.native\r\n\r\n return this.$r(_prop, children)\r\n },\r\n makeCol(rule, uni, children) {\r\n const col = rule.col\r\n return this.$r(\r\n {\r\n class: this.$render.mergeClass(col.class, 'fc-form-col'),\r\n type: 'col',\r\n props: col || { span: 24 },\r\n key: `${uni}col`\r\n },\r\n children\r\n )\r\n },\r\n makeRow(children) {\r\n const row = this.options.row || {}\r\n return this.$r(\r\n {\r\n type: 'row',\r\n props: row,\r\n class: this.$render.mergeClass(row.class, 'fc-form-row'),\r\n key: `${this.key}row`\r\n },\r\n children\r\n )\r\n },\r\n makeFormBtn() {\r\n let vn = []\r\n if (!isFalse(this.options.submitBtn.show)) {\r\n vn.push(this.makeSubmitBtn())\r\n }\r\n if (!isFalse(this.options.resetBtn.show)) {\r\n vn.push(this.makeResetBtn())\r\n }\r\n if (!vn.length) {\r\n return\r\n }\r\n let { labelCol, wrapperCol, layout } = this.rule.props\r\n if (layout !== 'horizontal') {\r\n labelCol = wrapperCol = {}\r\n }\r\n const item = this.$r(\r\n {\r\n type: 'formItem',\r\n class: 'fc-form-item fc-form-footer',\r\n key: `${this.key}fb`,\r\n props: {\r\n labelCol,\r\n wrapperCol,\r\n label: ' ',\r\n colon: false\r\n }\r\n },\r\n vn\r\n )\r\n\r\n return layout === 'inline'\r\n ? item\r\n : this.$r(\r\n {\r\n type: 'col',\r\n class: 'fc-form-col',\r\n props: { span: 24 },\r\n key: `${this.key}fc`\r\n },\r\n [item]\r\n )\r\n },\r\n\r\n makeResetBtn() {\r\n const resetBtn = { ...this.options.resetBtn }\r\n const innerText =\r\n resetBtn.innerText || this.$handle.api.t('reset') || '重置'\r\n delete resetBtn.innerText\r\n delete resetBtn.click\r\n delete resetBtn.col\r\n delete resetBtn.show\r\n return this.$r(\r\n {\r\n type: 'button',\r\n props: resetBtn,\r\n class: 'fc-reset-btn',\r\n style: { width: resetBtn.width, marginLeft: '10px' },\r\n on: {\r\n click: () => {\r\n const fApi = this.$handle.api\r\n this.options.resetBtn.click\r\n ? this.options.resetBtn.click(fApi)\r\n : fApi.resetFields()\r\n }\r\n },\r\n key: `${this.key}b2`\r\n },\r\n [innerText]\r\n )\r\n },\r\n makeSubmitBtn() {\r\n const submitBtn = { ...this.options.submitBtn }\r\n const innerText =\r\n submitBtn.innerText || this.$handle.api.t('submit') || '提交'\r\n delete submitBtn.innerText\r\n delete submitBtn.click\r\n delete submitBtn.col\r\n delete submitBtn.show\r\n return this.$r(\r\n {\r\n type: 'button',\r\n props: submitBtn,\r\n class: 'fc-submit-btn',\r\n style: { width: submitBtn.width },\r\n on: {\r\n click: () => {\r\n const fApi = this.$handle.api\r\n this.options.submitBtn.click\r\n ? this.options.submitBtn.click(fApi)\r\n : fApi.submit().catch(() => {})\r\n }\r\n },\r\n key: `${this.key}b1`\r\n },\r\n [innerText]\r\n )\r\n }\r\n}\r\n","const UNDEF = undefined\n\nexport default function getConfig() {\n return {\n form: {\n hideRequiredMark: false,\n layout: 'horizontal',\n labelAlign: 'right',\n labelCol: {\n span: 3\n },\n wrapperCol: {\n span: 21\n },\n validateOnRuleChange: true\n },\n row: {\n gutter: 0\n },\n submitBtn: {\n disabled: false,\n loading: false,\n type: 'primary',\n innerText: '',\n show: false,\n col: UNDEF,\n click: UNDEF\n },\n resetBtn: {\n disabled: false,\n loading: false,\n type: 'default',\n innerText: '',\n show: false,\n col: UNDEF,\n click: UNDEF\n }\n }\n}\n","import { creatorFactory } from '@longhongguo/form-create-core/src/index'\n\nconst maker = {}\n\nfunction useAlias(maker) {\n ;[\n 'treeSelect',\n 'upload',\n 'frame',\n 'autoComplete',\n 'cascader',\n 'datePicker',\n 'frame',\n 'inputNumber',\n 'inputPassword',\n 'radio',\n 'rate',\n 'switch',\n 'rate',\n 'slider',\n 'timePicker'\n ].reduce((maker, name) => {\n maker[name] = creatorFactory(name)\n return maker\n }, maker)\n maker.auto = maker.autoComplete\n maker.number = maker.inputNumber\n maker.time = maker.timePicker\n maker.password = maker.inputPassword\n}\n\nfunction useFrame(maker) {\n const types = {\n frameInputs: ['input', 0],\n frameFiles: ['file', 0],\n frameImages: ['image', 0],\n frameInputOne: ['input', 1],\n frameFileOne: ['file', 1],\n frameImageOne: ['image', 1]\n }\n\n Object.keys(types).reduce((maker, key) => {\n maker[key] = creatorFactory('frame', (m) =>\n m.props({ type: types[key][0], maxLength: types[key][1] })\n )\n return maker\n }, maker)\n\n maker.frameInput = maker.frameInputs\n maker.frameFile = maker.frameFiles\n maker.frameImage = maker.frameImages\n}\n\nfunction useSlider(maker) {\n maker['sliderRange'] = creatorFactory('slider', { range: true })\n}\n\nfunction useSelect(m) {\n const name = 'select'\n m.selectMultiple = creatorFactory(name, { mode: 'multiple' })\n m.selectTags = creatorFactory(name, { mode: 'tags' })\n m.selectCombobox = creatorFactory(name, { mode: 'combobox' })\n}\n\nfunction useUpload(maker) {\n const types = {\n image: ['image', 0],\n file: ['file', 0],\n uploadFileOne: ['file', 1],\n uploadImageOne: ['image', 1]\n }\n\n Object.keys(types).reduce((maker, key) => {\n maker[key] = creatorFactory('upload', (m) =>\n m.props({\n uploadType: types[key][0],\n maxLength: types[key][1]\n })\n )\n return maker\n }, maker)\n\n maker.uploadImage = maker.image\n maker.uploadFile = maker.file\n}\n\nfunction useCusStoreSelect(maker) {\n maker.cusStoreSelect = creatorFactory('cusStoreSelect')\n maker.storeSelect = maker.cusStoreSelect\n}\n\nfunction useCusUserSelect(maker) {\n maker.cusUserSelect = creatorFactory('cusUserSelect')\n maker.userSelect = maker.cusUserSelect\n}\n\nfunction useText(maker) {\n maker.text = creatorFactory('text')\n}\n\nfunction useFlex(maker) {\n maker.flex = creatorFactory('flex')\n}\n\nfunction useSpace(maker) {\n maker.space = creatorFactory('space')\n}\n\nfunction useSpin(maker) {\n maker.spin = creatorFactory('spin')\n}\n\nuseAlias(maker)\nuseSlider(maker)\nuseFrame(maker)\nuseUpload(maker)\nuseSelect(maker)\nuseCusStoreSelect(maker)\nuseCusUserSelect(maker)\nuseText(maker)\nuseFlex(maker)\nuseSpace(maker)\nuseSpin(maker)\n\nexport default maker\n","/**\r\n * 常用校验工具类\r\n * 提供各种日常校验方法\r\n */\r\nclass Validator {\r\n /**\r\n * 校验手机号(中国大陆)\r\n * @param {string} value - 要校验的值\r\n * @param {boolean} strict - 是否严格模式(11位,1开头),默认 true\r\n * @returns {boolean} 校验结果\r\n */\r\n mobile(value, strict = false) {\r\n if (!value) return false\r\n const str = String(value).trim()\r\n if (strict) {\r\n // 严格模式:11位,1开头,第二位为3-9\r\n return /^1[3-9]\\d{9}$/.test(str)\r\n } else {\r\n // 宽松模式:1开头,10-11位数字\r\n return /^1\\d{10,11}$/.test(str)\r\n }\r\n }\r\n\r\n /**\r\n * 校验邮箱\r\n * @param {string} value - 要校验的值\r\n * @returns {boolean} 校验结果\r\n */\r\n email(value) {\r\n if (!value) return false\r\n const str = String(value).trim()\r\n // 邮箱正则:支持常见邮箱格式\r\n return /^[a-zA-Z0-9.!#$%&'*+\\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/.test(\r\n str\r\n )\r\n }\r\n\r\n /**\r\n * 校验身份证号(中国大陆18位)\r\n * @param {string} value - 要校验的值\r\n * @param {boolean} checkCode - 是否校验校验码,默认 true\r\n * @returns {boolean} 校验结果\r\n */\r\n idCard(value, checkCode = true) {\r\n if (!value) return false\r\n const str = String(value).trim().toUpperCase()\r\n\r\n // 基本格式校验:18位,前17位数字,最后一位数字或X\r\n if (!/^\\d{17}[\\dX]$/.test(str)) {\r\n return false\r\n }\r\n\r\n if (!checkCode) {\r\n return true\r\n }\r\n\r\n // 校验码校验\r\n const weights = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]\r\n const checkCodes = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2']\r\n\r\n let sum = 0\r\n for (let i = 0; i < 17; i++) {\r\n sum += parseInt(str[i]) * weights[i]\r\n }\r\n const checkCodeIndex = sum % 11\r\n return str[17] === checkCodes[checkCodeIndex]\r\n }\r\n\r\n /**\r\n * 校验URL\r\n * @param {string} value - 要校验的值\r\n * @param {object} options - 选项\r\n * @param {boolean} options.requireProtocol - 是否要求协议(http/https),默认 false\r\n * @returns {boolean} 校验结果\r\n */\r\n url(value, options = {}) {\r\n if (!value) return false\r\n const str = String(value).trim()\r\n const { requireProtocol = false } = options\r\n\r\n if (requireProtocol) {\r\n return /^https?:\\/\\/.+\\..+/.test(str)\r\n } else {\r\n // 支持带协议或不带协议\r\n return /^(https?:\\/\\/)?([\\da-z\\.-]+)\\.([a-z\\.]{2,6})([\\/\\w \\.-]*)*\\/?$/.test(\r\n str\r\n )\r\n }\r\n }\r\n\r\n /**\r\n * 校验IP地址(IPv4)\r\n * @param {string} value - 要校验的值\r\n * @returns {boolean} 校验结果\r\n */\r\n ip(value) {\r\n if (!value) return false\r\n const str = String(value).trim()\r\n const parts = str.split('.')\r\n if (parts.length !== 4) return false\r\n return parts.every((part) => {\r\n const num = parseInt(part, 10)\r\n return num >= 0 && num <= 255 && String(num) === part\r\n })\r\n }\r\n\r\n /**\r\n * 校验数字\r\n * @param {string|number} value - 要校验的值\r\n * @param {object} options - 选项\r\n * @param {boolean} options.integer - 是否必须为整数,默认 false\r\n * @param {boolean} options.positive - 是否必须为正数,默认 false\r\n * @param {boolean} options.negative - 是否必须为负数,默认 false\r\n * @param {number} options.min - 最小值\r\n * @param {number} options.max - 最大值\r\n * @returns {boolean} 校验结果\r\n */\r\n number(value, options = {}) {\r\n if (value === null || value === undefined || value === '') return false\r\n const num = Number(value)\r\n if (isNaN(num)) return false\r\n\r\n const {\r\n integer = false,\r\n positive = false,\r\n negative = false,\r\n min,\r\n max\r\n } = options\r\n\r\n if (integer && !Number.isInteger(num)) return false\r\n if (positive && num <= 0) return false\r\n if (negative && num >= 0) return false\r\n if (min !== undefined && num < min) return false\r\n if (max !== undefined && num > max) return false\r\n\r\n return true\r\n }\r\n\r\n /**\r\n * 校验字符串长度\r\n * @param {string} value - 要校验的值\r\n * @param {object} options - 选项\r\n * @param {number} options.min - 最小长度\r\n * @param {number} options.max - 最大长度\r\n * @param {number} options.len - 固定长度(优先级高于 min/max)\r\n * @returns {boolean} 校验结果\r\n */\r\n length(value, options = {}) {\r\n if (value === null || value === undefined) return false\r\n const str = String(value)\r\n const { min, max, len } = options\r\n\r\n if (len !== undefined) {\r\n return str.length === len\r\n }\r\n\r\n if (min !== undefined && str.length < min) return false\r\n if (max !== undefined && str.length > max) return false\r\n\r\n return true\r\n }\r\n\r\n /**\r\n * 校验正则表达式\r\n * @param {string} value - 要校验的值\r\n * @param {RegExp|string} pattern - 正则表达式或正则字符串\r\n * @returns {boolean} 校验结果\r\n */\r\n pattern(value, pattern) {\r\n if (!value || !pattern) return false\r\n const str = String(value)\r\n let regex\r\n if (pattern instanceof RegExp) {\r\n regex = pattern\r\n } else {\r\n try {\r\n regex = new RegExp(pattern)\r\n } catch (e) {\r\n return false\r\n }\r\n }\r\n return regex.test(str)\r\n }\r\n\r\n /**\r\n * 校验日期\r\n * @param {string|Date} value - 要校验的值\r\n * @param {object} options - 选项\r\n * @param {string|Date} options.min - 最小日期\r\n * @param {string|Date} options.max - 最大日期\r\n * @param {string} options.format - 日期格式,如 'YYYY-MM-DD',默认自动识别\r\n * @returns {boolean} 校验结果\r\n */\r\n date(value, options = {}) {\r\n if (!value) return false\r\n let date\r\n if (value instanceof Date) {\r\n date = value\r\n } else {\r\n date = new Date(value)\r\n if (isNaN(date.getTime())) return false\r\n }\r\n\r\n const { min, max } = options\r\n if (min) {\r\n const minDate = min instanceof Date ? min : new Date(min)\r\n if (date < minDate) return false\r\n }\r\n if (max) {\r\n const maxDate = max instanceof Date ? max : new Date(max)\r\n if (date > maxDate) return false\r\n }\r\n\r\n return true\r\n }\r\n\r\n /**\r\n * 校验是否为空\r\n * @param {*} value - 要校验的值\r\n * @param {boolean} trim - 是否去除空格,默认 true\r\n * @returns {boolean} 是否为空\r\n */\r\n empty(value, trim = true) {\r\n if (value === null || value === undefined) return true\r\n if (typeof value === 'string') {\r\n return trim ? value.trim() === '' : value === ''\r\n }\r\n if (Array.isArray(value)) {\r\n return value.length === 0\r\n }\r\n if (typeof value === 'object') {\r\n return Object.keys(value).length === 0\r\n }\r\n return false\r\n }\r\n\r\n /**\r\n * 校验是否不为空(empty 的反向)\r\n * @param {*} value - 要校验的值\r\n * @param {boolean} trim - 是否去除空格,默认 true\r\n * @returns {boolean} 是否不为空\r\n */\r\n notEmpty(value, trim = true) {\r\n return !this.empty(value, trim)\r\n }\r\n\r\n /**\r\n * 校验中文\r\n * @param {string} value - 要校验的值\r\n * @returns {boolean} 校验结果\r\n */\r\n chinese(value) {\r\n if (!value) return false\r\n return /^[\\u4e00-\\u9fa5]+$/.test(String(value))\r\n }\r\n\r\n /**\r\n * 校验字母\r\n * @param {string} value - 要校验的值\r\n * @param {boolean} caseSensitive - 是否区分大小写,默认 false(不区分)\r\n * @returns {boolean} 校验结果\r\n */\r\n alpha(value, caseSensitive = false) {\r\n if (!value) return false\r\n const str = String(value)\r\n if (caseSensitive) {\r\n return /^[a-zA-Z]+$/.test(str)\r\n } else {\r\n return /^[a-z]+$/i.test(str)\r\n }\r\n }\r\n\r\n /**\r\n * 校验字母和数字\r\n * @param {string} value - 要校验的值\r\n * @returns {boolean} 校验结果\r\n */\r\n alphanumeric(value) {\r\n if (!value) return false\r\n return /^[a-zA-Z0-9]+$/.test(String(value))\r\n }\r\n\r\n /**\r\n * 校验整数\r\n * @param {string|number} value - 要校验的值\r\n * @returns {boolean} 校验结果\r\n */\r\n integer(value) {\r\n return this.number(value, { integer: true })\r\n }\r\n\r\n /**\r\n * 校验正数\r\n * @param {string|number} value - 要校验的值\r\n * @returns {boolean} 校验结果\r\n */\r\n positive(value) {\r\n return this.number(value, { positive: true })\r\n }\r\n\r\n /**\r\n * 校验负数\r\n * @param {string|number} value - 要校验的值\r\n * @returns {boolean} 校验结果\r\n */\r\n negative(value) {\r\n return this.number(value, { negative: true })\r\n }\r\n\r\n /**\r\n * 校验银行卡号(中国大陆,16-19位)\r\n * @param {string} value - 要校验的值\r\n * @returns {boolean} 校验结果\r\n */\r\n bankCard(value) {\r\n if (!value) return false\r\n const str = String(value).replace(/\\s/g, '')\r\n // 银行卡号通常是16-19位数字\r\n return /^\\d{16,19}$/.test(str)\r\n }\r\n\r\n /**\r\n * 校验邮政编码(中国大陆,6位数字)\r\n * @param {string} value - 要校验的值\r\n * @returns {boolean} 校验结果\r\n */\r\n postcode(value) {\r\n if (!value) return false\r\n return /^\\d{6}$/.test(String(value).trim())\r\n }\r\n\r\n /**\r\n * 校验车牌号(中国大陆)\r\n * @param {string} value - 要校验的值\r\n * @returns {boolean} 校验结果\r\n */\r\n licensePlate(value) {\r\n if (!value) return false\r\n const str = String(value).trim().toUpperCase()\r\n // 支持普通车牌和新能源车牌\r\n return (\r\n /^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领][A-Z][A-Z0-9]{4,5}[A-Z0-9挂学警港澳]$/.test(\r\n str\r\n ) ||\r\n /^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领][A-Z]((\\d{5}[DF])|([DF][A-Z0-9]\\d{4}))$/.test(\r\n str\r\n )\r\n )\r\n }\r\n\r\n /**\r\n * 校验统一社会信用代码(18位)\r\n * @param {string} value - 要校验的值\r\n * @returns {boolean} 校验结果\r\n */\r\n creditCode(value) {\r\n if (!value) return false\r\n const str = String(value).trim().toUpperCase()\r\n // 统一社会信用代码:18位,字母数字组合\r\n return /^[0-9A-HJ-NPQRTUWXY]{2}\\d{6}[0-9A-HJ-NPQRTUWXY]{10}$/.test(str)\r\n }\r\n\r\n /**\r\n * 校验值是否在指定范围内\r\n * @param {*} value - 要校验的值\r\n * @param {Array} enumList - 允许的值列表\r\n * @returns {boolean} 校验结果\r\n */\r\n enum(value, enumList) {\r\n if (!Array.isArray(enumList) || enumList.length === 0) return false\r\n return enumList.includes(value)\r\n }\r\n\r\n /**\r\n * 校验值是否相等\r\n * @param {*} value1 - 第一个值\r\n * @param {*} value2 - 第二个值\r\n * @param {boolean} strict - 是否严格相等(===),默认 true\r\n * @returns {boolean} 校验结果\r\n */\r\n equal(value1, value2, strict = false) {\r\n if (strict) {\r\n return value1 === value2\r\n } else {\r\n return value1 == value2 // eslint-disable-line eqeqeq\r\n }\r\n }\r\n\r\n /**\r\n * 校验值是否不相等\r\n * @param {*} value1 - 第一个值\r\n * @param {*} value2 - 第二个值\r\n * @param {boolean} strict - 是否严格相等(===),默认 true\r\n * @returns {boolean} 校验结果\r\n */\r\n notEqual(value1, value2, strict = true) {\r\n return !this.equal(value1, value2, strict)\r\n }\r\n\r\n /**\r\n * 校验是否全为大写\r\n * @param {string} value - 要校验的值\r\n * @returns {boolean} 校验结果\r\n */\r\n uppercase(value) {\r\n if (!value) return false\r\n const str = String(value)\r\n return str === str.toUpperCase() && /[A-Z]/.test(str)\r\n }\r\n\r\n /**\r\n * 校验是否全为小写\r\n * @param {string} value - 要校验的值\r\n * @returns {boolean} 校验结果\r\n */\r\n lowercase(value) {\r\n if (!value) return false\r\n const str = String(value)\r\n return str === str.toLowerCase() && /[a-z]/.test(str)\r\n }\r\n\r\n /**\r\n * 校验用户名(字母、数字、下划线,3-20位)\r\n * @param {string} value - 要校验的值\r\n * @param {object} options - 选项\r\n * @param {number} options.min - 最小长度,默认 3\r\n * @param {number} options.max - 最大长度,默认 20\r\n * @returns {boolean} 校验结果\r\n */\r\n username(value, options = {}) {\r\n if (!value) return false\r\n const str = String(value).trim()\r\n const { min = 3, max = 20 } = options\r\n if (str.length < min || str.length > max) return false\r\n return /^[a-zA-Z0-9_]+$/.test(str)\r\n }\r\n\r\n /**\r\n * 校验密码强度\r\n * @param {string} value - 要校验的值\r\n * @param {object} options - 选项\r\n * @param {number} options.min - 最小长度,默认 6\r\n * @param {number} options.max - 最大长度,默认 20\r\n * @param {boolean} options.requireNumber - 是否必须包含数字,默认 false\r\n * @param {boolean} options.requireLetter - 是否必须包含字母,默认 false\r\n * @param {boolean} options.requireSpecial - 是否必须包含特殊字符,默认 false\r\n * @returns {boolean} 校验结果\r\n */\r\n password(value, options = {}) {\r\n if (!value) return false\r\n const str = String(value)\r\n const {\r\n min = 6,\r\n max = 20,\r\n requireNumber = false,\r\n requireLetter = false,\r\n requireSpecial = false\r\n } = options\r\n\r\n if (str.length < min || str.length > max) return false\r\n if (requireNumber && !/\\d/.test(str)) return false\r\n if (requireLetter && !/[a-zA-Z]/.test(str)) return false\r\n if (requireSpecial && !/[!@#$%^&*(),.?\":{}|<>]/.test(str)) return false\r\n\r\n return true\r\n }\r\n\r\n /**\r\n * 校验十六进制颜色值\r\n * @param {string} value - 要校验的值(如 #fff 或 #ffffff)\r\n * @returns {boolean} 校验结果\r\n */\r\n hexColor(value) {\r\n if (!value) return false\r\n return /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/.test(String(value).trim())\r\n }\r\n\r\n /**\r\n * 校验QQ号(5-11位数字)\r\n * @param {string} value - 要校验的值\r\n * @returns {boolean} 校验结果\r\n */\r\n qq(value) {\r\n if (!value) return false\r\n return /^[1-9]\\d{4,10}$/.test(String(value).trim())\r\n }\r\n\r\n /**\r\n * 校验微信号(6-20位,字母、数字、下划线、减号)\r\n * @param {string} value - 要校验的值\r\n * @returns {boolean} 校验结果\r\n */\r\n wechat(value) {\r\n if (!value) return false\r\n return /^[a-zA-Z0-9_-]{6,20}$/.test(String(value).trim())\r\n }\r\n\r\n /**\r\n * 校验固定电话(中国大陆)\r\n * @param {string} value - 要校验的值\r\n * @returns {boolean} 校验结果\r\n */\r\n tel(value) {\r\n if (!value) return false\r\n const str = String(value).trim()\r\n // 支持带区号的固定电话:010-12345678 或 01012345678\r\n return /^(0\\d{2,3}-?)?\\d{7,8}$/.test(str)\r\n }\r\n\r\n /**\r\n * 校验MAC地址\r\n * @param {string} value - 要校验的值\r\n * @returns {boolean} 校验结果\r\n */\r\n mac(value) {\r\n if (!value) return false\r\n const str = String(value).trim().toUpperCase()\r\n return /^([0-9A-F]{2}:){5}[0-9A-F]{2}$/.test(str)\r\n }\r\n\r\n /**\r\n * 校验Base64编码\r\n * @param {string} value - 要校验的值\r\n * @returns {boolean} 校验结果\r\n */\r\n base64(value) {\r\n if (!value) return false\r\n const str = String(value).trim()\r\n if (str.length % 4 !== 0) return false\r\n try {\r\n return btoa(atob(str)) === str\r\n } catch (e) {\r\n return false\r\n }\r\n }\r\n\r\n /**\r\n * 校验JSON字符串\r\n * @param {string} value - 要校验的值\r\n * @returns {boolean} 校验结果\r\n */\r\n json(value) {\r\n if (!value) return false\r\n try {\r\n JSON.parse(String(value))\r\n return true\r\n } catch (e) {\r\n return false\r\n }\r\n }\r\n\r\n /**\r\n * 校验数字字符串(纯数字组成)\r\n * @param {string} value - 要校验的值\r\n * @returns {boolean} 校验结果\r\n */\r\n numeric(value) {\r\n if (value === null || value === undefined) return false\r\n return /^\\d+$/.test(String(value))\r\n }\r\n\r\n /**\r\n * 校验URL路径(不含协议和域名)\r\n * @param {string} value - 要校验的值\r\n * @returns {boolean} 校验结果\r\n */\r\n path(value) {\r\n if (!value) return false\r\n return /^\\/[^\\s]*$/.test(String(value).trim())\r\n }\r\n\r\n /**\r\n * 校验端口号(1-65535)\r\n * @param {string|number} value - 要校验的值\r\n * @returns {boolean} 校验结果\r\n */\r\n port(value) {\r\n return this.number(value, { integer: true, min: 1, max: 65535 })\r\n }\r\n}\r\n\r\n// 创建单例实例\r\nconst validator = new Validator()\r\n\r\nexport default validator\r\n","import extend from '@form-create/utils/lib/extend'\nimport is from '@form-create/utils/lib/type'\nimport { invoke } from '@longhongguo/form-create-core/src/frame/util'\nimport toArray from '@form-create/utils/lib/toarray'\nimport validator from './test'\nimport moment from 'moment'\n\nfunction tidyBtnProp(btn, def) {\n if (is.Boolean(btn)) btn = { show: btn }\n else if (!is.Undef(btn) && !is.Object(btn)) btn = { show: def }\n return btn\n}\n\nexport default function extendApi(api, h) {\n return {\n formEl() {\n return h.$manager.form()\n },\n wrapEl(id) {\n const ctx = h.getFieldCtx(id)\n if (!ctx) return\n return h.vm.refs[ctx.wrapRef]\n },\n validate(callback) {\n return new Promise((resolve, reject) => {\n const forms = api.children\n const all = [h.$manager.validate()]\n forms\n .filter((v) => !v.isScope)\n .forEach((v) => {\n all.push(v.validate())\n })\n Promise.all(all)\n .then(() => {\n resolve(true)\n callback && callback(true)\n })\n .catch((e) => {\n reject(e)\n callback && callback(e)\n h.vm.emit('validate-fail', e, { api })\n h.emitEvent('validate-fail', e, { api })\n })\n })\n },\n validateField(field, callback) {\n return new Promise((resolve, reject) => {\n const ctx = h.getFieldCtx(field)\n if (!ctx) return\n const sub = h.subForm[ctx.id]\n const all = [h.$manager.validateField(ctx.id)]\n toArray(sub)\n .filter((v) => !v.isScope)\n .forEach((v) => {\n all.push(v.validate())\n })\n Promise.all(all)\n .then(() => {\n resolve(null)\n callback && callback(null)\n })\n .catch((e) => {\n reject(e)\n callback && callback(e)\n h.vm.emit('validate-field-fail', e, { field, api })\n })\n })\n },\n clearValidateState(fields, clearSub = true) {\n api.helper.tidyFields(fields).forEach((field) => {\n if (clearSub) this.clearSubValidateState(field)\n h.getCtxs(field).forEach((ctx) => {\n h.$manager.clearValidateState(ctx)\n })\n })\n },\n clearSubValidateState(fields) {\n api.helper.tidyFields(fields).forEach((field) => {\n h.getCtxs(field).forEach((ctx) => {\n const subForm = h.subForm[ctx.id]\n if (!subForm) return\n if (Array.isArray(subForm)) {\n subForm.forEach((form) => {\n form.clearValidateState()\n })\n } else if (subForm) {\n subForm.clearValidateState()\n }\n })\n })\n },\n btn: {\n loading: (loading = true) => {\n api.submitBtnProps({ loading: !!loading })\n },\n disabled: (disabled = true) => {\n api.submitBtnProps({ disabled: !!disabled })\n },\n show: (isShow = true) => {\n api.submitBtnProps({ show: !!isShow })\n }\n },\n resetBtn: {\n loading: (loading = true) => {\n api.resetBtnProps({ loading: !!loading })\n },\n disabled: (disabled = true) => {\n api.resetBtnProps({ disabled: !!disabled })\n },\n show: (isShow = true) => {\n api.resetBtnProps({ show: !!isShow })\n }\n },\n submitBtnProps: (props = {}) => {\n let btn = tidyBtnProp(h.options.submitBtn, true)\n extend(btn, props)\n h.options.submitBtn = btn\n api.refreshOptions()\n },\n resetBtnProps: (props = {}) => {\n let btn = tidyBtnProp(h.options.resetBtn, false)\n extend(btn, props)\n h.options.resetBtn = btn\n api.refreshOptions()\n },\n submit(successFn, failFn) {\n return new Promise((resolve, reject) => {\n const promise =\n h.options.validateOnSubmit === false\n ? Promise.resolve()\n : api.validate()\n promise\n .then(() => {\n let formData = api.formData()\n h.beforeSubmit(formData)\n .then(() => {\n is.Function(successFn) && invoke(() => successFn(formData, api))\n is.Function(h.options.onSubmit) &&\n invoke(() => h.options.onSubmit(formData, api))\n h.vm.emit('submit', formData, api)\n resolve(formData)\n })\n .catch((e) => {})\n })\n .catch((...args) => {\n is.Function(failFn) && invoke(() => failFn(api, ...args))\n reject(...args)\n })\n })\n },\n /**\n * 封装请求工具,用于自定义校验规则等场景\n * 基于 frame/fetch.js 封装的 fetch 方法\n *\n * @param {string|object} config - 请求配置,可以是 URL 字符串或配置对象\n * @param {string} config.action - 请求地址(必需)\n * @param {string} config.method - 请求方法,默认 'get'\n * @param {object} config.data - 请求数据(POST/PUT等),用于表单或JSON格式\n * @param {object} config.query - 查询参数(GET请求)\n * @param {string} config.dataType - 数据类型:'json' 表示 JSON 格式(默认),其他值表示表单格式(FormData)\n * @param {object} config.headers - 请求头\n * @param {function|string} config.parse - 数据解析函数或路径字符串\n * @returns {Promise} 返回 Promise,resolve 时返回解析后的数据\n *\n * @example\n * // JSON 格式 POST 请求(默认)\n * await this.api.request({\n * action: '/api/check-username',\n * method: 'post',\n * data: { username: 'test' },\n * dataType: 'json' // 或不设置,默认 JSON\n * });\n *\n * @example\n * // 表单格式 POST 请求\n * await this.api.request({\n * action: '/api/check-username',\n * method: 'post',\n * data: { username: 'test' },\n * dataType: 'form' // 或任意非 'json' 的值,会使用 FormData\n * });\n *\n * @example\n * // 在自定义校验规则中使用\n * validator: async function(value, callback) {\n * try {\n * const result = await this.api.request({\n * action: '/api/check-username',\n * method: 'post',\n * data: { username: value }, // 使用 data,不是 params\n * dataType: 'form' // 表单形式\n * });\n * if (result.exists) {\n * callback('用户名已存在');\n * } else {\n * callback();\n * }\n * } catch (error) {\n * callback('校验失败,请稍后重试');\n * }\n * }\n */\n request(config) {\n // 如果传入的是字符串,转换为配置对象\n if (typeof config === 'string') {\n config = { action: config }\n }\n // 使用 api.fetch 方法,它内部使用 frame/fetch.js 封装的 asyncFetch\n return api.fetch(config)\n },\n // 节流,在指定时间间隔内,如果多次触发,只执行一次\n throttle(fn, delay) {\n let lastTime = 0\n return function (...args) {\n const context = this\n const now = Date.now()\n if (now - lastTime >= (delay || 0)) {\n lastTime = now\n fn.call(context, ...args)\n }\n }\n },\n // 防抖,在指定时间间隔内,如果多次触发,只执行最后一次\n debounce(fn, delay) {\n let timer = null\n return function (...args) {\n const context = this\n if (timer !== null) {\n clearTimeout(timer)\n }\n timer = setTimeout(() => {\n fn.call(context, ...args)\n }, delay || 0)\n }\n },\n /**\n * 校验工具类\n * 提供各种常用的校验方法\n *\n * @example\n * // 校验手机号\n * if (this.api.validator.mobile('13800138000')) {\n * console.log('手机号格式正确')\n * }\n *\n * @example\n * // 校验邮箱\n * if (this.api.validator.email('test@example.com')) {\n * console.log('邮箱格式正确')\n * }\n *\n * @example\n * // 在自定义校验规则中使用\n * validator: function(value, callback) {\n * if (!this.api.validator.mobile(value)) {\n * callback('请输入正确的手机号')\n * } else {\n * callback()\n * }\n * }\n */\n $validator: validator,\n $moment: moment\n }\n}\n","export default {\n autoComplete: 'value',\n cascader: 'value',\n inputNumber: 'value',\n inputPassword: 'value',\n textarea: 'value',\n rate: 'value',\n slider: 'value',\n treeSelect: 'value',\n switch: 'checked',\n cusStoreSelect: 'modelValue',\n cusUserSelect: 'modelValue'\n}\n","import is from '@form-create/utils/lib/type';\n\nconst required = {\n name: 'required',\n load(inject, rule, api) {\n const val = parseVal(inject.getValue());\n if (val.required === false) {\n inject.clearProp();\n api.clearValidateState([rule.field]);\n } else {\n const validate = {\n required: true,\n validator(_, v) {\n return new Promise((resolve, reject) => {\n is.empty(v) ? reject(validate.message) : resolve();\n })\n },\n ...val,\n };\n const title = rule.__fc__.refRule?.__$title?.value;\n if (!validate.message) {\n validate.message = api.t('required', {title}) || (title + (api.getLocale() === 'en' ? ' is required' : '不能为空'));\n } else {\n const match = validate.message.match(/^\\{\\{\\s*\\$t\\.(.+)\\s*\\}\\}$/);\n if (match) {\n validate.message = api.t(match[1], {title});\n }\n }\n inject.getProp().validate = [validate];\n }\n api.sync(rule);\n },\n watch(...args) {\n required.load(...args);\n }\n}\n\nfunction parseVal(val) {\n if (is.Boolean(val)) {\n return {required: val}\n } else if (is.String(val)) {\n return {message: val};\n } else if (is.Undef(val)) {\n return {required: false};\n } else if (is.Function(val)) {\n return {validator: val};\n } else if (!is.Object(val)) {\n return {};\n } else {\n return val;\n }\n}\n\n\nexport default required\n","import components from '../components'\nimport parsers from '../parsers'\nimport alias from './alias'\nimport manager from './manager'\nimport FormCreateFactory from '@longhongguo/form-create-core/src/index'\nimport makers from './maker'\nimport '../style/index.css'\nimport '../style/icon.css'\nimport '@longhongguo/component-antdv-upload/dist/index.css'\nimport extendApi from './api'\nimport modelFields from './modelFields'\nimport required from './provider'\n\nfunction install(FormCreate) {\n FormCreate.componentAlias(alias)\n\n Object.keys(modelFields).forEach((k) => {\n FormCreate.setModelField(k, modelFields[k])\n })\n\n components.forEach((component) => {\n FormCreate.component(component.name, component)\n })\n\n FormCreate.register(required)\n\n parsers.forEach((parser) => {\n FormCreate.parser(parser)\n })\n\n Object.keys(makers).forEach((name) => {\n FormCreate.maker[name] = makers[name]\n })\n\n if (typeof window !== 'undefined' && window.antd) {\n FormCreate.useApp((_, app) => {\n app.use(window.antd)\n })\n }\n}\n\nexport default function antdvFormCreate() {\n return FormCreateFactory({\n ui: 'process.env.UI',\n version: 'process.env.VERSION',\n manager,\n install,\n extendApi,\n attrs: {\n normal: ['col', 'wrap'],\n array: ['className'],\n key: ['title', 'info']\n }\n })\n}\n","import antdvFormCreate from './core/index';\n\nconst FormCreate = antdvFormCreate();\n\nif (typeof window !== 'undefined') {\n window.formCreate = FormCreate;\n}\n\nconst maker = FormCreate.maker;\n\nexport {maker}\n\nexport default FormCreate;\n"],"names":["script$6","name","_hoisted_1","class","_openBlock","_createElementBlock","_cache","_createElementVNode","height","width","xmlns","viewBox","d","fill","script$5","defineComponent","props","modelValue","type","Array","default","options","sourceItems","multiple","Boolean","maxTagCount","Number","undefined","placeholder","String","disabled","style","Object","valueKey","labelKey","allowClear","bordered","emits","computed","currentValue","get","isArray","this","map","item","value","[object Object]","getLabel","label","set","val","arrayValue","$emit","hasValue","length","displayValue","displayLabel","allSelectedItems","displayItems","items","slice","remainingCount","total","Math","max","showClear","methods","findOptionByValue","find","opt","optValue","option","removeItem","itemValue","event","stopPropagation","newValue","filter","some","newItem","clearValue","_hoisted_6","_hoisted_8","opacity","_hoisted_11","_hoisted_12","_createCommentVNode","_ctx","_Fragment","key","tabindex","_renderList","index","title","_toDisplayString","onClick","$event","role","aria-label","focusable","data-icon","aria-hidden","fill-rule","_hoisted_10","_hoisted_13","args","_hoisted_14","_hoisted_3","_hoisted_4","script$4","components","CusSelect","formCreateInject","field","extraQuery","extraQueryFn","Function","data","messageId","pendingCallbacks","internalOptions","mergedOptions","optionMap","Map","forEach","from","values","watch","immediate","handler","newOptions","mounted","window","addEventListener","handleMessage","beforeUnmount","removeEventListener","serializeForPostMessage","JSON","parse","stringify","error","console","warn","result","prototype","hasOwnProperty","call","e","handleClick","msgId","Date","now","currentArrayValue","valueToSend","serializedCurrentValue","assign","message","parent","postMessage","mergeOptions","handleUpdate","handleChange","callback","newItems","triggerValidate","$nextTick","api","validateField","catch","$parent","$options","fapi","_createVNode","_component_CusSelect","model-value","source-items","max-tag-count","onUpdate:modelValue","onChange","script$3","selectType","script$2","columns","required","filterEmptyColumn","deletable","addable","reactive","submitBtn","resetBtn","min","updateTable","deep","formCreateInject.preview","n","emptyRule","children","colspan","rule","trs","Form","markRaw","form","$form","copyTrs","oldValue","_isEmpty","native","subRule","textAlign","preview","t","formChange","updateValue","tr","idx","getChildrenFormData","v","flag","keys","k","str","setRawData","formData","raw","setChildrenFormData","splice","clearEmpty","addEmpty","addRaw","push","delRaw","updateRaw","parseJson","indexOf","innerText","loadRule","header","body","column","align","toJson","border","cellspacing","cellpadding","created","_normalizeClass","_fc-disabled","$props","_createBlock","_resolveDynamicComponent","$data","extendOption","onEmitEvent","_component_a_button","font-weight","script$1","$slots","_hoisted_2","_renderSlot","script","color","colStyle","w","is","upload","frame","group","subForm","QuestionCircleOutlined","CusStoreSelect","CusUserSelect","TableForm","TableFormView","TableFormColumnView","checkbox","modelField","mergeProp","ctx","prop","hasProperty","radio","select","fetchData","effectData","loading","render","newChildren","notFoundContent","$render","defaultRender","cascader","loadData","_ctx$$handle","$handle","ctxRef","parsedFn","parseFn","code","trim","startsWith","selectedOptions","targetOption","isLeaf","updateOptions","_ctxRef$prop","_ctxRef$rule","currentOptions","targetIndex","findIndex","id","deepSet","sync","refresh","then","finally","FORMAT_TYPE","date","month","week","quarter","year","datePicker","maker","reduce","initial","creatorFactory","dateRange","datetimeRange","m","showTime","picker","valueFormat","vNode","range","hidden","text","loadChildren","_ctx$prop$props","_ctx$prop$props2","bindField","template","setTimeout","loadStrVar","getValue","renderChildren","_ctx$rule","currentChildren","join","_ctx$prop$props3","_ctx$prop$props4","_ctx$prop$props5","bindMode","loadDataConfig","attr","to","modify","wait","effect","_textLoadDataWatched","loadDataRef","toRef","newVal","oldVal","formCreateChild","innerHTML","make","input","idate","textarea","search","password","timePicker","tree","fieldNames","checkedKeys","checkable","row","_","col","span","parsers","toFormValue","toValue","formValue","vnode","on","originalUpdateModelValue","nextTick","fieldName","fieldCtx","getFieldCtx","$manager","originalChange","inject","flexDirection","flexWrap","justifyContent","alignItems","alignContent","vertical","justify","flex-start","flex-end","center","space-between","space-around","space-evenly","baseline","stretch","gap","existingStyle","display","userDisplay","_fd","_fw","_jc","_ai","_ac","otherStyles","flexStyles","existingPropStyle","existingPropsStyle","child","show","_ctx$rule$props$child","_ctx$rule$props","isVertical","ensureClass","childFlex","includes","flexValue","_ref","_ctx$rule$props$child2","_ctx$rule$props2","childWidth","widthValue","childrenNodes","direction","size","wrap","spaceStyles","compact","_ref2","_ctx$rule$containerMo","_ctx$rule$props3","_ctx$rule$props4","containerMode","_ref3","_ctx$prop$props$spinn","spinning","hasChildren","_ctx$rule$props5","_ctx$rule$props6","_ctx$prop$props6","_ctx$rule$props7","_ctx$prop$props7","_ref4","_ref5","_ctx$rule$containerMo2","_ctx$rule$props8","_ctx$prop$props8","tip","delay","alias","tooltip","PRE","popover","button","icon","slider","rate","timeRangePicker","rangePicker","switch","inputNumber","treeSelect","inputPassword","formItem","flex","space","space-compact","spin","autoComplete","transfer","array","object","image","aImage","tidy","isFalse","tidyRule","_rule","manager","validate","Promise","validateFields","clearValidateState","fItem","vm","refs","wrapRef","clearValidate","tidyOptions","tidyBool","def","info","placement","mergeProps","parentType","parentMenu","_menu","onPreview","originalOnPreview","sendPreviewMessage","file","url","uid","timestamp","apply","arguments","originalPreview","sendImagePreviewMessage","src","imageSrc","originalOnVisibleChange","onVisibleChange","visible","prevVisible","getDefaultOptions","hideRequiredMark","layout","labelAlign","labelCol","wrapperCol","validateOnRuleChange","gutter","click","adapterValidate","validator","resolve","reject","err","update","submit","preventDefault","beforeRender","ref","extend","className","model","slotLen","setSlot","makeFormBtn","$r","getSlots","makeRow","makeWrap","uni","isTitle","_col","cls","shouldDisableCol","hasFeedback","rules","injectValidate","mergeClass","makeInfo","makeCol","_ctx$refRule","_ctx$refRule2","titleProp","infoProp","isTip","titleSlot","getSlot","refRule","__$title","_ctx$refRule3","__$info","slot","_prop","vn","makeSubmitBtn","makeResetBtn","colon","marginLeft","fApi","resetFields","auto","number","time","useAlias","useSlider","types","frameInputs","frameFiles","frameImages","frameInputOne","frameFileOne","frameImageOne","maxLength","frameInput","frameFile","frameImage","useFrame","uploadFileOne","uploadImageOne","uploadType","uploadImage","uploadFile","useUpload","selectMultiple","mode","selectTags","selectCombobox","cusStoreSelect","storeSelect","useCusStoreSelect","cusUserSelect","userSelect","useCusUserSelect","useText","useFlex","useSpace","useSpin","mobile","strict","test","email","idCard","checkCode","toUpperCase","weights","sum","i","parseInt","checkCodeIndex","requireProtocol","ip","parts","split","every","part","num","isNaN","integer","positive","negative","isInteger","len","pattern","regex","RegExp","getTime","empty","notEmpty","chinese","alpha","caseSensitive","alphanumeric","bankCard","replace","postcode","licensePlate","creditCode","enum","enumList","equal","value1","value2","notEqual","uppercase","lowercase","toLowerCase","username","requireNumber","requireLetter","requireSpecial","hexColor","qq","wechat","tel","mac","base64","btoa","atob","json","numeric","path","port","tidyBtnProp","btn","Undef","extendApi","h","formEl","wrapEl","forms","all","isScope","emit","emitEvent","sub","toArray","fields","clearSub","helper","tidyFields","clearSubValidateState","getCtxs","submitBtnProps","isShow","resetBtnProps","refreshOptions","successFn","failFn","validateOnSubmit","beforeSubmit","invoke","onSubmit","request","config","action","fetch","throttle","fn","lastTime","context","debounce","timer","clearTimeout","$validator","$moment","moment","modelFields","load","parseVal","clearProp","_rule$__fc__$refRule","__fc__","match","getLocale","getProp","install","FormCreate","componentAlias","setModelField","component","register","parser","makers","antd","useApp","app","use","FormCreateFactory","ui","version","attrs","normal","formCreate"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"form-create.esm.js","sources":["../src/components/icon/QuestionCircleOutlined.vue","../src/components/icon/QuestionCircleOutlined.vue?vue&type=template&id=72badc20&lang.js","../src/components/CusSelect/index.vue","../src/components/CusSelect/index.vue?vue&type=template&id=228f8426&lang.js","../src/components/CusStoreSelect/index.vue","../src/components/CusStoreSelect/index.vue?vue&type=template&id=00ba930b&lang.js","../src/components/CusUserSelect/index.vue","../src/components/CusUserSelect/index.vue?vue&type=template&id=54621955&lang.js","../src/components/tableForm/TableForm.vue","../src/components/tableForm/TableForm.vue?vue&type=template&id=7d8ce230&lang.js","../src/components/tableForm/TableFormView.vue","../src/components/tableForm/TableFormView.vue?vue&type=template&id=13cd901b&lang.js","../src/components/tableForm/TableFormColumnView.vue","../src/components/tableForm/TableFormColumnView.vue?vue&type=template&id=4a2dbc30&lang.js","../src/components/index.js","../src/parsers/checkbox.js","../src/parsers/radio.js","../src/parsers/select.js","../src/parsers/cascader.js","../src/parsers/datePicker.js","../src/parsers/hidden.js","../src/parsers/text.js","../src/parsers/input.js","../src/parsers/timePicker.js","../src/parsers/tree.js","../src/parsers/row.js","../src/parsers/timeRangePicker.js","../src/parsers/index.js","../src/parsers/rangePicker.js","../src/parsers/cusStoreSelect.js","../src/parsers/cusUserSelect.js","../src/parsers/flex.js","../src/parsers/space.js","../src/parsers/spin.js","../src/parsers/div.js","../src/core/alias.js","../src/core/manager.js","../src/core/config.js","../src/core/maker.js","../src/core/test.js","../src/core/api.js","../src/core/modelFields.js","../src/core/provider.js","../src/core/index.js","../src/index.js"],"sourcesContent":["<template>\n <span class=\"anticon\">\n <svg height=\"1em\" width=\"1em\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 1024 1024\">\n <path\n d=\"M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448s448-200.6 448-448S759.4 64 512 64zm0 820c-205.4 0-372-166.6-372-372s166.6-372 372-372s372 166.6 372 372s-166.6 372-372 372z\"\n fill=\"currentColor\"></path>\n <path\n d=\"M623.6 316.7C593.6 290.4 554 276 512 276s-81.6 14.5-111.6 40.7C369.2 344 352 380.7 352 420v7.6c0 4.4 3.6 8 8 8h48c4.4 0 8-3.6 8-8V420c0-44.1 43.1-80 96-80s96 35.9 96 80c0 31.1-22 59.6-56.1 72.7c-21.2 8.1-39.2 22.3-52.1 40.9c-13.1 19-19.9 41.8-19.9 64.9V620c0 4.4 3.6 8 8 8h48c4.4 0 8-3.6 8-8v-22.7a48.3 48.3 0 0 1 30.9-44.8c59-22.7 97.1-74.7 97.1-132.5c.1-39.3-17.1-76-48.3-103.3zM472 732a40 40 0 1 0 80 0a40 40 0 1 0-80 0z\"\n fill=\"currentColor\"></path>\n </svg>\n </span>\n</template>\n\n<script>\nexport default {\n name: 'QuestionCircleOutlined'\n}\n</script>\n","<template>\n <span class=\"anticon\">\n <svg height=\"1em\" width=\"1em\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 1024 1024\">\n <path\n d=\"M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448s448-200.6 448-448S759.4 64 512 64zm0 820c-205.4 0-372-166.6-372-372s166.6-372 372-372s372 166.6 372 372s-166.6 372-372 372z\"\n fill=\"currentColor\"></path>\n <path\n d=\"M623.6 316.7C593.6 290.4 554 276 512 276s-81.6 14.5-111.6 40.7C369.2 344 352 380.7 352 420v7.6c0 4.4 3.6 8 8 8h48c4.4 0 8-3.6 8-8V420c0-44.1 43.1-80 96-80s96 35.9 96 80c0 31.1-22 59.6-56.1 72.7c-21.2 8.1-39.2 22.3-52.1 40.9c-13.1 19-19.9 41.8-19.9 64.9V620c0 4.4 3.6 8 8 8h48c4.4 0 8-3.6 8-8v-22.7a48.3 48.3 0 0 1 30.9-44.8c59-22.7 97.1-74.7 97.1-132.5c.1-39.3-17.1-76-48.3-103.3zM472 732a40 40 0 1 0 80 0a40 40 0 1 0-80 0z\"\n fill=\"currentColor\"></path>\n </svg>\n </span>\n</template>\n\n<script>\nexport default {\n name: 'QuestionCircleOutlined'\n}\n</script>\n","<template>\r\n <!-- 单个展示模式 -->\r\n <div\r\n v-if=\"!multiple\"\r\n class=\"fc-cus-select fc-cus-select-single\"\r\n :class=\"{\r\n 'fc-cus-select-disabled': disabled\r\n }\"\r\n :style=\"style\"\r\n :tabindex=\"disabled ? -1 : 0\"\r\n >\r\n <div\r\n class=\"fc-cus-select-selector\"\r\n :class=\"{\r\n 'fc-cus-select-selector-borderless': !bordered\r\n }\"\r\n >\r\n <span\r\n v-if=\"displayValue\"\r\n class=\"fc-cus-select-selection-item\"\r\n :title=\"displayLabel\"\r\n >\r\n {{ displayLabel }}\r\n </span>\r\n <span v-else class=\"fc-cus-select-selection-placeholder\">\r\n {{ placeholder || '请选择' }}\r\n </span>\r\n <span v-if=\"showClear\" class=\"fc-cus-select-clear\" @click=\"clearValue\">\r\n <span\r\n role=\"img\"\r\n aria-label=\"close-circle\"\r\n class=\"anticon anticon-close-circle\"\r\n >\r\n <svg\r\n focusable=\"false\"\r\n data-icon=\"close-circle\"\r\n width=\"1em\"\r\n height=\"1em\"\r\n fill=\"currentColor\"\r\n aria-hidden=\"true\"\r\n fill-rule=\"evenodd\"\r\n viewBox=\"64 64 896 896\"\r\n >\r\n <path\r\n d=\"M512 64c247.4 0 448 200.6 448 448S759.4 960 512 960 64 759.4 64 512 264.6 64 512 64zm127.98 274.82h-.04l-.08.06L512 466.75 384.14 338.88c-.04-.05-.06-.06-.08-.06a.12.12 0 00-.07 0c-.03 0-.05.01-.09.05l-45.02 45.02a.2.2 0 00-.05.09.12.12 0 000 .07v.02a.27.27 0 00.06.06L466.75 512 338.88 639.86c-.05.04-.06.06-.06.08a.12.12 0 000 .07c0 .03.01.05.05.09l45.02 45.02a.2.2 0 00.09.05.12.12 0 00.07 0c.02 0 .04-.01.08-.05L512 557.25l127.86 127.87c.04.04.06.05.08.05a.12.12 0 00.07 0c.03 0 .05-.01.09-.05l45.02-45.02a.2.2 0 00.05-.09.12.12 0 000-.07v-.02a.27.27 0 00-.05-.06L557.25 512l127.87-127.86c.04-.04.05-.06.05-.08a.12.12 0 000-.07c0-.03-.01-.05-.05-.09l-45.02-45.02a.2.2 0 00-.09-.05.12.12 0 00-.07 0z\"\r\n ></path>\r\n </svg>\r\n </span>\r\n </span>\r\n <span v-else class=\"fc-cus-select-arrow\">\r\n <span role=\"img\" aria-label=\"down\" class=\"anticon anticon-down\">\r\n <svg\r\n focusable=\"false\"\r\n data-icon=\"down\"\r\n width=\"1em\"\r\n height=\"1em\"\r\n fill=\"currentColor\"\r\n aria-hidden=\"true\"\r\n viewBox=\"64 64 896 896\"\r\n >\r\n <path\r\n d=\"M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z\"\r\n ></path>\r\n </svg>\r\n </span>\r\n </span>\r\n </div>\r\n </div>\r\n\r\n <!-- 多个展示模式 -->\r\n <div\r\n v-else\r\n class=\"fc-cus-select fc-cus-select-multiple\"\r\n :class=\"{\r\n 'fc-cus-select-disabled': disabled\r\n }\"\r\n :style=\"style\"\r\n :tabindex=\"disabled ? -1 : 0\"\r\n >\r\n <div\r\n class=\"fc-cus-select-selector\"\r\n :class=\"{\r\n 'fc-cus-select-selector-borderless': !bordered\r\n }\"\r\n >\r\n <div class=\"fc-cus-select-selection-overflow\">\r\n <!-- 显示的 tags -->\r\n <div\r\n v-for=\"(item, index) in displayItems\"\r\n :key=\"index\"\r\n class=\"fc-cus-select-selection-overflow-item\"\r\n style=\"opacity: 1\"\r\n >\r\n <span class=\"fc-cus-select-selection-item\" :title=\"item.label\">\r\n <span class=\"fc-cus-select-selection-item-content\">{{\r\n item.label\r\n }}</span>\r\n <span\r\n class=\"fc-cus-select-selection-item-remove\"\r\n @click=\"removeItem(item.value, $event)\"\r\n >\r\n <span role=\"img\" aria-label=\"close\" class=\"anticon anticon-close\">\r\n <svg\r\n focusable=\"false\"\r\n data-icon=\"close\"\r\n width=\"1em\"\r\n height=\"1em\"\r\n fill=\"currentColor\"\r\n aria-hidden=\"true\"\r\n fill-rule=\"evenodd\"\r\n viewBox=\"64 64 896 896\"\r\n >\r\n <path\r\n d=\"M799.86 166.31c.02 0 .04.02.08.06l57.69 57.7c.04.03.05.05.06.08a.12.12 0 010 .06c0 .03-.02.05-.06.09L569.93 512l287.7 287.7c.04.04.05.06.06.09a.12.12 0 010 .07c0 .02-.02.04-.06.08l-57.7 57.69c-.03.04-.05.05-.07.06a.12.12 0 01-.07 0c-.03 0-.05-.02-.09-.06L512 569.93l-287.7 287.7c-.04.04-.06.05-.09.06a.12.12 0 01-.07 0c-.02 0-.04-.02-.08-.06l-57.69-57.7c-.04-.03-.05-.05-.06-.07a.12.12 0 010-.07c0-.03.02-.05.06-.09L454.07 512l-287.7-287.7c-.04-.04-.05-.06-.06-.09a.12.12 0 010-.07c0-.02.02-.04.06-.08l57.7-57.69c.03-.04.05-.05.07-.06a.12.12 0 01.07 0c.03 0 .05.02.09.06L512 454.07l287.7-287.7c.04-.04.06-.05.09-.06a.12.12 0 01.07 0z\"\r\n ></path>\r\n </svg>\r\n </span>\r\n </span>\r\n </span>\r\n </div>\r\n\r\n <!-- 折叠提示 -->\r\n <div\r\n v-if=\"remainingCount > 0\"\r\n class=\"fc-cus-select-selection-overflow-item\"\r\n style=\"opacity: 1\"\r\n >\r\n <span class=\"fc-cus-select-selection-item\">\r\n <span class=\"fc-cus-select-selection-item-content\">\r\n +{{ remainingCount }}\r\n </span>\r\n </span>\r\n </div>\r\n\r\n <!-- 空值占位符 -->\r\n <span v-if=\"!hasValue\" class=\"fc-cus-select-selection-placeholder\">\r\n {{ placeholder || '请选择' }}\r\n </span>\r\n </div>\r\n <span v-if=\"showClear\" class=\"fc-cus-select-clear\" @click=\"clearValue\">\r\n <span\r\n role=\"img\"\r\n aria-label=\"close-circle\"\r\n class=\"anticon anticon-close-circle\"\r\n >\r\n <svg\r\n focusable=\"false\"\r\n data-icon=\"close-circle\"\r\n width=\"1em\"\r\n height=\"1em\"\r\n fill=\"currentColor\"\r\n aria-hidden=\"true\"\r\n fill-rule=\"evenodd\"\r\n viewBox=\"64 64 896 896\"\r\n >\r\n <path\r\n d=\"M512 64c247.4 0 448 200.6 448 448S759.4 960 512 960 64 759.4 64 512 264.6 64 512 64zm127.98 274.82h-.04l-.08.06L512 466.75 384.14 338.88c-.04-.05-.06-.06-.08-.06a.12.12 0 00-.07 0c-.03 0-.05.01-.09.05l-45.02 45.02a.2.2 0 00-.05.09.12.12 0 000 .07v.02a.27.27 0 00.06.06L466.75 512 338.88 639.86c-.05.04-.06.06-.06.08a.12.12 0 000 .07c0 .03.01.05.05.09l45.02 45.02a.2.2 0 00.09.05.12.12 0 00.07 0c.02 0 .04-.01.08-.05L512 557.25l127.86 127.87c.04.04.06.05.08.05a.12.12 0 00.07 0c.03 0 .05-.01.09-.05l45.02-45.02a.2.2 0 00.05-.09.12.12 0 000-.07v-.02a.27.27 0 00-.05-.06L557.25 512l127.87-127.86c.04-.04.05-.06.05-.08a.12.12 0 000-.07c0-.03-.01-.05-.05-.09l-45.02-45.02a.2.2 0 00-.09-.05.12.12 0 00-.07 0z\"\r\n ></path>\r\n </svg>\r\n </span>\r\n </span>\r\n <span v-else class=\"fc-cus-select-arrow\">\r\n <span role=\"img\" aria-label=\"down\" class=\"anticon anticon-down\">\r\n <svg\r\n focusable=\"false\"\r\n data-icon=\"down\"\r\n width=\"1em\"\r\n height=\"1em\"\r\n fill=\"currentColor\"\r\n aria-hidden=\"true\"\r\n viewBox=\"64 64 896 896\"\r\n >\r\n <path\r\n d=\"M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z\"\r\n ></path>\r\n </svg>\r\n </span>\r\n </span>\r\n </div>\r\n </div>\r\n</template>\r\n\r\n<script>\r\nimport { defineComponent } from 'vue'\r\n\r\nexport default defineComponent({\r\n name: 'CusSelect',\r\n props: {\r\n // 当前值:统一使用对象数组格式(支持 v-model)\r\n // 单选时:[{value: '1001', label: '门店1'}] 或 []\r\n // 多选时:[{value: '1001', label: '门店1'}, {value: '1002', label: '门店2'}] 或 []\r\n modelValue: {\r\n type: Array,\r\n default: () => []\r\n },\r\n // 选项列表\r\n options: {\r\n type: Array,\r\n default: () => []\r\n },\r\n // 源选项列表\r\n sourceItems: {\r\n type: Array,\r\n default: () => []\r\n },\r\n // 是否多选\r\n multiple: {\r\n type: Boolean,\r\n default: false\r\n },\r\n // 最多显示的 tag 数量(多选模式下有效)\r\n maxTagCount: {\r\n type: Number,\r\n default: undefined // 不限制时显示所有\r\n },\r\n // 占位符\r\n placeholder: {\r\n type: String,\r\n default: ''\r\n },\r\n // 是否禁用样式\r\n disabled: {\r\n type: Boolean,\r\n default: false\r\n },\r\n // 自定义样式\r\n style: {\r\n type: [String, Object],\r\n default: () => ({ width: '100%' })\r\n },\r\n // 选项的 value 字段名\r\n valueKey: {\r\n type: String,\r\n default: 'value'\r\n },\r\n // 选项的 label 字段名\r\n labelKey: {\r\n type: String,\r\n default: 'label'\r\n },\r\n // 是否允许清除\r\n allowClear: {\r\n type: Boolean,\r\n default: false\r\n },\r\n // 是否有边框\r\n bordered: {\r\n type: Boolean,\r\n default: true\r\n }\r\n },\r\n emits: ['update:modelValue', 'update:sourceItems', 'change'],\r\n computed: {\r\n // 统一处理值(支持 v-model),确保始终是对象数组格式\r\n currentValue: {\r\n get() {\r\n // 确保返回对象数组格式\r\n if (!Array.isArray(this.modelValue)) {\r\n // 如果是 null、undefined 或空字符串,返回空数组\r\n if (\r\n this.modelValue === null ||\r\n this.modelValue === undefined ||\r\n this.modelValue === ''\r\n ) {\r\n return []\r\n }\r\n // 如果是单个对象,转换为数组\r\n if (typeof this.modelValue === 'object') {\r\n return [this.modelValue]\r\n }\r\n // 如果是单个值,转换为对象数组格式\r\n return [\r\n { value: this.modelValue, label: this.getLabel(this.modelValue) }\r\n ]\r\n }\r\n // 确保数组中的每个元素都是对象格式\r\n return this.modelValue.map((item) => {\r\n if (\r\n typeof item === 'object' &&\r\n item !== null &&\r\n (item.value !== undefined || item[this.valueKey] !== undefined)\r\n ) {\r\n // 已经是对象格式\r\n return item\r\n }\r\n // 如果是单个值,转换为对象格式\r\n return {\r\n [this.valueKey]: item,\r\n [this.labelKey]: this.getLabel(item)\r\n }\r\n })\r\n },\r\n set(val) {\r\n // 确保设置的值是对象数组格式\r\n let arrayValue = []\r\n if (val !== null && val !== undefined) {\r\n if (Array.isArray(val)) {\r\n // 确保数组中的每个元素都是对象格式\r\n arrayValue = val.map((item) => {\r\n if (\r\n typeof item === 'object' &&\r\n item !== null &&\r\n (item.value !== undefined || item[this.valueKey] !== undefined)\r\n ) {\r\n return item\r\n }\r\n // 单个值转换为对象格式\r\n return {\r\n [this.valueKey]: item,\r\n [this.labelKey]: this.getLabel(item)\r\n }\r\n })\r\n } else if (typeof val === 'object' && val !== null) {\r\n // 单个对象转换为数组\r\n arrayValue = [val]\r\n } else {\r\n // 单个值转换为对象数组格式\r\n arrayValue = [\r\n { [this.valueKey]: val, [this.labelKey]: this.getLabel(val) }\r\n ]\r\n }\r\n }\r\n // 触发 update:modelValue 事件以支持 v-model\r\n this.$emit('update:modelValue', arrayValue)\r\n this.$emit('change', arrayValue)\r\n }\r\n },\r\n // 是否有值(统一判断数组长度)\r\n hasValue() {\r\n const val = this.currentValue\r\n return Array.isArray(val) && val.length > 0\r\n },\r\n // 单个模式:显示的值对象(从数组中取第一个)\r\n displayValue() {\r\n if (!this.hasValue) return null\r\n return this.currentValue[0]\r\n },\r\n // 单个模式:显示的标签\r\n displayLabel() {\r\n if (!this.displayValue) return ''\r\n const item = this.displayValue\r\n // 如果是对象格式,直接取 label\r\n if (typeof item === 'object' && item !== null) {\r\n return (\r\n item[this.labelKey] ||\r\n item.label ||\r\n String(item[this.valueKey] || item.value || '')\r\n )\r\n }\r\n // 如果不是对象,使用 getLabel 方法查找\r\n return this.getLabel(item)\r\n },\r\n // 多个模式:所有选中的项(直接使用对象数组)\r\n allSelectedItems() {\r\n const val = this.currentValue\r\n if (!Array.isArray(val) || val.length === 0) {\r\n return []\r\n }\r\n // 直接返回对象数组,确保格式统一\r\n return val.map((item) => {\r\n if (typeof item === 'object' && item !== null) {\r\n return {\r\n value: item[this.valueKey] || item.value,\r\n label:\r\n item[this.labelKey] ||\r\n item.label ||\r\n String(item[this.valueKey] || item.value || '')\r\n }\r\n }\r\n // 如果不是对象,转换为对象格式\r\n return {\r\n value: item,\r\n label: this.getLabel(item)\r\n }\r\n })\r\n },\r\n // 多个模式:显示的项(根据 maxTagCount 限制)\r\n displayItems() {\r\n const items = this.allSelectedItems\r\n if (this.maxTagCount === undefined || this.maxTagCount === null) {\r\n return items\r\n }\r\n return items.slice(0, this.maxTagCount)\r\n },\r\n // 多个模式:剩余未显示的项数量\r\n remainingCount() {\r\n if (this.maxTagCount === undefined || this.maxTagCount === null) {\r\n return 0\r\n }\r\n const total = this.allSelectedItems.length\r\n return Math.max(0, total - this.maxTagCount)\r\n },\r\n // 是否显示清除图标\r\n showClear() {\r\n return this.allowClear && this.hasValue && !this.disabled\r\n }\r\n },\r\n methods: {\r\n // 根据 value 查找对应的 option\r\n findOptionByValue(val) {\r\n if (!this.options || this.options.length === 0) {\r\n return null\r\n }\r\n return this.options.find((opt) => {\r\n const optValue = typeof opt === 'object' ? opt[this.valueKey] : opt\r\n return optValue === val || String(optValue) === String(val)\r\n })\r\n },\r\n // 获取显示的 label\r\n getLabel(val) {\r\n const option = this.findOptionByValue(val)\r\n if (option) {\r\n return typeof option === 'object' ? option[this.labelKey] : option\r\n }\r\n // 如果找不到对应的 option,直接显示 value\r\n return String(val)\r\n },\r\n // 删除单个项\r\n removeItem(itemValue, event) {\r\n if (this.disabled) return\r\n event.stopPropagation()\r\n const val = this.currentValue\r\n if (Array.isArray(val)) {\r\n // 根据 value 来过滤,支持对象数组格式\r\n const newValue = val.filter((item) => {\r\n if (typeof item === 'object' && item !== null) {\r\n const currentItemValue = item[this.valueKey] || item.value\r\n return currentItemValue !== itemValue\r\n }\r\n return item !== itemValue\r\n })\r\n const sourceItems = this.sourceItems.filter((item) => {\r\n return !newValue.some((newItem) => {\r\n return newItem[this.valueKey] === item[this.valueKey]\r\n })\r\n })\r\n this.$emit('update:sourceItems', sourceItems)\r\n this.currentValue = newValue\r\n }\r\n },\r\n // 清除所有值\r\n clearValue(event) {\r\n if (this.disabled) return\r\n event.stopPropagation()\r\n // 统一设置为空数组\r\n this.currentValue = []\r\n const sourceItems = this.sourceItems.filter((item) => {\r\n return !this.currentValue.some((newItem) => {\r\n return newItem[this.valueKey] === item[this.valueKey]\r\n })\r\n })\r\n this.$emit('update:sourceItems', sourceItems)\r\n }\r\n }\r\n})\r\n</script>\r\n","<template>\r\n <!-- 单个展示模式 -->\r\n <div\r\n v-if=\"!multiple\"\r\n class=\"fc-cus-select fc-cus-select-single\"\r\n :class=\"{\r\n 'fc-cus-select-disabled': disabled\r\n }\"\r\n :style=\"style\"\r\n :tabindex=\"disabled ? -1 : 0\"\r\n >\r\n <div\r\n class=\"fc-cus-select-selector\"\r\n :class=\"{\r\n 'fc-cus-select-selector-borderless': !bordered\r\n }\"\r\n >\r\n <span\r\n v-if=\"displayValue\"\r\n class=\"fc-cus-select-selection-item\"\r\n :title=\"displayLabel\"\r\n >\r\n {{ displayLabel }}\r\n </span>\r\n <span v-else class=\"fc-cus-select-selection-placeholder\">\r\n {{ placeholder || '请选择' }}\r\n </span>\r\n <span v-if=\"showClear\" class=\"fc-cus-select-clear\" @click=\"clearValue\">\r\n <span\r\n role=\"img\"\r\n aria-label=\"close-circle\"\r\n class=\"anticon anticon-close-circle\"\r\n >\r\n <svg\r\n focusable=\"false\"\r\n data-icon=\"close-circle\"\r\n width=\"1em\"\r\n height=\"1em\"\r\n fill=\"currentColor\"\r\n aria-hidden=\"true\"\r\n fill-rule=\"evenodd\"\r\n viewBox=\"64 64 896 896\"\r\n >\r\n <path\r\n d=\"M512 64c247.4 0 448 200.6 448 448S759.4 960 512 960 64 759.4 64 512 264.6 64 512 64zm127.98 274.82h-.04l-.08.06L512 466.75 384.14 338.88c-.04-.05-.06-.06-.08-.06a.12.12 0 00-.07 0c-.03 0-.05.01-.09.05l-45.02 45.02a.2.2 0 00-.05.09.12.12 0 000 .07v.02a.27.27 0 00.06.06L466.75 512 338.88 639.86c-.05.04-.06.06-.06.08a.12.12 0 000 .07c0 .03.01.05.05.09l45.02 45.02a.2.2 0 00.09.05.12.12 0 00.07 0c.02 0 .04-.01.08-.05L512 557.25l127.86 127.87c.04.04.06.05.08.05a.12.12 0 00.07 0c.03 0 .05-.01.09-.05l45.02-45.02a.2.2 0 00.05-.09.12.12 0 000-.07v-.02a.27.27 0 00-.05-.06L557.25 512l127.87-127.86c.04-.04.05-.06.05-.08a.12.12 0 000-.07c0-.03-.01-.05-.05-.09l-45.02-45.02a.2.2 0 00-.09-.05.12.12 0 00-.07 0z\"\r\n ></path>\r\n </svg>\r\n </span>\r\n </span>\r\n <span v-else class=\"fc-cus-select-arrow\">\r\n <span role=\"img\" aria-label=\"down\" class=\"anticon anticon-down\">\r\n <svg\r\n focusable=\"false\"\r\n data-icon=\"down\"\r\n width=\"1em\"\r\n height=\"1em\"\r\n fill=\"currentColor\"\r\n aria-hidden=\"true\"\r\n viewBox=\"64 64 896 896\"\r\n >\r\n <path\r\n d=\"M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z\"\r\n ></path>\r\n </svg>\r\n </span>\r\n </span>\r\n </div>\r\n </div>\r\n\r\n <!-- 多个展示模式 -->\r\n <div\r\n v-else\r\n class=\"fc-cus-select fc-cus-select-multiple\"\r\n :class=\"{\r\n 'fc-cus-select-disabled': disabled\r\n }\"\r\n :style=\"style\"\r\n :tabindex=\"disabled ? -1 : 0\"\r\n >\r\n <div\r\n class=\"fc-cus-select-selector\"\r\n :class=\"{\r\n 'fc-cus-select-selector-borderless': !bordered\r\n }\"\r\n >\r\n <div class=\"fc-cus-select-selection-overflow\">\r\n <!-- 显示的 tags -->\r\n <div\r\n v-for=\"(item, index) in displayItems\"\r\n :key=\"index\"\r\n class=\"fc-cus-select-selection-overflow-item\"\r\n style=\"opacity: 1\"\r\n >\r\n <span class=\"fc-cus-select-selection-item\" :title=\"item.label\">\r\n <span class=\"fc-cus-select-selection-item-content\">{{\r\n item.label\r\n }}</span>\r\n <span\r\n class=\"fc-cus-select-selection-item-remove\"\r\n @click=\"removeItem(item.value, $event)\"\r\n >\r\n <span role=\"img\" aria-label=\"close\" class=\"anticon anticon-close\">\r\n <svg\r\n focusable=\"false\"\r\n data-icon=\"close\"\r\n width=\"1em\"\r\n height=\"1em\"\r\n fill=\"currentColor\"\r\n aria-hidden=\"true\"\r\n fill-rule=\"evenodd\"\r\n viewBox=\"64 64 896 896\"\r\n >\r\n <path\r\n d=\"M799.86 166.31c.02 0 .04.02.08.06l57.69 57.7c.04.03.05.05.06.08a.12.12 0 010 .06c0 .03-.02.05-.06.09L569.93 512l287.7 287.7c.04.04.05.06.06.09a.12.12 0 010 .07c0 .02-.02.04-.06.08l-57.7 57.69c-.03.04-.05.05-.07.06a.12.12 0 01-.07 0c-.03 0-.05-.02-.09-.06L512 569.93l-287.7 287.7c-.04.04-.06.05-.09.06a.12.12 0 01-.07 0c-.02 0-.04-.02-.08-.06l-57.69-57.7c-.04-.03-.05-.05-.06-.07a.12.12 0 010-.07c0-.03.02-.05.06-.09L454.07 512l-287.7-287.7c-.04-.04-.05-.06-.06-.09a.12.12 0 010-.07c0-.02.02-.04.06-.08l57.7-57.69c.03-.04.05-.05.07-.06a.12.12 0 01.07 0c.03 0 .05.02.09.06L512 454.07l287.7-287.7c.04-.04.06-.05.09-.06a.12.12 0 01.07 0z\"\r\n ></path>\r\n </svg>\r\n </span>\r\n </span>\r\n </span>\r\n </div>\r\n\r\n <!-- 折叠提示 -->\r\n <div\r\n v-if=\"remainingCount > 0\"\r\n class=\"fc-cus-select-selection-overflow-item\"\r\n style=\"opacity: 1\"\r\n >\r\n <span class=\"fc-cus-select-selection-item\">\r\n <span class=\"fc-cus-select-selection-item-content\">\r\n +{{ remainingCount }}\r\n </span>\r\n </span>\r\n </div>\r\n\r\n <!-- 空值占位符 -->\r\n <span v-if=\"!hasValue\" class=\"fc-cus-select-selection-placeholder\">\r\n {{ placeholder || '请选择' }}\r\n </span>\r\n </div>\r\n <span v-if=\"showClear\" class=\"fc-cus-select-clear\" @click=\"clearValue\">\r\n <span\r\n role=\"img\"\r\n aria-label=\"close-circle\"\r\n class=\"anticon anticon-close-circle\"\r\n >\r\n <svg\r\n focusable=\"false\"\r\n data-icon=\"close-circle\"\r\n width=\"1em\"\r\n height=\"1em\"\r\n fill=\"currentColor\"\r\n aria-hidden=\"true\"\r\n fill-rule=\"evenodd\"\r\n viewBox=\"64 64 896 896\"\r\n >\r\n <path\r\n d=\"M512 64c247.4 0 448 200.6 448 448S759.4 960 512 960 64 759.4 64 512 264.6 64 512 64zm127.98 274.82h-.04l-.08.06L512 466.75 384.14 338.88c-.04-.05-.06-.06-.08-.06a.12.12 0 00-.07 0c-.03 0-.05.01-.09.05l-45.02 45.02a.2.2 0 00-.05.09.12.12 0 000 .07v.02a.27.27 0 00.06.06L466.75 512 338.88 639.86c-.05.04-.06.06-.06.08a.12.12 0 000 .07c0 .03.01.05.05.09l45.02 45.02a.2.2 0 00.09.05.12.12 0 00.07 0c.02 0 .04-.01.08-.05L512 557.25l127.86 127.87c.04.04.06.05.08.05a.12.12 0 00.07 0c.03 0 .05-.01.09-.05l45.02-45.02a.2.2 0 00.05-.09.12.12 0 000-.07v-.02a.27.27 0 00-.05-.06L557.25 512l127.87-127.86c.04-.04.05-.06.05-.08a.12.12 0 000-.07c0-.03-.01-.05-.05-.09l-45.02-45.02a.2.2 0 00-.09-.05.12.12 0 00-.07 0z\"\r\n ></path>\r\n </svg>\r\n </span>\r\n </span>\r\n <span v-else class=\"fc-cus-select-arrow\">\r\n <span role=\"img\" aria-label=\"down\" class=\"anticon anticon-down\">\r\n <svg\r\n focusable=\"false\"\r\n data-icon=\"down\"\r\n width=\"1em\"\r\n height=\"1em\"\r\n fill=\"currentColor\"\r\n aria-hidden=\"true\"\r\n viewBox=\"64 64 896 896\"\r\n >\r\n <path\r\n d=\"M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z\"\r\n ></path>\r\n </svg>\r\n </span>\r\n </span>\r\n </div>\r\n </div>\r\n</template>\r\n\r\n<script>\r\nimport { defineComponent } from 'vue'\r\n\r\nexport default defineComponent({\r\n name: 'CusSelect',\r\n props: {\r\n // 当前值:统一使用对象数组格式(支持 v-model)\r\n // 单选时:[{value: '1001', label: '门店1'}] 或 []\r\n // 多选时:[{value: '1001', label: '门店1'}, {value: '1002', label: '门店2'}] 或 []\r\n modelValue: {\r\n type: Array,\r\n default: () => []\r\n },\r\n // 选项列表\r\n options: {\r\n type: Array,\r\n default: () => []\r\n },\r\n // 源选项列表\r\n sourceItems: {\r\n type: Array,\r\n default: () => []\r\n },\r\n // 是否多选\r\n multiple: {\r\n type: Boolean,\r\n default: false\r\n },\r\n // 最多显示的 tag 数量(多选模式下有效)\r\n maxTagCount: {\r\n type: Number,\r\n default: undefined // 不限制时显示所有\r\n },\r\n // 占位符\r\n placeholder: {\r\n type: String,\r\n default: ''\r\n },\r\n // 是否禁用样式\r\n disabled: {\r\n type: Boolean,\r\n default: false\r\n },\r\n // 自定义样式\r\n style: {\r\n type: [String, Object],\r\n default: () => ({ width: '100%' })\r\n },\r\n // 选项的 value 字段名\r\n valueKey: {\r\n type: String,\r\n default: 'value'\r\n },\r\n // 选项的 label 字段名\r\n labelKey: {\r\n type: String,\r\n default: 'label'\r\n },\r\n // 是否允许清除\r\n allowClear: {\r\n type: Boolean,\r\n default: false\r\n },\r\n // 是否有边框\r\n bordered: {\r\n type: Boolean,\r\n default: true\r\n }\r\n },\r\n emits: ['update:modelValue', 'update:sourceItems', 'change'],\r\n computed: {\r\n // 统一处理值(支持 v-model),确保始终是对象数组格式\r\n currentValue: {\r\n get() {\r\n // 确保返回对象数组格式\r\n if (!Array.isArray(this.modelValue)) {\r\n // 如果是 null、undefined 或空字符串,返回空数组\r\n if (\r\n this.modelValue === null ||\r\n this.modelValue === undefined ||\r\n this.modelValue === ''\r\n ) {\r\n return []\r\n }\r\n // 如果是单个对象,转换为数组\r\n if (typeof this.modelValue === 'object') {\r\n return [this.modelValue]\r\n }\r\n // 如果是单个值,转换为对象数组格式\r\n return [\r\n { value: this.modelValue, label: this.getLabel(this.modelValue) }\r\n ]\r\n }\r\n // 确保数组中的每个元素都是对象格式\r\n return this.modelValue.map((item) => {\r\n if (\r\n typeof item === 'object' &&\r\n item !== null &&\r\n (item.value !== undefined || item[this.valueKey] !== undefined)\r\n ) {\r\n // 已经是对象格式\r\n return item\r\n }\r\n // 如果是单个值,转换为对象格式\r\n return {\r\n [this.valueKey]: item,\r\n [this.labelKey]: this.getLabel(item)\r\n }\r\n })\r\n },\r\n set(val) {\r\n // 确保设置的值是对象数组格式\r\n let arrayValue = []\r\n if (val !== null && val !== undefined) {\r\n if (Array.isArray(val)) {\r\n // 确保数组中的每个元素都是对象格式\r\n arrayValue = val.map((item) => {\r\n if (\r\n typeof item === 'object' &&\r\n item !== null &&\r\n (item.value !== undefined || item[this.valueKey] !== undefined)\r\n ) {\r\n return item\r\n }\r\n // 单个值转换为对象格式\r\n return {\r\n [this.valueKey]: item,\r\n [this.labelKey]: this.getLabel(item)\r\n }\r\n })\r\n } else if (typeof val === 'object' && val !== null) {\r\n // 单个对象转换为数组\r\n arrayValue = [val]\r\n } else {\r\n // 单个值转换为对象数组格式\r\n arrayValue = [\r\n { [this.valueKey]: val, [this.labelKey]: this.getLabel(val) }\r\n ]\r\n }\r\n }\r\n // 触发 update:modelValue 事件以支持 v-model\r\n this.$emit('update:modelValue', arrayValue)\r\n this.$emit('change', arrayValue)\r\n }\r\n },\r\n // 是否有值(统一判断数组长度)\r\n hasValue() {\r\n const val = this.currentValue\r\n return Array.isArray(val) && val.length > 0\r\n },\r\n // 单个模式:显示的值对象(从数组中取第一个)\r\n displayValue() {\r\n if (!this.hasValue) return null\r\n return this.currentValue[0]\r\n },\r\n // 单个模式:显示的标签\r\n displayLabel() {\r\n if (!this.displayValue) return ''\r\n const item = this.displayValue\r\n // 如果是对象格式,直接取 label\r\n if (typeof item === 'object' && item !== null) {\r\n return (\r\n item[this.labelKey] ||\r\n item.label ||\r\n String(item[this.valueKey] || item.value || '')\r\n )\r\n }\r\n // 如果不是对象,使用 getLabel 方法查找\r\n return this.getLabel(item)\r\n },\r\n // 多个模式:所有选中的项(直接使用对象数组)\r\n allSelectedItems() {\r\n const val = this.currentValue\r\n if (!Array.isArray(val) || val.length === 0) {\r\n return []\r\n }\r\n // 直接返回对象数组,确保格式统一\r\n return val.map((item) => {\r\n if (typeof item === 'object' && item !== null) {\r\n return {\r\n value: item[this.valueKey] || item.value,\r\n label:\r\n item[this.labelKey] ||\r\n item.label ||\r\n String(item[this.valueKey] || item.value || '')\r\n }\r\n }\r\n // 如果不是对象,转换为对象格式\r\n return {\r\n value: item,\r\n label: this.getLabel(item)\r\n }\r\n })\r\n },\r\n // 多个模式:显示的项(根据 maxTagCount 限制)\r\n displayItems() {\r\n const items = this.allSelectedItems\r\n if (this.maxTagCount === undefined || this.maxTagCount === null) {\r\n return items\r\n }\r\n return items.slice(0, this.maxTagCount)\r\n },\r\n // 多个模式:剩余未显示的项数量\r\n remainingCount() {\r\n if (this.maxTagCount === undefined || this.maxTagCount === null) {\r\n return 0\r\n }\r\n const total = this.allSelectedItems.length\r\n return Math.max(0, total - this.maxTagCount)\r\n },\r\n // 是否显示清除图标\r\n showClear() {\r\n return this.allowClear && this.hasValue && !this.disabled\r\n }\r\n },\r\n methods: {\r\n // 根据 value 查找对应的 option\r\n findOptionByValue(val) {\r\n if (!this.options || this.options.length === 0) {\r\n return null\r\n }\r\n return this.options.find((opt) => {\r\n const optValue = typeof opt === 'object' ? opt[this.valueKey] : opt\r\n return optValue === val || String(optValue) === String(val)\r\n })\r\n },\r\n // 获取显示的 label\r\n getLabel(val) {\r\n const option = this.findOptionByValue(val)\r\n if (option) {\r\n return typeof option === 'object' ? option[this.labelKey] : option\r\n }\r\n // 如果找不到对应的 option,直接显示 value\r\n return String(val)\r\n },\r\n // 删除单个项\r\n removeItem(itemValue, event) {\r\n if (this.disabled) return\r\n event.stopPropagation()\r\n const val = this.currentValue\r\n if (Array.isArray(val)) {\r\n // 根据 value 来过滤,支持对象数组格式\r\n const newValue = val.filter((item) => {\r\n if (typeof item === 'object' && item !== null) {\r\n const currentItemValue = item[this.valueKey] || item.value\r\n return currentItemValue !== itemValue\r\n }\r\n return item !== itemValue\r\n })\r\n const sourceItems = this.sourceItems.filter((item) => {\r\n return !newValue.some((newItem) => {\r\n return newItem[this.valueKey] === item[this.valueKey]\r\n })\r\n })\r\n this.$emit('update:sourceItems', sourceItems)\r\n this.currentValue = newValue\r\n }\r\n },\r\n // 清除所有值\r\n clearValue(event) {\r\n if (this.disabled) return\r\n event.stopPropagation()\r\n // 统一设置为空数组\r\n this.currentValue = []\r\n const sourceItems = this.sourceItems.filter((item) => {\r\n return !this.currentValue.some((newItem) => {\r\n return newItem[this.valueKey] === item[this.valueKey]\r\n })\r\n })\r\n this.$emit('update:sourceItems', sourceItems)\r\n }\r\n }\r\n})\r\n</script>\r\n","<template>\n <div @click=\"handleClick\">\n <CusSelect\n :model-value=\"modelValue\"\n :options=\"mergedOptions\"\n v-model:source-items=\"sourceItems\"\n :multiple=\"multiple\"\n :max-tag-count=\"maxTagCount\"\n :placeholder=\"placeholder\"\n :disabled=\"disabled\"\n :style=\"style\"\n :valueKey=\"valueKey\"\n :labelKey=\"labelKey\"\n :allowClear=\"allowClear\"\n :bordered=\"bordered\"\n @update:model-value=\"handleUpdate\"\n @change=\"handleChange\"\n />\n </div>\n</template>\n\n<script>\nimport { defineComponent } from 'vue'\nimport CusSelect from '../CusSelect/index.vue'\n\nexport default defineComponent({\n name: 'CusStoreSelect',\n components: {\n CusSelect\n },\n props: {\n // form-create 注入的对象,包含 API 等\n formCreateInject: {\n type: Object,\n default: null\n },\n // 当前值:统一使用数组格式(支持 v-model)\n // 单选时:[value] 或 []\n // 多选时:[value1, value2, ...] 或 []\n modelValue: {\n type: Array,\n default: () => []\n },\n // 选项列表\n options: {\n type: Array,\n default: () => []\n },\n // 是否多选\n multiple: {\n type: Boolean,\n default: false\n },\n // 最多显示的 tag 数量(多选模式下有效)\n maxTagCount: {\n type: Number,\n default: undefined // 不限制时显示所有\n },\n // 占位符\n placeholder: {\n type: String,\n default: '请选择'\n },\n // 是否禁用样式\n disabled: {\n type: Boolean,\n default: false\n },\n // 自定义样式\n style: {\n type: [String, Object],\n default: () => ({ width: '100%' })\n },\n // 选项的 value 字段名\n valueKey: {\n type: String,\n default: 'value'\n },\n // 选项的 label 字段名\n labelKey: {\n type: String,\n default: 'label'\n },\n // 是否允许清除\n allowClear: {\n type: Boolean,\n default: false\n },\n // 字段名,用于跨窗口通信时标识字段\n field: {\n type: String,\n default: ''\n },\n // 是否有边框\n bordered: {\n type: Boolean,\n default: true\n },\n // 额外查询参数\n extraQuery: {\n type: Object,\n default: () => ({})\n },\n extraQueryFn: {\n type: Function,\n default: () => {}\n }\n },\n emits: ['update:modelValue', 'change'],\n data() {\n return {\n // 消息ID计数器,用于标识每次请求\n messageId: 0,\n // 存储待处理的回调函数\n pendingCallbacks: {},\n // 内部维护的选项列表(合并父窗口返回的源对象)\n internalOptions: [],\n sourceItems: []\n }\n },\n computed: {\n // 合并内部选项和外部传入的选项\n mergedOptions() {\n // 如果内部有选项,优先使用内部选项\n if (this.internalOptions.length > 0) {\n // 合并去重:根据 valueKey 去重,保留内部选项(后添加的优先)\n const optionMap = new Map()\n // 先添加外部选项\n this.options.forEach((opt) => {\n const value = typeof opt === 'object' ? opt[this.valueKey] : opt\n optionMap.set(value, opt)\n })\n // 再添加内部选项(会覆盖相同 value 的选项)\n this.internalOptions.forEach((opt) => {\n const value = typeof opt === 'object' ? opt[this.valueKey] : opt\n optionMap.set(value, opt)\n })\n return Array.from(optionMap.values())\n }\n return this.options\n }\n },\n watch: {\n // 监听外部 options 变化,初始化内部选项列表\n options: {\n immediate: true,\n handler(newOptions) {\n // 如果内部选项为空,且外部有选项,初始化内部选项\n if (\n this.internalOptions.length === 0 &&\n Array.isArray(newOptions) &&\n newOptions.length > 0\n ) {\n this.internalOptions = [...newOptions]\n }\n }\n }\n },\n mounted() {\n // 监听父窗口返回的消息\n window.addEventListener('message', this.handleMessage)\n },\n beforeUnmount() {\n // 组件销毁时移除事件监听\n window.removeEventListener('message', this.handleMessage)\n },\n methods: {\n // 序列化数据,确保可以被 postMessage 发送\n // postMessage 使用结构化克隆算法,无法克隆 Vue 响应式代理对象\n serializeForPostMessage(data) {\n // 处理 null 和 undefined\n if (data === null || data === undefined) {\n return data\n }\n\n try {\n // 使用 JSON 序列化和反序列化来创建可克隆的副本\n // 这会移除 Vue 响应式代理、函数、Symbol 等不可序列化的内容\n return JSON.parse(JSON.stringify(data))\n } catch (error) {\n console.warn('CusStoreSelect: 数据序列化失败,尝试递归处理', error)\n\n // 如果 JSON 序列化失败(可能是循环引用),尝试递归处理\n if (Array.isArray(data)) {\n // 空数组直接返回\n if (data.length === 0) {\n return []\n }\n // 递归处理数组中的每个元素\n return data.map((item) => this.serializeForPostMessage(item))\n }\n\n if (typeof data === 'object') {\n const result = {}\n for (const key in data) {\n if (Object.prototype.hasOwnProperty.call(data, key)) {\n try {\n result[key] = this.serializeForPostMessage(data[key])\n } catch (e) {\n // 忽略无法序列化的属性,避免整个序列化失败\n console.warn(`CusStoreSelect: 跳过无法序列化的属性: ${key}`, e)\n }\n }\n }\n return result\n }\n\n // 基本类型(string, number, boolean)直接返回\n return data\n }\n },\n handleClick() {\n // 如果禁用,不处理\n if (this.disabled) {\n return\n }\n\n // 生成唯一消息ID\n const msgId = `store-select-${\n this.field || 'default'\n }-${Date.now()}-${++this.messageId}`\n\n // 序列化所有需要传递的数据,确保可以被 postMessage 发送\n // postMessage 无法发送 Vue 响应式代理对象,必须序列化\n // 获取当前值,确保是对象数组格式\n const currentArrayValue = Array.isArray(this.modelValue)\n ? this.modelValue\n : []\n // 从对象数组中提取 value 值,用于发送给父窗口\n // 单选时发送第一个对象的 value,多选时发送所有对象的 value 数组\n let valueToSend = null\n if (currentArrayValue.length > 0) {\n valueToSend = currentArrayValue\n }\n const serializedCurrentValue =\n valueToSend === null || valueToSend === undefined\n ? null\n : this.serializeForPostMessage(valueToSend)\n\n // 发送消息给父窗口,请求打开门店选择弹窗\n const extraQuery = {\n ...this.extraQuery\n }\n if (this.extraQueryFn) {\n Object.assign(extraQuery, this.extraQueryFn())\n }\n const message = {\n type: 'OPEN_STORE_SELECT',\n field: this.field || '',\n multiple: this.multiple,\n currentValue: serializedCurrentValue,\n valueKey: this.valueKey,\n labelKey: this.labelKey,\n extraQuery,\n messageId: msgId\n }\n\n // 发送到父窗口(支持 iframe 场景)\n if (window.parent && window.parent !== window) {\n try {\n window.parent.postMessage(message, '*')\n } catch (error) {\n console.error('CusStoreSelect: 发送消息失败', error)\n }\n } else {\n // 如果不在 iframe 中,也可以发送到当前窗口(用于测试)\n console.warn(\n 'CusStoreSelect: 当前不在 iframe 环境中,无法向父窗口发送消息'\n )\n }\n\n // 存储回调,等待父窗口返回结果\n this.pendingCallbacks[msgId] = (value, sourceItems) => {\n // 优先使用 sourceItems(源对象数组),如果没有则根据 value 和 options 构建\n if (\n sourceItems &&\n Array.isArray(sourceItems) &&\n sourceItems.length > 0\n ) {\n // 合并到内部选项列表\n this.mergeOptions(sourceItems)\n }\n\n this.sourceItems = sourceItems\n this.handleUpdate(value)\n this.handleChange(value)\n }\n },\n handleMessage(event) {\n // 验证消息来源(可选,根据实际需求调整)\n // if (event.origin !== 'expected-origin') return\n\n const data = event.data\n\n // 检查是否是门店选择返回的消息\n if (data && data.type === 'STORE_SELECT_RESULT') {\n const { field, value, sourceItems, messageId } = data\n\n // 验证字段名是否匹配\n if (field !== this.field) {\n return\n }\n\n // 查找对应的回调函数\n const callback = this.pendingCallbacks[messageId]\n if (callback) {\n // 执行回调,更新值并传递源对象\n // sourceItems: 源对象数组,包含完整的选项信息\n // 单选时:[{ value: '1001', label: '门店1', ... }]\n // 多选时:[{ value: '1001', label: '门店1', ... }, { value: '1002', label: '门店2', ... }]\n callback(value, sourceItems)\n // 清理已处理的回调\n delete this.pendingCallbacks[messageId]\n }\n }\n },\n // 合并选项到内部选项列表\n mergeOptions(newItems) {\n if (!Array.isArray(newItems) || newItems.length === 0) {\n return\n }\n\n // 创建选项映射,用于去重\n const optionMap = new Map()\n\n // 先将现有内部选项添加到映射\n this.internalOptions.forEach((opt) => {\n const value = typeof opt === 'object' ? opt[this.valueKey] : opt\n optionMap.set(value, opt)\n })\n\n // 再添加新选项(会覆盖相同 value 的选项)\n newItems.forEach((opt) => {\n const value = typeof opt === 'object' ? opt[this.valueKey] : opt\n optionMap.set(value, opt)\n })\n\n // 更新内部选项列表\n this.internalOptions = Array.from(optionMap.values())\n },\n handleUpdate(value) {\n this.$emit('update:modelValue', value)\n // 值更新后触发校验\n this.triggerValidate()\n },\n handleChange(value) {\n this.$emit(\n 'change',\n value,\n this.sourceItems && this.sourceItems.length > 0\n ? this.multiple\n ? this.sourceItems\n : this.sourceItems[0]\n : this.multiple\n ? []\n : null\n )\n },\n // 触发字段校验\n triggerValidate() {\n // 使用 nextTick 确保值已经更新完成\n this.$nextTick(() => {\n this.$nextTick(() => {\n try {\n // 方式1:通过 formCreateInject 中的 API 触发校验\n if (\n this.formCreateInject &&\n this.formCreateInject.api &&\n this.field\n ) {\n this.formCreateInject.api.validateField(this.field).catch(() => {\n // 校验失败时静默处理,错误会通过 form-item 显示\n })\n return\n }\n\n // 方式2:通过组件实例查找父组件中的 form-create API\n let parent = this.$parent\n while (parent) {\n if (\n parent.$options &&\n parent.$options.name === 'FormCreate' &&\n parent.fapi\n ) {\n if (this.field && parent.fapi.validateField) {\n parent.fapi.validateField(this.field).catch(() => {\n // 校验失败时静默处理\n })\n }\n break\n }\n parent = parent.$parent\n }\n } catch (error) {\n console.warn('CusStoreSelect: 触发校验失败', error)\n }\n })\n })\n }\n }\n})\n</script>\n","<template>\n <div @click=\"handleClick\">\n <CusSelect\n :model-value=\"modelValue\"\n :options=\"mergedOptions\"\n v-model:source-items=\"sourceItems\"\n :multiple=\"multiple\"\n :max-tag-count=\"maxTagCount\"\n :placeholder=\"placeholder\"\n :disabled=\"disabled\"\n :style=\"style\"\n :valueKey=\"valueKey\"\n :labelKey=\"labelKey\"\n :allowClear=\"allowClear\"\n :bordered=\"bordered\"\n @update:model-value=\"handleUpdate\"\n @change=\"handleChange\"\n />\n </div>\n</template>\n\n<script>\nimport { defineComponent } from 'vue'\nimport CusSelect from '../CusSelect/index.vue'\n\nexport default defineComponent({\n name: 'CusStoreSelect',\n components: {\n CusSelect\n },\n props: {\n // form-create 注入的对象,包含 API 等\n formCreateInject: {\n type: Object,\n default: null\n },\n // 当前值:统一使用数组格式(支持 v-model)\n // 单选时:[value] 或 []\n // 多选时:[value1, value2, ...] 或 []\n modelValue: {\n type: Array,\n default: () => []\n },\n // 选项列表\n options: {\n type: Array,\n default: () => []\n },\n // 是否多选\n multiple: {\n type: Boolean,\n default: false\n },\n // 最多显示的 tag 数量(多选模式下有效)\n maxTagCount: {\n type: Number,\n default: undefined // 不限制时显示所有\n },\n // 占位符\n placeholder: {\n type: String,\n default: '请选择'\n },\n // 是否禁用样式\n disabled: {\n type: Boolean,\n default: false\n },\n // 自定义样式\n style: {\n type: [String, Object],\n default: () => ({ width: '100%' })\n },\n // 选项的 value 字段名\n valueKey: {\n type: String,\n default: 'value'\n },\n // 选项的 label 字段名\n labelKey: {\n type: String,\n default: 'label'\n },\n // 是否允许清除\n allowClear: {\n type: Boolean,\n default: false\n },\n // 字段名,用于跨窗口通信时标识字段\n field: {\n type: String,\n default: ''\n },\n // 是否有边框\n bordered: {\n type: Boolean,\n default: true\n },\n // 额外查询参数\n extraQuery: {\n type: Object,\n default: () => ({})\n },\n extraQueryFn: {\n type: Function,\n default: () => {}\n }\n },\n emits: ['update:modelValue', 'change'],\n data() {\n return {\n // 消息ID计数器,用于标识每次请求\n messageId: 0,\n // 存储待处理的回调函数\n pendingCallbacks: {},\n // 内部维护的选项列表(合并父窗口返回的源对象)\n internalOptions: [],\n sourceItems: []\n }\n },\n computed: {\n // 合并内部选项和外部传入的选项\n mergedOptions() {\n // 如果内部有选项,优先使用内部选项\n if (this.internalOptions.length > 0) {\n // 合并去重:根据 valueKey 去重,保留内部选项(后添加的优先)\n const optionMap = new Map()\n // 先添加外部选项\n this.options.forEach((opt) => {\n const value = typeof opt === 'object' ? opt[this.valueKey] : opt\n optionMap.set(value, opt)\n })\n // 再添加内部选项(会覆盖相同 value 的选项)\n this.internalOptions.forEach((opt) => {\n const value = typeof opt === 'object' ? opt[this.valueKey] : opt\n optionMap.set(value, opt)\n })\n return Array.from(optionMap.values())\n }\n return this.options\n }\n },\n watch: {\n // 监听外部 options 变化,初始化内部选项列表\n options: {\n immediate: true,\n handler(newOptions) {\n // 如果内部选项为空,且外部有选项,初始化内部选项\n if (\n this.internalOptions.length === 0 &&\n Array.isArray(newOptions) &&\n newOptions.length > 0\n ) {\n this.internalOptions = [...newOptions]\n }\n }\n }\n },\n mounted() {\n // 监听父窗口返回的消息\n window.addEventListener('message', this.handleMessage)\n },\n beforeUnmount() {\n // 组件销毁时移除事件监听\n window.removeEventListener('message', this.handleMessage)\n },\n methods: {\n // 序列化数据,确保可以被 postMessage 发送\n // postMessage 使用结构化克隆算法,无法克隆 Vue 响应式代理对象\n serializeForPostMessage(data) {\n // 处理 null 和 undefined\n if (data === null || data === undefined) {\n return data\n }\n\n try {\n // 使用 JSON 序列化和反序列化来创建可克隆的副本\n // 这会移除 Vue 响应式代理、函数、Symbol 等不可序列化的内容\n return JSON.parse(JSON.stringify(data))\n } catch (error) {\n console.warn('CusStoreSelect: 数据序列化失败,尝试递归处理', error)\n\n // 如果 JSON 序列化失败(可能是循环引用),尝试递归处理\n if (Array.isArray(data)) {\n // 空数组直接返回\n if (data.length === 0) {\n return []\n }\n // 递归处理数组中的每个元素\n return data.map((item) => this.serializeForPostMessage(item))\n }\n\n if (typeof data === 'object') {\n const result = {}\n for (const key in data) {\n if (Object.prototype.hasOwnProperty.call(data, key)) {\n try {\n result[key] = this.serializeForPostMessage(data[key])\n } catch (e) {\n // 忽略无法序列化的属性,避免整个序列化失败\n console.warn(`CusStoreSelect: 跳过无法序列化的属性: ${key}`, e)\n }\n }\n }\n return result\n }\n\n // 基本类型(string, number, boolean)直接返回\n return data\n }\n },\n handleClick() {\n // 如果禁用,不处理\n if (this.disabled) {\n return\n }\n\n // 生成唯一消息ID\n const msgId = `store-select-${\n this.field || 'default'\n }-${Date.now()}-${++this.messageId}`\n\n // 序列化所有需要传递的数据,确保可以被 postMessage 发送\n // postMessage 无法发送 Vue 响应式代理对象,必须序列化\n // 获取当前值,确保是对象数组格式\n const currentArrayValue = Array.isArray(this.modelValue)\n ? this.modelValue\n : []\n // 从对象数组中提取 value 值,用于发送给父窗口\n // 单选时发送第一个对象的 value,多选时发送所有对象的 value 数组\n let valueToSend = null\n if (currentArrayValue.length > 0) {\n valueToSend = currentArrayValue\n }\n const serializedCurrentValue =\n valueToSend === null || valueToSend === undefined\n ? null\n : this.serializeForPostMessage(valueToSend)\n\n // 发送消息给父窗口,请求打开门店选择弹窗\n const extraQuery = {\n ...this.extraQuery\n }\n if (this.extraQueryFn) {\n Object.assign(extraQuery, this.extraQueryFn())\n }\n const message = {\n type: 'OPEN_STORE_SELECT',\n field: this.field || '',\n multiple: this.multiple,\n currentValue: serializedCurrentValue,\n valueKey: this.valueKey,\n labelKey: this.labelKey,\n extraQuery,\n messageId: msgId\n }\n\n // 发送到父窗口(支持 iframe 场景)\n if (window.parent && window.parent !== window) {\n try {\n window.parent.postMessage(message, '*')\n } catch (error) {\n console.error('CusStoreSelect: 发送消息失败', error)\n }\n } else {\n // 如果不在 iframe 中,也可以发送到当前窗口(用于测试)\n console.warn(\n 'CusStoreSelect: 当前不在 iframe 环境中,无法向父窗口发送消息'\n )\n }\n\n // 存储回调,等待父窗口返回结果\n this.pendingCallbacks[msgId] = (value, sourceItems) => {\n // 优先使用 sourceItems(源对象数组),如果没有则根据 value 和 options 构建\n if (\n sourceItems &&\n Array.isArray(sourceItems) &&\n sourceItems.length > 0\n ) {\n // 合并到内部选项列表\n this.mergeOptions(sourceItems)\n }\n\n this.sourceItems = sourceItems\n this.handleUpdate(value)\n this.handleChange(value)\n }\n },\n handleMessage(event) {\n // 验证消息来源(可选,根据实际需求调整)\n // if (event.origin !== 'expected-origin') return\n\n const data = event.data\n\n // 检查是否是门店选择返回的消息\n if (data && data.type === 'STORE_SELECT_RESULT') {\n const { field, value, sourceItems, messageId } = data\n\n // 验证字段名是否匹配\n if (field !== this.field) {\n return\n }\n\n // 查找对应的回调函数\n const callback = this.pendingCallbacks[messageId]\n if (callback) {\n // 执行回调,更新值并传递源对象\n // sourceItems: 源对象数组,包含完整的选项信息\n // 单选时:[{ value: '1001', label: '门店1', ... }]\n // 多选时:[{ value: '1001', label: '门店1', ... }, { value: '1002', label: '门店2', ... }]\n callback(value, sourceItems)\n // 清理已处理的回调\n delete this.pendingCallbacks[messageId]\n }\n }\n },\n // 合并选项到内部选项列表\n mergeOptions(newItems) {\n if (!Array.isArray(newItems) || newItems.length === 0) {\n return\n }\n\n // 创建选项映射,用于去重\n const optionMap = new Map()\n\n // 先将现有内部选项添加到映射\n this.internalOptions.forEach((opt) => {\n const value = typeof opt === 'object' ? opt[this.valueKey] : opt\n optionMap.set(value, opt)\n })\n\n // 再添加新选项(会覆盖相同 value 的选项)\n newItems.forEach((opt) => {\n const value = typeof opt === 'object' ? opt[this.valueKey] : opt\n optionMap.set(value, opt)\n })\n\n // 更新内部选项列表\n this.internalOptions = Array.from(optionMap.values())\n },\n handleUpdate(value) {\n this.$emit('update:modelValue', value)\n // 值更新后触发校验\n this.triggerValidate()\n },\n handleChange(value) {\n this.$emit(\n 'change',\n value,\n this.sourceItems && this.sourceItems.length > 0\n ? this.multiple\n ? this.sourceItems\n : this.sourceItems[0]\n : this.multiple\n ? []\n : null\n )\n },\n // 触发字段校验\n triggerValidate() {\n // 使用 nextTick 确保值已经更新完成\n this.$nextTick(() => {\n this.$nextTick(() => {\n try {\n // 方式1:通过 formCreateInject 中的 API 触发校验\n if (\n this.formCreateInject &&\n this.formCreateInject.api &&\n this.field\n ) {\n this.formCreateInject.api.validateField(this.field).catch(() => {\n // 校验失败时静默处理,错误会通过 form-item 显示\n })\n return\n }\n\n // 方式2:通过组件实例查找父组件中的 form-create API\n let parent = this.$parent\n while (parent) {\n if (\n parent.$options &&\n parent.$options.name === 'FormCreate' &&\n parent.fapi\n ) {\n if (this.field && parent.fapi.validateField) {\n parent.fapi.validateField(this.field).catch(() => {\n // 校验失败时静默处理\n })\n }\n break\n }\n parent = parent.$parent\n }\n } catch (error) {\n console.warn('CusStoreSelect: 触发校验失败', error)\n }\n })\n })\n }\n }\n})\n</script>\n","<template>\r\n <div @click=\"handleClick\">\r\n <CusSelect\r\n :model-value=\"modelValue\"\r\n :options=\"mergedOptions\"\r\n v-model:source-items=\"sourceItems\"\r\n :multiple=\"multiple\"\r\n :max-tag-count=\"maxTagCount\"\r\n :placeholder=\"placeholder\"\r\n :disabled=\"disabled\"\r\n :style=\"style\"\r\n :valueKey=\"valueKey\"\r\n :labelKey=\"labelKey\"\r\n :allowClear=\"allowClear\"\r\n :bordered=\"bordered\"\r\n @update:model-value=\"handleUpdate\"\r\n @change=\"handleChange\"\r\n />\r\n </div>\r\n</template>\r\n\r\n<script>\r\nimport { defineComponent } from 'vue'\r\nimport CusSelect from '../CusSelect/index.vue'\r\n\r\nexport default defineComponent({\r\n name: 'CusUserSelect',\r\n components: {\r\n CusSelect\r\n },\r\n props: {\r\n // form-create 注入的对象,包含 API 等\r\n formCreateInject: {\r\n type: Object,\r\n default: null\r\n },\r\n // 当前值:统一使用数组格式(支持 v-model)\r\n // 单选时:[value] 或 []\r\n // 多选时:[value1, value2, ...] 或 []\r\n modelValue: {\r\n type: Array,\r\n default: () => []\r\n },\r\n // 选项列表\r\n options: {\r\n type: Array,\r\n default: () => []\r\n },\r\n // 是否多选\r\n multiple: {\r\n type: Boolean,\r\n default: false\r\n },\r\n // 最多显示的 tag 数量(多选模式下有效)\r\n maxTagCount: {\r\n type: Number,\r\n default: undefined // 不限制时显示所有\r\n },\r\n // 占位符\r\n placeholder: {\r\n type: String,\r\n default: '请选择'\r\n },\r\n // 是否禁用样式\r\n disabled: {\r\n type: Boolean,\r\n default: false\r\n },\r\n // 自定义样式\r\n style: {\r\n type: [String, Object],\r\n default: () => ({ width: '100%' })\r\n },\r\n // 选项的 value 字段名\r\n valueKey: {\r\n type: String,\r\n default: 'value'\r\n },\r\n // 选项的 label 字段名\r\n labelKey: {\r\n type: String,\r\n default: 'label'\r\n },\r\n // 是否允许清除\r\n allowClear: {\r\n type: Boolean,\r\n default: false\r\n },\r\n // 字段名,用于跨窗口通信时标识字段\r\n field: {\r\n type: String,\r\n default: ''\r\n },\r\n // 是否有边框\r\n bordered: {\r\n type: Boolean,\r\n default: true\r\n },\r\n selectType: {\r\n type: [String, Number],\r\n default: null\r\n },\r\n extraQuery: {\r\n type: Object,\r\n default: () => ({})\r\n },\r\n extraQueryFn: {\r\n type: Function,\r\n default: () => {}\r\n }\r\n },\r\n emits: ['update:modelValue', 'change'],\r\n data() {\r\n return {\r\n // 消息ID计数器,用于标识每次请求\r\n messageId: 0,\r\n // 存储待处理的回调函数\r\n pendingCallbacks: {},\r\n // 内部维护的选项列表(合并父窗口返回的源对象)\r\n internalOptions: [],\r\n sourceItems: []\r\n }\r\n },\r\n computed: {\r\n // 合并内部选项和外部传入的选项\r\n mergedOptions() {\r\n // 如果内部有选项,优先使用内部选项\r\n if (this.internalOptions.length > 0) {\r\n // 合并去重:根据 valueKey 去重,保留内部选项(后添加的优先)\r\n const optionMap = new Map()\r\n // 先添加外部选项\r\n this.options.forEach((opt) => {\r\n const value = typeof opt === 'object' ? opt[this.valueKey] : opt\r\n optionMap.set(value, opt)\r\n })\r\n // 再添加内部选项(会覆盖相同 value 的选项)\r\n this.internalOptions.forEach((opt) => {\r\n const value = typeof opt === 'object' ? opt[this.valueKey] : opt\r\n optionMap.set(value, opt)\r\n })\r\n return Array.from(optionMap.values())\r\n }\r\n return this.options\r\n }\r\n },\r\n watch: {\r\n // 监听外部 options 变化,初始化内部选项列表\r\n options: {\r\n immediate: true,\r\n handler(newOptions) {\r\n // 如果内部选项为空,且外部有选项,初始化内部选项\r\n if (\r\n this.internalOptions.length === 0 &&\r\n Array.isArray(newOptions) &&\r\n newOptions.length > 0\r\n ) {\r\n this.internalOptions = [...newOptions]\r\n }\r\n }\r\n }\r\n },\r\n mounted() {\r\n // 监听父窗口返回的消息\r\n window.addEventListener('message', this.handleMessage)\r\n },\r\n beforeUnmount() {\r\n // 组件销毁时移除事件监听\r\n window.removeEventListener('message', this.handleMessage)\r\n },\r\n methods: {\r\n // 序列化数据,确保可以被 postMessage 发送\r\n // postMessage 使用结构化克隆算法,无法克隆 Vue 响应式代理对象\r\n serializeForPostMessage(data) {\r\n // 处理 null 和 undefined\r\n if (data === null || data === undefined) {\r\n return data\r\n }\r\n\r\n try {\r\n // 使用 JSON 序列化和反序列化来创建可克隆的副本\r\n // 这会移除 Vue 响应式代理、函数、Symbol 等不可序列化的内容\r\n return JSON.parse(JSON.stringify(data))\r\n } catch (error) {\r\n console.warn('CusUserSelect: 数据序列化失败,尝试递归处理', error)\r\n\r\n // 如果 JSON 序列化失败(可能是循环引用),尝试递归处理\r\n if (Array.isArray(data)) {\r\n // 空数组直接返回\r\n if (data.length === 0) {\r\n return []\r\n }\r\n // 递归处理数组中的每个元素\r\n return data.map((item) => this.serializeForPostMessage(item))\r\n }\r\n\r\n if (typeof data === 'object') {\r\n const result = {}\r\n for (const key in data) {\r\n if (Object.prototype.hasOwnProperty.call(data, key)) {\r\n try {\r\n result[key] = this.serializeForPostMessage(data[key])\r\n } catch (e) {\r\n // 忽略无法序列化的属性,避免整个序列化失败\r\n console.warn(`CusUserSelect: 跳过无法序列化的属性: ${key}`, e)\r\n }\r\n }\r\n }\r\n return result\r\n }\r\n\r\n // 基本类型(string, number, boolean)直接返回\r\n return data\r\n }\r\n },\r\n handleClick() {\r\n // 如果禁用,不处理\r\n if (this.disabled) {\r\n return\r\n }\r\n\r\n // 生成唯一消息ID\r\n const msgId = `user-select-${\r\n this.field || 'default'\r\n }-${Date.now()}-${++this.messageId}`\r\n\r\n // 序列化所有需要传递的数据,确保可以被 postMessage 发送\r\n // postMessage 无法发送 Vue 响应式代理对象,必须序列化\r\n // 获取当前值,确保是对象数组格式\r\n const currentArrayValue = Array.isArray(this.modelValue)\r\n ? this.modelValue\r\n : []\r\n // 从对象数组中提取 value 值,用于发送给父窗口\r\n // 单选时发送第一个对象的 value,多选时发送所有对象的 value 数组\r\n let valueToSend = null\r\n if (currentArrayValue.length > 0) {\r\n valueToSend = currentArrayValue\r\n }\r\n const serializedCurrentValue =\r\n valueToSend === null || valueToSend === undefined\r\n ? null\r\n : this.serializeForPostMessage(valueToSend)\r\n\r\n // 发送消息给父窗口,请求打开用户选择弹窗\r\n const extraQuery = {\r\n ...this.extraQuery\r\n }\r\n if (this.extraQueryFn) {\r\n Object.assign(extraQuery, this.extraQueryFn())\r\n }\r\n\r\n const message = {\r\n type: 'OPEN_USER_SELECT',\r\n field: this.field || '',\r\n multiple: this.multiple,\r\n currentValue: serializedCurrentValue,\r\n valueKey: this.valueKey,\r\n labelKey: this.labelKey,\r\n selectType: this.selectType,\r\n extraQuery,\r\n messageId: msgId\r\n }\r\n\r\n // 发送到父窗口(支持 iframe 场景)\r\n if (window.parent && window.parent !== window) {\r\n try {\r\n window.parent.postMessage(message, '*')\r\n } catch (error) {\r\n console.error('CusUserSelect: 发送消息失败', error)\r\n }\r\n } else {\r\n // 如果不在 iframe 中,也可以发送到当前窗口(用于测试)\r\n console.warn(\r\n 'CusUserSelect: 当前不在 iframe 环境中,无法向父窗口发送消息'\r\n )\r\n }\r\n\r\n // 存储回调,等待父窗口返回结果\r\n this.pendingCallbacks[msgId] = (value, sourceItems) => {\r\n // 优先使用 sourceItems(源对象数组),如果没有则根据 value 和 options 构建\r\n if (\r\n sourceItems &&\r\n Array.isArray(sourceItems) &&\r\n sourceItems.length > 0\r\n ) {\r\n // 合并到内部选项列表\r\n this.mergeOptions(sourceItems)\r\n }\r\n\r\n this.sourceItems = sourceItems\r\n\r\n this.handleUpdate(value)\r\n this.handleChange(value)\r\n }\r\n },\r\n handleMessage(event) {\r\n // 验证消息来源(可选,根据实际需求调整)\r\n // if (event.origin !== 'expected-origin') return\r\n\r\n const data = event.data\r\n\r\n // 检查是否是用户选择返回的消息\r\n if (data && data.type === 'USER_SELECT_RESULT') {\r\n const { field, value, sourceItems, messageId } = data\r\n\r\n // 验证字段名是否匹配\r\n if (field !== this.field) {\r\n return\r\n }\r\n\r\n // 查找对应的回调函数\r\n const callback = this.pendingCallbacks[messageId]\r\n if (callback) {\r\n // 执行回调,更新值并传递源对象\r\n // sourceItems: 源对象数组,包含完整的选项信息\r\n // 单选时:[{ value: '1001', label: '用户1', ... }]\r\n // 多选时:[{ value: '1001', label: '用户1', ... }, { value: '1002', label: '用户2', ... }]\r\n callback(value, sourceItems)\r\n // 清理已处理的回调\r\n delete this.pendingCallbacks[messageId]\r\n }\r\n }\r\n },\r\n // 合并选项到内部选项列表\r\n mergeOptions(newItems) {\r\n if (!Array.isArray(newItems) || newItems.length === 0) {\r\n return\r\n }\r\n\r\n // 创建选项映射,用于去重\r\n const optionMap = new Map()\r\n\r\n // 先将现有内部选项添加到映射\r\n this.internalOptions.forEach((opt) => {\r\n const value = typeof opt === 'object' ? opt[this.valueKey] : opt\r\n optionMap.set(value, opt)\r\n })\r\n\r\n // 再添加新选项(会覆盖相同 value 的选项)\r\n newItems.forEach((opt) => {\r\n const value = typeof opt === 'object' ? opt[this.valueKey] : opt\r\n optionMap.set(value, opt)\r\n })\r\n\r\n // 更新内部选项列表\r\n this.internalOptions = Array.from(optionMap.values())\r\n },\r\n handleUpdate(value) {\r\n this.$emit('update:modelValue', value)\r\n // 值更新后触发校验\r\n this.triggerValidate()\r\n },\r\n handleChange(value) {\r\n this.$emit(\r\n 'change',\r\n value,\r\n this.sourceItems && this.sourceItems.length > 0\r\n ? this.multiple\r\n ? this.sourceItems\r\n : this.sourceItems[0]\r\n : this.multiple\r\n ? []\r\n : null\r\n )\r\n },\r\n // 触发字段校验\r\n triggerValidate() {\r\n // 使用 nextTick 确保值已经更新完成\r\n this.$nextTick(() => {\r\n this.$nextTick(() => {\r\n try {\r\n // 方式1:通过 formCreateInject 中的 API 触发校验\r\n if (\r\n this.formCreateInject &&\r\n this.formCreateInject.api &&\r\n this.field\r\n ) {\r\n this.formCreateInject.api.validateField(this.field).catch(() => {\r\n // 校验失败时静默处理,错误会通过 form-item 显示\r\n })\r\n return\r\n }\r\n\r\n // 方式2:通过组件实例查找父组件中的 form-create API\r\n let parent = this.$parent\r\n while (parent) {\r\n if (\r\n parent.$options &&\r\n parent.$options.name === 'FormCreate' &&\r\n parent.fapi\r\n ) {\r\n if (this.field && parent.fapi.validateField) {\r\n parent.fapi.validateField(this.field).catch(() => {\r\n // 校验失败时静默处理\r\n })\r\n }\r\n break\r\n }\r\n parent = parent.$parent\r\n }\r\n } catch (error) {\r\n console.warn('CusUserSelect: 触发校验失败', error)\r\n }\r\n })\r\n })\r\n }\r\n }\r\n})\r\n</script>\r\n","<template>\r\n <div @click=\"handleClick\">\r\n <CusSelect\r\n :model-value=\"modelValue\"\r\n :options=\"mergedOptions\"\r\n v-model:source-items=\"sourceItems\"\r\n :multiple=\"multiple\"\r\n :max-tag-count=\"maxTagCount\"\r\n :placeholder=\"placeholder\"\r\n :disabled=\"disabled\"\r\n :style=\"style\"\r\n :valueKey=\"valueKey\"\r\n :labelKey=\"labelKey\"\r\n :allowClear=\"allowClear\"\r\n :bordered=\"bordered\"\r\n @update:model-value=\"handleUpdate\"\r\n @change=\"handleChange\"\r\n />\r\n </div>\r\n</template>\r\n\r\n<script>\r\nimport { defineComponent } from 'vue'\r\nimport CusSelect from '../CusSelect/index.vue'\r\n\r\nexport default defineComponent({\r\n name: 'CusUserSelect',\r\n components: {\r\n CusSelect\r\n },\r\n props: {\r\n // form-create 注入的对象,包含 API 等\r\n formCreateInject: {\r\n type: Object,\r\n default: null\r\n },\r\n // 当前值:统一使用数组格式(支持 v-model)\r\n // 单选时:[value] 或 []\r\n // 多选时:[value1, value2, ...] 或 []\r\n modelValue: {\r\n type: Array,\r\n default: () => []\r\n },\r\n // 选项列表\r\n options: {\r\n type: Array,\r\n default: () => []\r\n },\r\n // 是否多选\r\n multiple: {\r\n type: Boolean,\r\n default: false\r\n },\r\n // 最多显示的 tag 数量(多选模式下有效)\r\n maxTagCount: {\r\n type: Number,\r\n default: undefined // 不限制时显示所有\r\n },\r\n // 占位符\r\n placeholder: {\r\n type: String,\r\n default: '请选择'\r\n },\r\n // 是否禁用样式\r\n disabled: {\r\n type: Boolean,\r\n default: false\r\n },\r\n // 自定义样式\r\n style: {\r\n type: [String, Object],\r\n default: () => ({ width: '100%' })\r\n },\r\n // 选项的 value 字段名\r\n valueKey: {\r\n type: String,\r\n default: 'value'\r\n },\r\n // 选项的 label 字段名\r\n labelKey: {\r\n type: String,\r\n default: 'label'\r\n },\r\n // 是否允许清除\r\n allowClear: {\r\n type: Boolean,\r\n default: false\r\n },\r\n // 字段名,用于跨窗口通信时标识字段\r\n field: {\r\n type: String,\r\n default: ''\r\n },\r\n // 是否有边框\r\n bordered: {\r\n type: Boolean,\r\n default: true\r\n },\r\n selectType: {\r\n type: [String, Number],\r\n default: null\r\n },\r\n extraQuery: {\r\n type: Object,\r\n default: () => ({})\r\n },\r\n extraQueryFn: {\r\n type: Function,\r\n default: () => {}\r\n }\r\n },\r\n emits: ['update:modelValue', 'change'],\r\n data() {\r\n return {\r\n // 消息ID计数器,用于标识每次请求\r\n messageId: 0,\r\n // 存储待处理的回调函数\r\n pendingCallbacks: {},\r\n // 内部维护的选项列表(合并父窗口返回的源对象)\r\n internalOptions: [],\r\n sourceItems: []\r\n }\r\n },\r\n computed: {\r\n // 合并内部选项和外部传入的选项\r\n mergedOptions() {\r\n // 如果内部有选项,优先使用内部选项\r\n if (this.internalOptions.length > 0) {\r\n // 合并去重:根据 valueKey 去重,保留内部选项(后添加的优先)\r\n const optionMap = new Map()\r\n // 先添加外部选项\r\n this.options.forEach((opt) => {\r\n const value = typeof opt === 'object' ? opt[this.valueKey] : opt\r\n optionMap.set(value, opt)\r\n })\r\n // 再添加内部选项(会覆盖相同 value 的选项)\r\n this.internalOptions.forEach((opt) => {\r\n const value = typeof opt === 'object' ? opt[this.valueKey] : opt\r\n optionMap.set(value, opt)\r\n })\r\n return Array.from(optionMap.values())\r\n }\r\n return this.options\r\n }\r\n },\r\n watch: {\r\n // 监听外部 options 变化,初始化内部选项列表\r\n options: {\r\n immediate: true,\r\n handler(newOptions) {\r\n // 如果内部选项为空,且外部有选项,初始化内部选项\r\n if (\r\n this.internalOptions.length === 0 &&\r\n Array.isArray(newOptions) &&\r\n newOptions.length > 0\r\n ) {\r\n this.internalOptions = [...newOptions]\r\n }\r\n }\r\n }\r\n },\r\n mounted() {\r\n // 监听父窗口返回的消息\r\n window.addEventListener('message', this.handleMessage)\r\n },\r\n beforeUnmount() {\r\n // 组件销毁时移除事件监听\r\n window.removeEventListener('message', this.handleMessage)\r\n },\r\n methods: {\r\n // 序列化数据,确保可以被 postMessage 发送\r\n // postMessage 使用结构化克隆算法,无法克隆 Vue 响应式代理对象\r\n serializeForPostMessage(data) {\r\n // 处理 null 和 undefined\r\n if (data === null || data === undefined) {\r\n return data\r\n }\r\n\r\n try {\r\n // 使用 JSON 序列化和反序列化来创建可克隆的副本\r\n // 这会移除 Vue 响应式代理、函数、Symbol 等不可序列化的内容\r\n return JSON.parse(JSON.stringify(data))\r\n } catch (error) {\r\n console.warn('CusUserSelect: 数据序列化失败,尝试递归处理', error)\r\n\r\n // 如果 JSON 序列化失败(可能是循环引用),尝试递归处理\r\n if (Array.isArray(data)) {\r\n // 空数组直接返回\r\n if (data.length === 0) {\r\n return []\r\n }\r\n // 递归处理数组中的每个元素\r\n return data.map((item) => this.serializeForPostMessage(item))\r\n }\r\n\r\n if (typeof data === 'object') {\r\n const result = {}\r\n for (const key in data) {\r\n if (Object.prototype.hasOwnProperty.call(data, key)) {\r\n try {\r\n result[key] = this.serializeForPostMessage(data[key])\r\n } catch (e) {\r\n // 忽略无法序列化的属性,避免整个序列化失败\r\n console.warn(`CusUserSelect: 跳过无法序列化的属性: ${key}`, e)\r\n }\r\n }\r\n }\r\n return result\r\n }\r\n\r\n // 基本类型(string, number, boolean)直接返回\r\n return data\r\n }\r\n },\r\n handleClick() {\r\n // 如果禁用,不处理\r\n if (this.disabled) {\r\n return\r\n }\r\n\r\n // 生成唯一消息ID\r\n const msgId = `user-select-${\r\n this.field || 'default'\r\n }-${Date.now()}-${++this.messageId}`\r\n\r\n // 序列化所有需要传递的数据,确保可以被 postMessage 发送\r\n // postMessage 无法发送 Vue 响应式代理对象,必须序列化\r\n // 获取当前值,确保是对象数组格式\r\n const currentArrayValue = Array.isArray(this.modelValue)\r\n ? this.modelValue\r\n : []\r\n // 从对象数组中提取 value 值,用于发送给父窗口\r\n // 单选时发送第一个对象的 value,多选时发送所有对象的 value 数组\r\n let valueToSend = null\r\n if (currentArrayValue.length > 0) {\r\n valueToSend = currentArrayValue\r\n }\r\n const serializedCurrentValue =\r\n valueToSend === null || valueToSend === undefined\r\n ? null\r\n : this.serializeForPostMessage(valueToSend)\r\n\r\n // 发送消息给父窗口,请求打开用户选择弹窗\r\n const extraQuery = {\r\n ...this.extraQuery\r\n }\r\n if (this.extraQueryFn) {\r\n Object.assign(extraQuery, this.extraQueryFn())\r\n }\r\n\r\n const message = {\r\n type: 'OPEN_USER_SELECT',\r\n field: this.field || '',\r\n multiple: this.multiple,\r\n currentValue: serializedCurrentValue,\r\n valueKey: this.valueKey,\r\n labelKey: this.labelKey,\r\n selectType: this.selectType,\r\n extraQuery,\r\n messageId: msgId\r\n }\r\n\r\n // 发送到父窗口(支持 iframe 场景)\r\n if (window.parent && window.parent !== window) {\r\n try {\r\n window.parent.postMessage(message, '*')\r\n } catch (error) {\r\n console.error('CusUserSelect: 发送消息失败', error)\r\n }\r\n } else {\r\n // 如果不在 iframe 中,也可以发送到当前窗口(用于测试)\r\n console.warn(\r\n 'CusUserSelect: 当前不在 iframe 环境中,无法向父窗口发送消息'\r\n )\r\n }\r\n\r\n // 存储回调,等待父窗口返回结果\r\n this.pendingCallbacks[msgId] = (value, sourceItems) => {\r\n // 优先使用 sourceItems(源对象数组),如果没有则根据 value 和 options 构建\r\n if (\r\n sourceItems &&\r\n Array.isArray(sourceItems) &&\r\n sourceItems.length > 0\r\n ) {\r\n // 合并到内部选项列表\r\n this.mergeOptions(sourceItems)\r\n }\r\n\r\n this.sourceItems = sourceItems\r\n\r\n this.handleUpdate(value)\r\n this.handleChange(value)\r\n }\r\n },\r\n handleMessage(event) {\r\n // 验证消息来源(可选,根据实际需求调整)\r\n // if (event.origin !== 'expected-origin') return\r\n\r\n const data = event.data\r\n\r\n // 检查是否是用户选择返回的消息\r\n if (data && data.type === 'USER_SELECT_RESULT') {\r\n const { field, value, sourceItems, messageId } = data\r\n\r\n // 验证字段名是否匹配\r\n if (field !== this.field) {\r\n return\r\n }\r\n\r\n // 查找对应的回调函数\r\n const callback = this.pendingCallbacks[messageId]\r\n if (callback) {\r\n // 执行回调,更新值并传递源对象\r\n // sourceItems: 源对象数组,包含完整的选项信息\r\n // 单选时:[{ value: '1001', label: '用户1', ... }]\r\n // 多选时:[{ value: '1001', label: '用户1', ... }, { value: '1002', label: '用户2', ... }]\r\n callback(value, sourceItems)\r\n // 清理已处理的回调\r\n delete this.pendingCallbacks[messageId]\r\n }\r\n }\r\n },\r\n // 合并选项到内部选项列表\r\n mergeOptions(newItems) {\r\n if (!Array.isArray(newItems) || newItems.length === 0) {\r\n return\r\n }\r\n\r\n // 创建选项映射,用于去重\r\n const optionMap = new Map()\r\n\r\n // 先将现有内部选项添加到映射\r\n this.internalOptions.forEach((opt) => {\r\n const value = typeof opt === 'object' ? opt[this.valueKey] : opt\r\n optionMap.set(value, opt)\r\n })\r\n\r\n // 再添加新选项(会覆盖相同 value 的选项)\r\n newItems.forEach((opt) => {\r\n const value = typeof opt === 'object' ? opt[this.valueKey] : opt\r\n optionMap.set(value, opt)\r\n })\r\n\r\n // 更新内部选项列表\r\n this.internalOptions = Array.from(optionMap.values())\r\n },\r\n handleUpdate(value) {\r\n this.$emit('update:modelValue', value)\r\n // 值更新后触发校验\r\n this.triggerValidate()\r\n },\r\n handleChange(value) {\r\n this.$emit(\r\n 'change',\r\n value,\r\n this.sourceItems && this.sourceItems.length > 0\r\n ? this.multiple\r\n ? this.sourceItems\r\n : this.sourceItems[0]\r\n : this.multiple\r\n ? []\r\n : null\r\n )\r\n },\r\n // 触发字段校验\r\n triggerValidate() {\r\n // 使用 nextTick 确保值已经更新完成\r\n this.$nextTick(() => {\r\n this.$nextTick(() => {\r\n try {\r\n // 方式1:通过 formCreateInject 中的 API 触发校验\r\n if (\r\n this.formCreateInject &&\r\n this.formCreateInject.api &&\r\n this.field\r\n ) {\r\n this.formCreateInject.api.validateField(this.field).catch(() => {\r\n // 校验失败时静默处理,错误会通过 form-item 显示\r\n })\r\n return\r\n }\r\n\r\n // 方式2:通过组件实例查找父组件中的 form-create API\r\n let parent = this.$parent\r\n while (parent) {\r\n if (\r\n parent.$options &&\r\n parent.$options.name === 'FormCreate' &&\r\n parent.fapi\r\n ) {\r\n if (this.field && parent.fapi.validateField) {\r\n parent.fapi.validateField(this.field).catch(() => {\r\n // 校验失败时静默处理\r\n })\r\n }\r\n break\r\n }\r\n parent = parent.$parent\r\n }\r\n } catch (error) {\r\n console.warn('CusUserSelect: 触发校验失败', error)\r\n }\r\n })\r\n })\r\n }\r\n }\r\n})\r\n</script>\r\n","<template>\n <div class=\"_fc-table-form\" :class=\"{ '_fc-disabled': disabled }\">\n <component\n :is=\"Form\"\n :option=\"options\"\n :rule=\"rule\"\n :extendOption=\"true\"\n :disabled=\"disabled\"\n @change=\"formChange\"\n v-model:api=\"fapi\"\n @emit-event=\"$emit\"\n ></component>\n <a-button\n type=\"link\"\n class=\"fc-clock\"\n v-if=\"addable && (!max || max > this.trs.length)\"\n @click=\"addRaw(true)\"\n :disabled=\"disabled\"\n ><i class=\"fc-icon icon-add-circle\" style=\"font-weight: 700\"></i>\n {{ formCreateInject.t('add') || '添加' }}\n </a-button>\n </div>\n</template>\n\n<script>\nimport { markRaw, reactive } from 'vue'\n\nexport default {\n name: 'TableForm',\n emits: ['change', 'add', 'delete', 'update:modelValue'],\n props: {\n formCreateInject: Object,\n modelValue: {\n type: Array,\n default: () => []\n },\n columns: {\n type: Array,\n required: true,\n default: () => []\n },\n filterEmptyColumn: {\n type: Boolean,\n default: true\n },\n deletable: {\n type: Boolean,\n default: true\n },\n addable: {\n type: Boolean,\n default: true\n },\n options: {\n type: Object,\n default: () =>\n reactive({\n submitBtn: false,\n resetBtn: false\n })\n },\n min: Number,\n max: Number,\n disabled: Boolean\n },\n watch: {\n modelValue: {\n handler() {\n this.updateTable()\n },\n deep: true\n },\n 'formCreateInject.preview': function (n) {\n this.emptyRule.children[0].props.colspan =\n this.columns.length + (n ? 1 : 2)\n }\n },\n data() {\n return {\n rule: [],\n trs: [],\n fapi: {},\n Form: markRaw(this.formCreateInject.form.$form()),\n copyTrs: '',\n oldValue: '',\n emptyRule: {\n type: 'tr',\n _isEmpty: true,\n native: true,\n subRule: true,\n children: [\n {\n type: 'td',\n style: {\n textAlign: 'center'\n },\n native: true,\n subRule: true,\n props: {\n colspan:\n this.columns.length + (this.formCreateInject.preview ? 1 : 2)\n },\n children: [this.formCreateInject.t('dataEmpty') || '暂无数据']\n }\n ]\n }\n }\n },\n methods: {\n formChange() {\n this.updateValue()\n },\n updateValue() {\n const value = this.trs\n .map((tr, idx) => {\n return {\n ...(this.modelValue[idx] || {}),\n ...this.fapi.getChildrenFormData(tr)\n }\n })\n .filter((v) => {\n if (!this.filterEmptyColumn) {\n return true\n }\n if (v === undefined || v === null) {\n return false\n }\n let flag = false\n Object.keys(v).forEach((k) => {\n flag = flag || (v[k] !== undefined && v[k] !== '' && v[k] !== null)\n })\n return flag\n })\n const str = JSON.stringify(value)\n if (str !== this.oldValue) {\n this.oldValue = str\n this.$emit('update:modelValue', value)\n this.$emit('change', value)\n }\n },\n setRawData(idx, formData) {\n const raw = this.trs[idx]\n this.fapi.setChildrenFormData(raw, formData, true)\n },\n updateTable() {\n const str = JSON.stringify(this.modelValue)\n if (this.oldValue === str) {\n return\n }\n this.oldValue = str\n this.trs = this.trs.splice(0, this.modelValue.length)\n if (!this.modelValue.length) {\n this.addEmpty()\n } else {\n this.clearEmpty()\n }\n this.modelValue.forEach((data, idx) => {\n if (!this.trs[idx]) {\n this.addRaw()\n }\n this.setRawData(idx, data || {})\n })\n this.rule[0].children[1].children = this.trs\n },\n addEmpty() {\n if (this.trs.length) {\n this.trs.splice(0, this.trs.length)\n }\n this.trs.push(this.emptyRule)\n },\n clearEmpty() {\n if (this.trs[0] && this.trs[0]._isEmpty) {\n this.trs.splice(0, 1)\n }\n },\n delRaw(idx) {\n if (\n this.disabled ||\n !this.deletable ||\n (this.min > 0 && this.trs.length <= this.min)\n ) {\n return\n }\n this.trs.splice(idx, 1)\n this.updateValue()\n if (this.trs.length) {\n this.trs.forEach((tr) => this.updateRaw(tr))\n } else {\n this.addEmpty()\n }\n this.$emit('delete', idx)\n },\n addRaw(flag) {\n if (flag && this.disabled) {\n return\n }\n const tr = this.formCreateInject.form.parseJson(this.copyTrs)[0]\n if (this.trs.length === 1 && this.trs[0]._isEmpty) {\n this.trs.splice(0, 1)\n }\n this.trs.push(tr)\n this.updateRaw(tr)\n if (flag) {\n this.$emit('add', this.trs.length)\n this.updateValue()\n }\n },\n updateRaw(tr) {\n const idx = this.trs.indexOf(tr)\n tr.children[0].props.innerText = idx + 1\n tr.children[tr.children.length - 1].children[0].props.onClick = () => {\n this.delRaw(idx)\n }\n },\n loadRule() {\n const header = [\n {\n type: 'th',\n native: true,\n class: '_fc-tf-head-idx',\n props: {\n innerText: '#'\n }\n }\n ]\n let body = [\n {\n type: 'td',\n class: '_fc-tf-idx',\n native: true,\n props: {\n innerText: '0'\n }\n }\n ]\n this.columns.forEach((column) => {\n header.push({\n type: 'th',\n native: true,\n style: {\n ...(column.style || {}),\n textAlign: column.align || 'center'\n },\n class: column.required ? '_fc-tf-head-required' : '',\n props: {\n innerText: column.label || ''\n }\n })\n body.push({\n type: 'td',\n native: true,\n children: [...(column.rule || [])]\n })\n })\n header.push({\n type: 'th',\n native: true,\n class: '_fc-tf-edit fc-clock',\n props: {\n innerText: this.formCreateInject.t('operation') || '操作'\n }\n })\n body.push({\n type: 'td',\n native: true,\n class: '_fc-tf-btn fc-clock',\n children: [\n {\n type: 'i',\n native: true,\n class: 'fc-icon icon-delete',\n props: {}\n }\n ]\n })\n this.copyTrs = this.formCreateInject.form.toJson([\n {\n type: 'tr',\n native: true,\n subRule: true,\n children: body\n }\n ])\n this.rule = [\n {\n type: 'table',\n native: true,\n class: '_fc-tf-table',\n props: {\n border: '1',\n cellspacing: '0',\n cellpadding: '0'\n },\n children: [\n {\n type: 'thead',\n native: true,\n children: [\n {\n type: 'tr',\n native: true,\n children: header\n }\n ]\n },\n {\n type: 'tbody',\n native: true,\n children: this.trs\n }\n ]\n }\n ]\n }\n },\n created() {\n this.loadRule()\n },\n mounted() {\n this.updateTable()\n }\n}\n</script>\n","<template>\n <div class=\"_fc-table-form\" :class=\"{ '_fc-disabled': disabled }\">\n <component\n :is=\"Form\"\n :option=\"options\"\n :rule=\"rule\"\n :extendOption=\"true\"\n :disabled=\"disabled\"\n @change=\"formChange\"\n v-model:api=\"fapi\"\n @emit-event=\"$emit\"\n ></component>\n <a-button\n type=\"link\"\n class=\"fc-clock\"\n v-if=\"addable && (!max || max > this.trs.length)\"\n @click=\"addRaw(true)\"\n :disabled=\"disabled\"\n ><i class=\"fc-icon icon-add-circle\" style=\"font-weight: 700\"></i>\n {{ formCreateInject.t('add') || '添加' }}\n </a-button>\n </div>\n</template>\n\n<script>\nimport { markRaw, reactive } from 'vue'\n\nexport default {\n name: 'TableForm',\n emits: ['change', 'add', 'delete', 'update:modelValue'],\n props: {\n formCreateInject: Object,\n modelValue: {\n type: Array,\n default: () => []\n },\n columns: {\n type: Array,\n required: true,\n default: () => []\n },\n filterEmptyColumn: {\n type: Boolean,\n default: true\n },\n deletable: {\n type: Boolean,\n default: true\n },\n addable: {\n type: Boolean,\n default: true\n },\n options: {\n type: Object,\n default: () =>\n reactive({\n submitBtn: false,\n resetBtn: false\n })\n },\n min: Number,\n max: Number,\n disabled: Boolean\n },\n watch: {\n modelValue: {\n handler() {\n this.updateTable()\n },\n deep: true\n },\n 'formCreateInject.preview': function (n) {\n this.emptyRule.children[0].props.colspan =\n this.columns.length + (n ? 1 : 2)\n }\n },\n data() {\n return {\n rule: [],\n trs: [],\n fapi: {},\n Form: markRaw(this.formCreateInject.form.$form()),\n copyTrs: '',\n oldValue: '',\n emptyRule: {\n type: 'tr',\n _isEmpty: true,\n native: true,\n subRule: true,\n children: [\n {\n type: 'td',\n style: {\n textAlign: 'center'\n },\n native: true,\n subRule: true,\n props: {\n colspan:\n this.columns.length + (this.formCreateInject.preview ? 1 : 2)\n },\n children: [this.formCreateInject.t('dataEmpty') || '暂无数据']\n }\n ]\n }\n }\n },\n methods: {\n formChange() {\n this.updateValue()\n },\n updateValue() {\n const value = this.trs\n .map((tr, idx) => {\n return {\n ...(this.modelValue[idx] || {}),\n ...this.fapi.getChildrenFormData(tr)\n }\n })\n .filter((v) => {\n if (!this.filterEmptyColumn) {\n return true\n }\n if (v === undefined || v === null) {\n return false\n }\n let flag = false\n Object.keys(v).forEach((k) => {\n flag = flag || (v[k] !== undefined && v[k] !== '' && v[k] !== null)\n })\n return flag\n })\n const str = JSON.stringify(value)\n if (str !== this.oldValue) {\n this.oldValue = str\n this.$emit('update:modelValue', value)\n this.$emit('change', value)\n }\n },\n setRawData(idx, formData) {\n const raw = this.trs[idx]\n this.fapi.setChildrenFormData(raw, formData, true)\n },\n updateTable() {\n const str = JSON.stringify(this.modelValue)\n if (this.oldValue === str) {\n return\n }\n this.oldValue = str\n this.trs = this.trs.splice(0, this.modelValue.length)\n if (!this.modelValue.length) {\n this.addEmpty()\n } else {\n this.clearEmpty()\n }\n this.modelValue.forEach((data, idx) => {\n if (!this.trs[idx]) {\n this.addRaw()\n }\n this.setRawData(idx, data || {})\n })\n this.rule[0].children[1].children = this.trs\n },\n addEmpty() {\n if (this.trs.length) {\n this.trs.splice(0, this.trs.length)\n }\n this.trs.push(this.emptyRule)\n },\n clearEmpty() {\n if (this.trs[0] && this.trs[0]._isEmpty) {\n this.trs.splice(0, 1)\n }\n },\n delRaw(idx) {\n if (\n this.disabled ||\n !this.deletable ||\n (this.min > 0 && this.trs.length <= this.min)\n ) {\n return\n }\n this.trs.splice(idx, 1)\n this.updateValue()\n if (this.trs.length) {\n this.trs.forEach((tr) => this.updateRaw(tr))\n } else {\n this.addEmpty()\n }\n this.$emit('delete', idx)\n },\n addRaw(flag) {\n if (flag && this.disabled) {\n return\n }\n const tr = this.formCreateInject.form.parseJson(this.copyTrs)[0]\n if (this.trs.length === 1 && this.trs[0]._isEmpty) {\n this.trs.splice(0, 1)\n }\n this.trs.push(tr)\n this.updateRaw(tr)\n if (flag) {\n this.$emit('add', this.trs.length)\n this.updateValue()\n }\n },\n updateRaw(tr) {\n const idx = this.trs.indexOf(tr)\n tr.children[0].props.innerText = idx + 1\n tr.children[tr.children.length - 1].children[0].props.onClick = () => {\n this.delRaw(idx)\n }\n },\n loadRule() {\n const header = [\n {\n type: 'th',\n native: true,\n class: '_fc-tf-head-idx',\n props: {\n innerText: '#'\n }\n }\n ]\n let body = [\n {\n type: 'td',\n class: '_fc-tf-idx',\n native: true,\n props: {\n innerText: '0'\n }\n }\n ]\n this.columns.forEach((column) => {\n header.push({\n type: 'th',\n native: true,\n style: {\n ...(column.style || {}),\n textAlign: column.align || 'center'\n },\n class: column.required ? '_fc-tf-head-required' : '',\n props: {\n innerText: column.label || ''\n }\n })\n body.push({\n type: 'td',\n native: true,\n children: [...(column.rule || [])]\n })\n })\n header.push({\n type: 'th',\n native: true,\n class: '_fc-tf-edit fc-clock',\n props: {\n innerText: this.formCreateInject.t('operation') || '操作'\n }\n })\n body.push({\n type: 'td',\n native: true,\n class: '_fc-tf-btn fc-clock',\n children: [\n {\n type: 'i',\n native: true,\n class: 'fc-icon icon-delete',\n props: {}\n }\n ]\n })\n this.copyTrs = this.formCreateInject.form.toJson([\n {\n type: 'tr',\n native: true,\n subRule: true,\n children: body\n }\n ])\n this.rule = [\n {\n type: 'table',\n native: true,\n class: '_fc-tf-table',\n props: {\n border: '1',\n cellspacing: '0',\n cellpadding: '0'\n },\n children: [\n {\n type: 'thead',\n native: true,\n children: [\n {\n type: 'tr',\n native: true,\n children: header\n }\n ]\n },\n {\n type: 'tbody',\n native: true,\n children: this.trs\n }\n ]\n }\n ]\n }\n },\n created() {\n this.loadRule()\n },\n mounted() {\n this.updateTable()\n }\n}\n</script>\n","<template>\n <div class=\"_fd-table-form\">\n <div class=\"_fd-tf-wrap\" v-if=\"$slots.default\">\n <slot></slot>\n </div>\n <div class=\"_fc-child-empty\" v-else></div>\n </div>\n</template>\n\n<script>\nimport { defineComponent } from 'vue'\n\nexport default defineComponent({\n name: 'TableFormView',\n data() {\n return {}\n }\n})\n</script>\n","<template>\n <div class=\"_fd-table-form\">\n <div class=\"_fd-tf-wrap\" v-if=\"$slots.default\">\n <slot></slot>\n </div>\n <div class=\"_fc-child-empty\" v-else></div>\n </div>\n</template>\n\n<script>\nimport { defineComponent } from 'vue'\n\nexport default defineComponent({\n name: 'TableFormView',\n data() {\n return {}\n }\n})\n</script>\n","<template>\n <div class=\"_fd-tf-col\" :style=\"colStyle\">\n <div class=\"_fd-tf-title\" :style=\"{ textAlign: align || 'center' }\">\n <span v-if=\"required\" class=\"_fd-tf-required\">*</span>{{ label || '' }}\n </div>\n <div class=\"_fd-tf-con\">\n <slot></slot>\n </div>\n </div>\n</template>\n\n<script>\nimport is from '@form-create/utils/lib/type'\nimport { defineComponent } from 'vue'\n\nexport default defineComponent({\n name: 'TableFormColumnView',\n props: {\n label: String,\n align: String,\n width: [Number, String],\n color: String,\n required: Boolean\n },\n computed: {\n colStyle() {\n const w = this.width\n const style = {\n width: is.Number(w) ? `${w}px` : !w || w === 'auto' ? '180px' : w\n }\n if (this.color) {\n style.color = this.color\n }\n return style\n }\n },\n data() {\n return {}\n }\n})\n</script>\n","<template>\n <div class=\"_fd-tf-col\" :style=\"colStyle\">\n <div class=\"_fd-tf-title\" :style=\"{ textAlign: align || 'center' }\">\n <span v-if=\"required\" class=\"_fd-tf-required\">*</span>{{ label || '' }}\n </div>\n <div class=\"_fd-tf-con\">\n <slot></slot>\n </div>\n </div>\n</template>\n\n<script>\nimport is from '@form-create/utils/lib/type'\nimport { defineComponent } from 'vue'\n\nexport default defineComponent({\n name: 'TableFormColumnView',\n props: {\n label: String,\n align: String,\n width: [Number, String],\n color: String,\n required: Boolean\n },\n computed: {\n colStyle() {\n const w = this.width\n const style = {\n width: is.Number(w) ? `${w}px` : !w || w === 'auto' ? '180px' : w\n }\n if (this.color) {\n style.color = this.color\n }\n return style\n }\n },\n data() {\n return {}\n }\n})\n</script>\n","import upload from '@longhongguo/component-antdv-upload/src/index'\nimport frame from '@form-create/component-antdv-frame/src/index'\nimport group from '@form-create/component-antdv-group/src/index'\nimport subForm from '@form-create/component-subform/src/index'\nimport QuestionCircleOutlined from './icon/QuestionCircleOutlined.vue'\nimport CusSelect from './CusSelect/index.vue'\nimport CusStoreSelect from './CusStoreSelect/index.vue'\nimport CusUserSelect from './CusUserSelect/index.vue'\nimport TableForm from './tableForm/TableForm.vue'\nimport TableFormView from './tableForm/TableFormView.vue'\nimport TableFormColumnView from './tableForm/TableFormColumnView.vue'\n\nexport default [\n upload,\n frame,\n group,\n subForm,\n QuestionCircleOutlined,\n CusSelect,\n CusStoreSelect,\n CusUserSelect,\n TableForm,\n TableFormView,\n TableFormColumnView\n]\n","import {hasProperty} from '@form-create/utils/lib/type';\r\n\r\nexport default {\r\n name: 'checkbox',\r\n modelField: 'value',\r\n mergeProp(ctx) {\r\n const props = ctx.prop.props;\r\n if (!hasProperty(props, 'options'))\r\n props.options = ctx.prop.options || [];\r\n }\r\n\r\n}\r\n","import checkbox from './checkbox';\n\nexport default {\n ...checkbox, name: 'radio'\n};\n","import checkbox from './checkbox'\nimport { hasProperty } from '@form-create/utils/lib/type'\n\nexport default {\n ...checkbox,\n name: 'select',\n mergeProp(ctx) {\n const props = ctx.prop.props\n if (!hasProperty(props, 'options')) props.options = ctx.prop.options || []\n\n // 检测 loading 状态:从 effectData('fetch') 中获取 loading 状态\n const fetchData = ctx.effectData('fetch')\n const isLoading = fetchData && fetchData.loading === true\n\n // 如果正在加载,设置 disabled 和 loading\n if (isLoading) {\n props.disabled = true\n props.loading = true\n }\n },\n render(children, ctx) {\n // 检测 loading 状态(与 mergeProp 中的逻辑保持一致)\n const fetchData = ctx.effectData('fetch')\n const isLoading = fetchData && fetchData.loading === true\n\n // 如果有 loading 插槽且正在加载,将 loading 插槽传递给组件的 notFoundContent 插槽\n if (isLoading && children.loading) {\n // 将 loading 插槽合并到 children 中,作为 notFoundContent\n const newChildren = { ...children }\n newChildren.notFoundContent = children.loading\n return ctx.$render.defaultRender(ctx, newChildren)\n }\n\n // 调用默认渲染\n return ctx.$render.defaultRender(ctx, children)\n }\n}\n","import { hasProperty } from '@form-create/utils/lib/type'\r\nimport { parseFn } from '@form-create/utils/lib/json'\r\nimport is from '@form-create/utils/lib/type'\r\nimport deepSet from '@form-create/utils/lib/deepset'\r\n\r\nexport default {\r\n name: 'cascader',\r\n mergeProp(ctx) {\r\n const props = ctx.prop.props\r\n if (!hasProperty(props, 'options')) props.options = ctx.prop.options || []\r\n\r\n // 检测 loading 状态:从 effectData('fetch') 中获取 loading 状态\r\n const fetchData = ctx.effectData('fetch')\r\n const isLoading = fetchData && fetchData.loading === true\r\n\r\n // 如果正在加载,设置 disabled 和 loading\r\n if (isLoading) {\r\n props.disabled = true\r\n props.loading = true\r\n }\r\n\r\n // 处理 loadData 函数\r\n if (props.loadData) {\r\n const api = ctx.$handle?.api\r\n const rule = ctx.rule\r\n const ctxRef = ctx\r\n\r\n // 解析函数(如果是字符串)\r\n let parsedFn = is.String(props.loadData)\r\n ? parseFn(props.loadData)\r\n : props.loadData\r\n\r\n // 如果不是函数,尝试包装\r\n if (!is.Function(parsedFn) && is.String(props.loadData)) {\r\n try {\r\n const code = props.loadData.trim()\r\n if (\r\n !code.startsWith('function') &&\r\n !code.startsWith('[[FORM-CREATE-PREFIX-function') &&\r\n !code.startsWith('$FNX:')\r\n ) {\r\n parsedFn = new Function(\r\n 'selectedOptions',\r\n 'options',\r\n 'updateOptions',\r\n 'api',\r\n 'rule',\r\n code\r\n )\r\n }\r\n } catch (e) {\r\n console.error('Failed to parse loadData:', e)\r\n }\r\n }\r\n\r\n if (is.Function(parsedFn)) {\r\n // 包装 loadData 函数\r\n props.loadData = function (selectedOptions) {\r\n if (!selectedOptions || selectedOptions.length === 0) return\r\n\r\n const targetOption = selectedOptions[selectedOptions.length - 1]\r\n\r\n if (targetOption?.isLeaf === true) {\r\n return\r\n }\r\n\r\n const options = props.options || []\r\n\r\n // 创建 updateOptions 函数,完全按照 effect.fetch 的方式\r\n // 关键:effect.fetch 使用 deepSet(inject.getProp(), 'props.options', val) 然后 api.sync(rule)\r\n const updateOptions = () => {\r\n // 关键:创建新数组时,同时创建新对象,确保引用完全改变\r\n // 这样可以触发 Vue 的响应式更新,即使对象属性被修改了\r\n const currentOptions = props.options || []\r\n\r\n // 找到 targetOption 在数组中的索引\r\n let targetIndex = -1\r\n if (targetOption) {\r\n targetIndex = currentOptions.findIndex(\r\n (item) =>\r\n item.value === targetOption.value ||\r\n item.id === targetOption.id ||\r\n item === targetOption\r\n )\r\n }\r\n\r\n const newOptions = currentOptions.map((item, index) => {\r\n // 如果是 targetOption,创建包含所有修改的新对象\r\n if (index === targetIndex && targetOption) {\r\n const newTarget = { ...targetOption }\r\n return newTarget\r\n }\r\n // 其他对象创建新引用(浅拷贝即可)\r\n return { ...item }\r\n })\r\n\r\n // 完全按照 effect.fetch 的方式:使用 deepSet 在响应式对象上设置值\r\n // effect.fetch 使用: deepSet(inject.getProp(), 'props.options', val)\r\n // inject.getProp() 返回 ctx.effectData('fetch')\r\n // 所以我们应该在同一个位置设置:ctxRef.effectData('fetch')\r\n const fetchData = ctxRef.effectData('fetch')\r\n if (fetchData) {\r\n // 关键:在 fetchData 上设置,就像 effect.fetch 那样\r\n deepSet(fetchData, 'props.options', newOptions)\r\n }\r\n\r\n // 同时直接更新 props.options(这是最终传递给组件的值)\r\n props.options = newOptions\r\n\r\n // 同步到 ctx.prop.props.options(确保 mergeRule 能获取到最新值)\r\n if (ctxRef.prop?.props) {\r\n ctxRef.prop.props.options = newOptions\r\n }\r\n\r\n // 同步到 rule.props.options\r\n if (ctxRef.rule?.props) {\r\n ctxRef.rule.props.options = newOptions\r\n }\r\n\r\n // 调用 api.sync 触发更新,就像 effect.fetch 那样\r\n if (api && rule) {\r\n api.sync(rule)\r\n }\r\n\r\n // 刷新组件\r\n if (ctxRef.$handle) {\r\n ctxRef.$handle.refresh()\r\n }\r\n }\r\n\r\n // 关键:在调用用户函数之前,立即设置 loading 并更新\r\n // 这样确保 loading 状态能立即显示\r\n if (targetOption) {\r\n targetOption.loading = true\r\n updateOptions()\r\n }\r\n\r\n // 调用用户函数\r\n const result = parsedFn.call(\r\n this,\r\n selectedOptions,\r\n options,\r\n updateOptions,\r\n api,\r\n rule\r\n )\r\n\r\n // 如果用户函数返回 Promise,等待完成\r\n if (result && typeof result.then === 'function') {\r\n return result.finally(() => {\r\n updateOptions()\r\n })\r\n }\r\n\r\n return result\r\n }\r\n }\r\n }\r\n },\r\n render(children, ctx) {\r\n // 检测 loading 状态(与 mergeProp 中的逻辑保持一致)\r\n const fetchData = ctx.effectData('fetch')\r\n const isLoading = fetchData && fetchData.loading === true\r\n\r\n // 如果有 loading 插槽且正在加载,将 loading 插槽传递给组件的 notFoundContent 插槽\r\n if (isLoading && children.loading) {\r\n // 将 loading 插槽合并到 children 中,作为 notFoundContent\r\n const newChildren = { ...children }\r\n newChildren.notFoundContent = children.loading\r\n return ctx.$render.defaultRender(ctx, newChildren)\r\n }\r\n\r\n // 调用默认渲染\r\n return ctx.$render.defaultRender(ctx, children)\r\n }\r\n}\r\n","import { creatorFactory } from '@longhongguo/form-create-core/src/index'\n\nconst FORMAT_TYPE = {\n date: 'YYYY-MM-DD',\n month: 'YYYY-MM',\n week: 'YYYY-wo',\n quarter: 'YYYY-qQ',\n year: 'YYYY'\n}\n\nconst name = 'datePicker'\n\nexport default {\n name,\n maker: (function () {\n return ['date', 'month', 'week'].reduce(\n (initial, type) => {\n initial[type] = creatorFactory(name, { type })\n return initial\n },\n {\n dateRange: creatorFactory(name, { type: 'range' }),\n datetimeRange: creatorFactory(name, (m) =>\n m.props({ type: 'range', showTime: true })\n )\n }\n )\n })(),\n modelField: 'value',\n mergeProp(ctx) {\n const props = ctx.prop.props\n const type = props.type || props.picker\n if (!props.valueFormat) {\n props.valueFormat =\n (FORMAT_TYPE[type] || FORMAT_TYPE['date']) +\n (props.showTime && (!type || type === 'date') ? ' HH:mm:ss' : '')\n }\n },\n render(children, ctx) {\n return ctx.$render.vNode[\n (ctx.prop.props.range === true ? 'range' : 'date') + 'Picker'\n ](ctx.prop, children)\n }\n}\n","import { creatorFactory } from '@longhongguo/form-create-core/src/index'\n\nconst name = 'hidden'\n\nexport default {\n name,\n maker: {\n [name]: (field, value) => creatorFactory(name)('', field, value)\n },\n render() {\n return []\n }\n}\n","import is from '@form-create/utils/lib/type'\r\nimport { watch, toRef } from 'vue'\r\n\r\nexport default {\r\n name: 'text',\r\n // 设置 loadChildren 为 false,避免 children 被当作子组件处理\r\n // text 的 children 只是简单的文本内容,不需要作为子组件加载\r\n loadChildren: false,\r\n // 组件挂载后,手动触发一次 loadData 更新,确保表单数据准备好后再获取初始值\r\n mounted(ctx) {\r\n // 如果是动态绑定的 Text 组件,在挂载后手动解析模板并更新值\r\n const props = ctx.rule.props || {}\r\n const bindField =\r\n ctx.rule.bindField || props.bindField || ctx.prop.props?.bindField\r\n const template =\r\n ctx.rule.template || props.template || ctx.prop.props?.template\r\n\r\n if (template || bindField) {\r\n // 延迟执行,确保表单数据已经准备好\r\n setTimeout(() => {\r\n if (ctx.$handle && ctx.$handle.api) {\r\n try {\r\n let value = ''\r\n\r\n // 如果是模板模式,手动解析模板字符串\r\n if (template) {\r\n const formData = ctx.$handle.api.formData()\r\n // 使用 loadStrVar 解析模板,传入一个 get 函数来获取表单数据\r\n value = ctx.$handle.loadStrVar(\r\n template,\r\n (field) => {\r\n // 使用 api.getValue 获取表单字段值\r\n const val = ctx.$handle.api.getValue(field)\r\n // 如果 getValue 返回 undefined,尝试从 formData 直接获取\r\n if (\r\n val === undefined &&\r\n formData &&\r\n formData[field] !== undefined\r\n ) {\r\n return formData[field]\r\n }\r\n return val\r\n },\r\n null\r\n )\r\n }\r\n // 如果是字段绑定模式,直接获取字段值\r\n else if (bindField) {\r\n value = ctx.$handle.api.getValue(bindField) || ''\r\n }\r\n\r\n // 更新 rule.children(转换为字符串)\r\n if (value != null) {\r\n if (!ctx.rule.children) {\r\n ctx.rule.children = []\r\n }\r\n ctx.rule.children[0] = String(value)\r\n // 触发同步和刷新\r\n ctx.$handle.api.sync(ctx.rule)\r\n ctx.$handle.refresh()\r\n }\r\n } catch (e) {\r\n // 静默处理错误\r\n }\r\n }\r\n }, 500) // 增加延迟,确保表单数据完全准备好\r\n }\r\n },\r\n // 处理 children 的渲染,将 children 数组转换为可渲染的内容\r\n renderChildren(children, ctx) {\r\n // 使用 computed 确保响应式更新\r\n // 每次 rule.children 变化时,都会重新计算\r\n return {\r\n default: () => {\r\n // 每次都重新从 rule.children 获取最新值(loadData 会更新这个值)\r\n // 不要使用闭包中的 children 参数,因为它可能是旧值\r\n let currentChildren = ctx.rule?.children\r\n\r\n // 如果 rule.children 不存在,才使用传入的 children 参数(初始值)\r\n if (!currentChildren) {\r\n currentChildren = children\r\n }\r\n\r\n // 确保是数组\r\n const childrenArray = Array.isArray(currentChildren)\r\n ? currentChildren\r\n : [currentChildren]\r\n\r\n // 过滤并转换字符串,参考 html parser 的实现\r\n const text = childrenArray\r\n .filter((v) => v !== null && v !== undefined)\r\n .map((v) => {\r\n if (is.String(v)) {\r\n return v\r\n }\r\n // 如果是对象或其他类型,转换为字符串\r\n return String(v)\r\n })\r\n .join('')\r\n\r\n return text || ''\r\n }\r\n }\r\n },\r\n mergeProp(ctx) {\r\n // 确保没有 field 的组件能正常显示\r\n // 如果 prop.native 未设置,默认设置为 false,让组件被 makeWrap 包装(这样可以显示 title)\r\n // 但如果需要直接渲染,可以设置 native: true\r\n\r\n // 支持从多个位置读取配置:\r\n // 1. ctx.rule.bindField / ctx.rule.template(直接在 rule 中)\r\n // 2. ctx.rule.props.bindField / ctx.rule.props.template(在 props 中)\r\n // 3. ctx.prop.props.bindField / ctx.prop.props.template(在 prop.props 中)\r\n const props = ctx.rule.props || {}\r\n const bindField =\r\n ctx.rule.bindField || props.bindField || ctx.prop.props?.bindField\r\n const template =\r\n ctx.rule.template || props.template || ctx.prop.props?.template\r\n let bindMode =\r\n ctx.rule.bindMode || props.bindMode || ctx.prop.props?.bindMode\r\n\r\n // 如果没有设置 bindMode,根据是否有 bindField 或 template 自动判断\r\n if (!bindMode) {\r\n if (template) {\r\n bindMode = 'template'\r\n } else if (bindField) {\r\n bindMode = 'field'\r\n } else {\r\n bindMode = 'static'\r\n }\r\n }\r\n\r\n // 如果配置了 bindField(绑定单个字段),使用 loadData 来实现动态绑定\r\n if (bindMode === 'field' && bindField) {\r\n const loadDataConfig = {\r\n attr: bindField,\r\n to: 'child',\r\n modify: true,\r\n // 增加 debounce 延迟,避免频繁更新导致循环\r\n wait: 300,\r\n // 确保 watch 开启,但通过 debounce 控制频率\r\n watch: true\r\n }\r\n\r\n // 添加到 effect 中(避免重复添加)\r\n if (!ctx.rule.effect) {\r\n ctx.rule.effect = {}\r\n }\r\n if (!ctx.rule.effect.loadData) {\r\n ctx.rule.effect.loadData = []\r\n }\r\n // 检查是否已存在相同的配置,避免重复添加\r\n const exists = ctx.rule.effect.loadData.some(\r\n (item) => item.attr === bindField && item.to === 'child'\r\n )\r\n if (!exists) {\r\n ctx.rule.effect.loadData.push(loadDataConfig)\r\n // 手动触发 effect 来确保 loadData provider 被调用\r\n // 使用 effect 方法,它会正确设置 ctx 和 input\r\n if (ctx.$handle && ctx.$handle.effect) {\r\n ctx.$handle.effect(ctx, 'loaded')\r\n }\r\n }\r\n }\r\n // 如果配置了 template(模板字符串),支持多个字段绑定\r\n else if (bindMode === 'template' && template) {\r\n const loadDataConfig = {\r\n template: template,\r\n to: 'child',\r\n modify: true,\r\n // 增加 debounce 延迟,避免频繁更新导致循环\r\n wait: 300,\r\n // 确保 watch 开启,但通过 debounce 控制频率\r\n watch: true\r\n }\r\n\r\n if (!ctx.rule.effect) {\r\n ctx.rule.effect = {}\r\n }\r\n if (!ctx.rule.effect.loadData) {\r\n ctx.rule.effect.loadData = []\r\n }\r\n // 检查是否已存在相同的配置,避免重复添加\r\n const exists = ctx.rule.effect.loadData.some(\r\n (item) => item.template === template && item.to === 'child'\r\n )\r\n if (!exists) {\r\n ctx.rule.effect.loadData.push(loadDataConfig)\r\n // 手动触发 effect 来确保 loadData provider 被调用\r\n if (ctx.$handle && ctx.$handle.effect) {\r\n ctx.$handle.effect(ctx, 'loaded')\r\n // 同时手动添加 watch,监听 effect.loadData 的变化\r\n // 这样当 effect.loadData 被修改时,也会触发 provider\r\n if (!ctx._textLoadDataWatched) {\r\n ctx._textLoadDataWatched = true\r\n const loadDataRef = toRef(ctx.rule.effect, 'loadData')\r\n ctx.watch.push(\r\n watch(\r\n loadDataRef,\r\n (newVal, oldVal) => {\r\n ctx.$handle.effect(ctx, 'watch', { loadData: newVal })\r\n },\r\n { deep: true }\r\n )\r\n )\r\n }\r\n }\r\n }\r\n }\r\n // 静态模式:使用 formCreateChild 或 children 作为内容\r\n // formCreateChild 会作为 children[0] 渲染,如果已有 children,也会正常渲染\r\n\r\n // 如果配置了 formCreateChild,将其转换为 children\r\n if (ctx.rule.formCreateChild != null && !ctx.rule.children) {\r\n ctx.rule.children = [ctx.rule.formCreateChild]\r\n }\r\n\r\n // 确保 children 存在(如果没有设置,默认为空数组)\r\n if (!ctx.rule.children) {\r\n ctx.rule.children = []\r\n }\r\n\r\n // 对于动态绑定的情况,初始化时设置一个占位符,确保组件能被渲染\r\n // loadData 会在初始化后立即执行一次,更新这个值\r\n if (\r\n (bindMode === 'field' && bindField) ||\r\n (bindMode === 'template' && template)\r\n ) {\r\n // 如果 children 是空数组或未设置,设置为一个非空字符串\r\n // 这样确保组件会被渲染,然后 loadData 会更新内容\r\n if (\r\n !ctx.rule.children ||\r\n (Array.isArray(ctx.rule.children) && ctx.rule.children.length === 0)\r\n ) {\r\n // 对于 template 模式,先不设置占位符,等待 loadData 执行\r\n // 因为如果设置了占位符,可能会覆盖 loadData 的结果\r\n if (bindMode === 'template') {\r\n // template 模式下,等待 loadData 执行后更新\r\n // 但为了确保组件能渲染,至少设置一个空字符串\r\n ctx.rule.children = ['']\r\n } else {\r\n // field 模式下,设置一个空格字符串作为占位符\r\n ctx.rule.children = [' ']\r\n }\r\n }\r\n }\r\n },\r\n render(children, ctx) {\r\n // text 组件使用 div 渲染,内容来自 children\r\n // 使用 children.default() 获取响应式内容,参考 html parser 的实现\r\n\r\n // 获取文本内容(children.default() 会从 renderChildren 返回的响应式函数中获取)\r\n // renderChildren 返回的 default 函数会从 ctx.rule.children 获取最新值\r\n let text = ''\r\n if (children && typeof children.default === 'function') {\r\n try {\r\n text = children.default() || ''\r\n } catch (e) {\r\n text = ''\r\n }\r\n }\r\n\r\n // 确保 text 是字符串\r\n if (text == null || text === undefined) {\r\n text = ''\r\n } else {\r\n text = String(text)\r\n }\r\n\r\n // 复制 prop,避免修改原始对象\r\n const prop = { ...ctx.prop }\r\n if (!prop.props) {\r\n prop.props = {}\r\n }\r\n\r\n // 确保 type 是 'div'\r\n if (prop.type === 'text') {\r\n prop.type = 'div'\r\n }\r\n\r\n delete prop.props.innerHTML\r\n\r\n // 直接使用 vNode.make 渲染 div,文本作为子节点\r\n // 即使 text 为空,也传递 [text] 确保渲染出 div\r\n const vnode = ctx.vNode.make('div', prop, [text])\r\n return vnode\r\n }\r\n}\r\n","import { creatorFactory } from '@longhongguo/form-create-core/src/index'\n\nconst name = 'input'\nexport default {\n name,\n maker: (function () {\n return ['password', 'url', 'email', 'text', 'textarea', 'search'].reduce(\n (maker, type) => {\n maker[type] = creatorFactory(name, { type })\n return maker\n },\n {\n idate: creatorFactory(name, { type: 'date' })\n }\n )\n })(),\n modelField: 'value',\n render(children, ctx) {\n let type = ctx.prop.props.type\n if (['textarea', 'search', 'password'].indexOf(type) === -1) type = 'input'\n\n type =\n {\n textarea: 'aTextarea',\n search: 'aInputSearch',\n password: 'aInputPassword'\n }[type] || 'aInput'\n return ctx.$render.vNode.make(type, ctx.prop, children)\n }\n}\n","export default {\n name: 'timePicker',\n modelField: 'value',\n mergeProp(ctx) {\n const props = ctx.prop.props;\n if (!props.valueFormat) {\n props.valueFormat = 'HH:mm:ss';\n }\n },\n render(children, ctx) {\n return ctx.$render.vNode['time' +( ctx.prop.props.range === true ? 'Range' : '') + 'Picker'](ctx.prop, children);\n }\n\n}\n\n","export default {\n name: 'tree',\n modelField: 'checkedKeys',\n mergeProp(ctx) {\n const props = ctx.prop.props;\n if (!props.fieldNames)\n props.fieldNames = {\n key: 'id'\n };\n else if (!props.fieldNames.key) props.fieldNames.key = 'id';\n props.checkedKeys = ctx.rule.value;\n props.checkable = true;\n },\n\n}\n\n","export default {\n name: 'FcRow',\n render(_, ctx) {\n return ctx.vNode.col({props: {span: 24}}, {\n default: () => [\n ctx.vNode.row(ctx.prop, _)\n ]\n })\n }\n}\n","import timePicker from './timePicker';\n\nconst name = 'timeRangePicker';\n\nexport default {\n ...timePicker,\n name,\n render(children, ctx) {\n return ctx.$render.vNode['timeRangePicker'](ctx.prop, children);\n }\n}\n","import checkbox from './checkbox'\nimport radio from './radio'\nimport select from './select'\nimport cascader from './cascader'\nimport datePicker from './datePicker'\nimport hidden from './hidden'\nimport text from './text' // text parser 必须在 input 之前注册,避免被 input 的 maker.text 覆盖\nimport input from './input'\nimport timePicker from './timePicker'\nimport tree from './tree'\nimport row from './row'\nimport rangePicker from './rangePicker'\nimport timeRangePicker from './timeRangePicker'\nimport cusStoreSelect from './cusStoreSelect'\nimport cusUserSelect from './cusUserSelect'\nimport flex from './flex'\nimport space from './space'\nimport spin from './spin'\nimport div from './div'\n\nexport default [\n checkbox,\n datePicker,\n rangePicker,\n hidden,\n text, // text parser 必须在 input 之前,确保 type: 'text' 时优先匹配 text parser\n input,\n timePicker,\n timeRangePicker,\n tree,\n radio,\n select,\n cascader,\n row,\n cusStoreSelect,\n cusUserSelect,\n flex,\n space,\n spin,\n div\n]\n","import datePicker from './datePicker';\n\nconst name = 'rangePicker';\n\nexport default {\n ...datePicker,\n name,\n maker: {},\n render(children, ctx) {\n return ctx.$render.vNode['rangePicker'](ctx.prop, children);\n }\n}\n","import { hasProperty } from '@form-create/utils/lib/type'\r\nimport { nextTick } from 'vue'\r\n\r\nexport default {\r\n name: 'cusStoreSelect',\r\n modelField: 'modelValue',\r\n // 将 form-create 内部的值转换为对象数组格式\r\n toFormValue(value, ctx) {\r\n // 组件内部统一使用对象数组格式 [{value, label, ...}]\r\n if (value === null || value === undefined || value === '') {\r\n return []\r\n }\r\n if (Array.isArray(value)) {\r\n // 确保数组中的每个元素都是对象格式\r\n return value.map((item) => {\r\n if (\r\n typeof item === 'object' &&\r\n item !== null &&\r\n (item.value !== undefined || item.label !== undefined)\r\n ) {\r\n // 已经是对象格式\r\n return item\r\n }\r\n // 如果是单个值,需要转换为对象格式(但此时没有 label,会在组件内部处理)\r\n return item\r\n })\r\n }\r\n // 单个值转换为数组(组件内部会处理对象转换)\r\n return [value]\r\n },\r\n // 将组件返回的数组格式转换为 form-create 内部格式(可选,保持原值)\r\n toValue(formValue, ctx) {\r\n // 保持数组格式,不转换\r\n return formValue\r\n },\r\n mergeProp(ctx) {\r\n const props = ctx.prop.props\r\n // 确保 options 存在\r\n if (!hasProperty(props, 'options')) {\r\n props.options = ctx.prop.options || []\r\n }\r\n // 传递字段名到组件,用于跨窗口通信时标识字段\r\n if (!hasProperty(props, 'field')) {\r\n props.field = ctx.rule.field || ''\r\n }\r\n // 确保初始值转换为数组格式\r\n if (ctx.rule.value !== undefined) {\r\n const currentValue = ctx.rule.value\r\n if (\r\n currentValue === null ||\r\n currentValue === undefined ||\r\n currentValue === ''\r\n ) {\r\n ctx.rule.value = []\r\n } else if (!Array.isArray(currentValue)) {\r\n ctx.rule.value = [currentValue]\r\n }\r\n }\r\n },\r\n render(children, ctx) {\r\n // 使用默认渲染\r\n const vnode = ctx.$render.defaultRender(ctx, children)\r\n\r\n // 添加校验触发逻辑:在值变化时触发校验\r\n if (vnode && vnode.props && vnode.props.on) {\r\n // 保存原始的 update:modelValue 事件处理器(form-create 自动添加的)\r\n const originalUpdateModelValue = vnode.props.on['update:modelValue']\r\n\r\n // 创建校验触发函数\r\n const triggerValidate = () => {\r\n // 延迟触发校验,确保值已经更新完成\r\n // 使用多个 nextTick 确保 form-create 内部的值更新流程完成\r\n nextTick(() => {\r\n nextTick(() => {\r\n try {\r\n // 方式1:通过 field 名称触发校验(推荐)\r\n const fieldName = ctx.rule.field\r\n if (fieldName) {\r\n ctx.$handle.api.validateField(fieldName).catch(() => {\r\n // 校验失败时静默处理,错误会通过 form-item 显示\r\n })\r\n return\r\n }\r\n\r\n // 方式2:通过字段上下文ID触发校验(备用)\r\n const fieldCtx = ctx.$handle.getFieldCtx(ctx.rule.field)\r\n if (fieldCtx && fieldCtx.id) {\r\n ctx.$handle.$manager.validateField(fieldCtx.id).catch(() => {\r\n // 校验失败时静默处理,错误会通过 form-item 显示\r\n })\r\n }\r\n } catch (error) {\r\n // 静默处理错误,避免影响正常流程\r\n console.warn('CusStoreSelect: 触发校验失败', error)\r\n }\r\n })\r\n })\r\n }\r\n\r\n // 包装 update:modelValue 事件,在值更新后触发校验\r\n vnode.props.on['update:modelValue'] = (...args) => {\r\n // 先调用原始的事件处理器(form-create 的 onInput,会更新值和触发其他逻辑)\r\n if (originalUpdateModelValue) {\r\n originalUpdateModelValue(...args)\r\n }\r\n // 触发校验\r\n triggerValidate()\r\n }\r\n\r\n // 同时监听 change 事件,确保所有情况下都能触发校验\r\n const originalChange = vnode.props.on['change']\r\n if (originalChange) {\r\n vnode.props.on['change'] = (...args) => {\r\n // 先调用原始的 change 处理器\r\n originalChange(...args)\r\n // 触发校验\r\n triggerValidate()\r\n }\r\n } else {\r\n // 如果没有原始的 change 处理器,直接添加\r\n vnode.props.on['change'] = triggerValidate\r\n }\r\n }\r\n\r\n return vnode\r\n }\r\n}\r\n","import { hasProperty } from '@form-create/utils/lib/type'\r\nimport { nextTick } from 'vue'\r\n\r\nexport default {\r\n name: 'cusUserSelect',\r\n modelField: 'modelValue',\r\n // 将 form-create 内部的值转换为对象数组格式\r\n toFormValue(value, ctx) {\r\n // 组件内部统一使用对象数组格式 [{value, label, ...}]\r\n if (value === null || value === undefined || value === '') {\r\n return []\r\n }\r\n if (Array.isArray(value)) {\r\n // 确保数组中的每个元素都是对象格式\r\n return value.map((item) => {\r\n if (\r\n typeof item === 'object' &&\r\n item !== null &&\r\n (item.value !== undefined || item.label !== undefined)\r\n ) {\r\n // 已经是对象格式\r\n return item\r\n }\r\n // 如果是单个值,需要转换为对象格式(但此时没有 label,会在组件内部处理)\r\n return item\r\n })\r\n }\r\n // 单个值转换为数组(组件内部会处理对象转换)\r\n return [value]\r\n },\r\n // 将组件返回的数组格式转换为 form-create 内部格式(可选,保持原值)\r\n toValue(formValue, ctx) {\r\n // 保持数组格式,不转换\r\n return formValue\r\n },\r\n mergeProp(ctx) {\r\n const props = ctx.prop.props\r\n // 确保 options 存在\r\n if (!hasProperty(props, 'options')) {\r\n props.options = ctx.prop.options || []\r\n }\r\n // 传递字段名到组件,用于跨窗口通信时标识字段\r\n if (!hasProperty(props, 'field')) {\r\n props.field = ctx.rule.field || ''\r\n }\r\n // 传递 formCreateInject 到组件,用于在组件内部触发校验\r\n if (!hasProperty(props, 'formCreateInject')) {\r\n props.formCreateInject = ctx.inject\r\n }\r\n // 确保初始值转换为数组格式\r\n if (ctx.rule.value !== undefined) {\r\n const currentValue = ctx.rule.value\r\n if (\r\n currentValue === null ||\r\n currentValue === undefined ||\r\n currentValue === ''\r\n ) {\r\n ctx.rule.value = []\r\n } else if (!Array.isArray(currentValue)) {\r\n ctx.rule.value = [currentValue]\r\n }\r\n }\r\n },\r\n render(children, ctx) {\r\n // 使用默认渲染\r\n const vnode = ctx.$render.defaultRender(ctx, children)\r\n\r\n // 添加校验触发逻辑:在值变化时触发校验\r\n if (vnode && vnode.props && vnode.props.on) {\r\n // 保存原始的 update:modelValue 事件处理器(form-create 自动添加的)\r\n const originalUpdateModelValue = vnode.props.on['update:modelValue']\r\n\r\n // 创建校验触发函数\r\n const triggerValidate = () => {\r\n // 延迟触发校验,确保值已经更新完成\r\n // 使用多个 nextTick 确保 form-create 内部的值更新流程完成\r\n nextTick(() => {\r\n nextTick(() => {\r\n try {\r\n // 方式1:通过 field 名称触发校验(推荐)\r\n const fieldName = ctx.rule.field\r\n if (fieldName) {\r\n ctx.$handle.api.validateField(fieldName).catch(() => {\r\n // 校验失败时静默处理,错误会通过 form-item 显示\r\n })\r\n return\r\n }\r\n\r\n // 方式2:通过字段上下文ID触发校验(备用)\r\n const fieldCtx = ctx.$handle.getFieldCtx(ctx.rule.field)\r\n if (fieldCtx && fieldCtx.id) {\r\n ctx.$handle.$manager.validateField(fieldCtx.id).catch(() => {\r\n // 校验失败时静默处理,错误会通过 form-item 显示\r\n })\r\n }\r\n } catch (error) {\r\n // 静默处理错误,避免影响正常流程\r\n console.warn('CusUserSelect: 触发校验失败', error)\r\n }\r\n })\r\n })\r\n }\r\n\r\n // 包装 update:modelValue 事件,在值更新后触发校验\r\n vnode.props.on['update:modelValue'] = (...args) => {\r\n // 先调用原始的事件处理器(form-create 的 onInput,会更新值和触发其他逻辑)\r\n if (originalUpdateModelValue) {\r\n originalUpdateModelValue(...args)\r\n }\r\n // 触发校验\r\n triggerValidate()\r\n }\r\n\r\n // 同时监听 change 事件,确保所有情况下都能触发校验\r\n const originalChange = vnode.props.on['change']\r\n if (originalChange) {\r\n vnode.props.on['change'] = (...args) => {\r\n // 先调用原始的 change 处理器\r\n originalChange(...args)\r\n // 触发校验\r\n triggerValidate()\r\n }\r\n } else {\r\n // 如果没有原始的 change 处理器,直接添加\r\n vnode.props.on['change'] = triggerValidate\r\n }\r\n }\r\n\r\n return vnode\r\n }\r\n}\r\n","export default {\r\n name: 'flex',\r\n mergeProp(ctx) {\r\n // 从 props 中读取 flex 布局配置\r\n const props = ctx.rule.props || {}\r\n const flexDirection = props.flexDirection || ctx.rule.flexDirection || 'row'\r\n const flexWrap = props.flexWrap || ctx.rule.flexWrap || 'nowrap'\r\n const justifyContent =\r\n props.justifyContent || ctx.rule.justifyContent || 'flex-start'\r\n const alignItems = props.alignItems || ctx.rule.alignItems || 'flex-start'\r\n const alignContent =\r\n props.alignContent || ctx.rule.alignContent || 'flex-start'\r\n\r\n // 映射 CSS flexbox 值到 Ant Design Vue Flex 组件的 props\r\n const vertical =\r\n flexDirection === 'column' || flexDirection === 'column-reverse'\r\n const wrap = flexWrap === 'wrap'\r\n\r\n // 映射 justifyContent 到 justify\r\n const justifyMap = {\r\n 'flex-start': 'start',\r\n 'flex-end': 'end',\r\n center: 'center',\r\n 'space-between': 'space-between',\r\n 'space-around': 'space-around',\r\n 'space-evenly': 'space-evenly'\r\n }\r\n const justify = justifyMap[justifyContent] || 'start'\r\n\r\n // 映射 alignItems 到 align\r\n const alignMap = {\r\n 'flex-start': 'start',\r\n 'flex-end': 'end',\r\n center: 'center',\r\n baseline: 'baseline',\r\n stretch: 'stretch'\r\n }\r\n const align = alignMap[alignItems] || 'start'\r\n\r\n // 设置到 prop.props,用于传递给 a-flex 组件\r\n if (!ctx.prop.props) {\r\n ctx.prop.props = {}\r\n }\r\n\r\n // 映射 Ant Design Vue Flex 组件的 props\r\n ctx.prop.props.vertical = vertical\r\n // 注意:不设置 wrap prop,因为 Ant Design Vue 的 Flex 组件的 wrap prop 类型可能不匹配\r\n // 换行功能完全通过 CSS 样式来实现\r\n ctx.prop.props.justify = justify\r\n ctx.prop.props.align = align\r\n\r\n // 如果设置了 gap,也传递\r\n if (props.gap !== undefined) {\r\n ctx.prop.props.gap = props.gap\r\n }\r\n\r\n // 合并样式(不要直接修改 ctx.rule.style,避免响应式循环)\r\n const existingStyle = ctx.rule.style || {}\r\n // 排除已经被 Flex 组件处理的样式\r\n const {\r\n display: userDisplay,\r\n flexDirection: _fd,\r\n flexWrap: _fw,\r\n justifyContent: _jc,\r\n alignItems: _ai,\r\n alignContent: _ac,\r\n ...otherStyles\r\n } = existingStyle\r\n\r\n // 构建样式对象,确保从 props 读取的配置能够应用到样式中\r\n const flexStyles = {\r\n // 保留用户设置的 display,如果没有则设置为 'flex'\r\n display: userDisplay || 'flex',\r\n // 确保 flex 容器占满整行\r\n // 在样式中设置 flexWrap,确保从 props 读取的配置能够生效\r\n // 这是关键的:将 props.flexWrap 的值('wrap' 或 'nowrap')应用到样式中\r\n flexWrap: flexWrap,\r\n // 合并其他用户自定义样式\r\n ...otherStyles\r\n }\r\n\r\n // 如果设置了 alignContent,添加到样式中\r\n if (alignContent && alignContent !== 'flex-start') {\r\n flexStyles.alignContent = alignContent\r\n }\r\n\r\n // 同时设置到 ctx.prop.style 和 ctx.prop.props.style\r\n // form-create 会将 prop.style 应用到组件上,但有时也需要 prop.props.style\r\n // 保留已有的 prop.style 和 prop.props.style,然后合并新的样式\r\n const existingPropStyle = ctx.prop.style || {}\r\n const existingPropsStyle = ctx.prop.props?.style || {}\r\n\r\n // 合并样式到 ctx.prop.style(保留已有样式,新的样式优先)\r\n ctx.prop.style = {\r\n ...existingPropStyle,\r\n ...flexStyles\r\n }\r\n\r\n // 同时也合并到 props.style,确保样式生效\r\n if (!ctx.prop.props) {\r\n ctx.prop.props = {}\r\n }\r\n ctx.prop.props.style = {\r\n ...existingPropsStyle,\r\n ...flexStyles\r\n }\r\n\r\n // 确保 children 存在\r\n if (!ctx.rule.children) {\r\n ctx.rule.children = []\r\n }\r\n\r\n // 为 flex 容器的所有子组件设置 col: false,避免被 a-col 包装\r\n // 这样可以确保子组件直接作为 flex 子项,而不是占满整行\r\n if (ctx.rule.children && Array.isArray(ctx.rule.children)) {\r\n ctx.rule.children.forEach((child) => {\r\n if (\r\n child &&\r\n typeof child === 'object' &&\r\n !child.type === 'DragTool' &&\r\n !child.type === 'DragBox'\r\n ) {\r\n // 只有当 col 未设置或为默认值时才设置\r\n if (child.col === undefined || child.col === null) {\r\n child.col = false\r\n } else if (\r\n child.col &&\r\n typeof child.col === 'object' &&\r\n child.col.show !== false\r\n ) {\r\n child.col.show = false\r\n }\r\n }\r\n })\r\n }\r\n\r\n // 读取 resetMarginBottom 配置,用于重置包裹 flex 的 ant-form-item 的 margin-bottom\r\n const resetMarginBottom =\r\n props.resetMarginBottom ?? ctx.rule.resetMarginBottom ?? false\r\n if (resetMarginBottom) {\r\n // 将 class 添加到 wrap 配置中,使其应用到包裹 flex 的 ant-form-item 上\r\n if (!ctx.rule.wrap) {\r\n ctx.rule.wrap = {}\r\n }\r\n if (typeof ctx.rule.wrap === 'object' && !ctx.rule.wrap.class) {\r\n ctx.rule.wrap.class = ''\r\n }\r\n const wrapClass = typeof ctx.rule.wrap === 'object' \r\n ? (ctx.rule.wrap.class || '').split(' ').filter(Boolean)\r\n : []\r\n if (!wrapClass.includes('_fc-reset-margin-bottom')) {\r\n wrapClass.push('_fc-reset-margin-bottom')\r\n if (typeof ctx.rule.wrap === 'object') {\r\n ctx.rule.wrap.class = wrapClass.join(' ')\r\n }\r\n }\r\n }\r\n },\r\n render(children, ctx) {\r\n // 使用 Ant Design Vue 的 Flex 组件\r\n const prop = { ...ctx.prop }\r\n\r\n // 将 type 设置为 'a-flex',form-create 会自动识别\r\n if (prop.type === 'flex') {\r\n prop.type = 'a-flex'\r\n }\r\n\r\n // 读取 flexDirection 来判断是否是垂直方向\r\n const props = ctx.rule.props || {}\r\n const flexDirection = props.flexDirection || ctx.rule.flexDirection || 'row'\r\n const isVertical =\r\n flexDirection === 'column' || flexDirection === 'column-reverse'\r\n\r\n // 初始化 prop.props 和 prop.class(如果需要的话)\r\n if (!prop.props) {\r\n prop.props = {}\r\n }\r\n\r\n // 添加自定义 class 的辅助函数\r\n const ensureClass = () => {\r\n if (!prop.class) {\r\n prop.class = []\r\n }\r\n if (!Array.isArray(prop.class)) {\r\n prop.class = [prop.class]\r\n }\r\n }\r\n\r\n // 读取 childFlex 配置\r\n const childFlex = ctx.rule.props?.childFlex ?? ctx.rule.childFlex\r\n if (childFlex !== undefined && childFlex !== null && childFlex !== '') {\r\n ensureClass()\r\n if (!prop.class.includes('_fc-flex-container')) {\r\n prop.class.push('_fc-flex-container')\r\n }\r\n\r\n // 通过 CSS 变量传递 flex 值\r\n const flexValue = String(childFlex).trim()\r\n // 合并到样式中,设置 CSS 变量\r\n if (!prop.props.style) {\r\n prop.props.style = {}\r\n }\r\n prop.props.style['--fc-child-flex'] = flexValue\r\n\r\n // 同时也设置到 prop.style\r\n if (!prop.style) {\r\n prop.style = {}\r\n }\r\n prop.style['--fc-child-flex'] = flexValue\r\n }\r\n\r\n // 如果是垂直方向,读取 childWidth 配置(默认 100%)\r\n if (isVertical) {\r\n const childWidth =\r\n ctx.rule.props?.childWidth ?? ctx.rule.childWidth ?? '100%'\r\n\r\n ensureClass()\r\n if (!prop.class.includes('_fc-flex-container')) {\r\n prop.class.push('_fc-flex-container')\r\n }\r\n if (!prop.class.includes('_fc-flex-vertical')) {\r\n prop.class.push('_fc-flex-vertical')\r\n }\r\n\r\n // 通过 CSS 变量传递宽度值\r\n const widthValue = String(childWidth).trim()\r\n if (!prop.props.style) {\r\n prop.props.style = {}\r\n }\r\n prop.props.style['--fc-child-width'] = widthValue\r\n\r\n if (!prop.style) {\r\n prop.style = {}\r\n }\r\n prop.style['--fc-child-width'] = widthValue\r\n }\r\n\r\n // children 会通过 form-create 的机制自动渲染\r\n const childrenNodes = children || []\r\n\r\n // 将 flex 容器包装在 col 中,确保它占满整行(span: 24)\r\n // 这样 flex 容器才能有足够的宽度,子项才能自适应展示\r\n return ctx.vNode.col(\r\n { props: { span: 24 } },\r\n {\r\n default: () => [ctx.vNode.make('a-flex', prop, childrenNodes)]\r\n }\r\n )\r\n }\r\n}\r\n","export default {\r\n name: 'space',\r\n mergeProp(ctx) {\r\n // 从 props 中读取 Space 组件配置\r\n const props = ctx.rule.props || {}\r\n const direction = props.direction || ctx.rule.direction || 'horizontal'\r\n const size = props.size || ctx.rule.size || 'small'\r\n const align = props.align || ctx.rule.align\r\n const wrap = props.wrap || ctx.rule.wrap || false\r\n\r\n // 设置到 prop.props,用于传递给 a-space 组件\r\n if (!ctx.prop.props) {\r\n ctx.prop.props = {}\r\n }\r\n\r\n // 映射 Ant Design Vue Space 组件的 props\r\n ctx.prop.props.direction = direction\r\n ctx.prop.props.size = size\r\n if (align !== undefined && align !== null && align !== '') {\r\n ctx.prop.props.align = align\r\n }\r\n ctx.prop.props.wrap = wrap\r\n\r\n // 合并样式,确保 Space 容器占满整行\r\n const existingStyle = ctx.rule.style || {}\r\n const spaceStyles = {\r\n width: '100%',\r\n ...existingStyle\r\n }\r\n\r\n // 同时设置到 ctx.prop.style 和 ctx.prop.props.style\r\n if (!ctx.prop.style) {\r\n ctx.prop.style = {}\r\n }\r\n ctx.prop.style = { ...ctx.prop.style, ...spaceStyles }\r\n\r\n if (!ctx.prop.props.style) {\r\n ctx.prop.props.style = {}\r\n }\r\n ctx.prop.props.style = { ...ctx.prop.props.style, ...spaceStyles }\r\n\r\n // 确保 children 存在\r\n if (!ctx.rule.children) {\r\n ctx.rule.children = []\r\n }\r\n\r\n // 为 space 容器的所有子组件设置 col: false,避免被 a-col 包装\r\n // Space 组件会自动处理子项间距,不需要 col 包装\r\n if (ctx.rule.children && Array.isArray(ctx.rule.children)) {\r\n ctx.rule.children.forEach((child) => {\r\n if (\r\n child &&\r\n typeof child === 'object' &&\r\n child.type !== 'DragTool' &&\r\n child.type !== 'DragBox'\r\n ) {\r\n // 只有当 col 未设置或为默认值时才设置\r\n if (child.col === undefined || child.col === null) {\r\n child.col = false\r\n } else if (\r\n child.col &&\r\n typeof child.col === 'object' &&\r\n child.col.show !== false\r\n ) {\r\n child.col.show = false\r\n }\r\n }\r\n })\r\n }\r\n\r\n // 读取 resetMarginBottom 配置,用于重置包裹 space 的 ant-form-item 的 margin-bottom\r\n const resetMarginBottom =\r\n props.resetMarginBottom ?? ctx.rule.resetMarginBottom ?? false\r\n if (resetMarginBottom) {\r\n // 将 class 添加到 wrap 配置中,使其应用到包裹 space 的 ant-form-item 上\r\n if (!ctx.rule.wrap) {\r\n ctx.rule.wrap = {}\r\n }\r\n if (typeof ctx.rule.wrap === 'object' && !ctx.rule.wrap.class) {\r\n ctx.rule.wrap.class = ''\r\n }\r\n const wrapClass = typeof ctx.rule.wrap === 'object' \r\n ? (ctx.rule.wrap.class || '').split(' ').filter(Boolean)\r\n : []\r\n if (!wrapClass.includes('_fc-reset-margin-bottom')) {\r\n wrapClass.push('_fc-reset-margin-bottom')\r\n if (typeof ctx.rule.wrap === 'object') {\r\n ctx.rule.wrap.class = wrapClass.join(' ')\r\n }\r\n }\r\n }\r\n },\r\n render(children, ctx) {\r\n // 使用 Ant Design Vue 的 Space 组件\r\n const prop = { ...ctx.prop }\r\n\r\n // 读取 compact 配置,决定使用 Space 还是 Space.Compact\r\n const props = ctx.rule.props || {}\r\n const compact = props.compact || ctx.rule.compact || false\r\n\r\n // 根据 compact 属性决定使用哪个组件\r\n if (compact) {\r\n // 使用 Space.Compact 紧凑布局\r\n prop.type = 'a-space-compact'\r\n } else {\r\n // 使用普通 Space 组件\r\n if (prop.type === 'space') {\r\n prop.type = 'a-space'\r\n }\r\n }\r\n\r\n // children 会通过 form-create 的机制自动渲染\r\n const childrenNodes = children || []\r\n\r\n // 将 space 容器包装在 col 中,确保它占满整行(span: 24)\r\n // 这样 space 容器才能有足够的宽度\r\n return ctx.vNode.col(\r\n { props: { span: 24 } },\r\n {\r\n default: () => [ctx.vNode.make(prop.type, prop, childrenNodes)]\r\n }\r\n )\r\n }\r\n}\r\n","import { hasProperty } from '@form-create/utils/lib/type'\r\n\r\nexport default {\r\n name: 'spin',\r\n mergeProp(ctx) {\r\n // 确保不显示标题\r\n if (!ctx.rule.wrap) {\r\n ctx.rule.wrap = {}\r\n }\r\n ctx.rule.wrap.title = false\r\n\r\n const props = ctx.prop.props || {}\r\n\r\n // 读取 containerMode 配置\r\n const containerMode =\r\n ctx.rule.containerMode ??\r\n ctx.rule.props?.containerMode ??\r\n ctx.prop.props?.containerMode ??\r\n true\r\n\r\n // 如果不是容器模式,清空 children\r\n if (!containerMode) {\r\n ctx.rule.children = []\r\n }\r\n\r\n if (!hasProperty(props, 'spinning')) {\r\n props.spinning =\r\n ctx.prop.props?.spinning ?? ctx.rule.props?.spinning ?? false\r\n }\r\n\r\n // 如果没有子组件且不是容器模式,spinning 不应该为 true(避免显示空加载状态)\r\n const hasChildren =\r\n ctx.rule.children &&\r\n Array.isArray(ctx.rule.children) &&\r\n ctx.rule.children.length > 0\r\n if (!containerMode && !hasChildren && props.spinning) {\r\n // 独立模式下如果没有内容,不建议显示加载状态\r\n // 但这里不强制修改,让用户自己控制\r\n }\r\n\r\n // 支持从多个位置读取配置\r\n const bindField =\r\n ctx.rule.bindField ||\r\n ctx.rule.props?.bindField ||\r\n ctx.prop.props?.bindField\r\n let bindMode =\r\n ctx.rule.bindMode || ctx.rule.props?.bindMode || ctx.prop.props?.bindMode\r\n\r\n // 如果没有设置 bindMode,根据是否有 bindField 自动判断\r\n if (!bindMode) {\r\n if (bindField) {\r\n bindMode = 'field'\r\n } else {\r\n bindMode = 'static'\r\n }\r\n }\r\n\r\n // 如果配置了 bindField(绑定单个字段),使用 loadData 来实现动态绑定\r\n if (bindMode === 'field' && bindField) {\r\n const loadDataConfig = {\r\n attr: bindField,\r\n to: 'props.spinning',\r\n modify: true,\r\n wait: 300,\r\n watch: true\r\n }\r\n\r\n // 添加到 effect 中(避免重复添加)\r\n if (!ctx.rule.effect) {\r\n ctx.rule.effect = {}\r\n }\r\n if (!ctx.rule.effect.loadData) {\r\n ctx.rule.effect.loadData = []\r\n }\r\n // 检查是否已存在相同的配置,避免重复添加\r\n const exists = ctx.rule.effect.loadData.some(\r\n (item) => item.attr === bindField && item.to === 'props.spinning'\r\n )\r\n if (!exists) {\r\n ctx.rule.effect.loadData.push(loadDataConfig)\r\n // 手动触发 effect 来确保 loadData provider 被调用\r\n if (ctx.$handle && ctx.$handle.effect) {\r\n ctx.$handle.effect(ctx, 'loaded')\r\n }\r\n }\r\n }\r\n\r\n // 只在容器模式下处理 children\r\n if (containerMode) {\r\n // 确保 children 存在\r\n if (!ctx.rule.children) {\r\n ctx.rule.children = []\r\n }\r\n\r\n // 确保子组件不被 a-col 包装\r\n if (ctx.rule.children && Array.isArray(ctx.rule.children)) {\r\n ctx.rule.children.forEach((child) => {\r\n if (\r\n child &&\r\n typeof child === 'object' &&\r\n child.type !== 'DragTool' &&\r\n child.type !== 'DragBox'\r\n ) {\r\n // 只有当 col 未设置或为默认值时才设置\r\n if (child.col === undefined || child.col === null) {\r\n child.col = false\r\n } else if (\r\n child.col &&\r\n typeof child.col === 'object' &&\r\n child.col.show !== false\r\n ) {\r\n child.col.show = false\r\n }\r\n }\r\n })\r\n }\r\n }\r\n },\r\n render(children, ctx) {\r\n // 获取 spinning 状态\r\n const props = ctx.prop.props || {}\r\n const spinning = props.spinning || false\r\n\r\n // 设置组件类型为 a-spin\r\n if (!ctx.prop.props) {\r\n ctx.prop.props = {}\r\n }\r\n\r\n // 映射 props\r\n ctx.prop.props.spinning = spinning\r\n\r\n // 如果有 tip,设置 tip prop\r\n const tip = ctx.rule.tip || ctx.rule.props?.tip || ctx.prop.props?.tip\r\n if (tip) {\r\n ctx.prop.props.tip = tip\r\n }\r\n\r\n // 如果有 delay,设置 delay prop\r\n const delay =\r\n ctx.rule.delay || ctx.rule.props?.delay || ctx.prop.props?.delay\r\n if (delay != null) {\r\n ctx.prop.props.delay = delay\r\n }\r\n\r\n // 如果有 size,设置 size prop\r\n const size = ctx.rule.size || ctx.rule.props?.size || ctx.prop.props?.size\r\n if (size) {\r\n ctx.prop.props.size = size\r\n }\r\n\r\n // 设置类型为 a-spin\r\n if (ctx.prop.type === 'spin') {\r\n ctx.prop.type = 'a-spin'\r\n }\r\n\r\n // 读取 containerMode 配置\r\n const containerMode =\r\n ctx.rule.containerMode ??\r\n ctx.rule.props?.containerMode ??\r\n ctx.prop.props?.containerMode ??\r\n true\r\n\r\n // 如果不是容器模式,不渲染 children,直接使用 defaultRender\r\n if (!containerMode) {\r\n return ctx.$render.defaultRender(ctx, undefined)\r\n }\r\n\r\n // 容器模式:使用传入的 children 参数\r\n // children 参数已经是渲染好的 vnodes,直接传递给 a-spin\r\n const childrenNodes =\r\n children && Array.isArray(children) ? children : children || []\r\n\r\n // 将 spin 容器包装在 col 中,确保它占满整行(span: 24)\r\n // 直接使用 vNode.make 来渲染 a-spin,并传入 childrenNodes(类似 flex 组件的处理方式)\r\n return ctx.vNode.col(\r\n { props: { span: 24 } },\r\n {\r\n default: () => [ctx.vNode.make('a-spin', ctx.prop, childrenNodes)]\r\n }\r\n )\r\n }\r\n}\r\n","export default {\r\n name: 'div',\r\n mergeProp(ctx) {\r\n // 确保 children 存在\r\n if (!ctx.rule.children) {\r\n ctx.rule.children = []\r\n }\r\n\r\n // 为 div 容器的所有子组件设置 col: false,避免被 a-col 包装\r\n // 这样子组件可以直接作为 div 的子元素\r\n if (ctx.rule.children && Array.isArray(ctx.rule.children)) {\r\n ctx.rule.children.forEach((child) => {\r\n if (\r\n child &&\r\n typeof child === 'object' &&\r\n child.type !== 'DragTool' &&\r\n child.type !== 'DragBox'\r\n ) {\r\n // 只有当 col 未设置或为默认值时才设置\r\n if (child.col === undefined || child.col === null) {\r\n child.col = false\r\n } else if (\r\n child.col &&\r\n typeof child.col === 'object' &&\r\n child.col.show !== false\r\n ) {\r\n child.col.show = false\r\n }\r\n }\r\n })\r\n }\r\n },\r\n render(children, ctx) {\r\n // 使用简单的 div 元素作为容器\r\n const prop = { ...ctx.prop }\r\n\r\n // 确保 type 是 'div'\r\n if (prop.type === 'div') {\r\n prop.type = 'div'\r\n }\r\n\r\n // children 会通过 form-create 的机制自动渲染\r\n const childrenNodes = children || []\r\n\r\n // 直接返回 div,不使用 a-col 或 a-row 包装\r\n // 确保样式是自适应(width: 100% 可能会影响布局,所以不设置)\r\n if (!prop.props) {\r\n prop.props = {}\r\n }\r\n if (!prop.props.style) {\r\n prop.props.style = {}\r\n }\r\n // 宽高自适应,不设置固定值\r\n // 保留用户自定义的样式\r\n\r\n // 直接使用 vNode.make 渲染 div,不包装\r\n return ctx.vNode.make('div', prop, childrenNodes)\r\n }\r\n}\r\n\r\n","const PRE = 'a'\nexport default {\n tooltip: PRE + 'Tooltip',\n popover: PRE + 'Popover',\n button: PRE + 'Button',\n icon: PRE + 'Icon',\n slider: PRE + 'Slider',\n rate: PRE + 'Rate',\n upload: 'fcUpload',\n cascader: PRE + 'Cascader',\n timePicker: PRE + 'TimePicker',\n timeRangePicker: PRE + 'TimeRangePicker',\n datePicker: PRE + 'DatePicker',\n rangePicker: PRE + 'RangePicker',\n switch: PRE + 'Switch',\n select: PRE + 'Select',\n checkbox: PRE + 'CheckboxGroup',\n radio: PRE + 'RadioGroup',\n input: PRE + 'Input',\n inputNumber: PRE + 'InputNumber',\n treeSelect: PRE + 'TreeSelect',\n search: PRE + 'InputSearch',\n inputPassword: PRE + 'InputPassword',\n textarea: PRE + 'Textarea',\n formItem: PRE + 'FormItem',\n form: PRE + 'Form',\n frame: 'fcFrame',\n col: PRE + 'Col',\n row: PRE + 'Row',\n flex: PRE + 'Flex',\n space: PRE + 'Space',\n 'space-compact': PRE + 'SpaceCompact',\n spin: PRE + 'Spin',\n tree: PRE + 'Tree',\n autoComplete: PRE + 'AutoComplete',\n transfer: PRE + 'Transfer',\n group: 'fcGroup',\n array: 'fcGroup',\n subForm: 'fcSubForm',\n object: 'fcSubForm',\n image: PRE + 'Image',\n aImage: PRE + 'Image'\n}\n","import getConfig from './config'\r\nimport mergeProps from '@form-create/utils/lib/mergeprops'\r\nimport is, { hasProperty } from '@form-create/utils/lib/type'\r\nimport extend from '@form-create/utils/lib/extend'\r\n\r\nfunction isTooltip(info) {\r\n return info.type === 'tooltip'\r\n}\r\n\r\nfunction tidy(props, name) {\r\n if (!hasProperty(props, name)) return\r\n if (is.String(props[name])) {\r\n props[name] = { [name]: props[name], show: true }\r\n }\r\n}\r\n\r\nfunction isFalse(val) {\r\n return val === false\r\n}\r\n\r\nfunction tidyBool(opt, name) {\r\n if (hasProperty(opt, name) && !is.Object(opt[name])) {\r\n opt[name] = { show: !!opt[name] }\r\n }\r\n}\r\n\r\nfunction tidyRule(rule) {\r\n const _rule = { ...rule }\r\n delete _rule.children\r\n return _rule\r\n}\r\n\r\nexport default {\r\n validate() {\r\n const form = this.form()\r\n if (form) {\r\n return form.validate()\r\n } else {\r\n return new Promise((v) => v())\r\n }\r\n },\r\n validateField(field) {\r\n const form = this.form()\r\n if (form) {\r\n return form.validateFields(field)\r\n } else {\r\n return new Promise((v) => v())\r\n }\r\n },\r\n clearValidateState(ctx) {\r\n const fItem = this.vm.refs[ctx.wrapRef]\r\n if (fItem) {\r\n fItem.clearValidate()\r\n }\r\n },\r\n tidyOptions(options) {\r\n ;['submitBtn', 'resetBtn', 'row', 'info', 'wrap', 'col', 'title'].forEach(\r\n (name) => {\r\n tidyBool(options, name)\r\n }\r\n )\r\n return options\r\n },\r\n tidyRule({ prop }) {\r\n tidy(prop, 'title')\r\n tidy(prop, 'info')\r\n return prop\r\n },\r\n mergeProp(ctx) {\r\n const def = {\r\n info: {\r\n type: 'popover',\r\n placement: 'topLeft',\r\n icon: 'QuestionCircleOutlined'\r\n },\r\n title: {},\r\n col: { span: 24 },\r\n wrap: {}\r\n }\r\n ;['info', 'wrap', 'col', 'title'].forEach((name) => {\r\n ctx.prop[name] = mergeProps(\r\n [this.options[name] || {}, ctx.prop[name] || {}],\r\n def[name]\r\n )\r\n })\r\n\r\n // 检查父容器是否是 flex 或 space 类型,如果是,自动设置 col: false 避免被 a-col 包装\r\n // 需要在合并完 col 后再检查,确保能覆盖默认值\r\n if (ctx.parent && ctx.parent.rule) {\r\n const parentType = ctx.parent.rule.type\r\n const parentMenu = ctx.parent.rule._menu\r\n if (\r\n parentType === 'flex' ||\r\n parentType === 'a-flex' ||\r\n parentMenu?.name === 'flex' ||\r\n parentType === 'space' ||\r\n parentType === 'a-space' ||\r\n parentMenu?.name === 'space'\r\n ) {\r\n // 如果父容器是 flex 或 space,强制设置 col 为 false,禁用 col 包装\r\n ctx.prop.col = false\r\n // 同时设置 rule.col 以确保在 makeWrap 中也能识别\r\n if (ctx.rule) {\r\n ctx.rule.col = false\r\n }\r\n }\r\n }\r\n\r\n // 为 upload 组件自动添加 onPreview,确保始终向父窗口发送预览通知\r\n if (ctx.rule.type === 'upload' && !ctx.prop.props.onPreview) {\r\n const sendPreviewMessage = function (file) {\r\n if (window.parent && window.parent !== window) {\r\n window.parent.postMessage(\r\n {\r\n type: 'upload-preview',\r\n file: {\r\n url: file.url,\r\n name: file.name,\r\n uid: file.uid,\r\n size: file.size,\r\n type: file.type\r\n },\r\n timestamp: Date.now()\r\n },\r\n '*'\r\n )\r\n }\r\n }\r\n ctx.prop.props.onPreview = function (file) {\r\n sendPreviewMessage(file)\r\n // 不执行默认预览,只发送消息\r\n }\r\n } else if (ctx.rule.type === 'upload' && ctx.prop.props.onPreview) {\r\n // 如果用户已经设置了 onPreview,包装它以确保先发送消息\r\n const originalOnPreview = ctx.prop.props.onPreview\r\n const sendPreviewMessage = function (file) {\r\n if (window.parent && window.parent !== window) {\r\n window.parent.postMessage(\r\n {\r\n type: 'upload-preview',\r\n file: {\r\n url: file.url,\r\n name: file.name,\r\n uid: file.uid,\r\n size: file.size,\r\n type: file.type\r\n },\r\n timestamp: Date.now()\r\n },\r\n '*'\r\n )\r\n }\r\n }\r\n ctx.prop.props.onPreview = function (file) {\r\n sendPreviewMessage(file)\r\n if (originalOnPreview && typeof originalOnPreview === 'function') {\r\n originalOnPreview.apply(this, arguments)\r\n }\r\n }\r\n }\r\n\r\n // 为 aImage 组件自动添加预览拦截,确保始终向父窗口发送预览通知\r\n if (\r\n (ctx.rule.type === 'image' || ctx.rule.type === 'aImage') &&\r\n !ctx.prop.props.preview\r\n ) {\r\n const sendImagePreviewMessage = function (src) {\r\n if (window.parent && window.parent !== window) {\r\n window.parent.postMessage(\r\n {\r\n type: 'upload-preview',\r\n file: {\r\n url: src || ctx.prop.props.src || ''\r\n },\r\n timestamp: Date.now()\r\n },\r\n '*'\r\n )\r\n }\r\n }\r\n\r\n // 拦截 Image 组件的预览,发送消息给父窗口并阻止默认预览\r\n const imageSrc = ctx.prop.props.src || ''\r\n ctx.prop.props.preview = {\r\n visible: false,\r\n src: imageSrc,\r\n onVisibleChange: (visible, prevVisible) => {\r\n if (visible && !prevVisible) {\r\n // 发送预览通知给父窗口\r\n sendImagePreviewMessage(imageSrc)\r\n // 返回 false 阻止默认预览显示\r\n return false\r\n }\r\n }\r\n }\r\n } else if (\r\n (ctx.rule.type === 'image' || ctx.rule.type === 'aImage') &&\r\n ctx.prop.props.preview\r\n ) {\r\n // 如果用户已经设置了 preview,包装它以确保先发送消息\r\n const originalPreview = ctx.prop.props.preview\r\n const sendImagePreviewMessage = function (src) {\r\n if (window.parent && window.parent !== window) {\r\n window.parent.postMessage(\r\n {\r\n type: 'upload-preview',\r\n file: {\r\n url: src || ctx.prop.props.src || ''\r\n },\r\n timestamp: Date.now()\r\n },\r\n '*'\r\n )\r\n }\r\n }\r\n\r\n const imageSrc = ctx.prop.props.src || ''\r\n const originalOnVisibleChange = originalPreview?.onVisibleChange\r\n\r\n ctx.prop.props.preview = {\r\n ...originalPreview,\r\n visible: originalPreview.visible || false,\r\n src: originalPreview.src || imageSrc,\r\n onVisibleChange: (visible, prevVisible) => {\r\n if (visible && !prevVisible) {\r\n // 先发送消息给父窗口\r\n sendImagePreviewMessage(originalPreview.src || imageSrc)\r\n }\r\n // 执行用户自定义的 onVisibleChange\r\n if (\r\n originalOnVisibleChange &&\r\n typeof originalOnVisibleChange === 'function'\r\n ) {\r\n return originalOnVisibleChange.apply(this, arguments)\r\n }\r\n // 默认阻止预览显示\r\n return false\r\n }\r\n }\r\n }\r\n },\r\n getDefaultOptions() {\r\n return getConfig()\r\n },\r\n adapterValidate(validate, validator) {\r\n validate.validator = (rule, value) => {\r\n return new Promise((resolve, reject) => {\r\n const callback = (err) => {\r\n if (err) {\r\n reject(err)\r\n } else {\r\n resolve()\r\n }\r\n }\r\n return validator(value, callback)\r\n })\r\n }\r\n return validate\r\n },\r\n update() {\r\n const form = this.options.form\r\n this.rule = {\r\n props: { ...form },\r\n on: {\r\n submit: (e) => {\r\n e.preventDefault()\r\n }\r\n },\r\n style: form.style,\r\n type: 'form'\r\n }\r\n },\r\n beforeRender() {\r\n const { key, ref, $handle } = this\r\n const form = this.options.form\r\n extend(this.rule, {\r\n key,\r\n ref,\r\n class: [\r\n form.className,\r\n form.class,\r\n 'form-create',\r\n this.$handle.preview ? 'is-preview' : ''\r\n ]\r\n })\r\n extend(this.rule.props, {\r\n model: $handle.formData\r\n })\r\n },\r\n render(children) {\r\n if (children.slotLen() && !this.$handle.preview) {\r\n children.setSlot(undefined, () => this.makeFormBtn())\r\n }\r\n return this.$r(\r\n this.rule,\r\n isFalse(this.options.row.show)\r\n ? children.getSlots()\r\n : [this.makeRow(children)]\r\n )\r\n },\r\n makeWrap(ctx, children) {\r\n const rule = ctx.prop\r\n const uni = `${this.key}${ctx.key}`\r\n const col = rule.col\r\n const isTitle = this.isTitle(rule) && rule.wrap.title !== false\r\n const { layout, col: _col } = this.rule.props\r\n const cls = rule.wrap.class\r\n delete rule.wrap.class\r\n delete rule.wrap.title\r\n\r\n // 检查父容器是否是 flex 或 space 类型,如果是,强制禁用 col 包装\r\n let shouldDisableCol = false\r\n if (ctx.parent && ctx.parent.rule) {\r\n const parentType = ctx.parent.rule.type\r\n const parentMenu = ctx.parent.rule._menu\r\n if (\r\n parentType === 'flex' ||\r\n parentType === 'a-flex' ||\r\n parentMenu?.name === 'flex' ||\r\n parentType === 'space' ||\r\n parentType === 'a-space' ||\r\n parentMenu?.name === 'space'\r\n ) {\r\n shouldDisableCol = true\r\n }\r\n }\r\n\r\n const item = isFalse(rule.wrap.show)\r\n ? children\r\n : this.$r(\r\n mergeProps([\r\n rule.wrap,\r\n {\r\n props: {\r\n ...tidyRule(rule.wrap || {}),\r\n hasFeedback: rule.hasFeedback || false,\r\n name: ctx.id,\r\n rules: ctx.injectValidate(),\r\n ...(layout !== 'horizontal'\r\n ? { labelCol: {}, wrapperCol: {} }\r\n : {})\r\n },\r\n class: this.$render.mergeClass(\r\n cls || rule.className,\r\n 'fc-form-item'\r\n ),\r\n key: `${uni}fi`,\r\n ref: ctx.wrapRef,\r\n type: 'formItem'\r\n }\r\n ]),\r\n {\r\n default: () => children,\r\n ...(isTitle ? { label: () => this.makeInfo(rule, uni, ctx) } : {})\r\n }\r\n )\r\n // 如果父容器是 flex,或者 layout 是 inline,或者 col 被显式禁用,则不使用 col 包装\r\n return layout === 'inline' ||\r\n isFalse(_col) ||\r\n isFalse(col.show) ||\r\n shouldDisableCol\r\n ? item\r\n : this.makeCol(rule, uni, [item])\r\n },\r\n isTitle(rule) {\r\n if (this.options.form.title === false) return false\r\n const title = rule.title\r\n return !((!title.title && !title.native) || isFalse(title.show))\r\n },\r\n makeInfo(rule, uni, ctx) {\r\n const titleProp = { ...rule.title }\r\n const infoProp = { ...rule.info }\r\n if (this.options.form.title === false) return false\r\n if ((!titleProp.title && !titleProp.native) || isFalse(titleProp.show))\r\n return\r\n const isTip = isTooltip(infoProp)\r\n const titleSlot = this.getSlot('title')\r\n const children = [\r\n titleSlot\r\n ? titleSlot({\r\n title: ctx.refRule?.__$title?.value,\r\n rule: ctx.rule,\r\n options: this.options\r\n })\r\n : ctx.refRule?.__$title?.value\r\n ]\r\n\r\n if (\r\n !isFalse(infoProp.show) &&\r\n (infoProp.info || infoProp.native) &&\r\n !isFalse(infoProp.icon)\r\n ) {\r\n const prop = {\r\n type: infoProp.type || 'popover',\r\n props: tidyRule(infoProp),\r\n key: `${uni}pop`\r\n }\r\n\r\n delete prop.props.icon\r\n delete prop.props.show\r\n delete prop.props.info\r\n delete prop.props.align\r\n delete prop.props.native\r\n\r\n const field = isTip ? 'title' : 'content'\r\n if (infoProp.info && !hasProperty(prop.props, field)) {\r\n prop.props[field] = ctx.refRule?.__$info?.value\r\n }\r\n children[infoProp.align !== 'left' ? 'unshift' : 'push'](\r\n this.$r(mergeProps([infoProp, prop]), {\r\n [titleProp.slot || 'default']: () =>\r\n this.$r({\r\n type:\r\n infoProp.icon === true\r\n ? 'QuestionCircleOutlined'\r\n : infoProp.icon || '',\r\n props: {\r\n type:\r\n infoProp.icon === true\r\n ? 'QuestionCircleOutlined'\r\n : infoProp.icon\r\n },\r\n key: `${uni}i`\r\n })\r\n })\r\n )\r\n }\r\n\r\n const _prop = mergeProps([\r\n titleProp,\r\n {\r\n props: tidyRule(titleProp),\r\n key: `${uni}tit`,\r\n class: 'fc-form-title',\r\n type: titleProp.type || 'span'\r\n }\r\n ])\r\n\r\n delete _prop.props.show\r\n delete _prop.props.title\r\n delete _prop.props.native\r\n\r\n return this.$r(_prop, children)\r\n },\r\n makeCol(rule, uni, children) {\r\n const col = rule.col\r\n return this.$r(\r\n {\r\n class: this.$render.mergeClass(col.class, 'fc-form-col'),\r\n type: 'col',\r\n props: col || { span: 24 },\r\n key: `${uni}col`\r\n },\r\n children\r\n )\r\n },\r\n makeRow(children) {\r\n const row = this.options.row || {}\r\n return this.$r(\r\n {\r\n type: 'row',\r\n props: row,\r\n class: this.$render.mergeClass(row.class, 'fc-form-row'),\r\n key: `${this.key}row`\r\n },\r\n children\r\n )\r\n },\r\n makeFormBtn() {\r\n let vn = []\r\n if (!isFalse(this.options.submitBtn.show)) {\r\n vn.push(this.makeSubmitBtn())\r\n }\r\n if (!isFalse(this.options.resetBtn.show)) {\r\n vn.push(this.makeResetBtn())\r\n }\r\n if (!vn.length) {\r\n return\r\n }\r\n let { labelCol, wrapperCol, layout } = this.rule.props\r\n if (layout !== 'horizontal') {\r\n labelCol = wrapperCol = {}\r\n }\r\n const item = this.$r(\r\n {\r\n type: 'formItem',\r\n class: 'fc-form-item fc-form-footer',\r\n key: `${this.key}fb`,\r\n props: {\r\n labelCol,\r\n wrapperCol,\r\n label: ' ',\r\n colon: false\r\n }\r\n },\r\n vn\r\n )\r\n\r\n return layout === 'inline'\r\n ? item\r\n : this.$r(\r\n {\r\n type: 'col',\r\n class: 'fc-form-col',\r\n props: { span: 24 },\r\n key: `${this.key}fc`\r\n },\r\n [item]\r\n )\r\n },\r\n\r\n makeResetBtn() {\r\n const resetBtn = { ...this.options.resetBtn }\r\n const innerText =\r\n resetBtn.innerText || this.$handle.api.t('reset') || '重置'\r\n delete resetBtn.innerText\r\n delete resetBtn.click\r\n delete resetBtn.col\r\n delete resetBtn.show\r\n return this.$r(\r\n {\r\n type: 'button',\r\n props: resetBtn,\r\n class: 'fc-reset-btn',\r\n style: { width: resetBtn.width, marginLeft: '10px' },\r\n on: {\r\n click: () => {\r\n const fApi = this.$handle.api\r\n this.options.resetBtn.click\r\n ? this.options.resetBtn.click(fApi)\r\n : fApi.resetFields()\r\n }\r\n },\r\n key: `${this.key}b2`\r\n },\r\n [innerText]\r\n )\r\n },\r\n makeSubmitBtn() {\r\n const submitBtn = { ...this.options.submitBtn }\r\n const innerText =\r\n submitBtn.innerText || this.$handle.api.t('submit') || '提交'\r\n delete submitBtn.innerText\r\n delete submitBtn.click\r\n delete submitBtn.col\r\n delete submitBtn.show\r\n return this.$r(\r\n {\r\n type: 'button',\r\n props: submitBtn,\r\n class: 'fc-submit-btn',\r\n style: { width: submitBtn.width },\r\n on: {\r\n click: () => {\r\n const fApi = this.$handle.api\r\n this.options.submitBtn.click\r\n ? this.options.submitBtn.click(fApi)\r\n : fApi.submit().catch(() => {})\r\n }\r\n },\r\n key: `${this.key}b1`\r\n },\r\n [innerText]\r\n )\r\n }\r\n}\r\n","const UNDEF = undefined\n\nexport default function getConfig() {\n return {\n form: {\n hideRequiredMark: false,\n layout: 'horizontal',\n labelAlign: 'right',\n labelCol: {\n span: 3\n },\n wrapperCol: {\n span: 21\n },\n validateOnRuleChange: true\n },\n row: {\n gutter: 0\n },\n submitBtn: {\n disabled: false,\n loading: false,\n type: 'primary',\n innerText: '',\n show: false,\n col: UNDEF,\n click: UNDEF\n },\n resetBtn: {\n disabled: false,\n loading: false,\n type: 'default',\n innerText: '',\n show: false,\n col: UNDEF,\n click: UNDEF\n }\n }\n}\n","import { creatorFactory } from '@longhongguo/form-create-core/src/index'\n\nconst maker = {}\n\nfunction useAlias(maker) {\n ;[\n 'treeSelect',\n 'upload',\n 'frame',\n 'autoComplete',\n 'cascader',\n 'datePicker',\n 'frame',\n 'inputNumber',\n 'inputPassword',\n 'radio',\n 'rate',\n 'switch',\n 'rate',\n 'slider',\n 'timePicker'\n ].reduce((maker, name) => {\n maker[name] = creatorFactory(name)\n return maker\n }, maker)\n maker.auto = maker.autoComplete\n maker.number = maker.inputNumber\n maker.time = maker.timePicker\n maker.password = maker.inputPassword\n}\n\nfunction useFrame(maker) {\n const types = {\n frameInputs: ['input', 0],\n frameFiles: ['file', 0],\n frameImages: ['image', 0],\n frameInputOne: ['input', 1],\n frameFileOne: ['file', 1],\n frameImageOne: ['image', 1]\n }\n\n Object.keys(types).reduce((maker, key) => {\n maker[key] = creatorFactory('frame', (m) =>\n m.props({ type: types[key][0], maxLength: types[key][1] })\n )\n return maker\n }, maker)\n\n maker.frameInput = maker.frameInputs\n maker.frameFile = maker.frameFiles\n maker.frameImage = maker.frameImages\n}\n\nfunction useSlider(maker) {\n maker['sliderRange'] = creatorFactory('slider', { range: true })\n}\n\nfunction useSelect(m) {\n const name = 'select'\n m.selectMultiple = creatorFactory(name, { mode: 'multiple' })\n m.selectTags = creatorFactory(name, { mode: 'tags' })\n m.selectCombobox = creatorFactory(name, { mode: 'combobox' })\n}\n\nfunction useUpload(maker) {\n const types = {\n image: ['image', 0],\n file: ['file', 0],\n uploadFileOne: ['file', 1],\n uploadImageOne: ['image', 1]\n }\n\n Object.keys(types).reduce((maker, key) => {\n maker[key] = creatorFactory('upload', (m) =>\n m.props({\n uploadType: types[key][0],\n maxLength: types[key][1]\n })\n )\n return maker\n }, maker)\n\n maker.uploadImage = maker.image\n maker.uploadFile = maker.file\n}\n\nfunction useCusStoreSelect(maker) {\n maker.cusStoreSelect = creatorFactory('cusStoreSelect')\n maker.storeSelect = maker.cusStoreSelect\n}\n\nfunction useCusUserSelect(maker) {\n maker.cusUserSelect = creatorFactory('cusUserSelect')\n maker.userSelect = maker.cusUserSelect\n}\n\nfunction useText(maker) {\n maker.text = creatorFactory('text')\n}\n\nfunction useFlex(maker) {\n maker.flex = creatorFactory('flex')\n}\n\nfunction useSpace(maker) {\n maker.space = creatorFactory('space')\n}\n\nfunction useSpin(maker) {\n maker.spin = creatorFactory('spin')\n}\n\nuseAlias(maker)\nuseSlider(maker)\nuseFrame(maker)\nuseUpload(maker)\nuseSelect(maker)\nuseCusStoreSelect(maker)\nuseCusUserSelect(maker)\nuseText(maker)\nuseFlex(maker)\nuseSpace(maker)\nuseSpin(maker)\n\nexport default maker\n","/**\r\n * 常用校验工具类\r\n * 提供各种日常校验方法\r\n */\r\nclass Validator {\r\n /**\r\n * 校验手机号(中国大陆)\r\n * @param {string} value - 要校验的值\r\n * @param {boolean} strict - 是否严格模式(11位,1开头),默认 true\r\n * @returns {boolean} 校验结果\r\n */\r\n mobile(value, strict = false) {\r\n if (!value) return false\r\n const str = String(value).trim()\r\n if (strict) {\r\n // 严格模式:11位,1开头,第二位为3-9\r\n return /^1[3-9]\\d{9}$/.test(str)\r\n } else {\r\n // 宽松模式:1开头,10-11位数字\r\n return /^1\\d{10,11}$/.test(str)\r\n }\r\n }\r\n\r\n /**\r\n * 校验邮箱\r\n * @param {string} value - 要校验的值\r\n * @returns {boolean} 校验结果\r\n */\r\n email(value) {\r\n if (!value) return false\r\n const str = String(value).trim()\r\n // 邮箱正则:支持常见邮箱格式\r\n return /^[a-zA-Z0-9.!#$%&'*+\\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/.test(\r\n str\r\n )\r\n }\r\n\r\n /**\r\n * 校验身份证号(中国大陆18位)\r\n * @param {string} value - 要校验的值\r\n * @param {boolean} checkCode - 是否校验校验码,默认 true\r\n * @returns {boolean} 校验结果\r\n */\r\n idCard(value, checkCode = true) {\r\n if (!value) return false\r\n const str = String(value).trim().toUpperCase()\r\n\r\n // 基本格式校验:18位,前17位数字,最后一位数字或X\r\n if (!/^\\d{17}[\\dX]$/.test(str)) {\r\n return false\r\n }\r\n\r\n if (!checkCode) {\r\n return true\r\n }\r\n\r\n // 校验码校验\r\n const weights = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]\r\n const checkCodes = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2']\r\n\r\n let sum = 0\r\n for (let i = 0; i < 17; i++) {\r\n sum += parseInt(str[i]) * weights[i]\r\n }\r\n const checkCodeIndex = sum % 11\r\n return str[17] === checkCodes[checkCodeIndex]\r\n }\r\n\r\n /**\r\n * 校验URL\r\n * @param {string} value - 要校验的值\r\n * @param {object} options - 选项\r\n * @param {boolean} options.requireProtocol - 是否要求协议(http/https),默认 false\r\n * @returns {boolean} 校验结果\r\n */\r\n url(value, options = {}) {\r\n if (!value) return false\r\n const str = String(value).trim()\r\n const { requireProtocol = false } = options\r\n\r\n if (requireProtocol) {\r\n return /^https?:\\/\\/.+\\..+/.test(str)\r\n } else {\r\n // 支持带协议或不带协议\r\n return /^(https?:\\/\\/)?([\\da-z\\.-]+)\\.([a-z\\.]{2,6})([\\/\\w \\.-]*)*\\/?$/.test(\r\n str\r\n )\r\n }\r\n }\r\n\r\n /**\r\n * 校验IP地址(IPv4)\r\n * @param {string} value - 要校验的值\r\n * @returns {boolean} 校验结果\r\n */\r\n ip(value) {\r\n if (!value) return false\r\n const str = String(value).trim()\r\n const parts = str.split('.')\r\n if (parts.length !== 4) return false\r\n return parts.every((part) => {\r\n const num = parseInt(part, 10)\r\n return num >= 0 && num <= 255 && String(num) === part\r\n })\r\n }\r\n\r\n /**\r\n * 校验数字\r\n * @param {string|number} value - 要校验的值\r\n * @param {object} options - 选项\r\n * @param {boolean} options.integer - 是否必须为整数,默认 false\r\n * @param {boolean} options.positive - 是否必须为正数,默认 false\r\n * @param {boolean} options.negative - 是否必须为负数,默认 false\r\n * @param {number} options.min - 最小值\r\n * @param {number} options.max - 最大值\r\n * @returns {boolean} 校验结果\r\n */\r\n number(value, options = {}) {\r\n if (value === null || value === undefined || value === '') return false\r\n const num = Number(value)\r\n if (isNaN(num)) return false\r\n\r\n const {\r\n integer = false,\r\n positive = false,\r\n negative = false,\r\n min,\r\n max\r\n } = options\r\n\r\n if (integer && !Number.isInteger(num)) return false\r\n if (positive && num <= 0) return false\r\n if (negative && num >= 0) return false\r\n if (min !== undefined && num < min) return false\r\n if (max !== undefined && num > max) return false\r\n\r\n return true\r\n }\r\n\r\n /**\r\n * 校验字符串长度\r\n * @param {string} value - 要校验的值\r\n * @param {object} options - 选项\r\n * @param {number} options.min - 最小长度\r\n * @param {number} options.max - 最大长度\r\n * @param {number} options.len - 固定长度(优先级高于 min/max)\r\n * @returns {boolean} 校验结果\r\n */\r\n length(value, options = {}) {\r\n if (value === null || value === undefined) return false\r\n const str = String(value)\r\n const { min, max, len } = options\r\n\r\n if (len !== undefined) {\r\n return str.length === len\r\n }\r\n\r\n if (min !== undefined && str.length < min) return false\r\n if (max !== undefined && str.length > max) return false\r\n\r\n return true\r\n }\r\n\r\n /**\r\n * 校验正则表达式\r\n * @param {string} value - 要校验的值\r\n * @param {RegExp|string} pattern - 正则表达式或正则字符串\r\n * @returns {boolean} 校验结果\r\n */\r\n pattern(value, pattern) {\r\n if (!value || !pattern) return false\r\n const str = String(value)\r\n let regex\r\n if (pattern instanceof RegExp) {\r\n regex = pattern\r\n } else {\r\n try {\r\n regex = new RegExp(pattern)\r\n } catch (e) {\r\n return false\r\n }\r\n }\r\n return regex.test(str)\r\n }\r\n\r\n /**\r\n * 校验日期\r\n * @param {string|Date} value - 要校验的值\r\n * @param {object} options - 选项\r\n * @param {string|Date} options.min - 最小日期\r\n * @param {string|Date} options.max - 最大日期\r\n * @param {string} options.format - 日期格式,如 'YYYY-MM-DD',默认自动识别\r\n * @returns {boolean} 校验结果\r\n */\r\n date(value, options = {}) {\r\n if (!value) return false\r\n let date\r\n if (value instanceof Date) {\r\n date = value\r\n } else {\r\n date = new Date(value)\r\n if (isNaN(date.getTime())) return false\r\n }\r\n\r\n const { min, max } = options\r\n if (min) {\r\n const minDate = min instanceof Date ? min : new Date(min)\r\n if (date < minDate) return false\r\n }\r\n if (max) {\r\n const maxDate = max instanceof Date ? max : new Date(max)\r\n if (date > maxDate) return false\r\n }\r\n\r\n return true\r\n }\r\n\r\n /**\r\n * 校验是否为空\r\n * @param {*} value - 要校验的值\r\n * @param {boolean} trim - 是否去除空格,默认 true\r\n * @returns {boolean} 是否为空\r\n */\r\n empty(value, trim = true) {\r\n if (value === null || value === undefined) return true\r\n if (typeof value === 'string') {\r\n return trim ? value.trim() === '' : value === ''\r\n }\r\n if (Array.isArray(value)) {\r\n return value.length === 0\r\n }\r\n if (typeof value === 'object') {\r\n return Object.keys(value).length === 0\r\n }\r\n return false\r\n }\r\n\r\n /**\r\n * 校验是否不为空(empty 的反向)\r\n * @param {*} value - 要校验的值\r\n * @param {boolean} trim - 是否去除空格,默认 true\r\n * @returns {boolean} 是否不为空\r\n */\r\n notEmpty(value, trim = true) {\r\n return !this.empty(value, trim)\r\n }\r\n\r\n /**\r\n * 校验中文\r\n * @param {string} value - 要校验的值\r\n * @returns {boolean} 校验结果\r\n */\r\n chinese(value) {\r\n if (!value) return false\r\n return /^[\\u4e00-\\u9fa5]+$/.test(String(value))\r\n }\r\n\r\n /**\r\n * 校验字母\r\n * @param {string} value - 要校验的值\r\n * @param {boolean} caseSensitive - 是否区分大小写,默认 false(不区分)\r\n * @returns {boolean} 校验结果\r\n */\r\n alpha(value, caseSensitive = false) {\r\n if (!value) return false\r\n const str = String(value)\r\n if (caseSensitive) {\r\n return /^[a-zA-Z]+$/.test(str)\r\n } else {\r\n return /^[a-z]+$/i.test(str)\r\n }\r\n }\r\n\r\n /**\r\n * 校验字母和数字\r\n * @param {string} value - 要校验的值\r\n * @returns {boolean} 校验结果\r\n */\r\n alphanumeric(value) {\r\n if (!value) return false\r\n return /^[a-zA-Z0-9]+$/.test(String(value))\r\n }\r\n\r\n /**\r\n * 校验整数\r\n * @param {string|number} value - 要校验的值\r\n * @returns {boolean} 校验结果\r\n */\r\n integer(value) {\r\n return this.number(value, { integer: true })\r\n }\r\n\r\n /**\r\n * 校验正数\r\n * @param {string|number} value - 要校验的值\r\n * @returns {boolean} 校验结果\r\n */\r\n positive(value) {\r\n return this.number(value, { positive: true })\r\n }\r\n\r\n /**\r\n * 校验负数\r\n * @param {string|number} value - 要校验的值\r\n * @returns {boolean} 校验结果\r\n */\r\n negative(value) {\r\n return this.number(value, { negative: true })\r\n }\r\n\r\n /**\r\n * 校验银行卡号(中国大陆,16-19位)\r\n * @param {string} value - 要校验的值\r\n * @returns {boolean} 校验结果\r\n */\r\n bankCard(value) {\r\n if (!value) return false\r\n const str = String(value).replace(/\\s/g, '')\r\n // 银行卡号通常是16-19位数字\r\n return /^\\d{16,19}$/.test(str)\r\n }\r\n\r\n /**\r\n * 校验邮政编码(中国大陆,6位数字)\r\n * @param {string} value - 要校验的值\r\n * @returns {boolean} 校验结果\r\n */\r\n postcode(value) {\r\n if (!value) return false\r\n return /^\\d{6}$/.test(String(value).trim())\r\n }\r\n\r\n /**\r\n * 校验车牌号(中国大陆)\r\n * @param {string} value - 要校验的值\r\n * @returns {boolean} 校验结果\r\n */\r\n licensePlate(value) {\r\n if (!value) return false\r\n const str = String(value).trim().toUpperCase()\r\n // 支持普通车牌和新能源车牌\r\n return (\r\n /^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领][A-Z][A-Z0-9]{4,5}[A-Z0-9挂学警港澳]$/.test(\r\n str\r\n ) ||\r\n /^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领][A-Z]((\\d{5}[DF])|([DF][A-Z0-9]\\d{4}))$/.test(\r\n str\r\n )\r\n )\r\n }\r\n\r\n /**\r\n * 校验统一社会信用代码(18位)\r\n * @param {string} value - 要校验的值\r\n * @returns {boolean} 校验结果\r\n */\r\n creditCode(value) {\r\n if (!value) return false\r\n const str = String(value).trim().toUpperCase()\r\n // 统一社会信用代码:18位,字母数字组合\r\n return /^[0-9A-HJ-NPQRTUWXY]{2}\\d{6}[0-9A-HJ-NPQRTUWXY]{10}$/.test(str)\r\n }\r\n\r\n /**\r\n * 校验值是否在指定范围内\r\n * @param {*} value - 要校验的值\r\n * @param {Array} enumList - 允许的值列表\r\n * @returns {boolean} 校验结果\r\n */\r\n enum(value, enumList) {\r\n if (!Array.isArray(enumList) || enumList.length === 0) return false\r\n return enumList.includes(value)\r\n }\r\n\r\n /**\r\n * 校验值是否相等\r\n * @param {*} value1 - 第一个值\r\n * @param {*} value2 - 第二个值\r\n * @param {boolean} strict - 是否严格相等(===),默认 true\r\n * @returns {boolean} 校验结果\r\n */\r\n equal(value1, value2, strict = false) {\r\n if (strict) {\r\n return value1 === value2\r\n } else {\r\n return value1 == value2 // eslint-disable-line eqeqeq\r\n }\r\n }\r\n\r\n /**\r\n * 校验值是否不相等\r\n * @param {*} value1 - 第一个值\r\n * @param {*} value2 - 第二个值\r\n * @param {boolean} strict - 是否严格相等(===),默认 true\r\n * @returns {boolean} 校验结果\r\n */\r\n notEqual(value1, value2, strict = true) {\r\n return !this.equal(value1, value2, strict)\r\n }\r\n\r\n /**\r\n * 校验是否全为大写\r\n * @param {string} value - 要校验的值\r\n * @returns {boolean} 校验结果\r\n */\r\n uppercase(value) {\r\n if (!value) return false\r\n const str = String(value)\r\n return str === str.toUpperCase() && /[A-Z]/.test(str)\r\n }\r\n\r\n /**\r\n * 校验是否全为小写\r\n * @param {string} value - 要校验的值\r\n * @returns {boolean} 校验结果\r\n */\r\n lowercase(value) {\r\n if (!value) return false\r\n const str = String(value)\r\n return str === str.toLowerCase() && /[a-z]/.test(str)\r\n }\r\n\r\n /**\r\n * 校验用户名(字母、数字、下划线,3-20位)\r\n * @param {string} value - 要校验的值\r\n * @param {object} options - 选项\r\n * @param {number} options.min - 最小长度,默认 3\r\n * @param {number} options.max - 最大长度,默认 20\r\n * @returns {boolean} 校验结果\r\n */\r\n username(value, options = {}) {\r\n if (!value) return false\r\n const str = String(value).trim()\r\n const { min = 3, max = 20 } = options\r\n if (str.length < min || str.length > max) return false\r\n return /^[a-zA-Z0-9_]+$/.test(str)\r\n }\r\n\r\n /**\r\n * 校验密码强度\r\n * @param {string} value - 要校验的值\r\n * @param {object} options - 选项\r\n * @param {number} options.min - 最小长度,默认 6\r\n * @param {number} options.max - 最大长度,默认 20\r\n * @param {boolean} options.requireNumber - 是否必须包含数字,默认 false\r\n * @param {boolean} options.requireLetter - 是否必须包含字母,默认 false\r\n * @param {boolean} options.requireSpecial - 是否必须包含特殊字符,默认 false\r\n * @returns {boolean} 校验结果\r\n */\r\n password(value, options = {}) {\r\n if (!value) return false\r\n const str = String(value)\r\n const {\r\n min = 6,\r\n max = 20,\r\n requireNumber = false,\r\n requireLetter = false,\r\n requireSpecial = false\r\n } = options\r\n\r\n if (str.length < min || str.length > max) return false\r\n if (requireNumber && !/\\d/.test(str)) return false\r\n if (requireLetter && !/[a-zA-Z]/.test(str)) return false\r\n if (requireSpecial && !/[!@#$%^&*(),.?\":{}|<>]/.test(str)) return false\r\n\r\n return true\r\n }\r\n\r\n /**\r\n * 校验十六进制颜色值\r\n * @param {string} value - 要校验的值(如 #fff 或 #ffffff)\r\n * @returns {boolean} 校验结果\r\n */\r\n hexColor(value) {\r\n if (!value) return false\r\n return /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/.test(String(value).trim())\r\n }\r\n\r\n /**\r\n * 校验QQ号(5-11位数字)\r\n * @param {string} value - 要校验的值\r\n * @returns {boolean} 校验结果\r\n */\r\n qq(value) {\r\n if (!value) return false\r\n return /^[1-9]\\d{4,10}$/.test(String(value).trim())\r\n }\r\n\r\n /**\r\n * 校验微信号(6-20位,字母、数字、下划线、减号)\r\n * @param {string} value - 要校验的值\r\n * @returns {boolean} 校验结果\r\n */\r\n wechat(value) {\r\n if (!value) return false\r\n return /^[a-zA-Z0-9_-]{6,20}$/.test(String(value).trim())\r\n }\r\n\r\n /**\r\n * 校验固定电话(中国大陆)\r\n * @param {string} value - 要校验的值\r\n * @returns {boolean} 校验结果\r\n */\r\n tel(value) {\r\n if (!value) return false\r\n const str = String(value).trim()\r\n // 支持带区号的固定电话:010-12345678 或 01012345678\r\n return /^(0\\d{2,3}-?)?\\d{7,8}$/.test(str)\r\n }\r\n\r\n /**\r\n * 校验MAC地址\r\n * @param {string} value - 要校验的值\r\n * @returns {boolean} 校验结果\r\n */\r\n mac(value) {\r\n if (!value) return false\r\n const str = String(value).trim().toUpperCase()\r\n return /^([0-9A-F]{2}:){5}[0-9A-F]{2}$/.test(str)\r\n }\r\n\r\n /**\r\n * 校验Base64编码\r\n * @param {string} value - 要校验的值\r\n * @returns {boolean} 校验结果\r\n */\r\n base64(value) {\r\n if (!value) return false\r\n const str = String(value).trim()\r\n if (str.length % 4 !== 0) return false\r\n try {\r\n return btoa(atob(str)) === str\r\n } catch (e) {\r\n return false\r\n }\r\n }\r\n\r\n /**\r\n * 校验JSON字符串\r\n * @param {string} value - 要校验的值\r\n * @returns {boolean} 校验结果\r\n */\r\n json(value) {\r\n if (!value) return false\r\n try {\r\n JSON.parse(String(value))\r\n return true\r\n } catch (e) {\r\n return false\r\n }\r\n }\r\n\r\n /**\r\n * 校验数字字符串(纯数字组成)\r\n * @param {string} value - 要校验的值\r\n * @returns {boolean} 校验结果\r\n */\r\n numeric(value) {\r\n if (value === null || value === undefined) return false\r\n return /^\\d+$/.test(String(value))\r\n }\r\n\r\n /**\r\n * 校验URL路径(不含协议和域名)\r\n * @param {string} value - 要校验的值\r\n * @returns {boolean} 校验结果\r\n */\r\n path(value) {\r\n if (!value) return false\r\n return /^\\/[^\\s]*$/.test(String(value).trim())\r\n }\r\n\r\n /**\r\n * 校验端口号(1-65535)\r\n * @param {string|number} value - 要校验的值\r\n * @returns {boolean} 校验结果\r\n */\r\n port(value) {\r\n return this.number(value, { integer: true, min: 1, max: 65535 })\r\n }\r\n}\r\n\r\n// 创建单例实例\r\nconst validator = new Validator()\r\n\r\nexport default validator\r\n","import extend from '@form-create/utils/lib/extend'\nimport is from '@form-create/utils/lib/type'\nimport { invoke } from '@longhongguo/form-create-core/src/frame/util'\nimport toArray from '@form-create/utils/lib/toarray'\nimport validator from './test'\nimport moment from 'moment'\n\nfunction tidyBtnProp(btn, def) {\n if (is.Boolean(btn)) btn = { show: btn }\n else if (!is.Undef(btn) && !is.Object(btn)) btn = { show: def }\n return btn\n}\n\nexport default function extendApi(api, h) {\n return {\n formEl() {\n return h.$manager.form()\n },\n wrapEl(id) {\n const ctx = h.getFieldCtx(id)\n if (!ctx) return\n return h.vm.refs[ctx.wrapRef]\n },\n validate(callback) {\n return new Promise((resolve, reject) => {\n const forms = api.children\n const all = [h.$manager.validate()]\n forms\n .filter((v) => !v.isScope)\n .forEach((v) => {\n all.push(v.validate())\n })\n Promise.all(all)\n .then(() => {\n resolve(true)\n callback && callback(true)\n })\n .catch((e) => {\n reject(e)\n callback && callback(e)\n h.vm.emit('validate-fail', e, { api })\n h.emitEvent('validate-fail', e, { api })\n })\n })\n },\n validateField(field, callback) {\n return new Promise((resolve, reject) => {\n const ctx = h.getFieldCtx(field)\n if (!ctx) return\n const sub = h.subForm[ctx.id]\n const all = [h.$manager.validateField(ctx.id)]\n toArray(sub)\n .filter((v) => !v.isScope)\n .forEach((v) => {\n all.push(v.validate())\n })\n Promise.all(all)\n .then(() => {\n resolve(null)\n callback && callback(null)\n })\n .catch((e) => {\n reject(e)\n callback && callback(e)\n h.vm.emit('validate-field-fail', e, { field, api })\n })\n })\n },\n clearValidateState(fields, clearSub = true) {\n api.helper.tidyFields(fields).forEach((field) => {\n if (clearSub) this.clearSubValidateState(field)\n h.getCtxs(field).forEach((ctx) => {\n h.$manager.clearValidateState(ctx)\n })\n })\n },\n clearSubValidateState(fields) {\n api.helper.tidyFields(fields).forEach((field) => {\n h.getCtxs(field).forEach((ctx) => {\n const subForm = h.subForm[ctx.id]\n if (!subForm) return\n if (Array.isArray(subForm)) {\n subForm.forEach((form) => {\n form.clearValidateState()\n })\n } else if (subForm) {\n subForm.clearValidateState()\n }\n })\n })\n },\n btn: {\n loading: (loading = true) => {\n api.submitBtnProps({ loading: !!loading })\n },\n disabled: (disabled = true) => {\n api.submitBtnProps({ disabled: !!disabled })\n },\n show: (isShow = true) => {\n api.submitBtnProps({ show: !!isShow })\n }\n },\n resetBtn: {\n loading: (loading = true) => {\n api.resetBtnProps({ loading: !!loading })\n },\n disabled: (disabled = true) => {\n api.resetBtnProps({ disabled: !!disabled })\n },\n show: (isShow = true) => {\n api.resetBtnProps({ show: !!isShow })\n }\n },\n submitBtnProps: (props = {}) => {\n let btn = tidyBtnProp(h.options.submitBtn, true)\n extend(btn, props)\n h.options.submitBtn = btn\n api.refreshOptions()\n },\n resetBtnProps: (props = {}) => {\n let btn = tidyBtnProp(h.options.resetBtn, false)\n extend(btn, props)\n h.options.resetBtn = btn\n api.refreshOptions()\n },\n submit(successFn, failFn) {\n return new Promise((resolve, reject) => {\n const promise =\n h.options.validateOnSubmit === false\n ? Promise.resolve()\n : api.validate()\n promise\n .then(() => {\n let formData = api.formData()\n h.beforeSubmit(formData)\n .then(() => {\n is.Function(successFn) && invoke(() => successFn(formData, api))\n is.Function(h.options.onSubmit) &&\n invoke(() => h.options.onSubmit(formData, api))\n h.vm.emit('submit', formData, api)\n resolve(formData)\n })\n .catch((e) => {})\n })\n .catch((...args) => {\n is.Function(failFn) && invoke(() => failFn(api, ...args))\n reject(...args)\n })\n })\n },\n /**\n * 封装请求工具,用于自定义校验规则等场景\n * 基于 frame/fetch.js 封装的 fetch 方法\n *\n * @param {string|object} config - 请求配置,可以是 URL 字符串或配置对象\n * @param {string} config.action - 请求地址(必需)\n * @param {string} config.method - 请求方法,默认 'get'\n * @param {object} config.data - 请求数据(POST/PUT等),用于表单或JSON格式\n * @param {object} config.query - 查询参数(GET请求)\n * @param {string} config.dataType - 数据类型:'json' 表示 JSON 格式(默认),其他值表示表单格式(FormData)\n * @param {object} config.headers - 请求头\n * @param {function|string} config.parse - 数据解析函数或路径字符串\n * @returns {Promise} 返回 Promise,resolve 时返回解析后的数据\n *\n * @example\n * // JSON 格式 POST 请求(默认)\n * await this.api.request({\n * action: '/api/check-username',\n * method: 'post',\n * data: { username: 'test' },\n * dataType: 'json' // 或不设置,默认 JSON\n * });\n *\n * @example\n * // 表单格式 POST 请求\n * await this.api.request({\n * action: '/api/check-username',\n * method: 'post',\n * data: { username: 'test' },\n * dataType: 'form' // 或任意非 'json' 的值,会使用 FormData\n * });\n *\n * @example\n * // 在自定义校验规则中使用\n * validator: async function(value, callback) {\n * try {\n * const result = await this.api.request({\n * action: '/api/check-username',\n * method: 'post',\n * data: { username: value }, // 使用 data,不是 params\n * dataType: 'form' // 表单形式\n * });\n * if (result.exists) {\n * callback('用户名已存在');\n * } else {\n * callback();\n * }\n * } catch (error) {\n * callback('校验失败,请稍后重试');\n * }\n * }\n */\n request(config) {\n // 如果传入的是字符串,转换为配置对象\n if (typeof config === 'string') {\n config = { action: config }\n }\n // 使用 api.fetch 方法,它内部使用 frame/fetch.js 封装的 asyncFetch\n return api.fetch(config)\n },\n // 节流,在指定时间间隔内,如果多次触发,只执行一次\n throttle(fn, delay) {\n let lastTime = 0\n return function (...args) {\n const context = this\n const now = Date.now()\n if (now - lastTime >= (delay || 0)) {\n lastTime = now\n fn.call(context, ...args)\n }\n }\n },\n // 防抖,在指定时间间隔内,如果多次触发,只执行最后一次\n debounce(fn, delay) {\n let timer = null\n return function (...args) {\n const context = this\n if (timer !== null) {\n clearTimeout(timer)\n }\n timer = setTimeout(() => {\n fn.call(context, ...args)\n }, delay || 0)\n }\n },\n /**\n * 校验工具类\n * 提供各种常用的校验方法\n *\n * @example\n * // 校验手机号\n * if (this.api.validator.mobile('13800138000')) {\n * console.log('手机号格式正确')\n * }\n *\n * @example\n * // 校验邮箱\n * if (this.api.validator.email('test@example.com')) {\n * console.log('邮箱格式正确')\n * }\n *\n * @example\n * // 在自定义校验规则中使用\n * validator: function(value, callback) {\n * if (!this.api.validator.mobile(value)) {\n * callback('请输入正确的手机号')\n * } else {\n * callback()\n * }\n * }\n */\n $validator: validator,\n $moment: moment\n }\n}\n","export default {\n autoComplete: 'value',\n cascader: 'value',\n inputNumber: 'value',\n inputPassword: 'value',\n textarea: 'value',\n rate: 'value',\n slider: 'value',\n treeSelect: 'value',\n switch: 'checked',\n cusStoreSelect: 'modelValue',\n cusUserSelect: 'modelValue'\n}\n","import is from '@form-create/utils/lib/type';\n\nconst required = {\n name: 'required',\n load(inject, rule, api) {\n const val = parseVal(inject.getValue());\n if (val.required === false) {\n inject.clearProp();\n api.clearValidateState([rule.field]);\n } else {\n const validate = {\n required: true,\n validator(_, v) {\n return new Promise((resolve, reject) => {\n is.empty(v) ? reject(validate.message) : resolve();\n })\n },\n ...val,\n };\n const title = rule.__fc__.refRule?.__$title?.value;\n if (!validate.message) {\n validate.message = api.t('required', {title}) || (title + (api.getLocale() === 'en' ? ' is required' : '不能为空'));\n } else {\n const match = validate.message.match(/^\\{\\{\\s*\\$t\\.(.+)\\s*\\}\\}$/);\n if (match) {\n validate.message = api.t(match[1], {title});\n }\n }\n inject.getProp().validate = [validate];\n }\n api.sync(rule);\n },\n watch(...args) {\n required.load(...args);\n }\n}\n\nfunction parseVal(val) {\n if (is.Boolean(val)) {\n return {required: val}\n } else if (is.String(val)) {\n return {message: val};\n } else if (is.Undef(val)) {\n return {required: false};\n } else if (is.Function(val)) {\n return {validator: val};\n } else if (!is.Object(val)) {\n return {};\n } else {\n return val;\n }\n}\n\n\nexport default required\n","import components from '../components'\nimport parsers from '../parsers'\nimport alias from './alias'\nimport manager from './manager'\nimport FormCreateFactory from '@longhongguo/form-create-core/src/index'\nimport makers from './maker'\nimport '../style/index.css'\nimport '../style/icon.css'\nimport '@longhongguo/component-antdv-upload/dist/index.css'\nimport extendApi from './api'\nimport modelFields from './modelFields'\nimport required from './provider'\n\nfunction install(FormCreate) {\n FormCreate.componentAlias(alias)\n\n Object.keys(modelFields).forEach((k) => {\n FormCreate.setModelField(k, modelFields[k])\n })\n\n components.forEach((component) => {\n FormCreate.component(component.name, component)\n })\n\n FormCreate.register(required)\n\n parsers.forEach((parser) => {\n FormCreate.parser(parser)\n })\n\n Object.keys(makers).forEach((name) => {\n FormCreate.maker[name] = makers[name]\n })\n\n if (typeof window !== 'undefined' && window.antd) {\n FormCreate.useApp((_, app) => {\n app.use(window.antd)\n })\n }\n}\n\nexport default function antdvFormCreate() {\n return FormCreateFactory({\n ui: 'process.env.UI',\n version: 'process.env.VERSION',\n manager,\n install,\n extendApi,\n attrs: {\n normal: ['col', 'wrap'],\n array: ['className'],\n key: ['title', 'info']\n }\n })\n}\n","import antdvFormCreate from './core/index';\n\nconst FormCreate = antdvFormCreate();\n\nif (typeof window !== 'undefined') {\n window.formCreate = FormCreate;\n}\n\nconst maker = FormCreate.maker;\n\nexport {maker}\n\nexport default FormCreate;\n"],"names":["script$6","name","_hoisted_1","class","_openBlock","_createElementBlock","_cache","_createElementVNode","height","width","xmlns","viewBox","d","fill","script$5","defineComponent","props","modelValue","type","Array","default","options","sourceItems","multiple","Boolean","maxTagCount","Number","undefined","placeholder","String","disabled","style","Object","valueKey","labelKey","allowClear","bordered","emits","computed","currentValue","get","isArray","this","map","item","value","[object Object]","getLabel","label","set","val","arrayValue","$emit","hasValue","length","displayValue","displayLabel","allSelectedItems","displayItems","items","slice","remainingCount","total","Math","max","showClear","methods","findOptionByValue","find","opt","optValue","option","removeItem","itemValue","event","stopPropagation","newValue","filter","some","newItem","clearValue","_hoisted_6","_hoisted_8","opacity","_hoisted_11","_hoisted_12","_createCommentVNode","_ctx","_Fragment","key","tabindex","_renderList","index","title","_toDisplayString","onClick","$event","role","aria-label","focusable","data-icon","aria-hidden","fill-rule","_hoisted_10","_hoisted_13","args","_hoisted_14","_hoisted_3","_hoisted_4","script$4","components","CusSelect","formCreateInject","field","extraQuery","extraQueryFn","Function","data","messageId","pendingCallbacks","internalOptions","mergedOptions","optionMap","Map","forEach","from","values","watch","immediate","handler","newOptions","mounted","window","addEventListener","handleMessage","beforeUnmount","removeEventListener","serializeForPostMessage","JSON","parse","stringify","error","console","warn","result","prototype","hasOwnProperty","call","e","handleClick","msgId","Date","now","currentArrayValue","valueToSend","serializedCurrentValue","assign","message","parent","postMessage","mergeOptions","handleUpdate","handleChange","callback","newItems","triggerValidate","$nextTick","api","validateField","catch","$parent","$options","fapi","_createVNode","_component_CusSelect","model-value","source-items","max-tag-count","onUpdate:modelValue","onChange","script$3","selectType","script$2","columns","required","filterEmptyColumn","deletable","addable","reactive","submitBtn","resetBtn","min","updateTable","deep","formCreateInject.preview","n","emptyRule","children","colspan","rule","trs","Form","markRaw","form","$form","copyTrs","oldValue","_isEmpty","native","subRule","textAlign","preview","t","formChange","updateValue","tr","idx","getChildrenFormData","v","flag","keys","k","str","setRawData","formData","raw","setChildrenFormData","splice","clearEmpty","addEmpty","addRaw","push","delRaw","updateRaw","parseJson","indexOf","innerText","loadRule","header","body","column","align","toJson","border","cellspacing","cellpadding","created","_normalizeClass","_fc-disabled","$props","_createBlock","_resolveDynamicComponent","$data","extendOption","onEmitEvent","_component_a_button","font-weight","script$1","$slots","_hoisted_2","_renderSlot","script","color","colStyle","w","is","upload","frame","group","subForm","QuestionCircleOutlined","CusStoreSelect","CusUserSelect","TableForm","TableFormView","TableFormColumnView","checkbox","modelField","mergeProp","ctx","prop","hasProperty","radio","select","fetchData","effectData","loading","render","newChildren","notFoundContent","$render","defaultRender","cascader","loadData","_ctx$$handle","$handle","ctxRef","parsedFn","parseFn","code","trim","startsWith","selectedOptions","targetOption","isLeaf","updateOptions","_ctxRef$prop","_ctxRef$rule","currentOptions","targetIndex","findIndex","id","deepSet","sync","refresh","then","finally","FORMAT_TYPE","date","month","week","quarter","year","datePicker","maker","reduce","initial","creatorFactory","dateRange","datetimeRange","m","showTime","picker","valueFormat","vNode","range","hidden","text","loadChildren","_ctx$prop$props","_ctx$prop$props2","bindField","template","setTimeout","loadStrVar","getValue","renderChildren","_ctx$rule","currentChildren","join","_ctx$prop$props3","_ctx$prop$props4","_ctx$prop$props5","bindMode","loadDataConfig","attr","to","modify","wait","effect","_textLoadDataWatched","loadDataRef","toRef","newVal","oldVal","formCreateChild","innerHTML","make","input","idate","textarea","search","password","timePicker","tree","fieldNames","checkedKeys","checkable","row","_","col","span","parsers","toFormValue","toValue","formValue","vnode","on","originalUpdateModelValue","nextTick","fieldName","fieldCtx","getFieldCtx","$manager","originalChange","inject","_ref","_props$resetMarginBot","flexDirection","flexWrap","justifyContent","alignItems","alignContent","vertical","justify","flex-start","flex-end","center","space-between","space-around","space-evenly","baseline","stretch","gap","existingStyle","display","userDisplay","_fd","_fw","_jc","_ai","_ac","otherStyles","flexStyles","existingPropStyle","existingPropsStyle","child","show","resetMarginBottom","wrap","wrapClass","split","includes","_ctx$rule$props$child","_ctx$rule$props","isVertical","ensureClass","childFlex","flexValue","_ref2","_ctx$rule$props$child2","_ctx$rule$props2","childWidth","widthValue","childrenNodes","direction","size","spaceStyles","compact","_ctx$rule$containerMo","_ctx$rule$props3","_ctx$rule$props4","containerMode","_ref3","_ctx$prop$props$spinn","spinning","hasChildren","_ctx$rule$props5","_ctx$rule$props6","_ctx$prop$props6","_ctx$rule$props7","_ctx$prop$props7","_ref4","_ref5","_ctx$rule$containerMo2","_ctx$rule$props8","_ctx$prop$props8","tip","delay","alias","tooltip","PRE","popover","button","icon","slider","rate","timeRangePicker","rangePicker","switch","inputNumber","treeSelect","inputPassword","formItem","flex","space","space-compact","spin","autoComplete","transfer","array","object","image","aImage","tidy","isFalse","tidyRule","_rule","manager","validate","Promise","validateFields","clearValidateState","fItem","vm","refs","wrapRef","clearValidate","tidyOptions","tidyBool","def","info","placement","mergeProps","parentType","parentMenu","_menu","onPreview","originalOnPreview","sendPreviewMessage","file","url","uid","timestamp","apply","arguments","originalPreview","sendImagePreviewMessage","src","imageSrc","originalOnVisibleChange","onVisibleChange","visible","prevVisible","getDefaultOptions","hideRequiredMark","layout","labelAlign","labelCol","wrapperCol","validateOnRuleChange","gutter","click","adapterValidate","validator","resolve","reject","err","update","submit","preventDefault","beforeRender","ref","extend","className","model","slotLen","setSlot","makeFormBtn","$r","getSlots","makeRow","makeWrap","uni","isTitle","_col","cls","shouldDisableCol","hasFeedback","rules","injectValidate","mergeClass","makeInfo","makeCol","_ctx$refRule","_ctx$refRule2","titleProp","infoProp","isTip","titleSlot","getSlot","refRule","__$title","_ctx$refRule3","__$info","slot","_prop","vn","makeSubmitBtn","makeResetBtn","colon","marginLeft","fApi","resetFields","auto","number","time","useAlias","useSlider","types","frameInputs","frameFiles","frameImages","frameInputOne","frameFileOne","frameImageOne","maxLength","frameInput","frameFile","frameImage","useFrame","uploadFileOne","uploadImageOne","uploadType","uploadImage","uploadFile","useUpload","selectMultiple","mode","selectTags","selectCombobox","cusStoreSelect","storeSelect","useCusStoreSelect","cusUserSelect","userSelect","useCusUserSelect","useText","useFlex","useSpace","useSpin","mobile","strict","test","email","idCard","checkCode","toUpperCase","weights","sum","i","parseInt","checkCodeIndex","requireProtocol","ip","parts","every","part","num","isNaN","integer","positive","negative","isInteger","len","pattern","regex","RegExp","getTime","empty","notEmpty","chinese","alpha","caseSensitive","alphanumeric","bankCard","replace","postcode","licensePlate","creditCode","enum","enumList","equal","value1","value2","notEqual","uppercase","lowercase","toLowerCase","username","requireNumber","requireLetter","requireSpecial","hexColor","qq","wechat","tel","mac","base64","btoa","atob","json","numeric","path","port","tidyBtnProp","btn","Undef","extendApi","h","formEl","wrapEl","forms","all","isScope","emit","emitEvent","sub","toArray","fields","clearSub","helper","tidyFields","clearSubValidateState","getCtxs","submitBtnProps","isShow","resetBtnProps","refreshOptions","successFn","failFn","validateOnSubmit","beforeSubmit","invoke","onSubmit","request","config","action","fetch","throttle","fn","lastTime","context","debounce","timer","clearTimeout","$validator","$moment","moment","modelFields","load","parseVal","clearProp","_rule$__fc__$refRule","__fc__","match","getLocale","getProp","install","FormCreate","componentAlias","setModelField","component","register","parser","makers","antd","useApp","app","use","FormCreateFactory","ui","version","attrs","normal","formCreate"],"mappings":";;;;;;2pCAcA,IAAeA,EAAA,CACXC,KAAM,0BCdF,MAAAC,EAAA,CAAAC,MAAM,0CAAZ,OAAAC,IAAAC,EASM,OATNH,EASM,IAAAI,EAAA,KAAAA,EAAA,GAAA,CARJC,EAOK,MAAA,CAPAC,OAAO,MAAMC,MAAM,MAAMC,MAAM,6BAA6BC,QAAQ,kBACvEJ,EAE8B,OAAA,CAD1BK,EAAE,iLACFC,KAAK,iBACTN,EAE8B,OAAA,CAD1BK,EAAE,0aACFC,KAAK,2BCiLf,IAAAC,EAAeC,EAAgB,CAC7Bd,KAAM,YACNe,MAAO,CAILC,WAAY,CACVC,KAAMC,MACNC,QAASA,IAAM,IAGjBC,QAAS,CACPH,KAAMC,MACNC,QAASA,IAAM,IAGjBE,YAAa,CACXJ,KAAMC,MACNC,QAASA,IAAM,IAGjBG,SAAU,CACRL,KAAMM,QACNJ,SAAS,GAGXK,YAAa,CACXP,KAAMQ,OACNN,aAASO,GAGXC,YAAa,CACXV,KAAMW,OACNT,QAAS,IAGXU,SAAU,CACRZ,KAAMM,QACNJ,SAAS,GAGXW,MAAO,CACLb,KAAM,CAACW,OAAQG,QACfZ,QAASA,KAAO,CAAEX,MAAO,UAG3BwB,SAAU,CACRf,KAAMW,OACNT,QAAS,SAGXc,SAAU,CACRhB,KAAMW,OACNT,QAAS,SAGXe,WAAY,CACVjB,KAAMM,QACNJ,SAAS,GAGXgB,SAAU,CACRlB,KAAMM,QACNJ,SAAS,IAGbiB,MAAO,CAAC,oBAAqB,qBAAsB,UACnDC,SAAU,CAERC,aAAc,CACZC,MAEE,OAAKrB,MAAMsB,QAAQC,KAAKzB,YAmBjByB,KAAKzB,WAAW0B,IAAKC,GAER,iBAATA,GACE,OAATA,QACgBjB,IAAfiB,EAAKC,YAA+ClB,IAAxBiB,EAAKF,KAAKT,UAMlC,CACLa,CAACJ,KAAKT,UAAWW,EACjBE,CAACJ,KAAKR,UAAWQ,KAAKK,SAASH,IALxBA,GAvBa,OAApBF,KAAKzB,iBACeU,IAApBe,KAAKzB,YACe,KAApByB,KAAKzB,WAEE,GAGsB,iBAApByB,KAAKzB,WACP,CAACyB,KAAKzB,YAGR,CACL,CAAE4B,MAAOH,KAAKzB,WAAY+B,MAAON,KAAKK,SAASL,KAAKzB,eAoB1DgC,IAAIC,GAEF,IAAIC,EAAa,GACbD,MAAAA,IAGAC,EAFEhC,MAAMsB,QAAQS,GAEHA,EAAIP,IAAKC,GAEF,iBAATA,GACE,OAATA,QACgBjB,IAAfiB,EAAKC,YAA+ClB,IAAxBiB,EAAKF,KAAKT,UAKlC,CACLa,CAACJ,KAAKT,UAAWW,EACjBE,CAACJ,KAAKR,UAAWQ,KAAKK,SAASH,IALxBA,GAQa,iBAARM,GAA4B,OAARA,EAEvB,CAACA,GAGD,CACX,CAAEJ,CAACJ,KAAKT,UAAWiB,EAAKJ,CAACJ,KAAKR,UAAWQ,KAAKK,SAASG,MAK7DR,KAAKU,MAAM,oBAAqBD,GAChCT,KAAKU,MAAM,SAAUD,KAIzBE,WACE,MAAMH,EAAMR,KAAKH,aACjB,OAAOpB,MAAMsB,QAAQS,IAAQA,EAAII,OAAS,GAG5CC,eACE,OAAKb,KAAKW,SACHX,KAAKH,aAAa,GADE,MAI7BiB,eACE,IAAKd,KAAKa,aAAc,MAAO,GAC/B,MAAMX,EAAOF,KAAKa,aAElB,MAAoB,iBAATX,GAA8B,OAATA,EAE5BA,EAAKF,KAAKR,WACVU,EAAKI,OACLnB,OAAOe,EAAKF,KAAKT,WAAaW,EAAKC,OAAS,IAIzCH,KAAKK,SAASH,IAGvBa,mBACE,MAAMP,EAAMR,KAAKH,aACjB,OAAKpB,MAAMsB,QAAQS,IAAuB,IAAfA,EAAII,OAIxBJ,EAAIP,IAAKC,GACM,iBAATA,GAA8B,OAATA,EACvB,CACLC,MAAOD,EAAKF,KAAKT,WAAaW,EAAKC,MACnCG,MACEJ,EAAKF,KAAKR,WACVU,EAAKI,OACLnB,OAAOe,EAAKF,KAAKT,WAAaW,EAAKC,OAAS,KAI3C,CACLA,MAAOD,EACPI,MAAON,KAAKK,SAASH,KAhBhB,IAqBXc,eACE,MAAMC,EAAQjB,KAAKe,iBACnB,YAAyB9B,IAArBe,KAAKjB,aAAkD,OAArBiB,KAAKjB,YAClCkC,EAEFA,EAAMC,MAAM,EAAGlB,KAAKjB,cAG7BoC,iBACE,QAAyBlC,IAArBe,KAAKjB,aAAkD,OAArBiB,KAAKjB,YACzC,OAAO,EAET,MAAMqC,EAAQpB,KAAKe,iBAAiBH,OACpC,OAAOS,KAAKC,IAAI,EAAGF,EAAQpB,KAAKjB,cAGlCwC,YACE,OAAOvB,KAAKP,YAAcO,KAAKW,WAAaX,KAAKZ,WAGrDoC,QAAS,CAEPC,kBAAkBjB,GAChB,OAAKR,KAAKrB,SAAmC,IAAxBqB,KAAKrB,QAAQiC,OAG3BZ,KAAKrB,QAAQ+C,KAAMC,IACxB,MAAMC,EAA0B,iBAARD,EAAmBA,EAAI3B,KAAKT,UAAYoC,EAChE,OAAOC,IAAapB,GAAOrB,OAAOyC,KAAczC,OAAOqB,KAJhD,MAQXH,SAASG,GACP,MAAMqB,EAAS7B,KAAKyB,kBAAkBjB,GACtC,OAAIqB,EACuB,iBAAXA,EAAsBA,EAAO7B,KAAKR,UAAYqC,EAGvD1C,OAAOqB,IAGhBsB,WAAWC,EAAWC,GACpB,GAAIhC,KAAKZ,SAAU,OACnB4C,EAAMC,kBACN,MAAMzB,EAAMR,KAAKH,aACjB,GAAIpB,MAAMsB,QAAQS,GAAM,CAEtB,MAAM0B,EAAW1B,EAAI2B,OAAQjC,IAC3B,GAAoB,iBAATA,GAA8B,OAATA,EAAe,CAE7C,OADyBA,EAAKF,KAAKT,WAAaW,EAAKC,SACzB4B,EAE9B,OAAO7B,IAAS6B,IAEZnD,EAAcoB,KAAKpB,YAAYuD,OAAQjC,IACnCgC,EAASE,KAAMC,GACdA,EAAQrC,KAAKT,YAAcW,EAAKF,KAAKT,YAGhDS,KAAKU,MAAM,qBAAsB9B,GACjCoB,KAAKH,aAAeqC,IAIxBI,WAAWN,GACT,GAAIhC,KAAKZ,SAAU,OACnB4C,EAAMC,kBAENjC,KAAKH,aAAe,GACpB,MAAMjB,EAAcoB,KAAKpB,YAAYuD,OAAQjC,IACnCF,KAAKH,aAAauC,KAAMC,GACvBA,EAAQrC,KAAKT,YAAcW,EAAKF,KAAKT,YAGhDS,KAAKU,MAAM,qBAAsB9B,iDC3apBnB,MAAM,gDAyBNA,MAAM,sCAoCd8E,EAAA,CAAA9E,MAAM,gDASC+E,EAAA,CAAA/E,MAAM,+DA8BdA,MAAM,wCACN4B,MAAA,CAAiBoD,QAAA,MAEXC,EAAA,CAAAjF,MAAM,gCACJkF,EAAA,CAAAlF,MAAM,iDAOOA,MAAM,gDA0BlBA,MAAM,2EAhKvBmF,EAAc,YAELC,EAAQhE,cAmEjBlB,EA6GKmF,EAAA,CAAAC,IAAA,GAAA,CA9GLH,EAAc,YACd/E,EA6GK,MAAA,CA3GHJ,SAAM,uCAAqC,0BACnCoF,EAAAzD,YAGPC,QAAOwD,EAAKxD,OACZ2D,SAAUH,kBAEXhF,EAmGK,MAAA,CAlGHJ,SAAM,yBAAuB,sCACrBoF,EAAAnD,cAIR7B,EAqDK,MArDL0E,EAqDK,CApDHK,EAAgB,eAChBlF,GAAA,GAAAC,EAgCKmF,EA/BqB,KAAAG,EAAAJ,EAAA7B,aAAhB,CAAAd,EAAMgD,SADhBvF,EAgCK,MAAA,CA9BFoF,IAAKG,EACNzF,MAAM,wCACN4B,MAAA,CAAiBoD,QAAA,OAEjB5E,EAyBM,OAAA,CAzBAJ,MAAM,+BAAgC0F,MAAOjD,EAAKI,QACtDzC,EAEQ,OAFR2E,EACEY,EAAAlD,EAAKI,OAAI,GAEXzC,EAoBM,OAAA,CAnBJJ,MAAM,sCACL4F,WAAOR,EAAUf,WAAC5B,EAAKC,MAAOmD,qBAE/BzF,EAeM,OAAA,CAfA0F,KAAK,MAAMC,aAAW,QAAQ/F,MAAM,0BACxCI,EAaK,MAAA,CAZH4F,UAAU,QACVC,YAAU,QACV3F,MAAM,MACND,OAAO,MACPK,KAAK,eACLwF,cAAY,OACZC,YAAU,UACV3F,QAAQ,kBAERJ,EAEO,OAAA,CADLK,EAAE,6pBAQd0E,EAAY,UAEJC,EAAa1B,eAAA,GADrBzD,IAAAC,EAUK,MAVLkG,EAUK,CALHhG,EAIM,OAJN6E,EAIM,CAHJ7E,EAEM,OAFN8E,EAAkD,OAC5CE,uCAKVD,EAAa,WACAC,EAAQlC,2BAArBhD,EAEM,OAFNmG,EAEMV,EADDP,EAAU3D,aAAA,OAAA,MAGL2D,EAAStB,eAArB5D,EAqBM,OAAA,OArBiBF,MAAM,sBAAuB4F,4BAAOR,EAAUP,YAAAO,EAAAP,cAAAyB,sBACnElG,EAmBM,OAAA,CAlBJ0F,KAAK,MACLC,aAAW,eACX/F,MAAM,iCAENI,EAaK,MAAA,CAZH4F,UAAU,QACVC,YAAU,eACV3F,MAAM,MACND,OAAO,MACPK,KAAK,eACLwF,cAAY,OACZC,YAAU,UACV3F,QAAQ,kBAERJ,EAEO,OAAA,CADLK,EAAE,gtBAKVR,IAAAC,EAgBM,OAhBNqG,EAgBM,IAAApG,EAAA,KAAAA,EAAA,GAAA,CAfJC,EAcM,OAAA,CAdA0F,KAAK,MAAMC,aAAW,OAAO/F,MAAM,yBACvCI,EAYK,MAAA,CAXH4F,UAAU,QACVC,YAAU,OACV3F,MAAM,MACND,OAAO,MACPK,KAAK,eACLwF,cAAY,OACZ1F,QAAQ,kBAERJ,EAEO,OAAA,CADLK,EAAE,kOA3KdP,EAiEK,MAAA,OA/DHF,SAAM,qCAAmC,0BACjCoF,EAAAzD,YAGPC,QAAOwD,EAAKxD,OACZ2D,SAAUH,kBAEXhF,EAuDK,MAAA,CAtDHJ,SAAM,yBAAuB,sCACrBoF,EAAAnD,cAKAmD,EAAYhC,kBADpBlD,EAMM,OAAA,OAJJF,MAAM,+BACL0F,MAAON,EAAY/B,gBAEjB+B,2BAELlF,EAEM,OAFNsG,EAEMb,EADDP,EAAU3D,aAAA,OAAA,IAEH2D,EAAStB,eAArB5D,EAqBM,OAAA,OArBiBF,MAAM,sBAAuB4F,4BAAOR,EAAUP,YAAAO,EAAAP,cAAAyB,sBACnElG,EAmBM,OAAA,CAlBJ0F,KAAK,MACLC,aAAW,eACX/F,MAAM,iCAENI,EAaK,MAAA,CAZH4F,UAAU,QACVC,YAAU,eACV3F,MAAM,MACND,OAAO,MACPK,KAAK,eACLwF,cAAY,OACZC,YAAU,UACV3F,QAAQ,kBAERJ,EAEO,OAAA,CADLK,EAAE,gtBAKVR,IAAAC,EAgBM,OAhBNuG,EAgBM,IAAAtG,EAAA,KAAAA,EAAA,GAAA,CAfJC,EAcM,OAAA,CAdA0F,KAAK,MAAMC,aAAW,OAAO/F,MAAM,yBACvCI,EAYK,MAAA,CAXH4F,UAAU,QACVC,YAAU,OACV3F,MAAM,MACND,OAAO,MACPK,KAAK,eACLwF,cAAY,OACZ1F,QAAQ,kBAERJ,EAEO,OAAA,CADLK,EAAE,8NCpChB,IAAAiG,GAAe9F,EAAgB,CAC7Bd,KAAM,iBACN6G,WAAY,CACVC,UAAAA,GAEF/F,MAAO,CAELgG,iBAAkB,CAChB9F,KAAMc,OACNZ,QAAS,MAKXH,WAAY,CACVC,KAAMC,MACNC,QAASA,IAAM,IAGjBC,QAAS,CACPH,KAAMC,MACNC,QAASA,IAAM,IAGjBG,SAAU,CACRL,KAAMM,QACNJ,SAAS,GAGXK,YAAa,CACXP,KAAMQ,OACNN,aAASO,GAGXC,YAAa,CACXV,KAAMW,OACNT,QAAS,OAGXU,SAAU,CACRZ,KAAMM,QACNJ,SAAS,GAGXW,MAAO,CACLb,KAAM,CAACW,OAAQG,QACfZ,QAASA,KAAO,CAAEX,MAAO,UAG3BwB,SAAU,CACRf,KAAMW,OACNT,QAAS,SAGXc,SAAU,CACRhB,KAAMW,OACNT,QAAS,SAGXe,WAAY,CACVjB,KAAMM,QACNJ,SAAS,GAGX6F,MAAO,CACL/F,KAAMW,OACNT,QAAS,IAGXgB,SAAU,CACRlB,KAAMM,QACNJ,SAAS,GAGX8F,WAAY,CACVhG,KAAMc,OACNZ,QAASA,KAAO,KAElB+F,aAAc,CACZjG,KAAMkG,SACNhG,QAASA,SAGbiB,MAAO,CAAC,oBAAqB,UAC7BgF,KAAIA,KACK,CAELC,UAAW,EAEXC,iBAAkB,GAElBC,gBAAiB,GACjBlG,YAAa,KAGjBgB,SAAU,CAERmF,gBAEE,GAAI/E,KAAK8E,gBAAgBlE,OAAS,EAAG,CAEnC,MAAMoE,EAAY,IAAIC,IAWtB,OATAjF,KAAKrB,QAAQuG,QAASvD,IACpB,MAAMxB,EAAuB,iBAARwB,EAAmBA,EAAI3B,KAAKT,UAAYoC,EAC7DqD,EAAUzE,IAAIJ,EAAOwB,KAGvB3B,KAAK8E,gBAAgBI,QAASvD,IAC5B,MAAMxB,EAAuB,iBAARwB,EAAmBA,EAAI3B,KAAKT,UAAYoC,EAC7DqD,EAAUzE,IAAIJ,EAAOwB,KAEhBlD,MAAM0G,KAAKH,EAAUI,UAE9B,OAAOpF,KAAKrB,UAGhB0G,MAAO,CAEL1G,QAAS,CACP2G,WAAW,EACXC,QAAQC,GAG4B,IAAhCxF,KAAK8E,gBAAgBlE,QACrBnC,MAAMsB,QAAQyF,IACdA,EAAW5E,OAAS,IAEpBZ,KAAK8E,gBAAkB,IAAIU,OAKnCC,UAEEC,OAAOC,iBAAiB,UAAW3F,KAAK4F,gBAE1CC,gBAEEH,OAAOI,oBAAoB,UAAW9F,KAAK4F,gBAE7CpE,QAAS,CAGPuE,wBAAwBpB,GAEtB,GAAIA,MAAAA,EACF,OAAOA,EAGT,IAGE,OAAOqB,KAAKC,MAAMD,KAAKE,UAAUvB,IACjC,MAAOwB,GAIP,GAHAC,QAAQC,KAAK,iCAAkCF,GAG3C1H,MAAMsB,QAAQ4E,GAEhB,OAAoB,IAAhBA,EAAK/D,OACA,GAGF+D,EAAK1E,IAAKC,GAASF,KAAK+F,wBAAwB7F,IAGzD,GAAoB,iBAATyE,EAAmB,CAC5B,MAAM2B,EAAS,GACf,IAAK,MAAMvD,KAAO4B,EAChB,GAAIrF,OAAOiH,UAAUC,eAAeC,KAAK9B,EAAM5B,GAC7C,IACEuD,EAAOvD,GAAO/C,KAAK+F,wBAAwBpB,EAAK5B,IAChD,MAAO2D,GAEPN,QAAQC,KAAK,+BAA+BtD,EAAO2D,GAIzD,OAAOJ,EAIT,OAAO3B,IAGXgC,cAEE,GAAI3G,KAAKZ,SACP,OAIF,MAAMwH,EAAQ,gBACZ5G,KAAKuE,OAAS,aACZsC,KAAKC,WAAW9G,KAAK4E,YAKnBmC,EAAoBtI,MAAMsB,QAAQC,KAAKzB,YACzCyB,KAAKzB,WACL,GAGJ,IAAIyI,EAAc,KACdD,EAAkBnG,OAAS,IAC7BoG,EAAcD,GAEhB,MAAME,EACJD,MAAAA,EACI,KACAhH,KAAK+F,wBAAwBiB,GAG7BxC,EAAa,IACdxE,KAAKwE,YAENxE,KAAKyE,cACPnF,OAAO4H,OAAO1C,EAAYxE,KAAKyE,gBAEjC,MAAM0C,EAAU,CACd3I,KAAM,oBACN+F,MAAOvE,KAAKuE,OAAS,GACrB1F,SAAUmB,KAAKnB,SACfgB,aAAcoH,EACd1H,SAAUS,KAAKT,SACfC,SAAUQ,KAAKR,SACfgF,WAAAA,EACAI,UAAWgC,GAIb,GAAIlB,OAAO0B,QAAU1B,OAAO0B,SAAW1B,OACrC,IACEA,OAAO0B,OAAOC,YAAYF,EAAS,KACnC,MAAOhB,GACPC,QAAQD,MAAM,yBAA0BA,QAI1CC,QAAQC,KACN,8CAKJrG,KAAK6E,iBAAiB+B,GAAS,CAACzG,EAAOvB,KAGnCA,GACAH,MAAMsB,QAAQnB,IACdA,EAAYgC,OAAS,GAGrBZ,KAAKsH,aAAa1I,GAGpBoB,KAAKpB,YAAcA,EACnBoB,KAAKuH,aAAapH,GAClBH,KAAKwH,aAAarH,KAGtByF,cAAc5D,GAIZ,MAAM2C,EAAO3C,EAAM2C,KAGnB,GAAIA,GAAsB,wBAAdA,EAAKnG,KAAgC,CAC/C,MAAM+F,MAAEA,EAAKpE,MAAEA,EAAKvB,YAAEA,EAAWgG,UAAEA,GAAcD,EAGjD,GAAIJ,IAAUvE,KAAKuE,MACjB,OAIF,MAAMkD,EAAWzH,KAAK6E,iBAAiBD,GACnC6C,IAKFA,EAAStH,EAAOvB,UAEToB,KAAK6E,iBAAiBD,MAKnC0C,aAAaI,GACX,IAAKjJ,MAAMsB,QAAQ2H,IAAiC,IAApBA,EAAS9G,OACvC,OAIF,MAAMoE,EAAY,IAAIC,IAGtBjF,KAAK8E,gBAAgBI,QAASvD,IAC5B,MAAMxB,EAAuB,iBAARwB,EAAmBA,EAAI3B,KAAKT,UAAYoC,EAC7DqD,EAAUzE,IAAIJ,EAAOwB,KAIvB+F,EAASxC,QAASvD,IAChB,MAAMxB,EAAuB,iBAARwB,EAAmBA,EAAI3B,KAAKT,UAAYoC,EAC7DqD,EAAUzE,IAAIJ,EAAOwB,KAIvB3B,KAAK8E,gBAAkBrG,MAAM0G,KAAKH,EAAUI,WAE9CmC,aAAapH,GACXH,KAAKU,MAAM,oBAAqBP,GAEhCH,KAAK2H,mBAEPH,aAAarH,GACXH,KAAKU,MACH,SACAP,EACAH,KAAKpB,aAAeoB,KAAKpB,YAAYgC,OAAS,EAC1CZ,KAAKnB,SACHmB,KAAKpB,YACLoB,KAAKpB,YAAY,GACnBoB,KAAKnB,SACL,GACA,OAIR8I,kBAEE3H,KAAK4H,UAAU,KACb5H,KAAK4H,UAAU,KACb,IAEE,GACE5H,KAAKsE,kBACLtE,KAAKsE,iBAAiBuD,KACtB7H,KAAKuE,MAKL,YAHAvE,KAAKsE,iBAAiBuD,IAAIC,cAAc9H,KAAKuE,OAAOwD,MAAM,QAO5D,IAAIX,EAASpH,KAAKgI,QAClB,KAAOZ,GAAQ,CACb,GACEA,EAAOa,UACkB,eAAzBb,EAAOa,SAAS1K,MAChB6J,EAAOc,KACP,CACIlI,KAAKuE,OAAS6C,EAAOc,KAAKJ,eAC5BV,EAAOc,KAAKJ,cAAc9H,KAAKuE,OAAOwD,MAAM,QAI9C,MAEFX,EAASA,EAAOY,SAElB,MAAO7B,GACPC,QAAQC,KAAK,yBAA0BF,8ECzYjDxI,EAiBK,MAAA,CAjBC0F,4BAAOR,EAAW8D,aAAA9D,EAAA8D,eAAA5C,MACtBoE,EAeCC,EAAA,CAdEC,cAAaxF,EAAUtE,WACvBI,QAASkE,EAAakC,cACfuD,eAAczF,EAAWjE,kDAAXiE,EAAWjE,YAAA0E,GAChCzE,SAAUgE,EAAQhE,SAClB0J,gBAAe1F,EAAW9D,YAC1BG,YAAa2D,EAAW3D,YACxBE,SAAUyD,EAAQzD,SAClBC,QAAOwD,EAAKxD,OACZE,SAAUsD,EAAQtD,SAClBC,SAAUqD,EAAQrD,SAClBC,WAAYoD,EAAUpD,WACtBC,SAAUmD,EAAQnD,SAClB8I,sBAAoB3F,EAAY0E,aAChCkB,SAAQ5F,EAAY2E,6MCS3B,IAAAkB,GAAerK,EAAgB,CAC7Bd,KAAM,gBACN6G,WAAY,CACVC,UAAAA,GAEF/F,MAAO,CAELgG,iBAAkB,CAChB9F,KAAMc,OACNZ,QAAS,MAKXH,WAAY,CACVC,KAAMC,MACNC,QAASA,IAAM,IAGjBC,QAAS,CACPH,KAAMC,MACNC,QAASA,IAAM,IAGjBG,SAAU,CACRL,KAAMM,QACNJ,SAAS,GAGXK,YAAa,CACXP,KAAMQ,OACNN,aAASO,GAGXC,YAAa,CACXV,KAAMW,OACNT,QAAS,OAGXU,SAAU,CACRZ,KAAMM,QACNJ,SAAS,GAGXW,MAAO,CACLb,KAAM,CAACW,OAAQG,QACfZ,QAASA,KAAO,CAAEX,MAAO,UAG3BwB,SAAU,CACRf,KAAMW,OACNT,QAAS,SAGXc,SAAU,CACRhB,KAAMW,OACNT,QAAS,SAGXe,WAAY,CACVjB,KAAMM,QACNJ,SAAS,GAGX6F,MAAO,CACL/F,KAAMW,OACNT,QAAS,IAGXgB,SAAU,CACRlB,KAAMM,QACNJ,SAAS,GAEXiK,WAAY,CACVnK,KAAM,CAACW,OAAQH,QACfN,QAAS,MAEX8F,WAAY,CACVhG,KAAMc,OACNZ,QAASA,KAAO,KAElB+F,aAAc,CACZjG,KAAMkG,SACNhG,QAASA,SAGbiB,MAAO,CAAC,oBAAqB,UAC7BgF,KAAIA,KACK,CAELC,UAAW,EAEXC,iBAAkB,GAElBC,gBAAiB,GACjBlG,YAAa,KAGjBgB,SAAU,CAERmF,gBAEE,GAAI/E,KAAK8E,gBAAgBlE,OAAS,EAAG,CAEnC,MAAMoE,EAAY,IAAIC,IAWtB,OATAjF,KAAKrB,QAAQuG,QAASvD,IACpB,MAAMxB,EAAuB,iBAARwB,EAAmBA,EAAI3B,KAAKT,UAAYoC,EAC7DqD,EAAUzE,IAAIJ,EAAOwB,KAGvB3B,KAAK8E,gBAAgBI,QAASvD,IAC5B,MAAMxB,EAAuB,iBAARwB,EAAmBA,EAAI3B,KAAKT,UAAYoC,EAC7DqD,EAAUzE,IAAIJ,EAAOwB,KAEhBlD,MAAM0G,KAAKH,EAAUI,UAE9B,OAAOpF,KAAKrB,UAGhB0G,MAAO,CAEL1G,QAAS,CACP2G,WAAW,EACXC,QAAQC,GAG4B,IAAhCxF,KAAK8E,gBAAgBlE,QACrBnC,MAAMsB,QAAQyF,IACdA,EAAW5E,OAAS,IAEpBZ,KAAK8E,gBAAkB,IAAIU,OAKnCC,UAEEC,OAAOC,iBAAiB,UAAW3F,KAAK4F,gBAE1CC,gBAEEH,OAAOI,oBAAoB,UAAW9F,KAAK4F,gBAE7CpE,QAAS,CAGPuE,wBAAwBpB,GAEtB,GAAIA,MAAAA,EACF,OAAOA,EAGT,IAGE,OAAOqB,KAAKC,MAAMD,KAAKE,UAAUvB,IACjC,MAAOwB,GAIP,GAHAC,QAAQC,KAAK,gCAAiCF,GAG1C1H,MAAMsB,QAAQ4E,GAEhB,OAAoB,IAAhBA,EAAK/D,OACA,GAGF+D,EAAK1E,IAAKC,GAASF,KAAK+F,wBAAwB7F,IAGzD,GAAoB,iBAATyE,EAAmB,CAC5B,MAAM2B,EAAS,GACf,IAAK,MAAMvD,KAAO4B,EAChB,GAAIrF,OAAOiH,UAAUC,eAAeC,KAAK9B,EAAM5B,GAC7C,IACEuD,EAAOvD,GAAO/C,KAAK+F,wBAAwBpB,EAAK5B,IAChD,MAAO2D,GAEPN,QAAQC,KAAK,8BAA8BtD,EAAO2D,GAIxD,OAAOJ,EAIT,OAAO3B,IAGXgC,cAEE,GAAI3G,KAAKZ,SACP,OAIF,MAAMwH,EAAQ,eACZ5G,KAAKuE,OAAS,aACZsC,KAAKC,WAAW9G,KAAK4E,YAKnBmC,EAAoBtI,MAAMsB,QAAQC,KAAKzB,YACzCyB,KAAKzB,WACL,GAGJ,IAAIyI,EAAc,KACdD,EAAkBnG,OAAS,IAC7BoG,EAAcD,GAEhB,MAAME,EACJD,MAAAA,EACI,KACAhH,KAAK+F,wBAAwBiB,GAG7BxC,EAAa,IACdxE,KAAKwE,YAENxE,KAAKyE,cACPnF,OAAO4H,OAAO1C,EAAYxE,KAAKyE,gBAGjC,MAAM0C,EAAU,CACd3I,KAAM,mBACN+F,MAAOvE,KAAKuE,OAAS,GACrB1F,SAAUmB,KAAKnB,SACfgB,aAAcoH,EACd1H,SAAUS,KAAKT,SACfC,SAAUQ,KAAKR,SACfmJ,WAAY3I,KAAK2I,WACjBnE,WAAAA,EACAI,UAAWgC,GAIb,GAAIlB,OAAO0B,QAAU1B,OAAO0B,SAAW1B,OACrC,IACEA,OAAO0B,OAAOC,YAAYF,EAAS,KACnC,MAAOhB,GACPC,QAAQD,MAAM,wBAAyBA,QAIzCC,QAAQC,KACN,6CAKJrG,KAAK6E,iBAAiB+B,GAAS,CAACzG,EAAOvB,KAGnCA,GACAH,MAAMsB,QAAQnB,IACdA,EAAYgC,OAAS,GAGrBZ,KAAKsH,aAAa1I,GAGpBoB,KAAKpB,YAAcA,EAEnBoB,KAAKuH,aAAapH,GAClBH,KAAKwH,aAAarH,KAGtByF,cAAc5D,GAIZ,MAAM2C,EAAO3C,EAAM2C,KAGnB,GAAIA,GAAsB,uBAAdA,EAAKnG,KAA+B,CAC9C,MAAM+F,MAAEA,EAAKpE,MAAEA,EAAKvB,YAAEA,EAAWgG,UAAEA,GAAcD,EAGjD,GAAIJ,IAAUvE,KAAKuE,MACjB,OAIF,MAAMkD,EAAWzH,KAAK6E,iBAAiBD,GACnC6C,IAKFA,EAAStH,EAAOvB,UAEToB,KAAK6E,iBAAiBD,MAKnC0C,aAAaI,GACX,IAAKjJ,MAAMsB,QAAQ2H,IAAiC,IAApBA,EAAS9G,OACvC,OAIF,MAAMoE,EAAY,IAAIC,IAGtBjF,KAAK8E,gBAAgBI,QAASvD,IAC5B,MAAMxB,EAAuB,iBAARwB,EAAmBA,EAAI3B,KAAKT,UAAYoC,EAC7DqD,EAAUzE,IAAIJ,EAAOwB,KAIvB+F,EAASxC,QAASvD,IAChB,MAAMxB,EAAuB,iBAARwB,EAAmBA,EAAI3B,KAAKT,UAAYoC,EAC7DqD,EAAUzE,IAAIJ,EAAOwB,KAIvB3B,KAAK8E,gBAAkBrG,MAAM0G,KAAKH,EAAUI,WAE9CmC,aAAapH,GACXH,KAAKU,MAAM,oBAAqBP,GAEhCH,KAAK2H,mBAEPH,aAAarH,GACXH,KAAKU,MACH,SACAP,EACAH,KAAKpB,aAAeoB,KAAKpB,YAAYgC,OAAS,EAC1CZ,KAAKnB,SACHmB,KAAKpB,YACLoB,KAAKpB,YAAY,GACnBoB,KAAKnB,SACL,GACA,OAIR8I,kBAEE3H,KAAK4H,UAAU,KACb5H,KAAK4H,UAAU,KACb,IAEE,GACE5H,KAAKsE,kBACLtE,KAAKsE,iBAAiBuD,KACtB7H,KAAKuE,MAKL,YAHAvE,KAAKsE,iBAAiBuD,IAAIC,cAAc9H,KAAKuE,OAAOwD,MAAM,QAO5D,IAAIX,EAASpH,KAAKgI,QAClB,KAAOZ,GAAQ,CACb,GACEA,EAAOa,UACkB,eAAzBb,EAAOa,SAAS1K,MAChB6J,EAAOc,KACP,CACIlI,KAAKuE,OAAS6C,EAAOc,KAAKJ,eAC5BV,EAAOc,KAAKJ,cAAc9H,KAAKuE,OAAOwD,MAAM,QAI9C,MAEFX,EAASA,EAAOY,SAElB,MAAO7B,GACPC,QAAQC,KAAK,wBAAyBF,8EC/YhDxI,EAiBK,MAAA,CAjBC0F,4BAAOR,EAAW8D,aAAA9D,EAAA8D,eAAA5C,MACtBoE,EAeCC,EAAA,CAdEC,cAAaxF,EAAUtE,WACvBI,QAASkE,EAAakC,cACfuD,eAAczF,EAAWjE,kDAAXiE,EAAWjE,YAAA0E,GAChCzE,SAAUgE,EAAQhE,SAClB0J,gBAAe1F,EAAW9D,YAC1BG,YAAa2D,EAAW3D,YACxBE,SAAUyD,EAAQzD,SAClBC,QAAOwD,EAAKxD,OACZE,SAAUsD,EAAQtD,SAClBC,SAAUqD,EAAQrD,SAClBC,WAAYoD,EAAUpD,WACtBC,SAAUmD,EAAQnD,SAClB8I,sBAAoB3F,EAAY0E,aAChCkB,SAAQ5F,EAAY2E,6MCW3B,IAAeoB,GAAA,CACbrL,KAAM,YACNoC,MAAO,CAAC,SAAU,MAAO,SAAU,qBACnCrB,MAAO,CACLgG,iBAAkBhF,OAClBf,WAAY,CACVC,KAAMC,MACNC,QAASA,IAAM,IAEjBmK,QAAS,CACPrK,KAAMC,MACNqK,UAAU,EACVpK,QAASA,IAAM,IAEjBqK,kBAAmB,CACjBvK,KAAMM,QACNJ,SAAS,GAEXsK,UAAW,CACTxK,KAAMM,QACNJ,SAAS,GAEXuK,QAAS,CACPzK,KAAMM,QACNJ,SAAS,GAEXC,QAAS,CACPH,KAAMc,OACNZ,QAASA,IACPwK,EAAS,CACPC,WAAW,EACXC,UAAU,KAGhBC,IAAKrK,OACLsC,IAAKtC,OACLI,SAAUN,SAEZuG,MAAO,CACL9G,WAAY,CACVgH,UACEvF,KAAKsJ,eAEPC,MAAM,GAERC,2BAA4B,SAAUC,GACpCzJ,KAAK0J,UAAUC,SAAS,GAAGrL,MAAMsL,QAC/B5J,KAAK6I,QAAQjI,QAAU6I,EAAI,EAAI,KAGrC9E,OACE,MAAO,CACLkF,KAAM,GACNC,IAAK,GACL5B,KAAM,GACN6B,KAAMC,EAAQhK,KAAKsE,iBAAiB2F,KAAKC,SACzCC,QAAS,GACTC,SAAU,GACVV,UAAW,CACTlL,KAAM,KACN6L,UAAU,EACVC,QAAQ,EACRC,SAAS,EACTZ,SAAU,CACR,CACEnL,KAAM,KACNa,MAAO,CACLmL,UAAW,UAEbF,QAAQ,EACRC,SAAS,EACTjM,MAAO,CACLsL,QACE5J,KAAK6I,QAAQjI,QAAUZ,KAAKsE,iBAAiBmG,QAAU,EAAI,IAE/Dd,SAAU,CAAC3J,KAAKsE,iBAAiBoG,EAAE,cAAgB,aAM7DlJ,QAAS,CACPmJ,aACE3K,KAAK4K,eAEPA,cACE,MAAMzK,EAAQH,KAAK8J,IAChB7J,IAAI,CAAC4K,EAAIC,KACD,IACD9K,KAAKzB,WAAWuM,IAAQ,MACzB9K,KAAKkI,KAAK6C,oBAAoBF,MAGpC1I,OAAQ6I,IACP,IAAKhL,KAAK+I,kBACR,OAAO,EAET,GAAIiC,MAAAA,EACF,OAAO,EAET,IAAIC,GAAO,EAIX,OAHA3L,OAAO4L,KAAKF,GAAG9F,QAASiG,IACtBF,EAAOA,QAAkBhM,IAAT+L,EAAEG,IAA6B,KAATH,EAAEG,IAAsB,OAATH,EAAEG,KAElDF,IAELG,EAAMpF,KAAKE,UAAU/F,GACvBiL,IAAQpL,KAAKoK,WACfpK,KAAKoK,SAAWgB,EAChBpL,KAAKU,MAAM,oBAAqBP,GAChCH,KAAKU,MAAM,SAAUP,KAGzBkL,WAAWP,EAAKQ,GACd,MAAMC,EAAMvL,KAAK8J,IAAIgB,GACrB9K,KAAKkI,KAAKsD,oBAAoBD,EAAKD,GAAU,IAE/ChC,cACE,MAAM8B,EAAMpF,KAAKE,UAAUlG,KAAKzB,YAC5ByB,KAAKoK,WAAagB,IAGtBpL,KAAKoK,SAAWgB,EAChBpL,KAAK8J,IAAM9J,KAAK8J,IAAI2B,OAAO,EAAGzL,KAAKzB,WAAWqC,QACzCZ,KAAKzB,WAAWqC,OAGnBZ,KAAK0L,aAFL1L,KAAK2L,WAIP3L,KAAKzB,WAAW2G,QAAQ,CAACP,EAAMmG,KACxB9K,KAAK8J,IAAIgB,IACZ9K,KAAK4L,SAEP5L,KAAKqL,WAAWP,EAAKnG,GAAQ,MAE/B3E,KAAK6J,KAAK,GAAGF,SAAS,GAAGA,SAAW3J,KAAK8J,MAE3C6B,WACM3L,KAAK8J,IAAIlJ,QACXZ,KAAK8J,IAAI2B,OAAO,EAAGzL,KAAK8J,IAAIlJ,QAE9BZ,KAAK8J,IAAI+B,KAAK7L,KAAK0J,YAErBgC,aACM1L,KAAK8J,IAAI,IAAM9J,KAAK8J,IAAI,GAAGO,UAC7BrK,KAAK8J,IAAI2B,OAAO,EAAG,IAGvBK,OAAOhB,GAEH9K,KAAKZ,WACJY,KAAKgJ,WACLhJ,KAAKqJ,IAAM,GAAKrJ,KAAK8J,IAAIlJ,QAAUZ,KAAKqJ,MAI3CrJ,KAAK8J,IAAI2B,OAAOX,EAAK,GACrB9K,KAAK4K,cACD5K,KAAK8J,IAAIlJ,OACXZ,KAAK8J,IAAI5E,QAAS2F,GAAO7K,KAAK+L,UAAUlB,IAExC7K,KAAK2L,WAEP3L,KAAKU,MAAM,SAAUoK,KAEvBc,OAAOX,GACL,GAAIA,GAAQjL,KAAKZ,SACf,OAEF,MAAMyL,EAAK7K,KAAKsE,iBAAiB2F,KAAK+B,UAAUhM,KAAKmK,SAAS,GACtC,IAApBnK,KAAK8J,IAAIlJ,QAAgBZ,KAAK8J,IAAI,GAAGO,UACvCrK,KAAK8J,IAAI2B,OAAO,EAAG,GAErBzL,KAAK8J,IAAI+B,KAAKhB,GACd7K,KAAK+L,UAAUlB,GACXI,IACFjL,KAAKU,MAAM,MAAOV,KAAK8J,IAAIlJ,QAC3BZ,KAAK4K,gBAGTmB,UAAUlB,GACR,MAAMC,EAAM9K,KAAK8J,IAAImC,QAAQpB,GAC7BA,EAAGlB,SAAS,GAAGrL,MAAM4N,UAAYpB,EAAM,EACvCD,EAAGlB,SAASkB,EAAGlB,SAAS/I,OAAS,GAAG+I,SAAS,GAAGrL,MAAM+E,QAAU,KAC9DrD,KAAK8L,OAAOhB,KAGhBqB,WACE,MAAMC,EAAS,CACb,CACE5N,KAAM,KACN8L,QAAQ,EACR7M,MAAO,kBACPa,MAAO,CACL4N,UAAW,OAIjB,IAAIG,EAAO,CACT,CACE7N,KAAM,KACNf,MAAO,aACP6M,QAAQ,EACRhM,MAAO,CACL4N,UAAW,OAIjBlM,KAAK6I,QAAQ3D,QAASoH,IACpBF,EAAOP,KAAK,CACVrN,KAAM,KACN8L,QAAQ,EACRjL,MAAO,IACDiN,EAAOjN,OAAS,GACpBmL,UAAW8B,EAAOC,OAAS,UAE7B9O,MAAO6O,EAAOxD,SAAW,uBAAyB,GAClDxK,MAAO,CACL4N,UAAWI,EAAOhM,OAAS,MAG/B+L,EAAKR,KAAK,CACRrN,KAAM,KACN8L,QAAQ,EACRX,SAAU,IAAK2C,EAAOzC,MAAQ,QAGlCuC,EAAOP,KAAK,CACVrN,KAAM,KACN8L,QAAQ,EACR7M,MAAO,uBACPa,MAAO,CACL4N,UAAWlM,KAAKsE,iBAAiBoG,EAAE,cAAgB,QAGvD2B,EAAKR,KAAK,CACRrN,KAAM,KACN8L,QAAQ,EACR7M,MAAO,sBACPkM,SAAU,CACR,CACEnL,KAAM,IACN8L,QAAQ,EACR7M,MAAO,sBACPa,MAAO,OAIb0B,KAAKmK,QAAUnK,KAAKsE,iBAAiB2F,KAAKuC,OAAO,CAC/C,CACEhO,KAAM,KACN8L,QAAQ,EACRC,SAAS,EACTZ,SAAU0C,KAGdrM,KAAK6J,KAAO,CACV,CACErL,KAAM,QACN8L,QAAQ,EACR7M,MAAO,eACPa,MAAO,CACLmO,OAAQ,IACRC,YAAa,IACbC,YAAa,KAEfhD,SAAU,CACR,CACEnL,KAAM,QACN8L,QAAQ,EACRX,SAAU,CACR,CACEnL,KAAM,KACN8L,QAAQ,EACRX,SAAUyC,KAIhB,CACE5N,KAAM,QACN8L,QAAQ,EACRX,SAAU3J,KAAK8J,UAO3B8C,UACE5M,KAAKmM,YAEP1G,UACEzF,KAAKsJ,iFC9TP3L,EAoBK,MAAA,CApBAF,MAAKoP,EAAA,CAAC,iBAAe,CAAAC,eAA4BC,EAAS3N,eAC7D1B,IAAAsP,EASYC,EARLC,EAAInD,MAAA,CACRlI,OAAQkL,EAAOpO,QACfkL,KAAMqD,EAAIrD,KACVsD,cAAc,EACd/N,SAAU2N,EAAQ3N,SAClBqJ,SAAQR,EAAU0C,WACX9C,IAAKqF,EAAIhF,mCAAJgF,EAAIhF,KAAA5E,GAChB8J,YAAYvK,EAAKnC,6EAKZqM,EAAA9D,WAAa8D,EAAIzL,KAAGyL,MAAW/M,KAAA8J,IAAIlJ,aAH3CoM,EAQUK,EAAA,OAPR7O,KAAK,OACLf,MAAM,WAEL4F,uBAAO4E,EAAM2D,QAAA,IACbxM,SAAU2N,EAAQ3N,qBAClB,IAA+D,aAA/DvB,EAA+D,IAAA,CAA5DJ,MAAM,0BAA0B4B,MAAA,CAAwBiO,cAAA,oBAAI,IAChElK,EAAG2J,EAAgBzI,iBAACoG,EAAC,QAAA,MAAA,6CCP3B,IAAA6C,GAAelP,EAAgB,CAC7Bd,KAAM,gBACNoH,KAAIA,KACK,MCdJ,MAAAnH,GAAA,CAAAC,MAAM,4BACJA,MAAM,yBAGNA,MAAM,mDAJb,OAAAC,IAAAC,EAKK,MALLH,GAKK,CAJ4BqF,EAAA2K,OAAO9O,SAAtChB,IAAAC,EAEK,MAFL8P,GAEK,CADHC,EAAY7K,EAAA2K,OAAA,eAEd9P,IAAAC,EAAyC,MAAzCsG,QCUJ,IAAA0J,GAAetP,EAAgB,CAC7Bd,KAAM,sBACNe,MAAO,CACLgC,MAAOnB,OACPoN,MAAOpN,OACPpB,MAAO,CAACiB,OAAQG,QAChByO,MAAOzO,OACP2J,SAAUhK,SAEZc,SAAU,CACRiO,WACE,MAAMC,EAAI9N,KAAKjC,MACTsB,EAAQ,CACZtB,MAAOgQ,EAAG/O,OAAO8O,GAAQA,EAAH,KAAYA,GAAW,SAANA,EAAyBA,EAAV,SAKxD,OAHI9N,KAAK4N,QACPvO,EAAMuO,MAAQ5N,KAAK4N,OAEdvO,IAGXsF,KAAIA,KACK,sBClCiBlH,MAAM,mBAEzBgQ,GAAA,CAAAhQ,MAAM,yDAJbE,EAOK,MAAA,CAPAF,MAAM,aAAc4B,QAAOwD,EAAQgL,YACtChQ,EAEK,MAAA,CAFAJ,MAAM,eAAgB4B,mBAAoBwD,EAAM0J,OAAA,aACvC1J,EAAQiG,cAApBnL,EAAsD,OAAtDH,GAA8C,uBAAWqF,EAAMvC,OAAA,IAAA,OAEjEzC,EAEK,MAFL4P,GAEK,CADHC,EAAY7K,EAAA2K,OAAA,kBCMlB,IAAepJ,GAAA,CACb4J,EACAC,EACAC,EACAC,EACAC,EACA/J,EACAgK,GACAC,GACAC,GACAC,GACAC,ICrBaC,GAAA,CACXnR,KAAM,WACNoR,WAAY,QACZC,UAAUC,GACN,MAAMvQ,EAAQuQ,EAAIC,KAAKxQ,MAClByQ,EAAYzQ,EAAO,aACpBA,EAAMK,QAAUkQ,EAAIC,KAAKnQ,SAAW,MCNjCqQ,GAAA,IACRN,GAAUnR,KAAM,SCAR0R,GAAA,IACVP,GACHnR,KAAM,SACNqR,UAAUC,GACR,MAAMvQ,EAAQuQ,EAAIC,KAAKxQ,MAClByQ,EAAYzQ,EAAO,aAAYA,EAAMK,QAAUkQ,EAAIC,KAAKnQ,SAAW,IAGxE,MAAMuQ,EAAYL,EAAIM,WAAW,SACfD,IAAmC,IAAtBA,EAAUE,UAIvC9Q,EAAMc,UAAW,EACjBd,EAAM8Q,SAAU,IAGpBC,OAAO1F,EAAUkF,GAEf,MAAMK,EAAYL,EAAIM,WAAW,SAIjC,GAHkBD,IAAmC,IAAtBA,EAAUE,SAGxBzF,EAASyF,QAAS,CAEjC,MAAME,EAAc,IAAK3F,GAEzB,OADA2F,EAAYC,gBAAkB5F,EAASyF,QAChCP,EAAIW,QAAQC,cAAcZ,EAAKS,GAIxC,OAAOT,EAAIW,QAAQC,cAAcZ,EAAKlF,KC7B3B+F,GAAA,CACbnS,KAAM,WACNqR,UAAUC,GACR,MAAMvQ,EAAQuQ,EAAIC,KAAKxQ,MAClByQ,EAAYzQ,EAAO,aAAYA,EAAMK,QAAUkQ,EAAIC,KAAKnQ,SAAW,IAGxE,MAAMuQ,EAAYL,EAAIM,WAAW,SAUjC,GATkBD,IAAmC,IAAtBA,EAAUE,UAIvC9Q,EAAMc,UAAW,EACjBd,EAAM8Q,SAAU,GAId9Q,EAAMqR,SAAU,CAAA,IAAAC,EAClB,MAAM/H,EAAiB,QAAd+H,EAAGf,EAAIgB,eAAO,IAAAD,OAAA,EAAXA,EAAa/H,IACnBgC,EAAOgF,EAAIhF,KACXiG,EAASjB,EAGf,IAAIkB,EAAWhC,EAAG5O,OAAOb,EAAMqR,UAC3BK,EAAQ1R,EAAMqR,UACdrR,EAAMqR,SAGV,IAAK5B,EAAGrJ,SAASqL,IAAahC,EAAG5O,OAAOb,EAAMqR,UAC5C,IACE,MAAMM,EAAO3R,EAAMqR,SAASO,OAEzBD,EAAKE,WAAW,aAChBF,EAAKE,WAAW,kCAChBF,EAAKE,WAAW,WAEjBJ,EAAW,IAAIrL,SACb,kBACA,UACA,gBACA,MACA,OACAuL,IAGJ,MAAOvJ,GACPN,QAAQD,MAAM,4BAA6BO,GAI3CqH,EAAGrJ,SAASqL,KAEdzR,EAAMqR,SAAW,SAAUS,GACzB,IAAKA,GAA8C,IAA3BA,EAAgBxP,OAAc,OAEtD,MAAMyP,EAAeD,EAAgBA,EAAgBxP,OAAS,GAE9D,IAA6B,KAAzByP,MAAAA,OAAY,EAAZA,EAAcC,QAChB,OAGF,MAAM3R,EAAUL,EAAMK,SAAW,GAI3B4R,EAAgBA,KAAM,IAAAC,EAAAC,EAG1B,MAAMC,EAAiBpS,EAAMK,SAAW,GAGxC,IAAIgS,GAAe,EACfN,IACFM,EAAcD,EAAeE,UAC1B1Q,GACCA,EAAKC,QAAUkQ,EAAalQ,OAC5BD,EAAK2Q,KAAOR,EAAaQ,IACzB3Q,IAASmQ,IAIf,MAAM7K,EAAakL,EAAezQ,IAAI,CAACC,EAAMgD,KAE3C,GAAIA,IAAUyN,GAAeN,EAAc,CAEzC,MADkB,IAAKA,GAIzB,MAAO,IAAKnQ,KAORgP,EAAYY,EAAOX,WAAW,SAChCD,GAEF4B,EAAQ5B,EAAW,gBAAiB1J,GAItClH,EAAMK,QAAU6G,EAGDgL,QAAfA,EAAIV,EAAOhB,YAAP0B,IAAWA,GAAXA,EAAalS,QACfwR,EAAOhB,KAAKxQ,MAAMK,QAAU6G,GAIfiL,QAAfA,EAAIX,EAAOjG,YAAP4G,IAAWA,GAAXA,EAAanS,QACfwR,EAAOjG,KAAKvL,MAAMK,QAAU6G,GAI1BqC,GAAOgC,GACThC,EAAIkJ,KAAKlH,GAIPiG,EAAOD,SACTC,EAAOD,QAAQmB,WAMfX,IACFA,EAAajB,SAAU,EACvBmB,KAIF,MAAMjK,EAASyJ,EAAStJ,KACtBzG,KACAoQ,EACAzR,EACA4R,EACA1I,EACAgC,GAIF,OAAIvD,GAAiC,mBAAhBA,EAAO2K,KACnB3K,EAAO4K,QAAQ,KACpBX,MAIGjK,MAKf+I,OAAO1F,EAAUkF,GAEf,MAAMK,EAAYL,EAAIM,WAAW,SAIjC,GAHkBD,IAAmC,IAAtBA,EAAUE,SAGxBzF,EAASyF,QAAS,CAEjC,MAAME,EAAc,IAAK3F,GAEzB,OADA2F,EAAYC,gBAAkB5F,EAASyF,QAChCP,EAAIW,QAAQC,cAAcZ,EAAKS,GAIxC,OAAOT,EAAIW,QAAQC,cAAcZ,EAAKlF,KC3K1C,MAAMwH,GAAc,CAClBC,KAAM,aACNC,MAAO,UACPC,KAAM,UACNC,QAAS,UACTC,KAAM,QAGFjU,GAAO,aAEb,IAAekU,GAAA,MACblU,GACAmU,MACS,CAAC,OAAQ,QAAS,QAAQC,OAC/B,CAACC,EAASpT,KACRoT,EAAQpT,GAAQqT,EAAetU,GAAM,CAAEiB,KAAAA,IAChCoT,GAET,CACEE,UAAWD,EAAetU,GAAM,CAAEiB,KAAM,UACxCuT,cAAeF,EAAetU,GAAOyU,GACnCA,EAAE1T,MAAM,CAAEE,KAAM,QAASyT,UAAU,OAK3CtD,WAAY,QACZC,UAAUC,GACR,MAAMvQ,EAAQuQ,EAAIC,KAAKxQ,MACjBE,EAAOF,EAAME,MAAQF,EAAM4T,OAC5B5T,EAAM6T,cACT7T,EAAM6T,aACHhB,GAAY3S,IAAS2S,GAAkB,QACvC7S,EAAM2T,UAAczT,GAAiB,SAATA,EAAiC,GAAd,eAGtD6Q,OAAMA,CAAC1F,EAAUkF,IACRA,EAAIW,QAAQ4C,QACS,IAAzBvD,EAAIC,KAAKxQ,MAAM+T,MAAiB,QAAU,QAAU,UACrDxD,EAAIC,KAAMnF,ICrChB,IAAe2I,GAAA,MAFF,SAIXZ,MAAO,CACLY,OAAQ,CAAC/N,EAAOpE,IAAU0R,EALjB,SAKiBA,CAAqB,GAAItN,EAAOpE,IAE5DkP,OAAMA,IACG,ICPIkD,GAAA,CACbhV,KAAM,OAGNiV,cAAc,EAEd/M,QAAQoJ,GAAK,IAAA4D,EAAAC,EAEX,MAAMpU,EAAQuQ,EAAIhF,KAAKvL,OAAS,GAC1BqU,EACJ9D,EAAIhF,KAAK8I,WAAarU,EAAMqU,oBAASF,EAAI5D,EAAIC,KAAKxQ,aAAK,IAAAmU,OAAA,EAAdA,EAAgBE,WACrDC,EACJ/D,EAAIhF,KAAK+I,UAAYtU,EAAMsU,mBAAQF,EAAI7D,EAAIC,KAAKxQ,aAAK,IAAAoU,OAAA,EAAdA,EAAgBE,WAErDA,GAAYD,IAEdE,WAAW,KACT,GAAIhE,EAAIgB,SAAWhB,EAAIgB,QAAQhI,IAC7B,IACE,IAAI1H,EAAQ,GAGZ,GAAIyS,EAAU,CACZ,MAAMtH,EAAWuD,EAAIgB,QAAQhI,IAAIyD,WAEjCnL,EAAQ0O,EAAIgB,QAAQiD,WAClBF,EACCrO,IAEC,MAAM/D,EAAMqO,EAAIgB,QAAQhI,IAAIkL,SAASxO,GAErC,YACUtF,IAARuB,GACA8K,QACoBrM,IAApBqM,EAAS/G,GAEF+G,EAAS/G,GAEX/D,GAET,WAIKmS,IACPxS,EAAQ0O,EAAIgB,QAAQhI,IAAIkL,SAASJ,IAAc,IAIpC,MAATxS,IACG0O,EAAIhF,KAAKF,WACZkF,EAAIhF,KAAKF,SAAW,IAEtBkF,EAAIhF,KAAKF,SAAS,GAAKxK,OAAOgB,GAE9B0O,EAAIgB,QAAQhI,IAAIkJ,KAAKlC,EAAIhF,MACzBgF,EAAIgB,QAAQmB,WAEd,MAAOtK,MAIV,MAIPsM,eAAcA,CAACrJ,EAAUkF,KAGhB,CACLnQ,QAASA,KAAM,IAAAuU,EAGb,IAAIC,EAA0B,QAAXD,EAAGpE,EAAIhF,YAAI,IAAAoJ,OAAA,EAARA,EAAUtJ,SAG3BuJ,IACHA,EAAkBvJ,GAoBpB,OAhBsBlL,MAAMsB,QAAQmT,GAChCA,EACA,CAACA,IAIF/Q,OAAQ6I,GAAMA,MAAAA,GACd/K,IAAK+K,GACA+C,EAAG5O,OAAO6L,GACLA,EAGF7L,OAAO6L,IAEfmI,KAAK,KAEO,MAIrBvE,UAAUC,GAAK,IAAAuE,EAAAC,EAAAC,EASb,MAAMhV,EAAQuQ,EAAIhF,KAAKvL,OAAS,GAC1BqU,EACJ9D,EAAIhF,KAAK8I,WAAarU,EAAMqU,oBAASS,EAAIvE,EAAIC,KAAKxQ,aAAK,IAAA8U,OAAA,EAAdA,EAAgBT,WACrDC,EACJ/D,EAAIhF,KAAK+I,UAAYtU,EAAMsU,mBAAQS,EAAIxE,EAAIC,KAAKxQ,aAAK,IAAA+U,OAAA,EAAdA,EAAgBT,UACzD,IAAIW,EACF1E,EAAIhF,KAAK0J,UAAYjV,EAAMiV,mBAAQD,EAAIzE,EAAIC,KAAKxQ,aAAK,IAAAgV,OAAA,EAAdA,EAAgBC,UAczD,GAXKA,IAEDA,EADEX,EACS,WACFD,EACE,QAEA,UAKE,UAAbY,GAAwBZ,EAAW,CACrC,MAAMa,EAAiB,CACrBC,KAAMd,EACNe,GAAI,QACJC,QAAQ,EAERC,KAAM,IAENvO,OAAO,GAIJwJ,EAAIhF,KAAKgK,SACZhF,EAAIhF,KAAKgK,OAAS,IAEfhF,EAAIhF,KAAKgK,OAAOlE,WACnBd,EAAIhF,KAAKgK,OAAOlE,SAAW,IAGdd,EAAIhF,KAAKgK,OAAOlE,SAASvN,KACrClC,GAASA,EAAKuT,OAASd,GAAyB,UAAZzS,EAAKwT,MAG1C7E,EAAIhF,KAAKgK,OAAOlE,SAAS9D,KAAK2H,GAG1B3E,EAAIgB,SAAWhB,EAAIgB,QAAQgE,QAC7BhF,EAAIgB,QAAQgE,OAAOhF,EAAK,gBAKzB,GAAiB,aAAb0E,GAA2BX,EAAU,CAC5C,MAAMY,EAAiB,CACrBZ,SAAUA,EACVc,GAAI,QACJC,QAAQ,EAERC,KAAM,IAENvO,OAAO,GAGJwJ,EAAIhF,KAAKgK,SACZhF,EAAIhF,KAAKgK,OAAS,IAEfhF,EAAIhF,KAAKgK,OAAOlE,WACnBd,EAAIhF,KAAKgK,OAAOlE,SAAW,IAM7B,IAHed,EAAIhF,KAAKgK,OAAOlE,SAASvN,KACrClC,GAASA,EAAK0S,WAAaA,GAAwB,UAAZ1S,EAAKwT,MAG7C7E,EAAIhF,KAAKgK,OAAOlE,SAAS9D,KAAK2H,GAE1B3E,EAAIgB,SAAWhB,EAAIgB,QAAQgE,SAC7BhF,EAAIgB,QAAQgE,OAAOhF,EAAK,WAGnBA,EAAIiF,uBAAsB,CAC7BjF,EAAIiF,sBAAuB,EAC3B,MAAMC,EAAcC,EAAMnF,EAAIhF,KAAKgK,OAAQ,YAC3ChF,EAAIxJ,MAAMwG,KACRxG,EACE0O,EACA,CAACE,EAAQC,KACPrF,EAAIgB,QAAQgE,OAAOhF,EAAK,QAAS,CAAEc,SAAUsE,KAE/C,CAAE1K,MAAM,MAWY,MAA5BsF,EAAIhF,KAAKsK,iBAA4BtF,EAAIhF,KAAKF,WAChDkF,EAAIhF,KAAKF,SAAW,CAACkF,EAAIhF,KAAKsK,kBAI3BtF,EAAIhF,KAAKF,WACZkF,EAAIhF,KAAKF,SAAW,KAMN,UAAb4J,GAAwBZ,GACX,aAAbY,GAA2BX,MAKzB/D,EAAIhF,KAAKF,UACTlL,MAAMsB,QAAQ8O,EAAIhF,KAAKF,WAA0C,IAA7BkF,EAAIhF,KAAKF,SAAS/I,UAOrDiO,EAAIhF,KAAKF,SAHM,aAAb4J,EAGkB,CAAC,IAGD,CAAC,OAK7BlE,OAAO1F,EAAUkF,GAMf,IAAI0D,EAAO,GACX,GAAI5I,GAAwC,mBAArBA,EAASjL,QAC9B,IACE6T,EAAO5I,EAASjL,WAAa,GAC7B,MAAOgI,GACP6L,EAAO,GAMTA,EADU,MAARA,QAAyBtT,IAATsT,EACX,GAEApT,OAAOoT,GAIhB,MAAMzD,EAAO,IAAKD,EAAIC,MACjBA,EAAKxQ,QACRwQ,EAAKxQ,MAAQ,IAIG,SAAdwQ,EAAKtQ,OACPsQ,EAAKtQ,KAAO,cAGPsQ,EAAKxQ,MAAM8V,UAKlB,OADcvF,EAAIuD,MAAMiC,KAAK,MAAOvF,EAAM,CAACyD,MCzR/C,IAAe+B,GAAA,MADF,QAGX5C,MACS,CAAC,WAAY,MAAO,QAAS,OAAQ,WAAY,UAAUC,OAChE,CAACD,EAAOlT,KACNkT,EAAMlT,GAAQqT,EANT,QAM8B,CAAErT,KAAAA,IAC9BkT,GAET,CACE6C,MAAO1C,EAVF,QAUuB,CAAErT,KAAM,WAI1CmQ,WAAY,QACZU,OAAO1F,EAAUkF,GACf,IAAIrQ,EAAOqQ,EAAIC,KAAKxQ,MAAME,KAS1B,OAR0D,IAAtD,CAAC,WAAY,SAAU,YAAYyN,QAAQzN,KAAcA,EAAO,SAEpEA,EACE,CACEgW,SAAU,YACVC,OAAQ,eACRC,SAAU,kBACVlW,IAAS,SACNqQ,EAAIW,QAAQ4C,MAAMiC,KAAK7V,EAAMqQ,EAAIC,KAAMnF,KC3BnCgL,GAAA,CACXpX,KAAM,aACNoR,WAAY,QACZC,UAAUC,GACN,MAAMvQ,EAAQuQ,EAAIC,KAAKxQ,MAClBA,EAAM6T,cACP7T,EAAM6T,YAAc,aAG5B9C,OAAMA,CAAC1F,EAAUkF,IACNA,EAAIW,QAAQ4C,MAAM,SAAmC,IAAzBvD,EAAIC,KAAKxQ,MAAM+T,MAAiB,QAAU,IAAM,UAAUxD,EAAIC,KAAMnF,ICVhGiL,GAAA,CACXrX,KAAM,OACNoR,WAAY,cACZC,UAAUC,GACN,MAAMvQ,EAAQuQ,EAAIC,KAAKxQ,MAClBA,EAAMuW,WAIDvW,EAAMuW,WAAW9R,MAAKzE,EAAMuW,WAAW9R,IAAM,MAHnDzE,EAAMuW,WAAa,CACf9R,IAAK,MAGbzE,EAAMwW,YAAcjG,EAAIhF,KAAK1J,MAC7B7B,EAAMyW,WAAY,ICXXC,GAAA,CACXzX,KAAM,QACN8R,OAAMA,CAAC4F,EAAGpG,IACCA,EAAIuD,MAAM8C,IAAI,CAAC5W,MAAO,CAAC6W,KAAM,KAAM,CACtCzW,QAASA,IAAM,CACXmQ,EAAIuD,MAAM4C,IAAInG,EAAIC,KAAMmG,OCDxC,ICgBeG,GAAA,CACb1G,GACA+C,GClBa,IACRA,QAHM,cAKTC,MAAO,GACPrC,OAAMA,CAAC1F,EAAUkF,IACNA,EAAIW,QAAQ4C,MAAmB,YAAEvD,EAAIC,KAAMnF,IDexD2I,GACAC,GACA+B,GACAK,GDvBa,IACRA,GACHpX,KAJS,kBAKT8R,OAAMA,CAAC1F,EAAUkF,IACNA,EAAIW,QAAQ4C,MAAuB,gBAAEvD,EAAIC,KAAMnF,ICqB5DiL,GACA5F,GACAC,GACAS,GACAsF,GE9Ba,CACbzX,KAAM,iBACNoR,WAAY,aAEZ0G,YAAWA,CAAClV,EAAO0O,IAEb1O,MAAAA,GAAmD,KAAVA,EACpC,GAEL1B,MAAMsB,QAAQI,GAETA,EAAMF,IAAKC,IAEE,iBAATA,GACE,OAATA,QACgBjB,IAAfiB,EAAKC,OAAuBD,EAAKI,MAM7BJ,IAIJ,CAACC,GAGVmV,QAAOA,CAACC,EAAW1G,IAEV0G,EAET3G,UAAUC,GACR,MAAMvQ,EAAQuQ,EAAIC,KAAKxQ,MAUvB,GARKyQ,EAAYzQ,EAAO,aACtBA,EAAMK,QAAUkQ,EAAIC,KAAKnQ,SAAW,IAGjCoQ,EAAYzQ,EAAO,WACtBA,EAAMiG,MAAQsK,EAAIhF,KAAKtF,OAAS,SAGXtF,IAAnB4P,EAAIhF,KAAK1J,MAAqB,CAChC,MAAMN,EAAegP,EAAIhF,KAAK1J,MAE5BN,MAAAA,GAEiB,KAAjBA,EAEAgP,EAAIhF,KAAK1J,MAAQ,GACP1B,MAAMsB,QAAQF,KACxBgP,EAAIhF,KAAK1J,MAAQ,CAACN,MAIxBwP,OAAO1F,EAAUkF,GAEf,MAAM2G,EAAQ3G,EAAIW,QAAQC,cAAcZ,EAAKlF,GAG7C,GAAI6L,GAASA,EAAMlX,OAASkX,EAAMlX,MAAMmX,GAAI,CAE1C,MAAMC,EAA2BF,EAAMlX,MAAMmX,GAAG,qBAG1C9N,EAAkBA,KAGtBgO,EAAS,KACPA,EAAS,KACP,IAEE,MAAMC,EAAY/G,EAAIhF,KAAKtF,MAC3B,GAAIqR,EAIF,YAHA/G,EAAIgB,QAAQhI,IAAIC,cAAc8N,GAAW7N,MAAM,QAOjD,MAAM8N,EAAWhH,EAAIgB,QAAQiG,YAAYjH,EAAIhF,KAAKtF,OAC9CsR,GAAYA,EAAShF,IACvBhC,EAAIgB,QAAQkG,SAASjO,cAAc+N,EAAShF,IAAI9I,MAAM,QAIxD,MAAO5B,GAEPC,QAAQC,KAAK,yBAA0BF,SAO/CqP,EAAMlX,MAAMmX,GAAG,qBAAuB,IAAI1R,KAEpC2R,GACFA,KAA4B3R,GAG9B4D,KAIF,MAAMqO,EAAiBR,EAAMlX,MAAMmX,GAAW,OAE5CD,EAAMlX,MAAMmX,GAAW,OADrBO,EACyB,IAAIjS,KAE7BiS,KAAkBjS,GAElB4D,KAIyBA,EAI/B,OAAO6N,ICzHI,CACbjY,KAAM,gBACNoR,WAAY,aAEZ0G,YAAWA,CAAClV,EAAO0O,IAEb1O,MAAAA,GAAmD,KAAVA,EACpC,GAEL1B,MAAMsB,QAAQI,GAETA,EAAMF,IAAKC,IAEE,iBAATA,GACE,OAATA,QACgBjB,IAAfiB,EAAKC,OAAuBD,EAAKI,MAM7BJ,IAIJ,CAACC,GAGVmV,QAAOA,CAACC,EAAW1G,IAEV0G,EAET3G,UAAUC,GACR,MAAMvQ,EAAQuQ,EAAIC,KAAKxQ,MAcvB,GAZKyQ,EAAYzQ,EAAO,aACtBA,EAAMK,QAAUkQ,EAAIC,KAAKnQ,SAAW,IAGjCoQ,EAAYzQ,EAAO,WACtBA,EAAMiG,MAAQsK,EAAIhF,KAAKtF,OAAS,IAG7BwK,EAAYzQ,EAAO,sBACtBA,EAAMgG,iBAAmBuK,EAAIoH,aAGRhX,IAAnB4P,EAAIhF,KAAK1J,MAAqB,CAChC,MAAMN,EAAegP,EAAIhF,KAAK1J,MAE5BN,MAAAA,GAEiB,KAAjBA,EAEAgP,EAAIhF,KAAK1J,MAAQ,GACP1B,MAAMsB,QAAQF,KACxBgP,EAAIhF,KAAK1J,MAAQ,CAACN,MAIxBwP,OAAO1F,EAAUkF,GAEf,MAAM2G,EAAQ3G,EAAIW,QAAQC,cAAcZ,EAAKlF,GAG7C,GAAI6L,GAASA,EAAMlX,OAASkX,EAAMlX,MAAMmX,GAAI,CAE1C,MAAMC,EAA2BF,EAAMlX,MAAMmX,GAAG,qBAG1C9N,EAAkBA,KAGtBgO,EAAS,KACPA,EAAS,KACP,IAEE,MAAMC,EAAY/G,EAAIhF,KAAKtF,MAC3B,GAAIqR,EAIF,YAHA/G,EAAIgB,QAAQhI,IAAIC,cAAc8N,GAAW7N,MAAM,QAOjD,MAAM8N,EAAWhH,EAAIgB,QAAQiG,YAAYjH,EAAIhF,KAAKtF,OAC9CsR,GAAYA,EAAShF,IACvBhC,EAAIgB,QAAQkG,SAASjO,cAAc+N,EAAShF,IAAI9I,MAAM,QAIxD,MAAO5B,GAEPC,QAAQC,KAAK,wBAAyBF,SAO9CqP,EAAMlX,MAAMmX,GAAG,qBAAuB,IAAI1R,KAEpC2R,GACFA,KAA4B3R,GAG9B4D,KAIF,MAAMqO,EAAiBR,EAAMlX,MAAMmX,GAAW,OAE5CD,EAAMlX,MAAMmX,GAAW,OADrBO,EACyB,IAAIjS,KAE7BiS,KAAkBjS,GAElB4D,KAIyBA,EAI/B,OAAO6N,IChII,CACbjY,KAAM,OACNqR,UAAUC,GAAK,IAAA4D,EAAAyD,EAAAC,EAEb,MAAM7X,EAAQuQ,EAAIhF,KAAKvL,OAAS,GAC1B8X,EAAgB9X,EAAM8X,eAAiBvH,EAAIhF,KAAKuM,eAAiB,MACjEC,EAAW/X,EAAM+X,UAAYxH,EAAIhF,KAAKwM,UAAY,SAClDC,EACJhY,EAAMgY,gBAAkBzH,EAAIhF,KAAKyM,gBAAkB,aAC/CC,EAAajY,EAAMiY,YAAc1H,EAAIhF,KAAK0M,YAAc,aACxDC,EACJlY,EAAMkY,cAAgB3H,EAAIhF,KAAK2M,cAAgB,aAG3CC,EACc,WAAlBL,GAAgD,mBAAlBA,EAY1BM,EARa,CACjBC,aAAc,QACdC,WAAY,MACZC,OAAQ,SACRC,gBAAiB,gBACjBC,eAAgB,eAChBC,eAAgB,gBAESV,IAAmB,QAUxC/J,EAPW,CACfoK,aAAc,QACdC,WAAY,MACZC,OAAQ,SACRI,SAAU,WACVC,QAAS,WAEYX,IAAe,QAGjC1H,EAAIC,KAAKxQ,QACZuQ,EAAIC,KAAKxQ,MAAQ,IAInBuQ,EAAIC,KAAKxQ,MAAMmY,SAAWA,EAG1B5H,EAAIC,KAAKxQ,MAAMoY,QAAUA,EACzB7H,EAAIC,KAAKxQ,MAAMiO,MAAQA,OAGLtN,IAAdX,EAAM6Y,MACRtI,EAAIC,KAAKxQ,MAAM6Y,IAAM7Y,EAAM6Y,KAI7B,MAAMC,EAAgBvI,EAAIhF,KAAKxK,OAAS,IAGtCgY,QAASC,EACTlB,cAAemB,EACflB,SAAUmB,EACVlB,eAAgBmB,EAChBlB,WAAYmB,EACZlB,aAAcmB,KACXC,GACDR,EAGES,EAAa,CAEjBR,QAASC,GAAe,OAIxBjB,SAAUA,KAEPuB,GAIDpB,GAAiC,eAAjBA,IAClBqB,EAAWrB,aAAeA,GAM5B,MAAMsB,EAAoBjJ,EAAIC,KAAKzP,OAAS,GACtC0Y,GAAmC,QAAdtF,EAAA5D,EAAIC,KAAKxQ,aAATmU,IAAcA,OAAdA,EAAAA,EAAgBpT,QAAS,GAGpDwP,EAAIC,KAAKzP,MAAQ,IACZyY,KACAD,GAIAhJ,EAAIC,KAAKxQ,QACZuQ,EAAIC,KAAKxQ,MAAQ,IAEnBuQ,EAAIC,KAAKxQ,MAAMe,MAAQ,IAClB0Y,KACAF,GAIAhJ,EAAIhF,KAAKF,WACZkF,EAAIhF,KAAKF,SAAW,IAKlBkF,EAAIhF,KAAKF,UAAYlL,MAAMsB,QAAQ8O,EAAIhF,KAAKF,WAC9CkF,EAAIhF,KAAKF,SAASzE,QAAS8S,IAEvBA,GACiB,iBAAVA,GACS,cAAfA,EAAMxZ,MACS,aAAfwZ,EAAMxZ,YAGWS,IAAd+Y,EAAM9C,KAAmC,OAAd8C,EAAM9C,IACnC8C,EAAM9C,KAAM,EAEZ8C,EAAM9C,KACe,iBAAd8C,EAAM9C,MACM,IAAnB8C,EAAM9C,IAAI+C,OAEVD,EAAM9C,IAAI+C,MAAO,MASzB,WAFuB/B,EACE,QADFC,EACrB7X,EAAM4Z,yBAAiB,IAAA/B,EAAAA,EAAItH,EAAIhF,KAAKqO,yBAAiB,IAAAhC,GAAAA,EAChC,CAEhBrH,EAAIhF,KAAKsO,OACZtJ,EAAIhF,KAAKsO,KAAO,IAEW,iBAAlBtJ,EAAIhF,KAAKsO,MAAsBtJ,EAAIhF,KAAKsO,KAAK1a,QACtDoR,EAAIhF,KAAKsO,KAAK1a,MAAQ,IAExB,MAAM2a,EAAqC,iBAAlBvJ,EAAIhF,KAAKsO,MAC7BtJ,EAAIhF,KAAKsO,KAAK1a,OAAS,IAAI4a,MAAM,KAAKlW,OAAOrD,SAC9C,GACCsZ,EAAUE,SAAS,6BACtBF,EAAUvM,KAAK,2BACc,iBAAlBgD,EAAIhF,KAAKsO,OAClBtJ,EAAIhF,KAAKsO,KAAK1a,MAAQ2a,EAAUjF,KAAK,SAK7C9D,OAAO1F,EAAUkF,GAAK,IAAA0J,EAAAC,EAEpB,MAAM1J,EAAO,IAAKD,EAAIC,MAGJ,SAAdA,EAAKtQ,OACPsQ,EAAKtQ,KAAO,UAId,MACM4X,GADQvH,EAAIhF,KAAKvL,OAAS,IACJ8X,eAAiBvH,EAAIhF,KAAKuM,eAAiB,MACjEqC,EACc,WAAlBrC,GAAgD,mBAAlBA,EAG3BtH,EAAKxQ,QACRwQ,EAAKxQ,MAAQ,IAIf,MAAMoa,EAAcA,KACb5J,EAAKrR,QACRqR,EAAKrR,MAAQ,IAEVgB,MAAMsB,QAAQ+O,EAAKrR,SACtBqR,EAAKrR,MAAQ,CAACqR,EAAKrR,SAKjBkb,EAAqC,QAA5BJ,EAAiBC,QAAjBA,EAAG3J,EAAIhF,KAAKvL,iBAAKka,SAAdA,EAAgBG,iBAAS,IAAAJ,EAAAA,EAAI1J,EAAIhF,KAAK8O,UACxD,GAAIA,MAAAA,GAA+D,KAAdA,EAAkB,CACrED,IACK5J,EAAKrR,MAAM6a,SAAS,uBACvBxJ,EAAKrR,MAAMoO,KAAK,sBAIlB,MAAM+M,EAAYzZ,OAAOwZ,GAAWzI,OAE/BpB,EAAKxQ,MAAMe,QACdyP,EAAKxQ,MAAMe,MAAQ,IAErByP,EAAKxQ,MAAMe,MAAM,mBAAqBuZ,EAGjC9J,EAAKzP,QACRyP,EAAKzP,MAAQ,IAEfyP,EAAKzP,MAAM,mBAAqBuZ,EAIlC,GAAIH,EAAY,CAAA,IAAAI,EAAAC,EAAAC,EACd,MAAMC,EAC6CH,QADnCA,EACYC,QADZA,EACA,QADAC,EACdlK,EAAIhF,KAAKvL,aAATya,IAAcA,OAAdA,EAAAA,EAAgBC,kBAAUF,IAAAA,EAAAA,EAAIjK,EAAIhF,KAAKmP,kBAAUH,IAAAA,EAAAA,EAAI,OAEvDH,IACK5J,EAAKrR,MAAM6a,SAAS,uBACvBxJ,EAAKrR,MAAMoO,KAAK,sBAEbiD,EAAKrR,MAAM6a,SAAS,sBACvBxJ,EAAKrR,MAAMoO,KAAK,qBAIlB,MAAMoN,EAAa9Z,OAAO6Z,GAAY9I,OACjCpB,EAAKxQ,MAAMe,QACdyP,EAAKxQ,MAAMe,MAAQ,IAErByP,EAAKxQ,MAAMe,MAAM,oBAAsB4Z,EAElCnK,EAAKzP,QACRyP,EAAKzP,MAAQ,IAEfyP,EAAKzP,MAAM,oBAAsB4Z,EAInC,MAAMC,EAAgBvP,GAAY,GAIlC,OAAOkF,EAAIuD,MAAM8C,IACf,CAAE5W,MAAO,CAAE6W,KAAM,KACjB,CACEzW,QAASA,IAAM,CAACmQ,EAAIuD,MAAMiC,KAAK,SAAUvF,EAAMoK,QCrPxC,CACb3b,KAAM,QACNqR,UAAUC,GAAK,IAAAqH,EAAAC,EAEb,MAAM7X,EAAQuQ,EAAIhF,KAAKvL,OAAS,GAC1B6a,EAAY7a,EAAM6a,WAAatK,EAAIhF,KAAKsP,WAAa,aACrDC,EAAO9a,EAAM8a,MAAQvK,EAAIhF,KAAKuP,MAAQ,QACtC7M,EAAQjO,EAAMiO,OAASsC,EAAIhF,KAAK0C,MAChC4L,EAAO7Z,EAAM6Z,MAAQtJ,EAAIhF,KAAKsO,OAAQ,EAGvCtJ,EAAIC,KAAKxQ,QACZuQ,EAAIC,KAAKxQ,MAAQ,IAInBuQ,EAAIC,KAAKxQ,MAAM6a,UAAYA,EAC3BtK,EAAIC,KAAKxQ,MAAM8a,KAAOA,EAClB7M,MAAAA,GAAmD,KAAVA,IAC3CsC,EAAIC,KAAKxQ,MAAMiO,MAAQA,GAEzBsC,EAAIC,KAAKxQ,MAAM6Z,KAAOA,EAGtB,MACMkB,EAAc,CAClBtb,MAAO,UAFa8Q,EAAIhF,KAAKxK,OAAS,IAOnCwP,EAAIC,KAAKzP,QACZwP,EAAIC,KAAKzP,MAAQ,IAEnBwP,EAAIC,KAAKzP,MAAQ,IAAKwP,EAAIC,KAAKzP,SAAUga,GAEpCxK,EAAIC,KAAKxQ,MAAMe,QAClBwP,EAAIC,KAAKxQ,MAAMe,MAAQ,IAEzBwP,EAAIC,KAAKxQ,MAAMe,MAAQ,IAAKwP,EAAIC,KAAKxQ,MAAMe,SAAUga,GAGhDxK,EAAIhF,KAAKF,WACZkF,EAAIhF,KAAKF,SAAW,IAKlBkF,EAAIhF,KAAKF,UAAYlL,MAAMsB,QAAQ8O,EAAIhF,KAAKF,WAC9CkF,EAAIhF,KAAKF,SAASzE,QAAS8S,IAEvBA,GACiB,iBAAVA,GACQ,aAAfA,EAAMxZ,MACS,YAAfwZ,EAAMxZ,YAGYS,IAAd+Y,EAAM9C,KAAmC,OAAd8C,EAAM9C,IACnC8C,EAAM9C,KAAM,EAEZ8C,EAAM9C,KACe,iBAAd8C,EAAM9C,MACM,IAAnB8C,EAAM9C,IAAI+C,OAEVD,EAAM9C,IAAI+C,MAAO,MASzB,WAFuB/B,EACE,QADFC,EACrB7X,EAAM4Z,yBAAiB,IAAA/B,EAAAA,EAAItH,EAAIhF,KAAKqO,yBAAiB,IAAAhC,GAAAA,EAChC,CAEhBrH,EAAIhF,KAAKsO,OACZtJ,EAAIhF,KAAKsO,KAAO,IAEW,iBAAlBtJ,EAAIhF,KAAKsO,MAAsBtJ,EAAIhF,KAAKsO,KAAK1a,QACtDoR,EAAIhF,KAAKsO,KAAK1a,MAAQ,IAExB,MAAM2a,EAAqC,iBAAlBvJ,EAAIhF,KAAKsO,MAC7BtJ,EAAIhF,KAAKsO,KAAK1a,OAAS,IAAI4a,MAAM,KAAKlW,OAAOrD,SAC9C,GACCsZ,EAAUE,SAAS,6BACtBF,EAAUvM,KAAK,2BACc,iBAAlBgD,EAAIhF,KAAKsO,OAClBtJ,EAAIhF,KAAKsO,KAAK1a,MAAQ2a,EAAUjF,KAAK,SAK7C9D,OAAO1F,EAAUkF,GAEf,MAAMC,EAAO,IAAKD,EAAIC,OAGRD,EAAIhF,KAAKvL,OAAS,IACVgb,SAAWzK,EAAIhF,KAAKyP,UAAW,EAKnDxK,EAAKtQ,KAAO,kBAGM,UAAdsQ,EAAKtQ,OACPsQ,EAAKtQ,KAAO,WAKhB,MAAM0a,EAAgBvP,GAAY,GAIlC,OAAOkF,EAAIuD,MAAM8C,IACf,CAAE5W,MAAO,CAAE6W,KAAM,KACjB,CACEzW,QAASA,IAAM,CAACmQ,EAAIuD,MAAMiC,KAAKvF,EAAKtQ,KAAMsQ,EAAMoK,QCrHzC,CACb3b,KAAM,OACNqR,UAAUC,GAAK,IAAAqH,EAAA2C,EAAAU,EAAAf,EAAA/F,EAAA+G,EAAApG,EAAAqG,EAAApG,EAERxE,EAAIhF,KAAKsO,OACZtJ,EAAIhF,KAAKsO,KAAO,IAElBtJ,EAAIhF,KAAKsO,KAAKhV,OAAQ,EAEtB,MAAM7E,EAAQuQ,EAAIC,KAAKxQ,OAAS,GAG1Bob,EAGyB,QAHZxD,EAEY,QAFZ2C,EACKU,QADLA,EACjB1K,EAAIhF,KAAK6P,qBAAaH,IAAAA,EAAAA,EACRf,QADQA,EACtB3J,EAAIhF,KAAKvL,iBAAKka,SAAdA,EAAgBkB,qBAAa,IAAAb,EAAAA,EACf,QADepG,EAC7B5D,EAAIC,KAAKxQ,aAAK,IAAAmU,OAAA,EAAdA,EAAgBiH,qBAAa,IAAAxD,GAAAA,EAQM,IAAAyD,EAAAC,EAAAlH,EAAAqG,GAJhCW,IACH7K,EAAIhF,KAAKF,SAAW,IAGjBoF,EAAYzQ,EAAO,eACtBA,EAAMub,SACgD,QADxCF,EACY,QADZC,EACE,QADFlH,EACZ7D,EAAIC,KAAKxQ,aAAToU,IAAcA,OAAdA,EAAAA,EAAgBmH,gBAAQD,IAAAA,EAAAA,EAAkB,QAAlBb,EAAIlK,EAAIhF,KAAKvL,aAATya,IAAcA,OAAdA,EAAAA,EAAgBc,gBAAQF,IAAAA,GAAAA,GAIxD,MAAMG,EACJjL,EAAIhF,KAAKF,UACTlL,MAAMsB,QAAQ8O,EAAIhF,KAAKF,WACvBkF,EAAIhF,KAAKF,SAAS/I,OAAS,GACxB8Y,IAAkBI,GAAexb,EAAMub,SAM5C,MAAMlH,EACJ9D,EAAIhF,KAAK8I,YACK6G,QADIA,EAClB3K,EAAIhF,KAAKvL,aAATkb,IAAcA,OAAdA,EAAAA,EAAgB7G,aACFS,QADWA,EACzBvE,EAAIC,KAAKxQ,aAAT8U,IAAcA,OAAdA,EAAAA,EAAgBT,WAClB,IAAIY,EACF1E,EAAIhF,KAAK0J,WAA0BkG,QAAlBA,EAAI5K,EAAIhF,KAAKvL,aAATmb,IAAcA,OAAdA,EAAAA,EAAgBlG,YAA0BF,QAAlBA,EAAIxE,EAAIC,KAAKxQ,aAAT+U,IAAcA,OAAdA,EAAAA,EAAgBE,UAYnE,GATKA,IAEDA,EADEZ,EACS,QAEA,UAKE,UAAbY,GAAwBZ,EAAW,CACrC,MAAMa,EAAiB,CACrBC,KAAMd,EACNe,GAAI,iBACJC,QAAQ,EACRC,KAAM,IACNvO,OAAO,GAIJwJ,EAAIhF,KAAKgK,SACZhF,EAAIhF,KAAKgK,OAAS,IAEfhF,EAAIhF,KAAKgK,OAAOlE,WACnBd,EAAIhF,KAAKgK,OAAOlE,SAAW,IAGdd,EAAIhF,KAAKgK,OAAOlE,SAASvN,KACrClC,GAASA,EAAKuT,OAASd,GAAyB,mBAAZzS,EAAKwT,MAG1C7E,EAAIhF,KAAKgK,OAAOlE,SAAS9D,KAAK2H,GAE1B3E,EAAIgB,SAAWhB,EAAIgB,QAAQgE,QAC7BhF,EAAIgB,QAAQgE,OAAOhF,EAAK,WAM1B6K,IAEG7K,EAAIhF,KAAKF,WACZkF,EAAIhF,KAAKF,SAAW,IAIlBkF,EAAIhF,KAAKF,UAAYlL,MAAMsB,QAAQ8O,EAAIhF,KAAKF,WAC9CkF,EAAIhF,KAAKF,SAASzE,QAAS8S,IAEvBA,GACiB,iBAAVA,GACQ,aAAfA,EAAMxZ,MACS,YAAfwZ,EAAMxZ,YAGYS,IAAd+Y,EAAM9C,KAAmC,OAAd8C,EAAM9C,IACnC8C,EAAM9C,KAAM,EAEZ8C,EAAM9C,KACe,iBAAd8C,EAAM9C,MACM,IAAnB8C,EAAM9C,IAAI+C,OAEVD,EAAM9C,IAAI+C,MAAO,QAO7B5I,OAAO1F,EAAUkF,GAAK,IAAAkL,EAAAzG,EAAA0G,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAEpB,MACMX,GADQhL,EAAIC,KAAKxQ,OAAS,IACTub,WAAY,EAG9BhL,EAAIC,KAAKxQ,QACZuQ,EAAIC,KAAKxQ,MAAQ,IAInBuQ,EAAIC,KAAKxQ,MAAMub,SAAWA,EAG1B,MAAMY,EAAM5L,EAAIhF,KAAK4Q,MAAqBV,QAAlBA,EAAIlL,EAAIhF,KAAKvL,aAATyb,IAAcA,OAAdA,EAAAA,EAAgBU,OAAqBnH,QAAlBA,EAAIzE,EAAIC,KAAKxQ,aAATgV,IAAcA,OAAdA,EAAAA,EAAgBmH,KAC/DA,IACF5L,EAAIC,KAAKxQ,MAAMmc,IAAMA,GAIvB,MAAMC,EACJ7L,EAAIhF,KAAK6Q,QAAuBV,QAAlBA,EAAInL,EAAIhF,KAAKvL,aAAT0b,IAAcA,OAAdA,EAAAA,EAAgBU,SAAuBT,QAAlBA,EAAIpL,EAAIC,KAAKxQ,aAAT2b,IAAcA,OAAdA,EAAAA,EAAgBS,OAChD,MAATA,IACF7L,EAAIC,KAAKxQ,MAAMoc,MAAQA,GAIzB,MAAMtB,EAAOvK,EAAIhF,KAAKuP,OAAsBc,QAAlBA,EAAIrL,EAAIhF,KAAKvL,aAAT4b,IAAcA,OAAdA,EAAAA,EAAgBd,QAAsBe,QAAlBA,EAAItL,EAAIC,KAAKxQ,aAAT6b,IAAcA,OAAdA,EAAAA,EAAgBf,MAClEA,IACFvK,EAAIC,KAAKxQ,MAAM8a,KAAOA,GAIF,SAAlBvK,EAAIC,KAAKtQ,OACXqQ,EAAIC,KAAKtQ,KAAO,UAWlB,KAJ+B,QAHZ4b,EAEY,QAFZC,EACKC,QADLA,EACjBzL,EAAIhF,KAAK6P,qBAAaY,IAAAA,EAAAA,EACRC,QADQA,EACtB1L,EAAIhF,KAAKvL,iBAAKic,SAAdA,EAAgBb,qBAAa,IAAAW,EAAAA,EACf,QADeG,EAC7B3L,EAAIC,KAAKxQ,aAAK,IAAAkc,OAAA,EAAdA,EAAgBd,qBAAa,IAAAU,GAAAA,GAK7B,OAAOvL,EAAIW,QAAQC,cAAcZ,OAAK5P,GAKxC,MAAMia,EACJvP,GAAYlL,MAAMsB,QAAQ4J,GAAYA,EAAWA,GAAY,GAI/D,OAAOkF,EAAIuD,MAAM8C,IACf,CAAE5W,MAAO,CAAE6W,KAAM,KACjB,CACEzW,QAASA,IAAM,CAACmQ,EAAIuD,MAAMiC,KAAK,SAAUxF,EAAIC,KAAMoK,QCjL5C,CACb3b,KAAM,MACNqR,UAAUC,GAEHA,EAAIhF,KAAKF,WACZkF,EAAIhF,KAAKF,SAAW,IAKlBkF,EAAIhF,KAAKF,UAAYlL,MAAMsB,QAAQ8O,EAAIhF,KAAKF,WAC9CkF,EAAIhF,KAAKF,SAASzE,QAAS8S,IAEvBA,GACiB,iBAAVA,GACQ,aAAfA,EAAMxZ,MACS,YAAfwZ,EAAMxZ,YAGYS,IAAd+Y,EAAM9C,KAAmC,OAAd8C,EAAM9C,IACnC8C,EAAM9C,KAAM,EAEZ8C,EAAM9C,KACe,iBAAd8C,EAAM9C,MACM,IAAnB8C,EAAM9C,IAAI+C,OAEVD,EAAM9C,IAAI+C,MAAO,OAM3B5I,OAAO1F,EAAUkF,GAEf,MAAMC,EAAO,IAAKD,EAAIC,MAGJ,QAAdA,EAAKtQ,OACPsQ,EAAKtQ,KAAO,OAId,MAAM0a,EAAgBvP,GAAY,GAclC,OAVKmF,EAAKxQ,QACRwQ,EAAKxQ,MAAQ,IAEVwQ,EAAKxQ,MAAMe,QACdyP,EAAKxQ,MAAMe,MAAQ,IAMdwP,EAAIuD,MAAMiC,KAAK,MAAOvF,EAAMoK,MCvDvC,IAAeyB,GAAA,CACbC,QAASC,WACTC,QAASD,WACTE,OAAQF,UACRG,KAAMH,QACNI,OAAQJ,UACRK,KAAML,QACN7M,OAAQ,WACR0B,SAAUmL,YACVlG,WAAYkG,cACZM,gBAAiBN,mBACjBpJ,WAAYoJ,cACZO,YAAaP,eACbQ,OAAQR,UACR5L,OAAQ4L,UACRnM,SAAUmM,iBACV7L,MAAO6L,cACPvG,MAAOuG,SACPS,YAAaT,eACbU,WAAYV,cACZpG,OAAQoG,eACRW,cAAeX,iBACfrG,SAAUqG,YACVY,SAAUZ,YACV5Q,KAAM4Q,QACN5M,MAAO,UACPiH,IAAK2F,OACL7F,IAAK6F,OACLa,KAAMb,QACNc,MAAOd,SACPe,gBAAiBf,gBACjBgB,KAAMhB,QACNjG,KAAMiG,QACNiB,aAAcjB,gBACdkB,SAAUlB,YACV3M,MAAO,UACP8N,MAAO,UACP7N,QAAS,YACT8N,OAAQ,YACRC,MAAOrB,SACPsB,OAAQtB,UChCV,SAASuB,GAAK9d,EAAOf,GACdwR,EAAYzQ,EAAOf,IACpBwQ,EAAG5O,OAAOb,EAAMf,MAClBe,EAAMf,GAAQ,CAAE6C,CAAC7C,GAAOe,EAAMf,GAAO0a,MAAM,IAI/C,SAASoE,GAAQ7b,GACf,OAAe,IAARA,EAST,SAAS8b,GAASzS,GAChB,MAAM0S,EAAQ,IAAK1S,GAEnB,cADO0S,EAAM5S,SACN4S,EAGT,IAAeC,GAAA,CACbC,WACE,MAAMxS,EAAOjK,KAAKiK,OAClB,OAAIA,EACKA,EAAKwS,WAEL,IAAIC,QAAS1R,GAAMA,MAG9BlD,cAAcvD,GACZ,MAAM0F,EAAOjK,KAAKiK,OAClB,OAAIA,EACKA,EAAK0S,eAAepY,GAEpB,IAAImY,QAAS1R,GAAMA,MAG9B4R,mBAAmB/N,GACjB,MAAMgO,EAAQ7c,KAAK8c,GAAGC,KAAKlO,EAAImO,SAC3BH,GACFA,EAAMI,iBAGVC,YAAYve,IACT,CAAC,YAAa,WAAY,MAAO,OAAQ,OAAQ,MAAO,SAASuG,QAC/D3H,KArCP,SAAkBoE,EAAKpE,GACjBwR,EAAYpN,EAAKpE,KAAUwQ,EAAGzO,OAAOqC,EAAIpE,MAC3CoE,EAAIpE,GAAQ,CAAE0a,OAAQtW,EAAIpE,KAoCtB4f,CAASxe,EAASpB,KAGfoB,GAET2d,SAAQA,EAACxN,KAAEA,MACTsN,GAAKtN,EAAM,SACXsN,GAAKtN,EAAM,QACJA,GAETF,UAAUC,GACR,MAAMuO,EAAM,CACVC,KAAM,CACJ7e,KAAM,UACN8e,UAAW,UACXtC,KAAM,0BAER7X,MAAO,GACP+R,IAAK,CAAEC,KAAM,IACbgD,KAAM,IAWR,GATC,CAAC,OAAQ,OAAQ,MAAO,SAASjT,QAAS3H,IACzCsR,EAAIC,KAAKvR,GAAQggB,EACf,CAACvd,KAAKrB,QAAQpB,IAAS,GAAIsR,EAAIC,KAAKvR,IAAS,IAC7C6f,EAAI7f,MAMJsR,EAAIzH,QAAUyH,EAAIzH,OAAOyC,KAAM,CACjC,MAAM2T,EAAa3O,EAAIzH,OAAOyC,KAAKrL,KAC7Bif,EAAa5O,EAAIzH,OAAOyC,KAAK6T,MAElB,SAAfF,GACe,WAAfA,GACqB,UAArBC,MAAAA,OAAU,EAAVA,EAAYlgB,OACG,UAAfigB,GACe,YAAfA,GACqB,WAArBC,MAAAA,OAAAA,EAAAA,EAAYlgB,QAGZsR,EAAIC,KAAKoG,KAAM,EAEXrG,EAAIhF,OACNgF,EAAIhF,KAAKqL,KAAM,IAMrB,GAAsB,WAAlBrG,EAAIhF,KAAKrL,MAAsBqQ,EAAIC,KAAKxQ,MAAMqf,WAuB3C,GAAsB,WAAlB9O,EAAIhF,KAAKrL,MAAqBqQ,EAAIC,KAAKxQ,MAAMqf,UAAW,CAEjE,MAAMC,EAAoB/O,EAAIC,KAAKxQ,MAAMqf,UACnCE,EAAqB,SAAUC,GAC/BpY,OAAO0B,QAAU1B,OAAO0B,SAAW1B,QACrCA,OAAO0B,OAAOC,YACZ,CACE7I,KAAM,iBACNsf,KAAM,CACJC,IAAKD,EAAKC,IACVxgB,KAAMugB,EAAKvgB,KACXygB,IAAKF,EAAKE,IACV5E,KAAM0E,EAAK1E,KACX5a,KAAMsf,EAAKtf,MAEbyf,UAAWpX,KAAKC,OAElB,MAIN+H,EAAIC,KAAKxQ,MAAMqf,UAAY,SAAUG,GACnCD,EAAmBC,GACfF,GAAkD,mBAAtBA,GAC9BA,EAAkBM,MAAMle,KAAMme,iBA/CyB,CAC3D,MAAMN,EAAqB,SAAUC,GAC/BpY,OAAO0B,QAAU1B,OAAO0B,SAAW1B,QACrCA,OAAO0B,OAAOC,YACZ,CACE7I,KAAM,iBACNsf,KAAM,CACJC,IAAKD,EAAKC,IACVxgB,KAAMugB,EAAKvgB,KACXygB,IAAKF,EAAKE,IACV5E,KAAM0E,EAAK1E,KACX5a,KAAMsf,EAAKtf,MAEbyf,UAAWpX,KAAKC,OAElB,MAIN+H,EAAIC,KAAKxQ,MAAMqf,UAAY,SAAUG,GACnCD,EAAmBC,IAiCvB,GACqB,UAAlBjP,EAAIhF,KAAKrL,MAAsC,WAAlBqQ,EAAIhF,KAAKrL,MACtCqQ,EAAIC,KAAKxQ,MAAMmM,SA+BX,IACc,UAAlBoE,EAAIhF,KAAKrL,MAAsC,WAAlBqQ,EAAIhF,KAAKrL,OACvCqQ,EAAIC,KAAKxQ,MAAMmM,QACf,CAEA,MAAM2T,EAAkBvP,EAAIC,KAAKxQ,MAAMmM,QACjC4T,EAA0B,SAAUC,GACpC5Y,OAAO0B,QAAU1B,OAAO0B,SAAW1B,QACrCA,OAAO0B,OAAOC,YACZ,CACE7I,KAAM,iBACNsf,KAAM,CACJC,IAAKO,GAAOzP,EAAIC,KAAKxQ,MAAMggB,KAAO,IAEpCL,UAAWpX,KAAKC,OAElB,MAKAyX,EAAW1P,EAAIC,KAAKxQ,MAAMggB,KAAO,GACjCE,EAA0BJ,MAAAA,OAAAA,EAAAA,EAAiBK,gBAEjD5P,EAAIC,KAAKxQ,MAAMmM,QAAU,IACpB2T,EACHM,QAASN,EAAgBM,UAAW,EACpCJ,IAAKF,EAAgBE,KAAOC,EAC5BE,gBAAiBA,CAACC,EAASC,KACrBD,IAAYC,GAEdN,EAAwBD,EAAgBE,KAAOC,MAI/CC,GACmC,mBAA5BA,IAEAA,EAAwBN,MAAMle,KAAMme,kBApEjD,CACA,MAAME,EAA0B,SAAUC,GACpC5Y,OAAO0B,QAAU1B,OAAO0B,SAAW1B,QACrCA,OAAO0B,OAAOC,YACZ,CACE7I,KAAM,iBACNsf,KAAM,CACJC,IAAKO,GAAOzP,EAAIC,KAAKxQ,MAAMggB,KAAO,IAEpCL,UAAWpX,KAAKC,OAElB,MAMAyX,EAAW1P,EAAIC,KAAKxQ,MAAMggB,KAAO,GACvCzP,EAAIC,KAAKxQ,MAAMmM,QAAU,CACvBiU,SAAS,EACTJ,IAAKC,EACLE,gBAAiBA,CAACC,EAASC,KACzB,GAAID,IAAYC,EAId,OAFAN,EAAwBE,IAEjB,MAkDjBK,kBAAiBA,KC9OV,CACL3U,KAAM,CACJ4U,kBAAkB,EAClBC,OAAQ,aACRC,WAAY,QACZC,SAAU,CACR7J,KAAM,GAER8J,WAAY,CACV9J,KAAM,IAER+J,sBAAsB,GAExBlK,IAAK,CACHmK,OAAQ,GAEVhW,UAAW,CACT/J,UAAU,EACVgQ,SAAS,EACT5Q,KAAM,UACN0N,UAAW,GACX+L,MAAM,EACN/C,SAzBQjW,EA0BRmgB,WA1BQngB,GA4BVmK,SAAU,CACRhK,UAAU,EACVgQ,SAAS,EACT5Q,KAAM,UACN0N,UAAW,GACX+L,MAAM,EACN/C,SAlCQjW,EAmCRmgB,WAnCQngB,KDoPZogB,gBAAeA,CAAC5C,EAAU6C,KACxB7C,EAAS6C,UAAY,CAACzV,EAAM1J,IACnB,IAAIuc,QAAQ,CAAC6C,EAASC,IAQpBF,EAAUnf,EAPCsf,IACZA,EACFD,EAAOC,GAEPF,OAMD9C,GAETiD,SACE,MAAMzV,EAAOjK,KAAKrB,QAAQsL,KAC1BjK,KAAK6J,KAAO,CACVvL,MAAO,IAAK2L,GACZwL,GAAI,CACFkK,OAASjZ,IACPA,EAAEkZ,mBAGNvgB,MAAO4K,EAAK5K,MACZb,KAAM,SAGVqhB,eACE,MAAM9c,IAAEA,EAAG+c,IAAEA,EAAGjQ,QAAEA,GAAY7P,KACxBiK,EAAOjK,KAAKrB,QAAQsL,KAC1B8V,EAAO/f,KAAK6J,KAAM,CAChB9G,IAAAA,EACA+c,IAAAA,EACAriB,MAAO,CACLwM,EAAK+V,UACL/V,EAAKxM,MACL,cACAuC,KAAK6P,QAAQpF,QAAU,aAAe,MAG1CsV,EAAO/f,KAAK6J,KAAKvL,MAAO,CACtB2hB,MAAOpQ,EAAQvE,YAGnB+D,OAAO1F,GAIL,OAHIA,EAASuW,YAAclgB,KAAK6P,QAAQpF,SACtCd,EAASwW,aAAQlhB,EAAW,IAAMe,KAAKogB,eAElCpgB,KAAKqgB,GACVrgB,KAAK6J,KACLwS,GAAQrc,KAAKrB,QAAQqW,IAAIiD,MACrBtO,EAAS2W,WACT,CAACtgB,KAAKugB,QAAQ5W,MAGtB6W,SAAS3R,EAAKlF,GACZ,MAAME,EAAOgF,EAAIC,KACX2R,EAAM,GAAGzgB,KAAK+C,MAAM8L,EAAI9L,MACxBmS,EAAMrL,EAAKqL,IACXwL,EAAU1gB,KAAK0gB,QAAQ7W,KAA6B,IAApBA,EAAKsO,KAAKhV,OAC1C2b,OAAEA,EAAQ5J,IAAKyL,GAAS3gB,KAAK6J,KAAKvL,MAClCsiB,EAAM/W,EAAKsO,KAAK1a,aACfoM,EAAKsO,KAAK1a,aACVoM,EAAKsO,KAAKhV,MAGjB,IAAI0d,GAAmB,EACvB,GAAIhS,EAAIzH,QAAUyH,EAAIzH,OAAOyC,KAAM,CACjC,MAAM2T,EAAa3O,EAAIzH,OAAOyC,KAAKrL,KAC7Bif,EAAa5O,EAAIzH,OAAOyC,KAAK6T,MAElB,SAAfF,GACe,WAAfA,GACqB,UAArBC,MAAAA,OAAU,EAAVA,EAAYlgB,OACG,UAAfigB,GACe,YAAfA,GACqB,WAArBC,MAAAA,OAAAA,EAAAA,EAAYlgB,QAEZsjB,GAAmB,GAIvB,MAAM3gB,EAAOmc,GAAQxS,EAAKsO,KAAKF,MAC3BtO,EACA3J,KAAKqgB,GACH9C,EAAW,CACT1T,EAAKsO,KACL,CACE7Z,MAAO,IACFge,GAASzS,EAAKsO,MAAQ,IACzB2I,YAAajX,EAAKiX,cAAe,EACjCvjB,KAAMsR,EAAIgC,GACVkQ,MAAOlS,EAAImS,oBACI,eAAXlC,EACA,CAAEE,SAAU,GAAIC,WAAY,IAC5B,IAENxhB,MAAOuC,KAAKwP,QAAQyR,WAClBL,GAAO/W,EAAKmW,UACZ,gBAEFjd,IAAQ0d,EAAH,KACLX,IAAKjR,EAAImO,QACTxe,KAAM,cAGV,CACEE,QAASA,IAAMiL,KACX+W,EAAU,CAAEpgB,MAAOA,IAAMN,KAAKkhB,SAASrX,EAAM4W,EAAK5R,IAAS,KAIvE,MAAkB,WAAXiQ,GACLzC,GAAQsE,IACRtE,GAAQnH,EAAI+C,OACZ4I,EACE3gB,EACAF,KAAKmhB,QAAQtX,EAAM4W,EAAK,CAACvgB,KAE/BwgB,QAAQ7W,GACN,IAAgC,IAA5B7J,KAAKrB,QAAQsL,KAAK9G,MAAiB,OAAO,EAC9C,MAAMA,EAAQ0G,EAAK1G,MACnB,SAAWA,EAAMA,QAAUA,EAAMmH,QAAW+R,GAAQlZ,EAAM8U,QAE5DiJ,SAASrX,EAAM4W,EAAK5R,GAAK,IAAAuS,EAAAC,EACvB,MAAMC,EAAY,IAAKzX,EAAK1G,OACtBoe,EAAW,IAAK1X,EAAKwT,MAC3B,IAAgC,IAA5Brd,KAAKrB,QAAQsL,KAAK9G,MAAiB,OAAO,EAC9C,IAAMme,EAAUne,QAAUme,EAAUhX,QAAW+R,GAAQiF,EAAUrJ,MAC/D,OACF,MAAMuJ,EAjXa,YAiXKD,EAjXd/iB,KAkXV,MAAMijB,EAAYzhB,KAAK0hB,QAAQ,SACzB/X,EAAW,CACf8X,EACIA,EAAU,CACRte,cAAKie,EAAEvS,EAAI8S,eAAO,IAAAP,GAAU,QAAVA,EAAXA,EAAaQ,gBAAbR,IAAqBA,OAArBA,EAAAA,EAAuBjhB,MAC9B0J,KAAMgF,EAAIhF,KACVlL,QAASqB,KAAKrB,kBACd0iB,EACFxS,EAAI8S,eAAO,IAAAN,GAAU,QAAVA,EAAXA,EAAaO,gBAAbP,IAAqBA,OAArBA,EAAAA,EAAuBlhB,OAG7B,IACGkc,GAAQkF,EAAStJ,QACjBsJ,EAASlE,MAAQkE,EAASjX,UAC1B+R,GAAQkF,EAASvG,MAClB,CACA,MAAMlM,EAAO,CACXtQ,KAAM+iB,EAAS/iB,MAAQ,UACvBF,MAAOge,GAASiF,GAChBxe,IAAQ0d,EAAH,cAGA3R,EAAKxQ,MAAM0c,YACXlM,EAAKxQ,MAAM2Z,YACXnJ,EAAKxQ,MAAM+e,YACXvO,EAAKxQ,MAAMiO,aACXuC,EAAKxQ,MAAMgM,OAElB,MAAM/F,EAAQid,EAAQ,QAAU,UACsB,IAAAK,EAAtD,GAAIN,EAASlE,OAAStO,EAAYD,EAAKxQ,MAAOiG,GAC5CuK,EAAKxQ,MAAMiG,GAAoB,QAAdsd,EAAGhT,EAAI8S,eAAOE,IAAAA,WAAAA,EAAXA,EAAaC,eAAO,IAAAD,OAAA,EAApBA,EAAsB1hB,MAE5CwJ,EAA4B,SAAnB4X,EAAShV,MAAmB,UAAY,QAC/CvM,KAAKqgB,GAAG9C,EAAW,CAACgE,EAAUzS,IAAQ,CACpC1O,CAACkhB,EAAUS,MAAQ,WAAY,IAC7B/hB,KAAKqgB,GAAG,CACN7hB,MACoB,IAAlB+iB,EAASvG,KACL,yBACAuG,EAASvG,MAAQ,GACvB1c,MAAO,CACLE,MACoB,IAAlB+iB,EAASvG,KACL,yBACAuG,EAASvG,MAEjBjY,IAAQ0d,EAAH,SAMf,MAAMuB,EAAQzE,EAAW,CACvB+D,EACA,CACEhjB,MAAOge,GAASgF,GAChBve,IAAQ0d,EAAH,MACLhjB,MAAO,gBACPe,KAAM8iB,EAAU9iB,MAAQ,UAQ5B,cAJOwjB,EAAM1jB,MAAM2Z,YACZ+J,EAAM1jB,MAAM6E,aACZ6e,EAAM1jB,MAAMgM,OAEZtK,KAAKqgB,GAAG2B,EAAOrY,IAExBwX,QAAQtX,EAAM4W,EAAK9W,GACjB,MAAMuL,EAAMrL,EAAKqL,IACjB,OAAOlV,KAAKqgB,GACV,CACE5iB,MAAOuC,KAAKwP,QAAQyR,WAAW/L,EAAIzX,MAAO,eAC1Ce,KAAM,MACNF,MAAO4W,GAAO,CAAEC,KAAM,IACtBpS,IAAQ0d,EAAH,OAEP9W,IAGJ4W,QAAQ5W,GACN,MAAMqL,EAAMhV,KAAKrB,QAAQqW,KAAO,GAChC,OAAOhV,KAAKqgB,GACV,CACE7hB,KAAM,MACNF,MAAO0W,EACPvX,MAAOuC,KAAKwP,QAAQyR,WAAWjM,EAAIvX,MAAO,eAC1CsF,IAAQ/C,KAAK+C,IAAR,OAEP4G,IAGJyW,cACE,IAAI6B,EAAK,GAOT,GANK5F,GAAQrc,KAAKrB,QAAQwK,UAAU8O,OAClCgK,EAAGpW,KAAK7L,KAAKkiB,iBAEV7F,GAAQrc,KAAKrB,QAAQyK,SAAS6O,OACjCgK,EAAGpW,KAAK7L,KAAKmiB,iBAEVF,EAAGrhB,OACN,OAEF,IAAIoe,SAAEA,EAAQC,WAAEA,EAAUH,OAAEA,GAAW9e,KAAK6J,KAAKvL,MAClC,eAAXwgB,IACFE,EAAWC,EAAa,IAE1B,MAAM/e,EAAOF,KAAKqgB,GAChB,CACE7hB,KAAM,WACNf,MAAO,8BACPsF,IAAQ/C,KAAK+C,IAAR,KACLzE,MAAO,CACL0gB,SAAAA,EACAC,WAAAA,EACA3e,MAAO,IACP8hB,OAAO,IAGXH,GAGF,MAAkB,WAAXnD,EACH5e,EACAF,KAAKqgB,GACH,CACE7hB,KAAM,MACNf,MAAO,cACPa,MAAO,CAAE6W,KAAM,IACfpS,IAAQ/C,KAAK+C,IAAR,MAEP,CAAC7C,KAITiiB,eACE,MAAM/Y,EAAW,IAAKpJ,KAAKrB,QAAQyK,UAC7B8C,EACJ9C,EAAS8C,WAAalM,KAAK6P,QAAQhI,IAAI6C,EAAE,UAAY,KAKvD,cAJOtB,EAAS8C,iBACT9C,EAASgW,aACThW,EAAS8L,WACT9L,EAAS6O,KACTjY,KAAKqgB,GACV,CACE7hB,KAAM,SACNF,MAAO8K,EACP3L,MAAO,eACP4B,MAAO,CAAEtB,MAAOqL,EAASrL,MAAOskB,WAAY,QAC5C5M,GAAI,CACF2J,MAAOA,KACL,MAAMkD,EAAOtiB,KAAK6P,QAAQhI,IAC1B7H,KAAKrB,QAAQyK,SAASgW,MAClBpf,KAAKrB,QAAQyK,SAASgW,MAAMkD,GAC5BA,EAAKC,gBAGbxf,IAAQ/C,KAAK+C,IAAR,MAEP,CAACmJ,KAGLgW,gBACE,MAAM/Y,EAAY,IAAKnJ,KAAKrB,QAAQwK,WAC9B+C,EACJ/C,EAAU+C,WAAalM,KAAK6P,QAAQhI,IAAI6C,EAAE,WAAa,KAKzD,cAJOvB,EAAU+C,iBACV/C,EAAUiW,aACVjW,EAAU+L,WACV/L,EAAU8O,KACVjY,KAAKqgB,GACV,CACE7hB,KAAM,SACNF,MAAO6K,EACP1L,MAAO,gBACP4B,MAAO,CAAEtB,MAAOoL,EAAUpL,OAC1B0X,GAAI,CACF2J,MAAOA,KACL,MAAMkD,EAAOtiB,KAAK6P,QAAQhI,IAC1B7H,KAAKrB,QAAQwK,UAAUiW,MACnBpf,KAAKrB,QAAQwK,UAAUiW,MAAMkD,GAC7BA,EAAK3C,SAAS5X,MAAM,UAG5BhF,IAAQ/C,KAAK+C,IAAR,MAEP,CAACmJ,MEhjBP,MAAMwF,GAAQ,GAuDd,IAAmBM,IArDnB,SAAkBN,GACf,CACC,aACA,SACA,QACA,eACA,WACA,aACA,QACA,cACA,gBACA,QACA,OACA,SACA,OACA,SACA,cACAC,OAAO,CAACD,EAAOnU,KACfmU,EAAMnU,GAAQsU,EAAetU,GACtBmU,GACNA,GACHA,EAAM8Q,KAAO9Q,EAAMoK,aACnBpK,EAAM+Q,OAAS/Q,EAAM4J,YACrB5J,EAAMgR,KAAOhR,EAAMiD,WACnBjD,EAAMgD,SAAWhD,EAAM8J,cAoFzBmH,CAASjR,IA3DT,SAAmBA,GACjBA,EAAmB,YAAIG,EAAe,SAAU,CAAEQ,OAAO,IA2D3DuQ,CAAUlR,IAlFV,SAAkBA,GAChB,MAAMmR,EAAQ,CACZC,YAAa,CAAC,QAAS,GACvBC,WAAY,CAAC,OAAQ,GACrBC,YAAa,CAAC,QAAS,GACvBC,cAAe,CAAC,QAAS,GACzBC,aAAc,CAAC,OAAQ,GACvBC,cAAe,CAAC,QAAS,IAG3B7jB,OAAO4L,KAAK2X,GAAOlR,OAAO,CAACD,EAAO3O,KAChC2O,EAAM3O,GAAO8O,EAAe,QAAUG,GACpCA,EAAE1T,MAAM,CAAEE,KAAMqkB,EAAM9f,GAAK,GAAIqgB,UAAWP,EAAM9f,GAAK,MAEhD2O,GACNA,GAEHA,EAAM2R,WAAa3R,EAAMoR,YACzBpR,EAAM4R,UAAY5R,EAAMqR,WACxBrR,EAAM6R,WAAa7R,EAAMsR,YAgE3BQ,CAAS9R,IAlDT,SAAmBA,GACjB,MAAMmR,EAAQ,CACZ3G,MAAO,CAAC,QAAS,GACjB4B,KAAM,CAAC,OAAQ,GACf2F,cAAe,CAAC,OAAQ,GACxBC,eAAgB,CAAC,QAAS,IAG5BpkB,OAAO4L,KAAK2X,GAAOlR,OAAO,CAACD,EAAO3O,KAChC2O,EAAM3O,GAAO8O,EAAe,SAAWG,GACrCA,EAAE1T,MAAM,CACNqlB,WAAYd,EAAM9f,GAAK,GACvBqgB,UAAWP,EAAM9f,GAAK,MAGnB2O,GACNA,GAEHA,EAAMkS,YAAclS,EAAMwK,MAC1BxK,EAAMmS,WAAanS,EAAMoM,KAgC3BgG,CAAUpS,KA1DSM,GA2DTN,IAzDNqS,eAAiBlS,EADN,SAC2B,CAAEmS,KAAM,aAChDhS,GAAEiS,WAAapS,EAFF,SAEuB,CAAEmS,KAAM,SAC5ChS,GAAEkS,eAAiBrS,EAHN,SAG2B,CAAEmS,KAAM,aAyBlD,SAA2BtS,GACzBA,EAAMyS,eAAiBtS,EAAe,kBACtCH,EAAM0S,YAAc1S,EAAMyS,eA6B5BE,CAAkB3S,IA1BlB,SAA0BA,GACxBA,EAAM4S,cAAgBzS,EAAe,iBACrCH,EAAM6S,WAAa7S,EAAM4S,cAyB3BE,CAAiB9S,IAtBjB,SAAiBA,GACfA,EAAMa,KAAOV,EAAe,QAsB9B4S,CAAQ/S,IAnBR,SAAiBA,GACfA,EAAMgK,KAAO7J,EAAe,QAmB9B6S,CAAQhT,IAhBR,SAAkBA,GAChBA,EAAMiK,MAAQ9J,EAAe,SAgB/B8S,CAASjT,IAbT,SAAiBA,GACfA,EAAMmK,KAAOhK,EAAe,QAa9B+S,CAAQlT,IC6cR,MAAM4N,GAAY,IAnkBlB,MAOEuF,OAAO1kB,EAAO2kB,GAAS,GACrB,IAAK3kB,EAAO,OAAO,EACnB,MAAMiL,EAAMjM,OAAOgB,GAAO+P,OAC1B,OAAI4U,EAEK,gBAAgBC,KAAK3Z,GAGrB,eAAe2Z,KAAK3Z,GAS/B4Z,MAAM7kB,GACJ,IAAKA,EAAO,OAAO,EACnB,MAAMiL,EAAMjM,OAAOgB,GAAO+P,OAE1B,MAAO,wIAAwI6U,KAC7I3Z,GAUJ6Z,OAAO9kB,EAAO+kB,GAAY,GACxB,IAAK/kB,EAAO,OAAO,EACnB,MAAMiL,EAAMjM,OAAOgB,GAAO+P,OAAOiV,cAGjC,IAAK,gBAAgBJ,KAAK3Z,GACxB,OAAO,EAGT,IAAK8Z,EACH,OAAO,EAIT,MAAME,EAAU,CAAC,EAAG,EAAG,GAAI,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,GAAI,EAAG,EAAG,EAAG,GAGnE,IAAIC,EAAM,EACV,IAAK,IAAIC,EAAI,EAAGA,EAAI,GAAIA,IACtBD,GAAOE,SAASna,EAAIka,IAAMF,EAAQE,GAEpC,MAAME,EAAiBH,EAAM,GAC7B,OAAOja,EAAI,MAPQ,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAOxCoa,GAUhCzH,IAAI5d,EAAOxB,EAAU,IACnB,IAAKwB,EAAO,OAAO,EACnB,MAAMiL,EAAMjM,OAAOgB,GAAO+P,QACpBuV,gBAAEA,GAAkB,GAAU9mB,EAEpC,OAAI8mB,EACK,qBAAqBV,KAAK3Z,GAG1B,iEAAiE2Z,KACtE3Z,GAUNsa,GAAGvlB,GACD,IAAKA,EAAO,OAAO,EACnB,MACMwlB,EADMxmB,OAAOgB,GAAO+P,OACRmI,MAAM,KACxB,OAAqB,IAAjBsN,EAAM/kB,QACH+kB,EAAMC,MAAOC,IAClB,MAAMC,EAAMP,SAASM,EAAM,IAC3B,OAAOC,GAAO,GAAKA,GAAO,KAAO3mB,OAAO2mB,KAASD,IAerDpD,OAAOtiB,EAAOxB,EAAU,IACtB,GAAIwB,MAAAA,GAAmD,KAAVA,EAAc,OAAO,EAClE,MAAM2lB,EAAM9mB,OAAOmB,GACnB,GAAI4lB,MAAMD,GAAM,OAAO,EAEvB,MAAME,QACJA,GAAU,EAAKC,SACfA,GAAW,EAAKC,SAChBA,GAAW,EAAK7c,IAChBA,EAAG/H,IACHA,GACE3C,EAEJ,QAAIqnB,IAAYhnB,OAAOmnB,UAAUL,QAC7BG,GAAYH,GAAO,OACnBI,GAAYJ,GAAO,YACX7mB,IAARoK,GAAqByc,EAAMzc,WACnBpK,IAARqC,GAAqBwkB,EAAMxkB,MAcjCV,OAAOT,EAAOxB,EAAU,IACtB,GAAIwB,MAAAA,EAAuC,OAAO,EAClD,MAAMiL,EAAMjM,OAAOgB,IACbkJ,IAAEA,EAAG/H,IAAEA,EAAG8kB,IAAEA,GAAQznB,EAE1B,YAAYM,IAARmnB,EACKhb,EAAIxK,SAAWwlB,SAGZnnB,IAARoK,GAAqB+B,EAAIxK,OAASyI,WAC1BpK,IAARqC,GAAqB8J,EAAIxK,OAASU,GAWxC+kB,QAAQlmB,EAAOkmB,GACb,IAAKlmB,IAAUkmB,EAAS,OAAO,EAC/B,MAAMjb,EAAMjM,OAAOgB,GACnB,IAAImmB,EACJ,GAAID,aAAmBE,OACrBD,EAAQD,OAER,IACEC,EAAQ,IAAIC,OAAOF,GACnB,MAAO3f,GACP,OAAO,EAGX,OAAO4f,EAAMvB,KAAK3Z,GAYpBgG,KAAKjR,EAAOxB,EAAU,IACpB,IAAKwB,EAAO,OAAO,EACnB,IAAIiR,EACJ,GAAIjR,aAAiB0G,KACnBuK,EAAOjR,OAGP,GADAiR,EAAO,IAAIvK,KAAK1G,GACZ4lB,MAAM3U,EAAKoV,WAAY,OAAO,EAGpC,MAAMnd,IAAEA,EAAG/H,IAAEA,GAAQ3C,EACrB,GAAI0K,EAAK,CAEP,GAAI+H,GADY/H,aAAexC,KAAOwC,EAAM,IAAIxC,KAAKwC,IACjC,OAAO,EAE7B,GAAI/H,EAAK,CAEP,GAAI8P,GADY9P,aAAeuF,KAAOvF,EAAM,IAAIuF,KAAKvF,IACjC,OAAO,EAG7B,OAAO,EASTmlB,MAAMtmB,EAAO+P,GAAO,GAClB,OAAI/P,MAAAA,IACiB,iBAAVA,EACF+P,EAAwB,KAAjB/P,EAAM+P,OAA0B,KAAV/P,EAElC1B,MAAMsB,QAAQI,GACQ,IAAjBA,EAAMS,OAEM,iBAAVT,GAC4B,IAA9Bb,OAAO4L,KAAK/K,GAAOS,QAW9B8lB,SAASvmB,EAAO+P,GAAO,GACrB,OAAQlQ,KAAKymB,MAAMtmB,EAAO+P,GAQ5ByW,QAAQxmB,GACN,QAAKA,GACE,qBAAqB4kB,KAAK5lB,OAAOgB,IAS1CymB,MAAMzmB,EAAO0mB,GAAgB,GAC3B,IAAK1mB,EAAO,OAAO,EACnB,MAAMiL,EAAMjM,OAAOgB,GACnB,OAAI0mB,EACK,cAAc9B,KAAK3Z,GAEnB,YAAY2Z,KAAK3Z,GAS5B0b,aAAa3mB,GACX,QAAKA,GACE,iBAAiB4kB,KAAK5lB,OAAOgB,IAQtC6lB,QAAQ7lB,GACN,OAAOH,KAAKyiB,OAAOtiB,EAAO,CAAE6lB,SAAS,IAQvCC,SAAS9lB,GACP,OAAOH,KAAKyiB,OAAOtiB,EAAO,CAAE8lB,UAAU,IAQxCC,SAAS/lB,GACP,OAAOH,KAAKyiB,OAAOtiB,EAAO,CAAE+lB,UAAU,IAQxCa,SAAS5mB,GACP,IAAKA,EAAO,OAAO,EACnB,MAAMiL,EAAMjM,OAAOgB,GAAO6mB,QAAQ,MAAO,IAEzC,MAAO,cAAcjC,KAAK3Z,GAQ5B6b,SAAS9mB,GACP,QAAKA,GACE,UAAU4kB,KAAK5lB,OAAOgB,GAAO+P,QAQtCgX,aAAa/mB,GACX,IAAKA,EAAO,OAAO,EACnB,MAAMiL,EAAMjM,OAAOgB,GAAO+P,OAAOiV,cAEjC,MACE,uEAAuEJ,KACrE3Z,IAEF,8EAA8E2Z,KAC5E3Z,GAUN+b,WAAWhnB,GACT,IAAKA,EAAO,OAAO,EACnB,MAAMiL,EAAMjM,OAAOgB,GAAO+P,OAAOiV,cAEjC,MAAO,uDAAuDJ,KAAK3Z,GASrEgc,KAAKjnB,EAAOknB,GACV,SAAK5oB,MAAMsB,QAAQsnB,IAAiC,IAApBA,EAASzmB,SAClCymB,EAAS/O,SAASnY,GAU3BmnB,MAAMC,EAAQC,EAAQ1C,GAAS,GAC7B,OAAIA,EACKyC,IAAWC,EAEXD,GAAUC,EAWrBC,SAASF,EAAQC,EAAQ1C,GAAS,GAChC,OAAQ9kB,KAAKsnB,MAAMC,EAAQC,EAAQ1C,GAQrC4C,UAAUvnB,GACR,IAAKA,EAAO,OAAO,EACnB,MAAMiL,EAAMjM,OAAOgB,GACnB,OAAOiL,IAAQA,EAAI+Z,eAAiB,QAAQJ,KAAK3Z,GAQnDuc,UAAUxnB,GACR,IAAKA,EAAO,OAAO,EACnB,MAAMiL,EAAMjM,OAAOgB,GACnB,OAAOiL,IAAQA,EAAIwc,eAAiB,QAAQ7C,KAAK3Z,GAWnDyc,SAAS1nB,EAAOxB,EAAU,IACxB,IAAKwB,EAAO,OAAO,EACnB,MAAMiL,EAAMjM,OAAOgB,GAAO+P,QACpB7G,IAAEA,EAAM,EAAC/H,IAAEA,EAAM,IAAO3C,EAC9B,QAAIyM,EAAIxK,OAASyI,GAAO+B,EAAIxK,OAASU,IAC9B,kBAAkByjB,KAAK3Z,GAchCsJ,SAASvU,EAAOxB,EAAU,IACxB,IAAKwB,EAAO,OAAO,EACnB,MAAMiL,EAAMjM,OAAOgB,IACbkJ,IACJA,EAAM,EAAC/H,IACPA,EAAM,GAAEwmB,cACRA,GAAgB,EAAKC,cACrBA,GAAgB,EAAKC,eACrBA,GAAiB,GACfrpB,EAEJ,QAAIyM,EAAIxK,OAASyI,GAAO+B,EAAIxK,OAASU,OACjCwmB,IAAkB,KAAK/C,KAAK3Z,QAC5B2c,IAAkB,WAAWhD,KAAK3Z,OAClC4c,IAAmB,yBAAyBjD,KAAK3Z,MAUvD6c,SAAS9nB,GACP,QAAKA,GACE,qCAAqC4kB,KAAK5lB,OAAOgB,GAAO+P,QAQjEgY,GAAG/nB,GACD,QAAKA,GACE,kBAAkB4kB,KAAK5lB,OAAOgB,GAAO+P,QAQ9CiY,OAAOhoB,GACL,QAAKA,GACE,wBAAwB4kB,KAAK5lB,OAAOgB,GAAO+P,QAQpDkY,IAAIjoB,GACF,IAAKA,EAAO,OAAO,EACnB,MAAMiL,EAAMjM,OAAOgB,GAAO+P,OAE1B,MAAO,yBAAyB6U,KAAK3Z,GAQvCid,IAAIloB,GACF,IAAKA,EAAO,OAAO,EACnB,MAAMiL,EAAMjM,OAAOgB,GAAO+P,OAAOiV,cACjC,MAAO,iCAAiCJ,KAAK3Z,GAQ/Ckd,OAAOnoB,GACL,IAAKA,EAAO,OAAO,EACnB,MAAMiL,EAAMjM,OAAOgB,GAAO+P,OAC1B,GAAI9E,EAAIxK,OAAS,GAAM,EAAG,OAAO,EACjC,IACE,OAAO2nB,KAAKC,KAAKpd,MAAUA,EAC3B,MAAO1E,GACP,OAAO,GASX+hB,KAAKtoB,GACH,IAAKA,EAAO,OAAO,EACnB,IAEE,OADA6F,KAAKC,MAAM9G,OAAOgB,KACX,EACP,MAAOuG,GACP,OAAO,GASXgiB,QAAQvoB,GACN,OAAIA,MAAAA,GACG,QAAQ4kB,KAAK5lB,OAAOgB,IAQ7BwoB,KAAKxoB,GACH,QAAKA,GACE,aAAa4kB,KAAK5lB,OAAOgB,GAAO+P,QAQzC0Y,KAAKzoB,GACH,OAAOH,KAAKyiB,OAAOtiB,EAAO,CAAE6lB,SAAS,EAAM3c,IAAK,EAAG/H,IAAK,UC3jB5D,SAASunB,GAAYC,EAAK1L,GAGxB,OAFIrP,EAAGjP,QAAQgqB,GAAMA,EAAM,CAAE7Q,KAAM6Q,GACzB/a,EAAGgb,MAAMD,IAAS/a,EAAGzO,OAAOwpB,KAAMA,EAAM,CAAE7Q,KAAMmF,IACnD0L,EAGM,SAASE,GAAUnhB,EAAKohB,GACrC,MAAO,CACLC,OAAMA,IACGD,EAAElT,SAAS9L,OAEpBkf,OAAOtY,GACL,MAAMhC,EAAMoa,EAAEnT,YAAYjF,GAC1B,GAAKhC,EACL,OAAOoa,EAAEnM,GAAGC,KAAKlO,EAAImO,UAEvBP,SAAShV,GACA,IAAIiV,QAAQ,CAAC6C,EAASC,KAC3B,MAAM4J,EAAQvhB,EAAI8B,SACZ0f,EAAM,CAACJ,EAAElT,SAAS0G,YACxB2M,EACGjnB,OAAQ6I,IAAOA,EAAEse,SACjBpkB,QAAS8F,IACRqe,EAAIxd,KAAKb,EAAEyR,cAEfC,QAAQ2M,IAAIA,GACTpY,KAAK,KACJsO,GAAQ,GACR9X,GAAYA,GAAS,KAEtBM,MAAOrB,IACN8Y,EAAO9Y,GACPe,GAAYA,EAASf,GACrBuiB,EAAEnM,GAAGyM,KAAK,gBAAiB7iB,EAAG,CAAEmB,IAAAA,IAChCohB,EAAEO,UAAU,gBAAiB9iB,EAAG,CAAEmB,IAAAA,QAI1CC,cAAaA,CAACvD,EAAOkD,IACZ,IAAIiV,QAAQ,CAAC6C,EAASC,KAC3B,MAAM3Q,EAAMoa,EAAEnT,YAAYvR,GAC1B,IAAKsK,EAAK,OACV,MAAM4a,EAAMR,EAAE9a,QAAQU,EAAIgC,IACpBwY,EAAM,CAACJ,EAAElT,SAASjO,cAAc+G,EAAIgC,KAC1C6Y,EAAQD,GACLtnB,OAAQ6I,IAAOA,EAAEse,SACjBpkB,QAAS8F,IACRqe,EAAIxd,KAAKb,EAAEyR,cAEfC,QAAQ2M,IAAIA,GACTpY,KAAK,KACJsO,EAAQ,MACR9X,GAAYA,EAAS,QAEtBM,MAAOrB,IACN8Y,EAAO9Y,GACPe,GAAYA,EAASf,GACrBuiB,EAAEnM,GAAGyM,KAAK,sBAAuB7iB,EAAG,CAAEnC,MAAAA,EAAOsD,IAAAA,QAIrD+U,mBAAmB+M,EAAQC,GAAW,GACpC/hB,EAAIgiB,OAAOC,WAAWH,GAAQzkB,QAASX,IACjCqlB,GAAU5pB,KAAK+pB,sBAAsBxlB,GACzC0kB,EAAEe,QAAQzlB,GAAOW,QAAS2J,IACxBoa,EAAElT,SAAS6G,mBAAmB/N,QAIpCkb,sBAAsBJ,GACpB9hB,EAAIgiB,OAAOC,WAAWH,GAAQzkB,QAASX,IACrC0kB,EAAEe,QAAQzlB,GAAOW,QAAS2J,IACxB,MAAMV,EAAU8a,EAAE9a,QAAQU,EAAIgC,IACzB1C,IACD1P,MAAMsB,QAAQoO,GAChBA,EAAQjJ,QAAS+E,IACfA,EAAK2S,uBAEEzO,GACTA,EAAQyO,2BAKhBkM,IAAK,CACH1Z,QAASA,CAACA,GAAU,KAClBvH,EAAIoiB,eAAe,CAAE7a,UAAWA,KAElChQ,SAAUA,CAACA,GAAW,KACpByI,EAAIoiB,eAAe,CAAE7qB,WAAYA,KAEnC6Y,KAAMA,CAACiS,GAAS,KACdriB,EAAIoiB,eAAe,CAAEhS,OAAQiS,MAGjC9gB,SAAU,CACRgG,QAASA,CAACA,GAAU,KAClBvH,EAAIsiB,cAAc,CAAE/a,UAAWA,KAEjChQ,SAAUA,CAACA,GAAW,KACpByI,EAAIsiB,cAAc,CAAE/qB,WAAYA,KAElC6Y,KAAMA,CAACiS,GAAS,KACdriB,EAAIsiB,cAAc,CAAElS,OAAQiS,MAGhCD,eAAgBA,CAAC3rB,EAAQ,MACvB,IAAIwqB,EAAMD,GAAYI,EAAEtqB,QAAQwK,WAAW,GAC3C4W,EAAO+I,EAAKxqB,GACZ2qB,EAAEtqB,QAAQwK,UAAY2f,EACtBjhB,EAAIuiB,kBAEND,cAAeA,CAAC7rB,EAAQ,MACtB,IAAIwqB,EAAMD,GAAYI,EAAEtqB,QAAQyK,UAAU,GAC1C2W,EAAO+I,EAAKxqB,GACZ2qB,EAAEtqB,QAAQyK,SAAW0f,EACrBjhB,EAAIuiB,kBAENzK,OAAMA,CAAC0K,EAAWC,IACT,IAAI5N,QAAQ,CAAC6C,EAASC,OAEM,IAA/ByJ,EAAEtqB,QAAQ4rB,iBACN7N,QAAQ6C,UACR1X,EAAI4U,YAEPxL,KAAK,KACJ,IAAI3F,EAAWzD,EAAIyD,WACnB2d,EAAEuB,aAAalf,GACZ2F,KAAK,KACJlD,EAAGrJ,SAAS2lB,IAAcI,EAAO,IAAMJ,EAAU/e,EAAUzD,IAC3DkG,EAAGrJ,SAASukB,EAAEtqB,QAAQ+rB,WACpBD,EAAO,IAAMxB,EAAEtqB,QAAQ+rB,SAASpf,EAAUzD,IAC5CohB,EAAEnM,GAAGyM,KAAK,SAAUje,EAAUzD,GAC9B0X,EAAQjU,KAETvD,MAAOrB,SAEXqB,MAAM,IAAIhE,KACTgK,EAAGrJ,SAAS4lB,IAAWG,EAAO,IAAMH,EAAOziB,KAAQ9D,IACnDyb,KAAUzb,OAwDlB4mB,QAAQC,IAEgB,iBAAXA,IACTA,EAAS,CAAEC,OAAQD,IAGd/iB,EAAIijB,MAAMF,IAGnBG,SAASC,EAAItQ,GACX,IAAIuQ,EAAW,EACf,OAAO,YAAalnB,GAClB,MAAMmnB,EAAUlrB,KACV8G,EAAMD,KAAKC,MACbA,EAAMmkB,IAAavQ,GAAS,KAC9BuQ,EAAWnkB,EACXkkB,EAAGvkB,KAAKykB,KAAYnnB,MAK1BonB,SAASH,EAAItQ,GACX,IAAI0Q,EAAQ,KACZ,OAAO,YAAarnB,GAClB,MAAMmnB,EAAUlrB,KACF,OAAVorB,GACFC,aAAaD,GAEfA,EAAQvY,WAAW,KACjBmY,EAAGvkB,KAAKykB,KAAYnnB,IACnB2W,GAAS,KA6BhB4Q,WAAYhM,GACZiM,QAASC,GCtQb,IAAeC,GAAA,CACb3P,aAAc,QACdpM,SAAU,QACV4L,YAAa,QACbE,cAAe,QACfhH,SAAU,QACV0G,KAAM,QACND,OAAQ,QACRM,WAAY,QACZF,OAAQ,UACR8I,eAAgB,aAChBG,cAAe,cCTjB,MAAMxb,GAAW,CACbvL,KAAM,WACNmuB,KAAKzV,EAAQpM,EAAMhC,GACf,MAAMrH,EAgCd,SAAkBA,GACd,OAAIuN,EAAGjP,QAAQ0B,GACJ,CAACsI,SAAUtI,GACXuN,EAAG5O,OAAOqB,GACV,CAAC2G,QAAS3G,GACVuN,EAAGgb,MAAMvoB,GACT,CAACsI,UAAU,GACXiF,EAAGrJ,SAASlE,GACZ,CAAC8e,UAAW9e,GACXuN,EAAGzO,OAAOkB,GAGXA,EAFA,GA1CKmrB,CAAS1V,EAAOlD,YAC5B,IAAqB,IAAjBvS,EAAIsI,SACJmN,EAAO2V,YACP/jB,EAAI+U,mBAAmB,CAAC/S,EAAKtF,YAC1B,CAAA,IAAAsnB,EACH,MAAMpP,EAAW,CACb3T,UAAU,EACVwW,UAASA,CAACrK,EAAGjK,IACF,IAAI0R,QAAQ,CAAC6C,EAASC,KACzBzR,EAAG0Y,MAAMzb,GAAKwU,EAAO/C,EAAStV,SAAWoY,SAG9C/e,GAED2C,EAA2B0oB,QAAtBA,EAAGhiB,EAAKiiB,OAAOnK,mBAAOkK,WAAAA,EAAnBA,EAAqBjK,gBAAQ,IAAAiK,OAAA,EAA7BA,EAA+B1rB,MAC7C,GAAKsc,EAAStV,QAEP,CACH,MAAM4kB,EAAQtP,EAAStV,QAAQ4kB,MAAM,6BACjCA,IACAtP,EAAStV,QAAUU,EAAI6C,EAAEqhB,EAAM,GAAI,CAAC5oB,MAAAA,UAJxCsZ,EAAStV,QAAUU,EAAI6C,EAAE,WAAY,CAACvH,MAAAA,KAAYA,GAA6B,OAApB0E,EAAImkB,YAAuB,eAAiB,QAO3G/V,EAAOgW,UAAUxP,SAAW,CAACA,GAEjC5U,EAAIkJ,KAAKlH,IAEbxE,SAAStB,GACL+E,GAAS4iB,QAAQ3nB,KCpBzB,SAASmoB,GAAQC,GACfA,EAAWC,eAAezR,IAE1Brb,OAAO4L,KAAKugB,IAAavmB,QAASiG,IAChCghB,EAAWE,cAAclhB,EAAGsgB,GAAYtgB,MAG1C/G,GAAWc,QAASonB,IAClBH,EAAWG,UAAUA,EAAU/uB,KAAM+uB,KAGvCH,EAAWI,SAASzjB,IAEpBsM,GAAQlQ,QAASsnB,IACfL,EAAWK,OAAOA,KAGpBltB,OAAO4L,KAAKuhB,IAAQvnB,QAAS3H,IAC3B4uB,EAAWza,MAAMnU,GAAQkvB,GAAOlvB,KAGZ,oBAAXmI,QAA0BA,OAAOgnB,MAC1CP,EAAWQ,OAAO,CAAC1X,EAAG2X,KACpBA,EAAIC,IAAInnB,OAAOgnB,QClCrB,MAAMP,GDwCGW,EAAkB,CACvBC,GAAI,mBACJC,QAAS,WACTxQ,QAAAA,GACA0P,QAAAA,GACAlD,UAAAA,GACAiE,MAAO,CACLC,OAAQ,CAAC,MAAO,QAChBlR,MAAO,CAAC,aACRjZ,IAAK,CAAC,QAAS,WC/CC,oBAAX2C,SACPA,OAAOynB,WAAahB,IAGxB,MAAMza,GAAQya,GAAWza"}
|