form-design-v3 1.0.0 → 1.0.2
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/{CodeEditor-B7PzbdP9.js → CodeEditor-CJeYvarM.js} +1 -2
- package/form-design-v3.css +1 -0
- package/form-design-v3.es.js +13 -0
- package/form-design-v3.umd.cjs +4 -0
- package/index-BNitnTdB.js +3578 -0
- package/index.d.ts +83 -19
- package/package.json +2 -2
- package/CodeEditor-B7PzbdP9.js.map +0 -1
- package/CodeEditor-d-AMHZfA.js +0 -56
- package/CodeEditor-d-AMHZfA.js.map +0 -1
- package/form-designer.css +0 -1
- package/index-DCHlgXXr.js +0 -3033
- package/index-DCHlgXXr.js.map +0 -1
- package/index-oUADtA5r.js +0 -3016
- package/index-oUADtA5r.js.map +0 -1
- package/mt-form-designer.es.js +0 -12
- package/mt-form-designer.es.js.map +0 -1
- package/mt-form-designer.umd.cjs +0 -5
- package/mt-form-designer.umd.cjs.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"mt-form-designer.umd.cjs","sources":["../src/widgets/registry.ts","../src/widgets/label/LabelDesign.vue","../src/widgets/label/LabelRender.vue","../src/widgets/label/LabelPanel.vue","../src/widgets/label/index.ts","../src/components/LucideIcon.vue","../src/widgets/card/CardDesign.vue","../src/widgets/visibility.ts","../src/widgets/card/CardRender.vue","../src/components/FdSwitch.vue","../src/widgets/card/icons.ts","../src/widgets/card/index.ts","../src/widgets/card/CardPanel.vue","../src/widgets/slot/SlotDesign.vue","../src/widgets/slot/SlotRender.vue","../src/widgets/slot/index.ts","../src/widgets/slot/SlotPanel.vue","../src/widgets/subtable/SubtableDesign.vue","../src/widgets/subtable/SubtableRender.vue","../src/api/mock.ts","../src/widgets/subtable/SubtablePanel.vue","../src/widgets/subtable/index.ts","../src/widgets/grid/GridDesign.vue","../src/components/WidgetHost.vue","../src/widgets/grid/corner.ts","../src/widgets/grid/GridRender.vue","../src/widgets/grid/index.ts","../src/widgets/grid/GridPanel.vue","../src/widgets/text/TextDesign.vue","../src/widgets/text/TextRender.vue","../src/widgets/text/index.ts","../src/widgets/text/TextPanel.vue","../src/widgets/index.ts","../src/stores/designer.ts","../src/api/index.ts","../src/storage/formStorage.ts","../src/utils/formEvents.ts","../src/components/renderer/Renderer.vue","../src/components/designer/ComponentTree.vue","../src/components/designer/Toolbar.vue","../src/components/designer/WidgetPalette.vue","../src/types/schema.ts","../src/components/designer/FormEventsPanel.vue","../src/components/designer/PropertyPanel.vue","../src/components/designer/CanvasNode.vue","../src/components/designer/Designer.vue","../src/components/renderer/renderForm.ts","../src/index.ts","../src/components/designer/CodeEditor.vue"],"sourcesContent":["import type { WidgetType, WidgetProps } from '@/types'\nimport type { WidgetDefinition } from './types'\n\nconst registry = new Map<WidgetType, WidgetDefinition>()\n\nexport function registerComponent(def: WidgetDefinition): void {\n registry.set(def.type, def)\n}\n\nexport function getWidgetDef(type: WidgetType): WidgetDefinition | undefined {\n return registry.get(type)\n}\n\nexport function getAllWidgetDefs(): WidgetDefinition[] {\n return Array.from(registry.values())\n}\n\nexport function isRegistered(type: WidgetType): boolean {\n return registry.has(type)\n}\n\n/** 创建控件默认节点(生成唯一 id) */\nexport function createWidget(type: WidgetType): WidgetProps {\n const def = getWidgetDef(type)\n if (!def) throw new Error(`未注册的控件类型: ${type}`)\n const base = def.createDefaultProps()\n return { ...base, id: `${type}_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 7)}` }\n}\n","<script setup lang=\"ts\">\nimport { useDesignerStore } from '@/stores/designer'\nimport type { LabelWidgetProps } from '@/types'\n\ndefineProps<{ node: LabelWidgetProps }>()\n\nconst store = useDesignerStore()\n</script>\n\n<template>\n <div class=\"fd-label-design\" :class=\"{ 'is-mobile': store.device === 'mobile' }\">\n <span class=\"fd-label-name\">{{ node.label || '标题' }}</span>\n <span class=\"fd-label-value\" :class=\"{ 'fd-label-value--link': !!node.bindLink }\" :style=\"node.color ? { color: node.color } : undefined\">\n <template v-if=\"node.bindLink\">{{ node.bindField || node.bindLink }}</template>\n <template v-else>{{ node.bindField || '未绑定字段' }}</template>\n </span>\n </div>\n</template>\n\n<style scoped>\n.fd-label-design {\n display: flex;\n align-items: stretch;\n font-size: 1.4rem;\n line-height: 1.5;\n border: 1px solid var(--fd-color-border);\n border-radius: var(--fd-radius-base);\n overflow: hidden;\n}\n.fd-label-name {\n width: 16rem;\n flex-shrink: 0;\n padding: 1.1rem 1.2rem;\n background: var(--fd-color-bg-hover);\n border-right: 1px solid var(--fd-color-border);\n color: var(--fd-color-text-secondary);\n text-align: right;\n font-weight: 500;\n}\n.fd-label-design.is-mobile .fd-label-name {\n width: 12rem;\n}\n.fd-label-value {\n flex: 1;\n min-width: 0;\n padding: 1.1rem 1.2rem;\n background: var(--fd-color-bg-panel);\n color: var(--fd-color-text);\n white-space: pre-wrap;\n word-break: break-all;\n}\n.fd-label-value--link {\n color: var(--fd-color-primary);\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed, ref, onMounted, onUnmounted } from 'vue'\nimport { useDesignerStore } from '@/stores/designer'\nimport type { LabelWidgetProps } from '@/types'\n\nconst props = defineProps<{\n node: LabelWidgetProps\n /** 绑定字段运行时的值(来自 formData) */\n value?: unknown\n /** 运行态字段值映射(bindLink 取链接 URL) */\n formData?: Record<string, unknown>\n}>()\n\n/** 是否绑定链接:值以主题色展示并可点击 */\nconst isLink = computed(() => !!props.node.bindLink)\n/** 链接 URL:来自绑定链接字段的运行态值 */\nconst linkUrl = computed(() => {\n const raw = props.node.bindLink ? props.formData?.[props.node.bindLink] : undefined\n return raw == null ? '' : String(raw)\n})\n/** 展示文本:优先绑定字段值,其次链接地址 */\nconst display = computed(() => {\n if (props.value !== undefined && props.value !== null && props.value !== '') return String(props.value)\n if (linkUrl.value) return linkUrl.value\n return ''\n})\n\n/** 响应式移动端检测:设计器设备切换 + 独立渲染时视口宽度 */\nconst designerStore = useDesignerStore()\nconst _mqMobile = ref(false)\nlet _mq: MediaQueryList | null = null\n\nonMounted(() => {\n _mq = window.matchMedia('(max-width: 768px)')\n _mqMobile.value = _mq.matches\n _mq.addEventListener('change', (e) => { _mqMobile.value = e.matches })\n})\nonUnmounted(() => {\n if (_mq) _mq.removeEventListener('change', () => {})\n})\n\nconst isMobile = computed(() => designerStore.device === 'mobile' || _mqMobile.value)\n</script>\n\n<template>\n <div class=\"fd-label-render\" :class=\"{ 'is-mobile': isMobile }\">\n <span class=\"fd-label-name\">{{ node.label || '标题' }}</span>\n <span class=\"fd-label-value\" :class=\"{ 'fd-label-value--link': isLink }\" :data-key=\"node.bindField\" :style=\"node.color ? { color: node.color } : undefined\">\n <a v-if=\"linkUrl\" class=\"fd-label-link\" :href=\"linkUrl\" target=\"_blank\" rel=\"noopener noreferrer\">{{ display }}</a>\n <template v-else>{{ display }}</template>\n </span>\n </div>\n</template>\n\n<style scoped>\n.fd-label-render {\n display: flex;\n align-items: stretch;\n font-size: 1.4rem;\n line-height: 1.5;\n border: 1px solid var(--fd-color-border);\n border-radius: var(--fd-radius-base);\n overflow: hidden;\n}\n.fd-label-name {\n width: 16rem;\n flex-shrink: 0;\n padding: 1.1rem 1.2rem;\n background: var(--fd-color-bg-hover);\n border-right: 1px solid var(--fd-color-border);\n color: var(--fd-color-text-secondary);\n text-align: right;\n font-weight: 500;\n}\n.fd-label-render.is-mobile .fd-label-name {\n width: 12rem;\n}\n.fd-label-value {\n flex: 1;\n min-width: 0;\n padding: 1.1rem 1.2rem;\n background: var(--fd-color-bg-panel);\n color: var(--fd-color-text);\n white-space: pre-wrap;\n word-break: break-all;\n}\n.fd-label-value--link {\n color: var(--fd-color-primary);\n}\n.fd-label-link {\n color: inherit;\n text-decoration: none;\n cursor: pointer;\n word-break: break-all;\n}\n.fd-label-link:hover {\n text-decoration: underline;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport { ElSelect, ElOption } from 'element-plus'\nimport 'element-plus/es/components/select/style/css'\nimport type { LabelWidgetProps, FieldMeta } from '@/types'\n\nconst props = defineProps<{\n node: LabelWidgetProps\n fields: FieldMeta[]\n}>()\n\nconst emit = defineEmits<{\n (e: 'update', patch: Partial<LabelWidgetProps>): void\n}>()\n\n/** 表单字段中的链接类型字段(dataType === 'link'),供「绑定链接」下拉 */\nconst linkFields = computed(() => props.fields.filter((f) => f.dataType === 'link'))\n\n/** 默认字体颜色(与 --fd-color-text 一致) */\nconst DEFAULT_COLOR = '#344054'\n\n/** 颜色输入:非 hex 时回退默认色,保证 color picker 不报错 */\nfunction hexOf(v?: string): string {\n return v && /^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/.test(v) ? v : DEFAULT_COLOR\n}\n\n/** 色板选择变更 */\nfunction onColorChange(e: Event) {\n emit('update', { color: (e.target as HTMLInputElement).value })\n}\n\n/** 绑定字段变更(el-select 返回类型较宽,统一转为字符串) */\nconst onBindFieldChange = (val: unknown) => {\n emit('update', { bindField: (val as string) ?? '' })\n}\n\n/** 绑定链接变更(el-select 返回类型较宽,统一转为字符串) */\nconst onBindLinkChange = (val: unknown) => {\n emit('update', { bindLink: (val as string) ?? '' })\n}\n</script>\n\n<template>\n <div class=\"fd-panel\">\n <div class=\"fd-panel-item\">\n <label>标题</label>\n <input :value=\"node.label\" @input=\"emit('update', { label: ($event.target as HTMLInputElement).value })\" />\n </div>\n <div class=\"fd-panel-item\">\n <label>绑定字段</label>\n <el-select\n :model-value=\"node.bindField\"\n filterable\n clearable\n placeholder=\"搜索并选择字段\"\n style=\"width: 100%\"\n @update:model-value=\"onBindFieldChange\"\n >\n <el-option label=\"不绑定\" value=\"\" />\n <el-option v-for=\"f in fields\" :key=\"f.name\" :label=\"`${f.label}(${f.name})`\" :value=\"f.name\" />\n </el-select>\n </div>\n <div class=\"fd-panel-item\">\n <label>绑定链接</label>\n <el-select\n :model-value=\"node.bindLink\"\n filterable\n clearable\n placeholder=\"搜索并选择链接字段\"\n style=\"width: 100%\"\n @update:model-value=\"onBindLinkChange\"\n >\n <el-option label=\"不绑定\" value=\"\" />\n <el-option v-for=\"f in linkFields\" :key=\"f.name\" :label=\"`${f.label}(${f.name})`\" :value=\"f.name\" />\n </el-select>\n </div>\n <div class=\"fd-panel-item\">\n <label>字体颜色</label>\n <div class=\"fd-color-row\">\n <input type=\"color\" :value=\"hexOf(node.color)\" @input=\"onColorChange\" />\n <input\n type=\"text\"\n :value=\"node.color\"\n @input=\"emit('update', { color: ($event.target as HTMLInputElement).value })\"\n placeholder=\"默认 #344054\"\n />\n </div>\n </div>\n </div>\n</template>\n\n<style scoped>\n.fd-panel {\n display: flex;\n flex-direction: column;\n gap: 1.2rem;\n}\n.fd-panel-item {\n display: flex;\n flex-direction: column;\n gap: 0.4rem;\n}\n.fd-panel-item label {\n font-size: 1.3rem;\n color: var(--fd-color-text-secondary);\n}\n.fd-panel-item input,\n.fd-panel-item select {\n height: 3.2rem;\n padding: 0 1rem;\n border: 1px solid var(--fd-color-border);\n border-radius: var(--fd-radius-base);\n font-size: 1.4rem;\n background: var(--fd-color-bg-panel);\n}\n\n/* 颜色输入:色板 + 文本输入(与 SubtablePanel 一致) */\n.fd-color-row {\n display: flex;\n gap: 0.6rem;\n align-items: center;\n}\n.fd-panel .fd-panel-item .fd-color-row input[type='color'] {\n width: 3.6rem;\n height: 3.2rem;\n padding: 0.2rem;\n flex-shrink: 0;\n border: 1px solid var(--fd-color-border);\n border-radius: var(--fd-radius-base);\n background: var(--fd-color-bg-panel);\n cursor: pointer;\n}\n.fd-color-row input:not([type='color']) {\n flex: 1;\n min-width: 0;\n}\n</style>\n","import type { WidgetProps } from '@/types'\nimport type { WidgetDefinition } from '../types'\nimport LabelDesign from './LabelDesign.vue'\nimport LabelRender from './LabelRender.vue'\nimport LabelPanel from './LabelPanel.vue'\n\nexport const labelDefinition: WidgetDefinition = {\n type: 'label',\n title: 'Label 文本',\n design: LabelDesign,\n render: LabelRender,\n panel: LabelPanel,\n isContainer: false,\n createDefaultProps: (): WidgetProps => ({\n id: '',\n type: 'label',\n label: 'Label 文本',\n bindField: '',\n bindLink: '',\n color: '#344054',\n }),\n serialize: (props: WidgetProps) => props,\n}\n","<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport type { Component } from 'vue'\nimport { icons } from 'lucide-vue-next'\n\n/**\n * 通用 lucide 图标组件:按名称动态渲染 lucide-vue-next 图标。\n * 继承父元素 color(lucide 默认 stroke=currentColor)。\n */\nconst props = withDefaults(\n defineProps<{\n /** 图标名(PascalCase,如 ScanSearch / Download) */\n name: string\n /** 图标尺寸(px 或任意 CSS 尺寸) */\n size?: number | string\n /** 描边宽度 */\n strokeWidth?: number\n }>(),\n {\n size: 18,\n strokeWidth: 2,\n },\n)\n\nconst icon = computed<Component | null>(() => {\n if (!props.name) return null\n return (icons as Record<string, Component>)[props.name] || null\n})\n</script>\n\n<template>\n <component :is=\"icon\" v-if=\"icon\" :size=\"size\" :stroke-width=\"strokeWidth\" />\n</template>\n","<script setup lang=\"ts\">\nimport type { CardWidgetProps } from '@/types'\nimport { useDesignerStore } from '@/stores/designer'\nimport LucideIcon from '@/components/LucideIcon.vue'\n\nconst props = defineProps<{ node: CardWidgetProps }>()\nconst store = useDesignerStore()\n\n/** 设计器中点击箭头展开/收起(视图操作,不计入撤销) */\nfunction toggleExpanded() {\n store.setExpanded(props.node.id, !props.node.expanded)\n}\n</script>\n\n<template>\n <div class=\"fd-card-design\">\n <div class=\"fd-card-head\">\n <span v-if=\"node.icon\" class=\"fd-card-icon\" :style=\"{ background: node.iconBgColor || undefined }\">\n <LucideIcon :name=\"node.icon\" :size=\"18\" />\n </span>\n <span class=\"fd-card-title\">{{ node.label || '卡片标题' }}</span>\n <span\n class=\"fd-card-arrow\"\n :class=\"{ 'is-open': node.expanded }\"\n :title=\"node.expanded ? '收起' : '展开'\"\n @click.stop=\"toggleExpanded\"\n >\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <polyline points=\"6 9 12 15 18 9\" />\n </svg>\n </span>\n </div>\n <div v-show=\"node.expanded\" class=\"fd-card-body\">\n <slot name=\"children\">\n <div class=\"fd-card-empty\">拖拽子控件到此处</div>\n </slot>\n </div>\n </div>\n</template>\n\n<style scoped>\n.fd-card-design {\n border: 1px solid var(--fd-color-border);\n border-radius: 14px;\n background: var(--fd-color-bg-panel);\n box-shadow: 0 2px 10px rgba(25, 55, 95, 0.06);\n overflow: hidden;\n}\n.fd-card-head {\n display: flex;\n align-items: center;\n gap: 10px;\n height: 64px;\n padding: 0 22px;\n background: transparent;\n}\n.fd-card-icon {\n width: 28px;\n height: 28px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n color: var(--fd-color-primary);\n background: var(--fd-color-primary-light);\n border-radius: 9px;\n}\n.fd-card-title {\n flex: 1;\n font-size: 17px;\n font-weight: 700;\n color: var(--fd-color-text);\n}\n.fd-card-arrow {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n width: 28px;\n height: 28px;\n border-radius: 8px;\n color: var(--fd-color-text-tertiary);\n cursor: pointer;\n transition: transform 0.3s, background 0.2s;\n}\n.fd-card-arrow:hover {\n background: var(--fd-color-bg-hover);\n}\n.fd-card-arrow svg {\n width: 16px;\n height: 16px;\n display: block;\n}\n.fd-card-arrow.is-open {\n transform: rotate(180deg);\n}\n.fd-card-body {\n padding: 0 22px 22px;\n min-height: 6rem;\n background: var(--fd-color-bg-panel);\n}\n.fd-card-empty {\n border: 1px dashed var(--fd-color-border);\n border-radius: var(--fd-radius-base);\n padding: 1.6rem;\n text-align: center;\n color: var(--fd-color-text-tertiary);\n font-size: 1.3rem;\n}\n</style>\n","import type { HiddenMode } from '@/types'\n\n/**\n * 依据「是否隐藏」模式与流程状态 status 判断控件是否应隐藏。\n *\n * status 源自渲染器接收到的表单数据:\n * - 查看 0\n * - 发起 10\n * - 审批 20\n *\n * 隐藏规则:\n * - none 不隐藏\n * - not-start 非发起时隐藏(status != 10)\n * - not-approval 非审批时隐藏(status != 20)\n */\nexport function isWidgetHidden(hiddenMode: HiddenMode | undefined, status: unknown): boolean {\n if (!hiddenMode || hiddenMode === 'none') return false\n const s = Number(status)\n if (hiddenMode === 'start') return s === 10\n if (hiddenMode === 'not-start') return s !== 10\n if (hiddenMode === 'not-approval') return s !== 20\n return false\n}\n","<script setup lang=\"ts\">\nimport { ref } from 'vue'\nimport type { CardWidgetProps } from '@/types'\nimport LucideIcon from '@/components/LucideIcon.vue'\nimport { isWidgetHidden } from '../visibility'\n\nconst props = defineProps<{\n node: CardWidgetProps\n /** 运行态表单数据(取 status 判断是否隐藏) */\n formData?: Record<string, unknown>\n}>()\nconst expanded = ref(props.node.expanded)\n</script>\n\n<template>\n <div v-if=\"!isWidgetHidden(node.hiddenMode, formData?.status)\" class=\"fd-card-render\">\n <div class=\"fd-card-head\" @click=\"expanded = !expanded\">\n <span v-if=\"node.icon\" class=\"fd-card-icon\" :style=\"{ background: node.iconBgColor || undefined }\">\n <LucideIcon :name=\"node.icon\" :size=\"18\" />\n </span>\n <span class=\"fd-card-title\">{{ node.label || '卡片标题' }}</span>\n <span class=\"fd-card-arrow\" :class=\"{ 'is-open': expanded }\">\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <polyline points=\"6 9 12 15 18 9\" />\n </svg>\n </span>\n </div>\n <div v-show=\"expanded\" class=\"fd-card-body\">\n <slot name=\"children\" />\n </div>\n </div>\n</template>\n\n<style scoped>\n.fd-card-render {\n border: 1px solid var(--fd-color-border);\n border-radius: 14px;\n background: var(--fd-color-bg-panel);\n box-shadow: 0 2px 10px rgba(25, 55, 95, 0.06);\n overflow: hidden;\n}\n.fd-card-head {\n display: flex;\n align-items: center;\n gap: 10px;\n height: 64px;\n padding: 0 22px;\n background: transparent;\n cursor: pointer;\n user-select: none;\n}\n.fd-card-icon {\n width: 28px;\n height: 28px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n color: var(--fd-color-primary);\n background: var(--fd-color-primary-light);\n border-radius: 9px;\n}\n.fd-card-title {\n flex: 1;\n font-size: 17px;\n font-weight: 700;\n color: var(--fd-color-text);\n}\n.fd-card-arrow {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n width: 28px;\n height: 28px;\n border-radius: 8px;\n color: var(--fd-color-text-tertiary);\n transition: transform 0.3s;\n}\n.fd-card-arrow svg {\n width: 16px;\n height: 16px;\n display: block;\n}\n.fd-card-arrow.is-open {\n transform: rotate(180deg);\n}\n.fd-card-body {\n padding: 0 22px 22px;\n min-height: 6rem;\n background: var(--fd-color-bg-panel);\n}\n</style>\n","<script setup lang=\"ts\">\ndefineProps<{ modelValue: boolean; disabled?: boolean }>()\nconst emit = defineEmits<{ (e: 'update:modelValue', value: boolean): void }>()\n</script>\n\n<template>\n <button\n type=\"button\"\n class=\"fd-switch\"\n :class=\"{ 'is-on': modelValue }\"\n :disabled=\"disabled\"\n role=\"switch\"\n :aria-checked=\"modelValue\"\n @click=\"emit('update:modelValue', !modelValue)\"\n >\n <span class=\"fd-switch-dot\"></span>\n </button>\n</template>\n\n<style scoped>\n.fd-switch {\n position: relative;\n width: 3.6rem;\n height: 2rem;\n padding: 0;\n border: none;\n border-radius: 1rem;\n background: var(--fd-color-border-hover);\n cursor: pointer;\n flex-shrink: 0;\n transition: background var(--fd-transition);\n}\n.fd-switch.is-on {\n background: var(--fd-color-primary);\n}\n.fd-switch:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n.fd-switch-dot {\n position: absolute;\n top: 0.2rem;\n left: 0.2rem;\n width: 1.6rem;\n height: 1.6rem;\n border-radius: 50%;\n background: #fff;\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);\n transition: transform var(--fd-transition);\n}\n.fd-switch.is-on .fd-switch-dot {\n transform: translateX(1.6rem);\n}\n</style>\n","/**\n * 卡片组件图标枚举(lucide 图标名)\n * 引入 approval-lease.html 使用的 lucide 图标依赖(lucide-vue-next),\n * 图标按名称动态渲染,避免使用图片资源。\n */\n\n/** 卡片组件可选 lucide 图标名(PascalCase,对应 lucide-vue-next 的图标组件) */\nexport const cardIconNames = [\n // 卡片 / 布局通用\n 'LayoutGrid',\n 'PanelTop',\n 'Folder',\n 'FolderOpen',\n 'FileText',\n 'ClipboardList',\n 'ClipboardCheck',\n // 业务语义(源自 approval-lease.html 卡片:铺位/品牌/合同/递增/免租/计费/预算/招调/指导价)\n 'MapPin',\n 'Store',\n 'Building2',\n 'Badge',\n 'Tag',\n 'CalendarDays',\n 'TrendingUp',\n 'Clock',\n 'Calculator',\n 'Receipt',\n 'Target',\n 'ChartPie',\n 'ChartLine',\n 'CircleDollarSign',\n // 通用 / 状态\n 'Briefcase',\n 'Scale',\n 'ShieldCheck',\n 'Sparkles',\n 'ScanSearch',\n 'MessageSquareText',\n 'GitBranch',\n 'Paperclip',\n 'Download',\n 'Upload',\n 'Network',\n 'Printer',\n 'CircleCheck',\n 'CircleAlert',\n 'Info',\n 'Bell',\n 'Settings',\n 'User',\n 'Users',\n 'Heart',\n 'Star',\n 'Lightbulb',\n 'Award',\n 'BookOpen',\n 'Coins',\n 'Wallet',\n] as const\n\nexport type CardIconName = (typeof cardIconNames)[number]\n","import type { WidgetProps } from '@/types'\nimport type { WidgetDefinition } from '../types'\nimport CardDesign from './CardDesign.vue'\nimport CardRender from './CardRender.vue'\nimport CardPanel from './CardPanel.vue'\n\nexport const cardDefinition: WidgetDefinition = {\n type: 'card',\n title: '卡片容器',\n design: CardDesign,\n render: CardRender,\n panel: CardPanel,\n isContainer: true,\n createDefaultProps: (): WidgetProps => ({\n id: '',\n type: 'card',\n label: '卡片标题',\n bindField: '',\n icon: '',\n iconBgColor: '',\n expanded: true,\n width: '',\n hiddenMode: 'none',\n children: [],\n }),\n serialize: (props: WidgetProps) => props,\n}\n","<script setup lang=\"ts\">\nimport { ref } from 'vue'\nimport type { CardWidgetProps, FieldMeta, HiddenMode } from '@/types'\nimport FdSwitch from '@/components/FdSwitch.vue'\nimport LucideIcon from '@/components/LucideIcon.vue'\nimport { cardIconNames } from './icons'\n\ndefineProps<{ node: CardWidgetProps; fields: FieldMeta[] }>()\nconst emit = defineEmits<{ (e: 'update', patch: Partial<CardWidgetProps>): void }>()\n\n/** 图标选择弹层开关 */\nconst iconOpen = ref(false)\n\nfunction selectIcon(icon: string) {\n emit('update', { icon })\n iconOpen.value = false\n}\n</script>\n\n<template>\n <div class=\"fd-panel\">\n <div class=\"fd-panel-item\">\n <label>标题</label>\n <input :value=\"node.label\" @input=\"emit('update', { label: ($event.target as HTMLInputElement).value })\" />\n </div>\n <div class=\"fd-panel-item\">\n <label>图标</label>\n <div class=\"fd-icon-picker\">\n <button type=\"button\" class=\"fd-icon-trigger\" @click=\"iconOpen = !iconOpen\">\n <LucideIcon v-if=\"node.icon\" :name=\"node.icon\" :size=\"16\" />\n <span v-else class=\"fd-icon-placeholder\">无图标</span>\n <svg class=\"fd-icon-caret\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <polyline points=\"6 9 12 15 18 9\" />\n </svg>\n </button>\n <div v-if=\"iconOpen\" class=\"fd-icon-popover\" @click.stop>\n <div class=\"fd-icon-grid\">\n <button type=\"button\" class=\"fd-icon-option\" :class=\"{ active: !node.icon }\" title=\"无图标\" @click=\"selectIcon('')\">\n <span class=\"fd-icon-none\">无</span>\n </button>\n <button\n v-for=\"ic in cardIconNames\"\n :key=\"ic\"\n type=\"button\"\n class=\"fd-icon-option\"\n :class=\"{ active: node.icon === ic }\"\n :title=\"ic\"\n @click=\"selectIcon(ic)\"\n >\n <LucideIcon :name=\"ic\" :size=\"18\" />\n </button>\n </div>\n </div>\n </div>\n </div>\n <div class=\"fd-panel-item\">\n <label>图标底色</label>\n <input :value=\"node.iconBgColor\" @input=\"emit('update', { iconBgColor: ($event.target as HTMLInputElement).value })\" />\n </div>\n <div class=\"fd-panel-item fd-panel-item--row\">\n <label>初始展开</label>\n <FdSwitch :model-value=\"node.expanded\" @update:model-value=\"emit('update', { expanded: $event })\" />\n </div>\n <div class=\"fd-panel-item\">\n <label>宽度</label>\n <input :value=\"node.width\" @input=\"emit('update', { width: ($event.target as HTMLInputElement).value })\" />\n </div>\n <div class=\"fd-panel-item\">\n <label>是否隐藏</label>\n <select :value=\"node.hiddenMode || 'none'\" @change=\"emit('update', { hiddenMode: ($event.target as HTMLSelectElement).value as HiddenMode })\">\n <option value=\"none\">不隐藏</option>\n <option value=\"start\">发起时隐藏</option>\n <option value=\"not-start\">非发起时隐藏</option>\n <option value=\"not-approval\">非审批时隐藏</option>\n </select>\n </div>\n </div>\n</template>\n\n<style scoped>\n.fd-panel {\n display: flex;\n flex-direction: column;\n gap: 1.2rem;\n}\n.fd-panel-item {\n display: flex;\n flex-direction: column;\n gap: 0.4rem;\n}\n.fd-panel-item--row {\n flex-direction: row;\n align-items: center;\n justify-content: space-between;\n}\n.fd-panel-item label {\n font-size: 1.3rem;\n color: var(--fd-color-text-secondary);\n}\n.fd-panel-item input,\n.fd-panel-item select {\n height: 3.2rem;\n padding: 0 1rem;\n border: 1px solid var(--fd-color-border);\n border-radius: var(--fd-radius-base);\n font-size: 1.4rem;\n background: var(--fd-color-bg-panel);\n}\n.fd-panel-item select {\n color: var(--fd-color-text);\n cursor: pointer;\n}\n/* 图标选择器 */\n.fd-icon-picker {\n position: relative;\n}\n.fd-icon-trigger {\n width: 100%;\n height: 3.2rem;\n padding: 0 0.8rem;\n display: flex;\n align-items: center;\n gap: 0.6rem;\n border: 1px solid var(--fd-color-border);\n border-radius: var(--fd-radius-base);\n background: var(--fd-color-bg-panel);\n color: var(--fd-color-text);\n cursor: pointer;\n}\n.fd-icon-trigger:hover {\n border-color: var(--fd-color-border-hover);\n}\n.fd-icon-placeholder {\n flex: 1;\n text-align: left;\n font-size: 1.4rem;\n color: var(--fd-color-text-tertiary);\n}\n.fd-icon-caret {\n width: 1.4rem;\n height: 1.4rem;\n margin-left: auto;\n color: var(--fd-color-text-tertiary);\n}\n.fd-icon-popover {\n position: absolute;\n z-index: 20;\n top: calc(100% + 0.4rem);\n left: 0;\n right: 0;\n padding: 0.8rem;\n border: 1px solid var(--fd-color-border);\n border-radius: var(--fd-radius-base);\n background: var(--fd-color-bg-panel);\n box-shadow: var(--fd-shadow-pop);\n max-height: 26rem;\n overflow-y: auto;\n}\n.fd-icon-grid {\n display: grid;\n grid-template-columns: repeat(6, 1fr);\n gap: 0.4rem;\n}\n.fd-icon-option {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n height: 3.2rem;\n border: 1px solid transparent;\n border-radius: var(--fd-radius-base);\n background: transparent;\n color: var(--fd-color-text);\n cursor: pointer;\n}\n.fd-icon-option:hover {\n background: var(--fd-color-bg-hover);\n}\n.fd-icon-option.active {\n border-color: var(--fd-color-primary);\n background: var(--fd-color-bg-active);\n color: var(--fd-color-primary);\n}\n.fd-icon-none {\n font-size: 1.2rem;\n}\n</style>\n","<script setup lang=\"ts\">\nimport type { SlotWidgetProps } from '@/types'\n\ndefineProps<{ node: SlotWidgetProps }>()\n</script>\n\n<template>\n <div class=\"fd-slot-design\">\n <span class=\"fd-slot-tag\">插槽</span>\n <span class=\"fd-slot-name\">{{ node.slotName || '未命名插槽' }}</span>\n <span class=\"fd-slot-hint\">宿主注入:{{ node.slotName }}</span>\n </div>\n</template>\n\n<style scoped>\n.fd-slot-design {\n display: flex;\n align-items: center;\n gap: 0.8rem;\n padding: 1.2rem 1.6rem;\n border: 1px dashed var(--fd-color-border-hover);\n border-radius: var(--fd-radius-base);\n background: var(--fd-color-bg-hover);\n}\n.fd-slot-tag {\n padding: 0.2rem 0.8rem;\n border-radius: var(--fd-radius-base);\n background: var(--fd-color-primary-light);\n color: var(--fd-color-primary);\n font-size: 1.2rem;\n}\n.fd-slot-name {\n font-weight: 600;\n color: var(--fd-color-text);\n}\n.fd-slot-hint {\n margin-left: auto;\n color: var(--fd-color-text-tertiary);\n font-size: 1.2rem;\n}\n</style>\n","<script setup lang=\"ts\">\nimport type { SlotWidgetProps, FormMode } from '@/types'\nimport { isWidgetHidden } from '../visibility'\n\ndefineProps<{\n node: SlotWidgetProps\n mode?: FormMode\n formId?: string\n formData?: Record<string, unknown>\n}>()\n</script>\n\n<template>\n <div v-if=\"!isWidgetHidden(node.hiddenMode, formData?.status)\" class=\"fd-slot-render\">\n <!-- 渲染时转为命名插槽,宿主按 slotName 注入内容(作用域插槽透传 node/formData 等) -->\n <slot\n :name=\"node.slotName\"\n :node=\"node\"\n :form-data=\"formData\"\n :mode=\"mode\"\n :form-id=\"formId\"\n >\n <div class=\"fd-slot-missing\">未注入插槽:{{ node.slotName }}</div>\n </slot>\n </div>\n</template>\n\n<style scoped>\n.fd-slot-render {\n margin: 0;\n}\n.fd-slot-missing {\n padding: 1.2rem 1.6rem;\n border: 1px dashed var(--fd-color-border-hover);\n border-radius: var(--fd-radius-base);\n background: var(--fd-color-bg-hover);\n color: var(--fd-color-text-tertiary);\n font-size: 1.3rem;\n}\n</style>\n","import type { WidgetProps } from '@/types'\nimport type { WidgetDefinition } from '../types'\nimport SlotDesign from './SlotDesign.vue'\nimport SlotRender from './SlotRender.vue'\nimport SlotPanel from './SlotPanel.vue'\n\nexport const slotDefinition: WidgetDefinition = {\n type: 'slot',\n title: '插槽',\n design: SlotDesign,\n render: SlotRender,\n panel: SlotPanel,\n isContainer: false,\n createDefaultProps: (): WidgetProps => ({\n id: '',\n type: 'slot',\n label: '插槽',\n bindField: '',\n slotName: '',\n slotProps: {},\n hiddenMode: 'none',\n }),\n serialize: (props: WidgetProps) => props,\n}\n","<script setup lang=\"ts\">\nimport type { SlotWidgetProps, FieldMeta, HiddenMode } from '@/types'\n\ndefineProps<{ node: SlotWidgetProps; fields: FieldMeta[] }>()\nconst emit = defineEmits<{ (e: 'update', patch: Partial<SlotWidgetProps>): void }>()\n</script>\n\n<template>\n <div class=\"fd-panel\">\n <div class=\"fd-panel-item\">\n <label>标题</label>\n <input :value=\"node.label\" @input=\"emit('update', { label: ($event.target as HTMLInputElement).value })\" />\n </div>\n <div class=\"fd-panel-item\">\n <label>插槽名</label>\n <input :value=\"node.slotName\" placeholder=\"如 header / basic-info\" @input=\"emit('update', { slotName: ($event.target as HTMLInputElement).value })\" />\n </div>\n <div class=\"fd-panel-item\">\n <label>是否隐藏</label>\n <select :value=\"node.hiddenMode || 'none'\" @change=\"emit('update', { hiddenMode: ($event.target as HTMLSelectElement).value as HiddenMode })\">\n <option value=\"none\">不隐藏</option>\n <option value=\"start\">发起时隐藏</option>\n <option value=\"not-start\">非发起时隐藏</option>\n <option value=\"not-approval\">非审批时隐藏</option>\n </select>\n </div>\n </div>\n</template>\n\n<style scoped>\n.fd-panel {\n display: flex;\n flex-direction: column;\n gap: 1.2rem;\n}\n.fd-panel-item {\n display: flex;\n flex-direction: column;\n gap: 0.4rem;\n}\n.fd-panel-item label {\n font-size: 1.3rem;\n color: var(--fd-color-text-secondary);\n}\n.fd-panel-item input,\n.fd-panel-item select {\n height: 3.2rem;\n padding: 0 1rem;\n border: 1px solid var(--fd-color-border);\n border-radius: var(--fd-radius-base);\n font-size: 1.4rem;\n background: var(--fd-color-bg-panel);\n}\n.fd-panel-item select {\n color: var(--fd-color-text);\n cursor: pointer;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport type { SubtableWidgetProps } from '@/types'\n\nconst props = defineProps<{ node: SubtableWidgetProps }>()\n\n/**\n * 展示形态:仅由「表格样式」配置决定(cards=卡片列表,其它=表格),不做响应式处理。\n */\nconst showTable = computed(() => props.node.tablestyle !== 'cards')\n</script>\n\n<template>\n <div class=\"fd-st-design\">\n <!-- 表格(表格样式 = table 时展示) -->\n <div v-if=\"showTable\" class=\"fd-st-table-wrap\">\n <table class=\"fd-st-table\">\n <thead>\n <tr>\n <th v-if=\"node.secondtableindex === '1'\" class=\"fd-st-seq\">序号</th>\n <th v-for=\"col in node.colnums.filter((c) => c.isshow === 1)\" :key=\"col.name\" :style=\"{ width: col.showwidth || undefined }\">\n {{ col.showname || col.major || col.name }}\n </th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <td v-if=\"node.secondtableindex === '1'\" class=\"fd-st-seq\">1</td>\n <td\n v-for=\"col in node.colnums.filter((c) => c.isshow === 1)\"\n :key=\"col.name\"\n class=\"fd-st-cell\"\n :class=\"{ 'fd-st-cell--link': !!col.bindLink }\"\n >\n {{ col.name }}\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n\n <!-- 卡片列表(表格样式 = cards 时展示) -->\n <div v-else class=\"fd-st-cards\">\n <div class=\"fd-st-card\">\n <div\n v-for=\"col in node.colnums.filter((c) => c.isshow === 1)\"\n :key=\"col.name\"\n class=\"fd-st-card-row\"\n >\n <span class=\"fd-st-card-label\">{{ col.showname || col.major }}</span>\n <span class=\"fd-st-card-value\" :class=\"{ 'fd-st-card-value--link': !!col.bindLink }\">{{ col.name }}</span>\n </div>\n </div>\n <div v-if=\"node.colnums.filter((c) => c.isshow === 1).length === 0\" class=\"fd-st-cards-empty\">\n 暂无列配置\n </div>\n </div>\n </div>\n</template>\n\n<style scoped>\n.fd-st-design {\n border-radius: var(--fd-radius-base);\n background: var(--fd-color-bg-panel);\n overflow: hidden;\n}\n/* 表格外层容器:宽度不足时横向滚动 */\n.fd-st-table-wrap {\n overflow-x: auto;\n}\n.fd-st-table {\n /* 内容宽于容器时按内容撑开(触发横向滚动),窄时仍撑满容器 */\n width: max-content;\n min-width: 100%;\n border-collapse: collapse;\n}\n.fd-st-table th {\n background: var(--fd-color-bg-hover);\n color: var(--fd-color-text-secondary);\n font-weight: 600;\n}\n.fd-st-table th,\n.fd-st-table td {\n border: 1px solid var(--fd-color-border);\n padding: 0.8rem 1rem;\n font-size: 1.3rem;\n text-align: left;\n}\n.fd-st-seq {\n width: 5rem;\n text-align: center !important;\n}\n.fd-st-cell {\n color: var(--fd-color-text-secondary);\n}\n/* 链接列:高亮 + pointer(设计态仅预览样式,不跳转) */\n.fd-st-cell--link {\n color: var(--fd-color-primary);\n cursor: pointer;\n}\n\n/* ===== 移动端:卡片列表(参考 image 3.png 风格) ===== */\n.fd-st-cards {\n display: flex;\n flex-direction: column;\n gap: .8rem;\n}\n.fd-st-card {\n display: flex;\n flex-direction: column;\n gap: 0.6rem;\n background: var(--fd-color-bg-panel);\n border-radius: var(--fd-radius-base);\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.06);\n border: 1px solid var(--fd-color-border);\n}\n.fd-st-card-row {\n display: flex;\n align-items: flex-start;\n padding: 1rem 1.4rem;\n border-bottom: 1px solid var(--fd-color-border);\n}\n.fd-st-card-row:last-child {\n border-bottom: none\n}\n.fd-st-card-label {\n flex: 0 0 11.5rem;\n max-width: 11.5rem;\n color: var(--fd-color-text-secondary);\n font-size: 1.3rem;\n}\n.fd-st-card-value {\n flex: 1 1 auto;\n min-width: 0;\n color: var(--fd-color-text);\n font-size: 1.3rem;\n word-break: break-all;\n display: flex;\n align-items: center\n}\n.fd-st-card-value--link {\n color: var(--fd-color-primary);\n cursor: pointer;\n}\n.fd-st-cards-empty {\n text-align: center;\n font-size: 1.3rem;\n color: var(--fd-color-text-tertiary);\n padding: 2rem 1rem;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport type { SubtableWidgetProps, ColumnConfig } from '@/types'\n\nconst props = defineProps<{\n node: SubtableWidgetProps\n formData?: Record<string, unknown>\n}>()\n\nconst cols = computed(() => props.node.colnums.filter((c) => c.isshow === 1))\nconst readonly = computed(() => props.node.isreadonly === '1')\n\nconst rows = computed<Record<string, unknown>[]>(() => {\n const raw = props.formData?.[props.node.secondtable]\n if (Array.isArray(raw)) return raw as Record<string, unknown>[]\n return []\n})\n\nconst visible = computed(() => {\n if (props.node.nodatahidetable === '1' && rows.value.length === 0) return false\n return true\n})\n\n/**\n * 展示形态:仅由「表格样式」配置决定(cards=卡片列表,其它=表格),不做响应式处理。\n */\nconst showTable = computed(() => props.node.tablestyle !== 'cards')\n\nfunction addRow() {\n if (readonly.value) return\n const blank: Record<string, unknown> = {}\n cols.value.forEach((c) => (blank[c.name] = ''))\n if (props.formData && Array.isArray(props.formData[props.node.secondtable])) {\n ;(props.formData[props.node.secondtable] as Record<string, unknown>[]).push(blank)\n }\n}\n\nfunction delRow(idx: number) {\n if (readonly.value) return\n if (props.formData && Array.isArray(props.formData[props.node.secondtable])) {\n ;(props.formData[props.node.secondtable] as Record<string, unknown>[]).splice(idx, 1)\n }\n}\n\nfunction cellText(row: Record<string, unknown>, name: string): string {\n const v = row[name]\n return v === undefined || v === null ? '' : String(v)\n}\n\n/** 链接地址:列绑定链接字段时取该字段在当前行的值;未绑定或空值返回 ''(按文本渲染) */\nfunction linkUrl(col: ColumnConfig, row: Record<string, unknown>): string {\n return col.bindLink ? cellText(row, col.bindLink) : ''\n}\n\n/**\n * 同内容合并:列开启(issamecolmerge === 1)时,同列相邻内容相同的单元格合并为一个(rowspan)。\n * spans[ci][ri]:该单元格纵向占据的行数;skipped[ci][ri]:是否被上方合并覆盖(不渲染 td)。\n * 空值不参与合并,避免整列空白被合成一格。\n */\nconst mergeInfo = computed(() => {\n const list = rows.value\n const spans: number[][] = []\n const skipped: boolean[][] = []\n cols.value.forEach((col, ci) => {\n spans[ci] = []\n skipped[ci] = []\n const enable = col.issamecolmerge === 1\n let start = 0\n for (let ri = 0; ri < list.length; ri++) {\n const cur = cellText(list[ri], col.name)\n const same =\n enable && cur !== '' && ri > 0 && cur === cellText(list[ri - 1], col.name)\n if (same) {\n skipped[ci][ri] = true\n spans[ci][start] += 1\n } else {\n skipped[ci][ri] = false\n spans[ci][ri] = 1\n start = ri\n }\n }\n })\n return { spans, skipped }\n})\n\n/** 单元格是否被上方合并覆盖(true 则不渲染该 td) */\nfunction isMerged(ci: number, ri: number): boolean {\n return mergeInfo.value.skipped[ci]?.[ri] === true\n}\n\n/** 合并单元格的 rowspan(1 时不输出属性) */\nfunction rowspanOf(ci: number, ri: number): number | undefined {\n const s = mergeInfo.value.spans[ci]?.[ri]\n return s && s > 1 ? s : undefined\n}\n</script>\n\n<template>\n <div v-if=\"visible\" class=\"fd-st-render\" :subtable-key=\"node.secondtable\">\n <!-- 表格 / 卡片列表(由「表格样式」配置决定) -->\n <div v-if=\"showTable\" class=\"fd-st-table-wrap\">\n <table class=\"fd-st-table\">\n <thead>\n <tr>\n <th v-if=\"node.secondtableindex === '1'\" class=\"fd-st-seq\">序号</th>\n <th v-for=\"col in cols\" :key=\"col.name\" :subtable-val=\"col.name\" :style=\"{ width: col.showwidth || undefined, textAlign: col.align || 'left' }\">\n {{ col.showname || col.major || col.name }}\n </th>\n <th v-if=\"!readonly\" class=\"fd-st-op\">操作</th>\n </tr>\n </thead>\n <tbody>\n <tr v-for=\"(row, idx) in rows\" :key=\"idx\">\n <td v-if=\"node.secondtableindex === '1'\" class=\"fd-st-seq\">{{ idx + 1 }}</td>\n <template v-for=\"(col, ci) in cols\" :key=\"col.name\">\n <td\n v-if=\"!isMerged(ci, idx)\"\n :rowspan=\"rowspanOf(ci, idx)\"\n :subtable-val=\"col.name\"\n :style=\"{ textAlign: col.align || 'left', color: col.prospect || undefined, background: col.background || undefined }\"\n >\n <a\n v-if=\"linkUrl(col, row)\"\n class=\"fd-st-link\"\n :href=\"linkUrl(col, row)\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >{{ cellText(row, col.name) }}</a>\n <template v-else>{{ cellText(row, col.name) }}</template>\n </td>\n </template>\n <td v-if=\"!readonly\" class=\"fd-st-op\">\n <button class=\"fd-btn fd-btn--danger\" @click=\"delRow(idx)\">删除</button>\n </td>\n </tr>\n <tr v-if=\"rows.length === 0\">\n <td :colspan=\"cols.length + (node.secondtableindex === '1' ? 1 : 0) + (readonly ? 0 : 1)\" class=\"fd-st-empty\">\n {{ node.nodatatitle === '1' ? '暂无数据' : '' }}\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n\n <!-- 卡片列表(表格样式 = cards 时展示) -->\n <div v-else class=\"fd-st-cards\">\n <div v-for=\"(row, idx) in rows\" :key=\"idx\" class=\"fd-st-card\">\n <div\n v-for=\"col in cols\"\n :key=\"col.name\"\n class=\"fd-st-card-row\"\n >\n <span class=\"fd-st-card-label\">{{ col.showname || col.major || col.name }}</span>\n <span class=\"fd-st-card-value\" :subtable-val=\"col.name\">\n <a\n v-if=\"linkUrl(col, row)\"\n class=\"fd-st-link\"\n :href=\"linkUrl(col, row)\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >{{ cellText(row, col.name) }}</a>\n <template v-else>{{ cellText(row, col.name) }}</template>\n </span>\n </div>\n <div v-if=\"!readonly\" class=\"fd-st-card-actions\">\n <button class=\"fd-btn fd-btn--danger fd-btn--sm\" @click=\"delRow(idx)\">删除</button>\n </div>\n </div>\n <div v-if=\"rows.length === 0\" class=\"fd-st-cards-empty\">\n {{ node.nodatatitle === '1' ? '暂无数据' : '' }}\n </div>\n </div>\n\n <button v-if=\"!readonly\" class=\"fd-btn fd-btn--primary fd-st-add\" @click=\"addRow\">新增一行</button>\n </div>\n</template>\n\n<style scoped>\n.fd-st-render {\n background: var(--fd-color-bg-panel);\n}\n/* 表格外层容器:宽度不足时横向滚动 */\n.fd-st-table-wrap {\n overflow-x: auto;\n}\n.fd-st-table {\n /* 内容宽于容器时按内容撑开(触发横向滚动),窄时仍撑满容器 */\n width: max-content;\n min-width: 100%;\n border-spacing: 0;\n border-collapse: separate;\n border: 1px solid #e4eaf2;\n border-radius: 1rem;\n overflow: hidden;\n background: #fff;\n}\n.fd-st-table th,\n.fd-st-table td {\n border: 0;\n border-right: 1px solid #e4eaf2;\n border-bottom: 1px solid #e4eaf2;\n padding: 1.1rem 1.2rem;\n line-height: 1.45;\n font-size: 1.3rem;\n}\n.fd-st-table tr > *:last-child {\n border-right: 0;\n}\n.fd-st-table th {\n color: #667085;\n background: #f8fafc;\n font-weight: 500;\n}\n.fd-st-table thead th {\n color: #475467;\n background: #f6f8fb;\n font-weight: 600;\n}\n.fd-st-seq {\n width: 5rem;\n text-align: center !important;\n}\n.fd-st-op {\n width: 8rem;\n text-align: center;\n}\n.fd-st-empty {\n text-align: center;\n color: var(--fd-color-text-secondary);\n padding: 1.6rem;\n}\n/* 链接列:主题色高亮 + pointer,点击新窗口打开 */\n.fd-st-link {\n color: var(--fd-color-primary);\n cursor: pointer;\n text-decoration: none;\n word-break: break-all;\n}\n.fd-st-link:hover {\n text-decoration: underline;\n}\n.fd-st-add {\n margin: 1rem 1.2rem;\n}\n\n/* ===== 移动端:卡片列表 ===== */\n.fd-st-cards {\n display: flex;\n flex-direction: column;\n gap: 0.8rem;\n}\n.fd-st-card {\n display: flex;\n flex-direction: column;\n background: var(--fd-color-bg-panel);\n border-radius: var(--fd-radius-base);\n box-shadow: 0 0.1rem 0.2rem rgba(0, 0, 0, 0.06);\n border: 1px solid var(--fd-color-border);\n}\n.fd-st-card-row {\n display: flex;\n align-items: flex-start;\n padding: 1rem 1.4rem;\n border-bottom: 1px solid var(--fd-color-border);\n}\n.fd-st-card-row:last-child {\n border-bottom: none;\n}\n.fd-st-card-label {\n flex: 0 0 11.5rem;\n max-width: 11.5rem;\n color: var(--fd-color-text-secondary);\n font-size: 1.3rem;\n}\n.fd-st-card-value {\n flex: 1 1 auto;\n min-width: 0;\n color: var(--fd-color-text);\n font-size: 1.3rem;\n word-break: break-all;\n}\n.fd-st-card-actions {\n display: flex;\n justify-content: flex-end;\n padding: 0.8rem 1.4rem;\n border-top: 1px solid var(--fd-color-border);\n}\n.fd-st-cards-empty {\n text-align: center;\n font-size: 1.3rem;\n color: var(--fd-color-text-secondary);\n padding: 2rem 1rem;\n}\n</style>\n","import template from '../../template_mock.json'\nimport type { FormSchema, ColumnConfig } from '@/types'\n\n/** 子表字段(用于生成默认列与预览行数据) */\nexport interface SubtableField {\n name: string\n label: string\n dataType: 'string' | 'date' | 'number' | 'money' | 'file' | 'link'\n}\n\n/** 子表定义:可绑定到子表组件的数据源 */\nexport interface SubtableDef {\n /** 子表名 / 业务对象标识(即 secondtable 取值) */\n name: string\n /** 子表显示名 */\n label: string\n /** 子表字段(决定默认展示列) */\n fields: SubtableField[]\n}\n\n/**\n * 可选子表枚举(后续由子表元数据接口下发;此处 mock)。\n * 字段整理自 approval-lease.html 各子表区块。\n */\nexport const mockSubtables: SubtableDef[] = [\n {\n name: 'SG_ZL_YYQHTSPC',\n label: '原合同退租信息',\n fields: [\n { name: 'shop_no', label: '铺位号', dataType: 'string' },\n { name: 'brand_name', label: '品牌名称', dataType: 'string' },\n { name: 'quit_reason', label: '合同退租原因', dataType: 'string' },\n { name: 'quit_date', label: '合同退租日期', dataType: 'date' },\n { name: 'deduct_amount', label: '合同扣款金额', dataType: 'money' },\n { name: 'detail', label: '详情', dataType: 'string' },\n { name: 'detail_url', label: '详情链接', dataType: 'link' },\n ],\n },\n {\n name: 'SG_ZL_YYQHTYS',\n label: '预算完成情况预测',\n fields: [\n { name: 'calibers', label: '测算口径', dataType: 'string' },\n { name: 'fee_item', label: '费项', dataType: 'string' },\n { name: 'annual_budget', label: '年度预算(A)', dataType: 'money' },\n { name: 'contract_receivable', label: '合同应收(B)', dataType: 'money' },\n { name: 'budget_gap', label: '预算缺口(C=B-A)', dataType: 'money' },\n { name: 'forecast_income', label: '预测收入(D)', dataType: 'money' },\n { name: 'forecast_gap', label: '预测缺口(E=D-A)', dataType: 'money' },\n { name: 'light', label: '亮灯提示', dataType: 'string' },\n ],\n },\n {\n name: 'SG_ZL_YYQHTHT',\n label: '合同列表',\n fields: [\n { name: 'seq', label: '序号', dataType: 'number' },\n { name: 'contract_type', label: '合同类型', dataType: 'string' },\n { name: 'contract_name', label: '合同名称', dataType: 'string' },\n { name: 'party_a', label: '甲方', dataType: 'string' },\n { name: 'party_b', label: '乙方', dataType: 'string' },\n { name: 'use_template', label: '使用合同模版', dataType: 'string' },\n { name: 'operate', label: '操作', dataType: 'string' },\n ],\n },\n {\n name: 'SG_ZL_YYQHTJB',\n label: '交办记录',\n fields: [\n { name: 'original_approver', label: '原审批人', dataType: 'string' },\n { name: 'delegate_to', label: '交办人', dataType: 'string' },\n { name: 'delegate_time', label: '交办时间', dataType: 'date' },\n { name: 'delegate_opinion', label: '交办意见', dataType: 'string' },\n ],\n },\n {\n name: 'SG_ZL_YYQHTFJ',\n label: '附件信息',\n fields: [\n { name: 'seq', label: '序号', dataType: 'number' },\n { name: 'attachment_type', label: '附件类型', dataType: 'string' },\n { name: 'file_name', label: '文件名称', dataType: 'file' },\n { name: 'upload_user', label: '上传人', dataType: 'string' },\n { name: 'upload_time', label: '上传时间', dataType: 'date' },\n ],\n },\n {\n name: 'SG_ZL_YYQHTTH',\n label: '退回详情',\n fields: [\n { name: 'approver', label: '审批人', dataType: 'string' },\n { name: 'description', label: '说明', dataType: 'string' },\n { name: 'reject_reason', label: '退回原因', dataType: 'string' },\n { name: 'reject_time', label: '时间', dataType: 'date' },\n ],\n },\n {\n name: 'SG_ZL_YYQHTFK',\n label: '合同付款计划',\n fields: [\n { name: 'pay_phase', label: '期次', dataType: 'string' },\n { name: 'pay_amount', label: '金额', dataType: 'money' },\n { name: 'pay_date', label: '计划付款日', dataType: 'date' },\n { name: 'pay_status', label: '状态', dataType: 'string' },\n ],\n },\n]\n\n/** 供「选择子表」下拉使用的选项 */\nexport const subtableOptions = mockSubtables.map((s) => ({ name: s.name, label: s.label }))\n\n/** 按子表名取定义 */\nexport function getSubtableDef(name: string): SubtableDef | undefined {\n return mockSubtables.find((s) => s.name === name)\n}\n\n/** 由子表字段生成默认列配置(不同子表默认展示字段不同) */\nexport function buildDefaultColumns(def: SubtableDef): ColumnConfig[] {\n return def.fields.map((f, i) => {\n const isFile = f.dataType === 'file'\n return {\n name: f.name,\n isshow: 1,\n major: '',\n showname: f.label,\n showwidth: '',\n background: '',\n prospect: '',\n issum: 0,\n index: i + 1,\n align: '',\n iscompletehide: 0,\n iscompletehidecode: '',\n issamecolmerge: 0,\n bindLink: '',\n editmode: { editmode: isFile ? 'files' : 'text', title: isFile ? '文件' : '文本' },\n events: [],\n }\n })\n}\n\n/** mock 默认表单模板(来自 template_mock.json) */\nexport function mockSchema(formId: string): FormSchema {\n return {\n ...(template as unknown as FormSchema),\n formId,\n }\n}\n","<script setup lang=\"ts\">\nimport { reactive, computed, nextTick } from 'vue'\nimport { ElSelect, ElOption } from 'element-plus'\nimport 'element-plus/es/components/select/style/css'\nimport type { SubtableWidgetProps, FieldMeta, ColumnConfig } from '@/types'\nimport FdSwitch from '@/components/FdSwitch.vue'\nimport { subtableOptions, getSubtableDef, buildDefaultColumns } from '@/api/mock'\n\nconst props = defineProps<{ node: SubtableWidgetProps; fields: FieldMeta[] }>()\nconst emit = defineEmits<{ (e: 'update', patch: Partial<SubtableWidgetProps>): void }>()\n\nfunction set<K extends keyof SubtableWidgetProps>(key: K, value: SubtableWidgetProps[K]) {\n emit('update', { [key]: value } as Partial<SubtableWidgetProps>)\n}\n\n/** 选择子表:写入 secondtable,并按该子表字段生成默认展示列(不同子表默认字段不同) */\nfunction onSelectSubtable(val: unknown) {\n const name = (val as string) ?? ''\n const def = getSubtableDef(name)\n const patch: Partial<SubtableWidgetProps> = { secondtable: name }\n if (def) {\n patch.displaytitle = def.label\n patch.colnums = buildDefaultColumns(def)\n }\n emit('update', patch)\n}\n\n/** 弹窗编辑态:克隆列对象,确定时写回 */\nconst dialog = reactive<{ open: boolean; index: number; draft: ColumnConfig | null }>({\n open: false,\n index: -1,\n draft: null,\n})\n\nfunction clone(col: ColumnConfig): ColumnConfig {\n return JSON.parse(JSON.stringify(col))\n}\n\nfunction openCol(idx: number) {\n dialog.index = idx\n dialog.draft = clone(props.node.colnums[idx])\n dialog.open = true\n}\n\nfunction closeDialog() {\n dialog.open = false\n dialog.draft = null\n dialog.index = -1\n}\n\nfunction saveCol() {\n if (dialog.draft && dialog.index >= 0) {\n const next = [...props.node.colnums]\n next[dialog.index] = dialog.draft\n emit('update', { colnums: next })\n }\n closeDialog()\n}\n\nfunction toggleCol(col: ColumnConfig, visible: boolean) {\n col.isshow = visible ? 1 : 0\n emit('update', { colnums: [...props.node.colnums] })\n}\n\nasync function addCol() {\n const col: ColumnConfig = {\n name: `col_${Date.now().toString(36)}`,\n isshow: 1,\n major: '',\n showname: '新列',\n showwidth: '',\n background: '',\n prospect: '',\n issum: 0,\n index: props.node.colnums.length + 1,\n align: '',\n iscompletehide: 0,\n iscompletehidecode: '',\n issamecolmerge: 0,\n bindLink: '',\n editmode: { editmode: 'text', title: '文本' },\n events: [],\n }\n emit('update', { colnums: [...props.node.colnums, col] })\n await nextTick()\n openCol(props.node.colnums.length - 1)\n}\n\nfunction delCol(idx: number) {\n const next = props.node.colnums.slice()\n next.splice(idx, 1)\n emit('update', { colnums: next })\n}\n\n/** 颜色输入:非 hex 时回退,保证 color picker 不报错 */\nfunction hexOf(v: string): string {\n return /^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/.test(v) ? v : '#ffffff'\n}\nfunction setColor(key: 'background' | 'prospect', e: Event) {\n if (dialog.draft) dialog.draft[key] = (e.target as HTMLInputElement).value\n}\n\n/** 当前子表字段集合(供列字段下拉选择) */\nconst subtableFields = computed(() => getSubtableDef(props.node.secondtable)?.fields ?? [])\n\n/** 子表字段中的链接类型字段(dataType === 'link'),供「链接」下拉绑定跳转地址 */\nconst linkFields = computed(() => subtableFields.value.filter((f) => f.dataType === 'link'))\n\n/** 绑定链接字段变更(空字符串表示不绑定) */\nfunction onBindLink(val: unknown) {\n if (!dialog.draft) return\n dialog.draft.bindLink = (val as string) ?? ''\n}\n\n/** 表格样式变更(空值回退 table) */\nfunction onTablestyle(val: unknown) {\n set('tablestyle', ((val as string) || 'table') as SubtableWidgetProps['tablestyle'])\n}\n\n/** 选择列字段:写入 name,并联动填充显示标题与编辑控件 */\nfunction onColField(e: Event) {\n if (!dialog.draft) return\n const name = (e.target as HTMLSelectElement).value\n dialog.draft.name = name\n const f = subtableFields.value.find((x) => x.name === name)\n if (f) {\n dialog.draft.showname = f.label\n const isFile = f.dataType === 'file'\n dialog.draft.editmode.editmode = isFile ? 'files' : 'text'\n dialog.draft.editmode.title = isFile ? '文件' : '文本'\n }\n}\n</script>\n\n<template>\n <div class=\"fd-panel\">\n <div class=\"fd-panel-item\">\n <label>选择子表</label>\n <el-select\n :model-value=\"node.secondtable\"\n filterable\n clearable\n placeholder=\"请选择子表\"\n style=\"width: 100%\"\n @update:model-value=\"onSelectSubtable\"\n >\n <el-option v-for=\"opt in subtableOptions\" :key=\"opt.name\" :label=\"`${opt.label}(${opt.name})`\" :value=\"opt.name\" />\n </el-select>\n </div>\n <div class=\"fd-panel-item fd-panel-item--row\">\n <label>只读</label>\n <FdSwitch :model-value=\"node.isreadonly === '1'\" @update:model-value=\"set('isreadonly', $event ? '1' : '0')\" />\n </div>\n <div class=\"fd-panel-item fd-panel-item--row\">\n <label>序号列</label>\n <FdSwitch :model-value=\"node.secondtableindex === '1'\" @update:model-value=\"set('secondtableindex', $event ? '1' : '0')\" />\n </div>\n <div class=\"fd-panel-item\">\n <label>表格样式</label>\n <el-select\n :model-value=\"node.tablestyle || 'table'\"\n style=\"width: 100%\"\n @update:model-value=\"onTablestyle\"\n >\n <el-option label=\"表格\" value=\"table\" />\n <el-option label=\"卡片列表\" value=\"cards\" />\n </el-select>\n </div>\n\n <!-- 列配置:精简卡片列表 -->\n <div class=\"fd-panel-item\">\n <div class=\"fd-cols-head\">\n <span>列配置({{ node.colnums.length }})</span>\n <button class=\"fd-btn fd-btn--primary fd-btn--sm\" @click=\"addCol\">+ 新增列</button>\n </div>\n\n <div v-if=\"node.colnums.length === 0\" class=\"fd-cols-empty\">\n 暂无列,点击「新增列」添加\n </div>\n\n <div v-for=\"(col, idx) in node.colnums\" :key=\"col.name\" class=\"fd-col-card\">\n <div class=\"fd-col-card-top\">\n <span class=\"fd-col-order\">{{ idx + 1 }}</span>\n <div class=\"fd-col-meta\">\n <span class=\"fd-col-title\">{{ col.showname || '未命名列' }}</span>\n <span class=\"fd-col-name-sub\">{{ col.name }}</span>\n </div>\n <span class=\"fd-col-tag\">{{ col.bindLink ? '链接' : '文本' }}</span>\n </div>\n <div class=\"fd-col-card-bottom\">\n <label class=\"fd-col-switch\">\n <span>显示</span>\n <FdSwitch :model-value=\"col.isshow === 1\" @update:model-value=\"toggleCol(col, $event)\" />\n </label>\n <div class=\"fd-col-actions\">\n <button class=\"fd-btn fd-btn--ghost fd-btn--sm\" @click=\"openCol(idx)\">设置</button>\n <button class=\"fd-btn fd-btn--danger fd-btn--sm\" @click=\"delCol(idx)\">删除</button>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- 列设置弹窗 -->\n <Teleport to=\"body\">\n <div v-if=\"dialog.open && dialog.draft\" class=\"fd-dialog-mask\" @click.self=\"closeDialog\">\n <div class=\"fd-dialog\" style=\"max-width: 560px;\">\n <div class=\"fd-dialog-head\">\n <span>列设置 · {{ dialog.draft.showname || dialog.draft.name || '新列' }}</span>\n <button class=\"fd-dialog-close\" @click=\"closeDialog\" title=\"关闭\">×</button>\n </div>\n <div class=\"fd-dialog-body\">\n <!-- 基本信息 -->\n <section class=\"fd-form-section\">\n <h5 class=\"fd-form-section-h\">基本信息</h5>\n <div class=\"fd-form-grid\">\n <div class=\"fd-form-item\">\n <label>列字段</label>\n <select :value=\"dialog.draft.name\" @change=\"onColField($event)\">\n <option value=\"\">请选择字段</option>\n <option v-for=\"f in subtableFields\" :key=\"f.name\" :value=\"f.name\">{{ f.label }}({{ f.name }})</option>\n </select>\n </div>\n <div class=\"fd-form-item\">\n <label>显示标题</label>\n <input :value=\"dialog.draft.showname\" @input=\"dialog.draft!.showname = ($event.target as HTMLInputElement).value\" placeholder=\"如 姓名\" />\n </div>\n <div class=\"fd-form-item\">\n <label>主表头分组</label>\n <input :value=\"dialog.draft.major\" @input=\"dialog.draft!.major = ($event.target as HTMLInputElement).value\" placeholder=\"可合并表头分组名\" />\n </div>\n <div class=\"fd-form-item\">\n <label>列序号</label>\n <input type=\"number\" min=\"1\" :value=\"dialog.draft.index\" @input=\"dialog.draft!.index = Number(($event.target as HTMLInputElement).value)\" />\n </div>\n </div>\n </section>\n\n <!-- 显示与样式 -->\n <section class=\"fd-form-section\">\n <h5 class=\"fd-form-section-h\">显示与样式</h5>\n <div class=\"fd-form-grid\">\n <div class=\"fd-form-item\">\n <label>列宽</label>\n <input :value=\"dialog.draft.showwidth\" @input=\"dialog.draft!.showwidth = ($event.target as HTMLInputElement).value\" placeholder=\"如 120px 或 20%\" />\n </div>\n <div class=\"fd-form-item\">\n <label>对齐方式</label>\n <select :value=\"dialog.draft.align\" @change=\"dialog.draft!.align = ($event.target as HTMLSelectElement).value as ColumnConfig['align']\">\n <option value=\"\">默认(左)</option>\n <option value=\"left\">左对齐</option>\n <option value=\"center\">居中</option>\n <option value=\"right\">右对齐</option>\n </select>\n </div>\n <div class=\"fd-form-item\">\n <label>背景色</label>\n <div class=\"fd-color-row\">\n <input type=\"color\" :value=\"hexOf(dialog.draft.background)\" @input=\"setColor('background', $event)\" />\n <input :value=\"dialog.draft.background\" @input=\"dialog.draft!.background = ($event.target as HTMLInputElement).value\" placeholder=\"如 #f5f7fa 或空\" />\n </div>\n </div>\n <div class=\"fd-form-item\">\n <label>字体色</label>\n <div class=\"fd-color-row\">\n <input type=\"color\" :value=\"hexOf(dialog.draft.prospect)\" @input=\"setColor('prospect', $event)\" />\n <input :value=\"dialog.draft.prospect\" @input=\"dialog.draft!.prospect = ($event.target as HTMLInputElement).value\" placeholder=\"如 #f5523a 或空\" />\n </div>\n </div>\n </div>\n </section>\n\n <!-- 编辑模式 -->\n <section class=\"fd-form-section\">\n <h5 class=\"fd-form-section-h\">编辑模式</h5>\n <div class=\"fd-form-grid\">\n <div class=\"fd-form-item\">\n <label>同内容合并</label>\n <FdSwitch :model-value=\"dialog.draft.issamecolmerge === 1\" @update:model-value=\"dialog.draft!.issamecolmerge = $event ? 1 : 0\" />\n </div>\n <div class=\"fd-form-item\">\n <label>链接</label>\n <select :value=\"dialog.draft.bindLink ?? ''\" @change=\"onBindLink(($event.target as HTMLSelectElement).value)\">\n <option value=\"\">不绑定</option>\n <option v-for=\"f in linkFields\" :key=\"f.name\" :value=\"f.name\">{{ f.label }}({{ f.name }})</option>\n </select>\n </div>\n </div>\n </section>\n </div>\n <div class=\"fd-dialog-foot\">\n <button class=\"fd-btn fd-btn--ghost\" @click=\"closeDialog\">取消</button>\n <button class=\"fd-btn fd-btn--primary\" @click=\"saveCol\">确定</button>\n </div>\n </div>\n </div>\n </Teleport>\n</template>\n\n<style scoped>\n.fd-panel { display: flex; flex-direction: column; gap: 1.2rem; }\n.fd-panel-item { display: flex; flex-direction: column; gap: 0.4rem; }\n.fd-panel-item--row { flex-direction: row; align-items: center; justify-content: space-between; }\n.fd-panel-item label { font-size: 1.3rem; color: var(--fd-color-text-secondary); }\n\n/* 列卡片列表 */\n.fd-cols-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 0.8rem; font-weight: 600; }\n.fd-cols-empty {\n font-size: 1.3rem; color: var(--fd-color-text-placeholder); text-align: center;\n padding: 1.6rem; border: 1px dashed var(--fd-color-border); border-radius: var(--fd-radius-base);\n}\n.fd-col-card {\n display: flex; flex-direction: column; gap: 0.8rem;\n padding: 1rem 1.2rem; margin-bottom: 0.8rem;\n border: 1px solid var(--fd-color-border); border-radius: var(--fd-radius-base);\n background: var(--fd-color-bg-panel); transition: border-color var(--fd-transition);\n}\n.fd-col-card:hover { border-color: var(--fd-color-primary); }\n.fd-col-card-top { display: flex; align-items: center; gap: 0.8rem; }\n.fd-col-order {\n flex-shrink: 0; width: 2.2rem; height: 2.2rem; border-radius: 50%;\n display: flex; align-items: center; justify-content: center;\n font-size: 1.2rem; font-weight: 600; color: var(--fd-color-primary);\n background: var(--fd-color-primary-light);\n}\n.fd-col-meta { flex: 1; display: flex; flex-direction: column; gap: 0.1rem; min-width: 0; }\n.fd-col-title { font-size: 1.4rem; font-weight: 600; color: var(--fd-color-text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n.fd-col-name-sub { font-size: 1.1rem; color: var(--fd-color-text-tertiary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n.fd-col-tag {\n flex-shrink: 0; font-size: 1.1rem; color: var(--fd-color-text-secondary);\n background: var(--fd-color-bg); border: 1px solid var(--fd-color-border);\n padding: 0.2rem 0.6rem; border-radius: var(--fd-radius-base);\n}\n.fd-col-card-bottom { display: flex; align-items: center; justify-content: space-between; }\n.fd-col-switch { display: flex; align-items: center; gap: 0.6rem; font-size: 1.3rem; color: var(--fd-color-text-secondary); }\n.fd-col-actions { display: flex; gap: 0.6rem; }\n\n/* 弹窗内表单:分组 + 两列网格 */\n.fd-form-section { margin-bottom: 1.6rem; }\n.fd-form-section:last-child { margin-bottom: 0; }\n.fd-form-section-h { margin: 0 0 0.8rem; font-size: 1.3rem; font-weight: 600; color: var(--fd-color-text-secondary); }\n.fd-form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 1.2rem 1.6rem; }\n.fd-form-item { display: flex; flex-direction: column; gap: 0.4rem; }\n.fd-form-item label { font-size: 1.3rem; color: var(--fd-color-text-secondary); }\n.fd-color-row { display: flex; gap: 0.6rem; align-items: center; }\n.fd-form-section .fd-form-item .fd-color-row input[type='color'] {\n width: 3.6rem; height: 3.2rem; padding: 0.2rem; flex-shrink: 0;\n border: 1px solid var(--fd-color-border); border-radius: var(--fd-radius-base);\n background: var(--fd-color-bg-panel); cursor: pointer;\n}\n.fd-form-section .fd-form-item .fd-switch { margin-top: .6rem; }\n.fd-color-row input[type='text'] { flex: 1; min-width: 0; }\n\n/* 按钮变体 */\n.fd-btn--sm { height: 2.6rem; padding: 0 1rem; font-size: 1.2rem; }\n.fd-btn--ghost { background: transparent; color: var(--fd-color-primary); border: 1px solid var(--fd-color-primary); }\n.fd-btn--ghost:hover { background: var(--fd-color-primary-light); }\n\n/* 弹窗(与项目 .fd-dialog 风格一致) */\n.fd-dialog-mask {\n position: fixed; inset: 0; z-index: 100;\n background: rgba(0, 0, 0, 0.45);\n display: flex; align-items: center; justify-content: center;\n}\n.fd-dialog {\n width: min(56rem, 92vw); max-height: 82vh;\n display: flex; flex-direction: column;\n background: var(--fd-color-bg-panel); border-radius: var(--fd-radius-lg);\n box-shadow: var(--fd-shadow-pop); overflow: hidden;\n}\n.fd-dialog-head {\n display: flex; align-items: center; gap: 1.2rem;\n padding: 1.2rem 1.6rem; border-bottom: 1px solid var(--fd-color-border);\n font-weight: 600; font-size: 1.5rem;\n}\n.fd-dialog-head span { margin-right: auto; }\n.fd-dialog-close {\n width: 3rem; height: 3rem; padding: 0; font-size: 2rem; line-height: 1;\n border: none; border-radius: var(--fd-radius-base);\n background: transparent; color: var(--fd-color-text-secondary); cursor: pointer;\n}\n.fd-dialog-close:hover { background: var(--fd-color-bg); color: var(--fd-color-text); }\n.fd-dialog-body { padding: 1.6rem; overflow: auto; }\n.fd-dialog-foot {\n display: flex; justify-content: flex-end; gap: 1rem;\n padding: 1.2rem 1.6rem; border-top: 1px solid var(--fd-color-border);\n}\n</style>\n","import type { WidgetProps, SubtableWidgetProps, ColumnConfig } from '@/types'\nimport type { WidgetDefinition } from '../types'\nimport SubtableDesign from './SubtableDesign.vue'\nimport SubtableRender from './SubtableRender.vue'\nimport SubtablePanel from './SubtablePanel.vue'\n\nfunction defaultColnums(): ColumnConfig[] {\n return [\n {\n name: 'field1',\n isshow: 1,\n major: '',\n showname: '字段一',\n showwidth: '',\n background: '',\n prospect: '',\n issum: 0,\n index: 1,\n align: '',\n iscompletehide: 0,\n iscompletehidecode: '',\n issamecolmerge: 0,\n bindLink: '',\n editmode: { editmode: 'text', title: '文本' },\n events: [],\n },\n {\n name: 'field2',\n isshow: 1,\n major: '',\n showname: '字段二',\n showwidth: '',\n background: '',\n prospect: '',\n issum: 0,\n index: 2,\n align: '',\n iscompletehide: 0,\n iscompletehidecode: '',\n issamecolmerge: 0,\n bindLink: '',\n editmode: { editmode: 'text', title: '文本' },\n events: [],\n },\n ]\n}\n\nexport const subtableDefinition: WidgetDefinition = {\n type: 'subtable',\n title: '子表',\n design: SubtableDesign,\n render: SubtableRender,\n panel: SubtablePanel,\n isContainer: false,\n createDefaultProps: (): WidgetProps => ({\n id: '',\n type: 'subtable',\n label: '子表',\n bindField: '',\n firsttable: '',\n secondtable: '',\n primarytablefiled: '',\n secondtableprimarykey: '',\n secondtablerelationfield: '',\n tabletype: 'subtable',\n displaytitle: '',\n tablestyle: 'table',\n isreadonly: '1',\n isnull: '0',\n issave: '0',\n secondtableindex: '0',\n nodatahidetable: '0',\n nodatatitle: '1',\n fixedcolumn: 0,\n tablewidth: 0,\n tableheight: 0,\n iscompletehide: '0',\n iscompletehidecode: '',\n colnums: defaultColnums(),\n events: [],\n } as SubtableWidgetProps),\n serialize: (props: WidgetProps) => props,\n}\n","<script setup lang=\"ts\">\nimport { useDesignerStore } from '@/stores/designer'\nimport type { GridWidgetProps } from '@/types'\n\ndefineProps<{ node: GridWidgetProps }>()\n\nconst store = useDesignerStore()\n</script>\n\n<template>\n <div class=\"fd-grid-design\" :class=\"{ 'is-mobile': store.device === 'mobile' }\">\n <slot name=\"children\" />\n </div>\n</template>\n\n<style scoped>\n.fd-grid-design {\n display: grid;\n grid-template-columns: repeat(24, 1fr);\n align-items: start;\n}\n.fd-grid-design.is-mobile {\n grid-template-columns: 1fr;\n}\n/* 栅栏格内 label 圆角贴合规则见 src/styles/base.css(按行定位类 is-g-corner-* 控制) */\n</style>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport type { WidgetNode, RenderMode, FormMode } from '@/types'\nimport { getWidgetDef } from '@/widgets/registry'\n\nconst props = defineProps<{\n node: WidgetNode\n mode: RenderMode\n /** 运行态表单模式 */\n formMode?: FormMode\n /** 运行态字段值映射(bindField -> value) */\n formData?: Record<string, unknown>\n /** 表单标识(透传给插槽等需要宿主上下文的控件) */\n formId?: string\n}>()\n\n// 显式声明插槽类型:打断递归组件中动态插槽(#[name])作用域参数的自引用推断。\ndefineSlots<Record<string, (scope: any) => any>>()\n\nconst def = computed(() => getWidgetDef(props.node.type))\nconst Comp = computed(() => {\n if (!def.value) return null\n return props.mode === 'design' ? def.value.design : def.value.render\n})\n\nconst valueOf = (bindField?: string) =>\n bindField && props.formData ? props.formData[bindField] : undefined\n</script>\n\n<template>\n <component\n :is=\"Comp\"\n v-if=\"Comp\"\n :node=\"node\"\n :value=\"valueOf(node.bindField)\"\n :form-data=\"formData\"\n v-bind=\"mode === 'render' ? { formMode, formId } : null\"\n >\n <!-- 将父级传入的插槽全部透传给控件组件(业务插槽最终流入 SlotRender) -->\n <template v-for=\"(_, name) in $slots\" :key=\"name\" #[name]=\"scope\">\n <slot :name=\"name\" v-bind=\"scope || {}\" />\n </template>\n\n <!--\n 容器:父级已提供 children 插槽时(设计态 CanvasNode)由上方 v-for 透传;\n 否则回退为内置递归渲染,并继续向下透传插槽与 formId。\n -->\n <template v-if=\"def?.isContainer && !$slots.children\" #children>\n <WidgetHost\n v-for=\"child in node.children\"\n :key=\"child.id\"\n :node=\"child\"\n :mode=\"mode\"\n :form-mode=\"formMode\"\n :form-data=\"formData\"\n :form-id=\"formId\"\n >\n <template v-for=\"(_, name) in $slots\" :key=\"name\" #[name]=\"scope\">\n <slot :name=\"name\" v-bind=\"scope || {}\" />\n </template>\n </WidgetHost>\n </template>\n </component>\n</template>\n","import type { WidgetNode } from '@/types'\n\n/** 栅栏格总列数:PC 24 等分;移动端单列(每项独占一行) */\nconst PC_COLUMNS = 24\n\ninterface ItemFlag {\n /** 所在行号(从 0 开始) */\n row: number\n /** 是否行首(位于该行最左) */\n rowFirst: boolean\n /** 是否行尾(位于该行最右) */\n rowLast: boolean\n}\n\n/**\n * 计算栅栏格子项的圆角定位类名。\n * 结合各子项 gridSpan 模拟换行摆放,得到每个子项所在行与行首/行尾位置,\n * 仅整体表格四角(首行行首/首行行尾/末行行首/末行行尾)对应的\n * label 子项需要 1rem 圆角,其余子项直角拼接。\n */\nexport function gridCornerClass(\n child: WidgetNode,\n index: number,\n siblings: WidgetNode[],\n layout: number,\n mobile = false,\n): string {\n if (child.type !== 'label' || !siblings.length) return ''\n const total = mobile ? 1 : PC_COLUMNS\n const spanOf = (n: WidgetNode): number => Math.min(Math.max(n.gridSpan || layout || total, 1), total)\n\n // 逐个模拟摆放,记录行号与行首/行尾\n const flags: ItemFlag[] = []\n let col = 0\n let row = 0\n for (const n of siblings) {\n const span = spanOf(n)\n if (col + span > total) {\n col = 0\n row++\n }\n const rowFirst = col === 0\n col += span\n const rowLast = col >= total\n flags.push({ row, rowFirst, rowLast })\n if (col >= total) {\n col = 0\n row++\n }\n }\n\n const f = flags[index]\n if (!f) return ''\n const lastRow = flags[flags.length - 1].row\n const isFirstRow = f.row === 0\n const isLastRow = f.row === lastRow\n\n const cls: string[] = []\n if (f.rowFirst && isFirstRow) cls.push('is-g-corner-tl')\n if (f.rowLast && isFirstRow) cls.push('is-g-corner-tr')\n if (f.rowFirst && isLastRow) cls.push('is-g-corner-bl')\n if (f.rowLast && isLastRow) cls.push('is-g-corner-br')\n return cls.join(' ')\n}\n","<script setup lang=\"ts\">\nimport { computed, ref, onMounted, onUnmounted } from 'vue'\nimport { useDesignerStore } from '@/stores/designer'\nimport type { GridWidgetProps, FormMode } from '@/types'\nimport WidgetHost from '@/components/WidgetHost.vue'\nimport { gridCornerClass } from './corner'\n\ndefineProps<{\n node: GridWidgetProps\n formMode?: FormMode\n formData?: Record<string, unknown>\n formId?: string\n}>()\n\nconst designerStore = useDesignerStore()\nconst _mqMobile = ref(false)\nlet _mq: MediaQueryList | null = null\n\nonMounted(() => {\n _mq = window.matchMedia('(max-width: 768px)')\n _mqMobile.value = _mq.matches\n _mq.addEventListener('change', (e) => { _mqMobile.value = e.matches })\n})\nonUnmounted(() => {\n if (_mq) _mq.removeEventListener('change', () => {})\n})\n\nconst isMobile = computed(() => designerStore.device === 'mobile' || _mqMobile.value)\n</script>\n\n<template>\n <div class=\"fd-grid-render\" :class=\"{ 'is-mobile': isMobile }\">\n <div\n v-for=\"(child, ci) in node.children\"\n :key=\"child.id\"\n class=\"fd-grid-cell\"\n :class=\"gridCornerClass(child, ci, node.children || [], node.layout || 24, isMobile)\"\n :style=\"{ gridColumn: `span ${child.gridSpan || node.layout}` }\"\n >\n <WidgetHost :node=\"child\" mode=\"render\" :form-mode=\"formMode\" :form-data=\"formData\" :form-id=\"formId\">\n <template v-for=\"(_, name) in $slots\" :key=\"name\" #[name]=\"scope\">\n <slot :name=\"name\" v-bind=\"scope || {}\" />\n </template>\n </WidgetHost>\n </div>\n </div>\n</template>\n\n<style scoped>\n.fd-grid-render {\n display: grid;\n grid-template-columns: repeat(24, 1fr);\n align-items: start;\n}\n.fd-grid-render.is-mobile {\n grid-template-columns: 1fr;\n}\n.fd-grid-cell {\n min-width: 0;\n}\n/* 栅栏格子项默认无间隔:消除子控件自身的下外边距 */\n.fd-grid-cell > :deep(*) {\n margin-bottom: 0;\n}\n/* 栅栏格内 label 圆角贴合规则见 src/styles/base.css(按行定位类 is-g-corner-* 控制) */\n</style>\n","import type { WidgetProps } from '@/types'\nimport type { WidgetDefinition } from '../types'\nimport GridDesign from './GridDesign.vue'\nimport GridRender from './GridRender.vue'\nimport GridPanel from './GridPanel.vue'\n\nexport const gridDefinition: WidgetDefinition = {\n type: 'grid',\n title: '栅栏格',\n design: GridDesign,\n render: GridRender,\n panel: GridPanel,\n isContainer: true,\n createDefaultProps: (): WidgetProps => ({\n id: '',\n type: 'grid',\n label: '栅栏格',\n bindField: '',\n // 默认 6 列布局\n layout: 8,\n children: [],\n }),\n serialize: (props: WidgetProps) => props,\n}\n","<script setup lang=\"ts\">\nimport type { GridWidgetProps, FieldMeta } from '@/types'\n\nconst props = defineProps<{ node: GridWidgetProps; fields: FieldMeta[] }>()\nconst emit = defineEmits<{ (e: 'update', patch: Partial<GridWidgetProps>): void }>()\n\n/** 布局选项:标签 -> 子组件默认占比(24 栅格制) */\nconst layoutOptions = [\n { label: '2列布局', value: 24 },\n { label: '4列布局', value: 12 },\n { label: '6列布局', value: 8 },\n { label: '8列布局', value: 6 },\n]\n\n/** 一键布局:按当前选中的布局(layout 即每项占比)批量更新所有子组件 */\nfunction applyLayout() {\n const span = props.node.layout || 24\n const children = (props.node.children ?? []).map((c) => ({ ...c, gridSpan: span }))\n emit('update', { children })\n}\n</script>\n\n<template>\n <div class=\"fd-panel\">\n <div class=\"fd-panel-item\">\n <label>布局</label>\n <select :value=\"node.layout\" @change=\"emit('update', { layout: Number(($event.target as HTMLSelectElement).value) })\">\n <option v-for=\"opt in layoutOptions\" :key=\"opt.value\" :value=\"opt.value\">{{ opt.label }}</option>\n </select>\n </div>\n <div class=\"fd-panel-item\">\n <label>一键布局</label>\n <button class=\"fd-btn fd-btn--primary fd-btn--sm fd-grid-apply\" @click=\"applyLayout\">\n 应用到全部子组件(每项占比 {{ node.layout || 24 }}/24)\n </button>\n </div>\n </div>\n</template>\n\n<style scoped>\n.fd-panel {\n display: flex;\n flex-direction: column;\n gap: 1.2rem;\n}\n.fd-panel-item {\n display: flex;\n flex-direction: column;\n gap: 0.4rem;\n}\n.fd-panel-item label {\n font-size: 1.3rem;\n color: var(--fd-color-text-secondary);\n}\n.fd-panel-item select {\n height: 3.2rem;\n padding: 0 1rem;\n border: 1px solid var(--fd-color-border);\n border-radius: var(--fd-radius-base);\n font-size: 1.4rem;\n background: var(--fd-color-bg-panel);\n}\n.fd-grid-apply {\n width: 100%;\n}\n</style>\n","<script setup lang=\"ts\">\nimport type { TextWidgetProps } from '@/types'\n\ndefineProps<{ node: TextWidgetProps }>()\n</script>\n\n<template>\n <div class=\"fd-text-design\" :style=\"{ display: node.display }\">{{ node.text || '文本内容' }}</div>\n</template>\n\n<style scoped>\n.fd-text-design {\n display: inline-block;\n padding: 0.4rem 0;\n font-size: 1.4rem;\n line-height: 1.5;\n color: var(--fd-color-text);\n white-space: pre-wrap;\n word-break: break-word;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport type { TextWidgetProps } from '@/types'\n\nconst props = defineProps<{ node: TextWidgetProps; value?: unknown }>()\n\n/** 绑定字段时展示字段值,未绑定时展示文本内容 */\nconst display = computed(() => {\n if (!props.node.bindField) return props.node.text\n const v = props.value\n return v === undefined || v === null ? '' : String(v)\n})\n</script>\n\n<template>\n <div class=\"fd-text-render\" :style=\"{ display: node.display }\">{{ display }}</div>\n</template>\n\n<style scoped>\n.fd-text-render {\n display: inline-block;\n padding: 0.4rem 0;\n font-size: 1.4rem;\n line-height: 1.5;\n color: var(--fd-color-text);\n white-space: pre-wrap;\n word-break: break-word;\n}\n</style>\n","import type { WidgetProps } from '@/types'\nimport type { WidgetDefinition } from '../types'\nimport TextDesign from './TextDesign.vue'\nimport TextRender from './TextRender.vue'\nimport TextPanel from './TextPanel.vue'\n\nexport const textDefinition: WidgetDefinition = {\n type: 'text',\n title: '文本',\n design: TextDesign,\n render: TextRender,\n panel: TextPanel,\n isContainer: false,\n createDefaultProps: (): WidgetProps => ({\n id: '',\n type: 'text',\n label: '文本',\n bindField: '',\n text: '文本内容',\n display: 'inline-block',\n }),\n serialize: (props: WidgetProps) => props,\n}\n","<script setup lang=\"ts\">\nimport type { TextWidgetProps, FieldMeta } from '@/types'\n\ndefineProps<{ node: TextWidgetProps; fields: FieldMeta[] }>()\nconst emit = defineEmits<{ (e: 'update', patch: Partial<TextWidgetProps>): void }>()\n</script>\n\n<template>\n <div class=\"fd-panel\">\n <div class=\"fd-panel-item\">\n <label>文本</label>\n <textarea\n rows=\"4\"\n :value=\"node.text\"\n @input=\"emit('update', { text: ($event.target as HTMLTextAreaElement).value })\"\n />\n </div>\n <div class=\"fd-panel-item\">\n <label>绑定字段</label>\n <select :value=\"node.bindField\" @change=\"emit('update', { bindField: ($event.target as HTMLSelectElement).value })\">\n <option value=\"\">不绑定</option>\n <option v-for=\"f in fields\" :key=\"f.name\" :value=\"f.name\">{{ f.label }}({{ f.name }})</option>\n </select>\n </div>\n <div class=\"fd-panel-item\">\n <label>对齐方式</label>\n <select\n :value=\"node.display\"\n @change=\"emit('update', { display: ($event.target as HTMLSelectElement).value as TextWidgetProps['display'] })\"\n >\n <option value=\"inline-block\">对齐</option>\n <option value=\"block\">换行</option>\n </select>\n </div>\n </div>\n</template>\n\n<style scoped>\n.fd-panel {\n display: flex;\n flex-direction: column;\n gap: 1.2rem;\n}\n.fd-panel-item {\n display: flex;\n flex-direction: column;\n gap: 0.4rem;\n}\n.fd-panel-item label {\n font-size: 1.3rem;\n color: var(--fd-color-text-secondary);\n}\n.fd-panel-item textarea,\n.fd-panel-item select {\n padding: 0.8rem 1rem;\n border: 1px solid var(--fd-color-border);\n border-radius: var(--fd-radius-base);\n font-size: 1.4rem;\n font-family: inherit;\n line-height: 1.5;\n background: var(--fd-color-bg-panel);\n}\n.fd-panel-item textarea {\n resize: vertical;\n}\n.fd-panel-item select {\n height: 3.2rem;\n}\n</style>\n","import { registerComponent } from './registry'\nimport { labelDefinition } from './label'\nimport { cardDefinition } from './card'\nimport { slotDefinition } from './slot'\nimport { subtableDefinition } from './subtable'\nimport { gridDefinition } from './grid'\nimport { textDefinition } from './text'\n\nlet registered = false\n\n/** 注册内置控件(幂等) */\nexport function registerBuiltinWidgets(): void {\n if (registered) return\n registered = true\n registerComponent(labelDefinition)\n registerComponent(cardDefinition)\n registerComponent(slotDefinition)\n registerComponent(subtableDefinition)\n registerComponent(gridDefinition)\n registerComponent(textDefinition)\n}\n\nexport * from './registry'\nexport * from './types'\n\n// 模块加载即注册内置控件,保证直接使用 Designer/Renderer(未走插件 install)时控件可用\nregisterBuiltinWidgets()\n","import { defineStore } from 'pinia'\nimport type {\n WidgetType,\n WidgetNode,\n FieldMeta,\n FormSchema,\n FormEvents,\n LifecycleHook,\n CustomEvent,\n} from '@/types'\nimport { createWidget, getWidgetDef } from '@/widgets'\n\nconst clone = <T>(v: T): T => JSON.parse(JSON.stringify(v))\n\ninterface State {\n formId: string\n dbtable: string\n fields: FieldMeta[]\n widgets: WidgetNode[]\n selectedId: string | null\n past: WidgetNode[][]\n future: WidgetNode[][]\n /** 拖拽来源 id(设计器内部拖拽用) */\n draggingId: string | null\n /** 画布设备预览(仅影响宽度,不进 Schema) */\n device: 'pc' | 'mobile'\n /** 拖拽插入指示:目标节点 id 与是否插在其前 */\n dragOverId: string | null\n dragBefore: boolean\n /** 拖拽放入容器高亮 */\n dropContainerId: string | null\n /** 是否选中「表单」本身(点击画板空白处) */\n selectedForm: boolean\n /** 表单级事件配置(全局事件) */\n events: FormEvents\n /** 是否由 formId 参数(prop / 路径)打开,决定保存时覆盖还是新建 */\n openedWithParam: boolean\n}\n\nfunction findNode(list: WidgetNode[], id: string): WidgetNode | null {\n for (const n of list) {\n if (n.id === id) return n\n if (n.children) {\n const f = findNode(n.children, id)\n if (f) return f\n }\n }\n return null\n}\n\nfunction removeNode(list: WidgetNode[], id: string): boolean {\n const i = list.findIndex((n) => n.id === id)\n if (i >= 0) {\n list.splice(i, 1)\n return true\n }\n for (const n of list) {\n if (n.children && removeNode(n.children, id)) return true\n }\n return false\n}\n\n/**\n * 显式声明 getters / actions 形状:\n * pinia 对 options store 的推断类型过大,生成 d.ts 时会触发 TS7056\n * (推断类型超出编译器序列化上限),故通过显式泛型参数固定 store 类型。\n */\ntype DesignerGetters = {\n selectedNode: (state: State) => WidgetNode | null\n canUndo: (state: State) => boolean\n canRedo: (state: State) => boolean\n customEventOptions: (state: State) => CustomEvent[]\n}\n\ninterface DesignerActions {\n commit(): void\n undo(): void\n redo(): void\n select(id: string | null): void\n selectForm(): void\n setLifecycleHook(hook: LifecycleHook, code: string): void\n addCustomEvent(): void\n updateCustomEvent(index: number, patch: Partial<CustomEvent>): void\n removeCustomEvent(index: number): void\n addWidget(type: WidgetType, parentId?: string | null, index?: number): void\n isDescendant(node: WidgetNode, maybeChildId: string): boolean\n moveNode(id: string, toParentId: string | null, index: number): void\n removeWidget(id: string): void\n moveSibling(id: string, delta: number): void\n updateNode(id: string, patch: Record<string, unknown>): void\n setDragging(id: string | null): void\n setExpanded(id: string, expanded: boolean): void\n dropTo(targetId: string | null): void\n loadSchema(schema: FormSchema): void\n toSchema(): FormSchema\n setFields(fields: FieldMeta[]): void\n}\n\nexport const useDesignerStore = defineStore<'designer', State, DesignerGetters, DesignerActions>('designer', {\n state: (): State => ({\n formId: 'SG_ZL_YYQHTSP',\n dbtable: 'SG_ZL_YYQHTSP',\n fields: [],\n widgets: [],\n selectedId: null,\n past: [],\n future: [],\n draggingId: null,\n device: 'pc',\n dragOverId: null,\n dragBefore: false,\n dropContainerId: null,\n selectedForm: false,\n events: { lifecycle: {}, custom: [] },\n openedWithParam: false,\n }),\n getters: {\n selectedNode: (s): WidgetNode | null => (s.selectedId ? findNode(s.widgets, s.selectedId) : null),\n canUndo: (s) => s.past.length > 0,\n canRedo: (s) => s.future.length > 0,\n /** 供控件「事件」下拉选择使用的自定义事件列表 */\n customEventOptions: (s): CustomEvent[] => s.events.custom,\n },\n actions: {\n /** 提交一次变更快照(用于撤销重做) */\n commit() {\n this.past.push(clone(this.widgets))\n if (this.past.length > 50) this.past.shift()\n this.future = []\n },\n undo() {\n const prev = this.past.pop()\n if (!prev) return\n this.future.push(clone(this.widgets))\n this.widgets = prev\n if (this.selectedId && !findNode(this.widgets, this.selectedId)) this.selectedId = null\n },\n redo() {\n const next = this.future.pop()\n if (!next) return\n this.past.push(clone(this.widgets))\n this.widgets = next\n },\n select(id: string | null) {\n this.selectedId = id\n this.selectedForm = false\n },\n /** 点击画板空白处:选中表单本身(用于配置表单级属性) */\n selectForm() {\n this.selectedId = null\n this.selectedForm = true\n },\n /** 设置生命周期事件代码片段 */\n setLifecycleHook(hook: LifecycleHook, code: string) {\n this.events.lifecycle[hook] = code\n },\n /** 新增一条自定义事件(默认占位) */\n addCustomEvent() {\n const n = this.events.custom.length + 1\n this.events.custom.push({ name: `event_${n}`, title: `自定义事件${n}`, handler: '' })\n },\n /** 更新某条自定义事件 */\n updateCustomEvent(index: number, patch: Partial<CustomEvent>) {\n const item = this.events.custom[index]\n if (item) Object.assign(item, patch)\n },\n /** 删除某条自定义事件 */\n removeCustomEvent(index: number) {\n this.events.custom.splice(index, 1)\n },\n /** 新增控件:parentId 指定容器,index 指定插入位置(不传则末尾) */\n addWidget(type: WidgetType, parentId?: string | null, index?: number) {\n const node = createWidget(type) as WidgetNode\n this.commit()\n const parent = parentId ? findNode(this.widgets, parentId) : null\n if (parent && getWidgetDef(parent.type)?.isContainer) {\n parent.children = parent.children || []\n // 拖入栅栏格:默认占比 = 栅栏格布局\n if (parent.type === 'grid' && node.gridSpan == null) {\n node.gridSpan = (parent as { layout?: number }).layout || 24\n }\n if (index == null || index > parent.children.length) parent.children.push(node)\n else parent.children.splice(Math.max(0, index), 0, node)\n } else {\n if (index == null || index > this.widgets.length) this.widgets.push(node)\n else this.widgets.splice(Math.max(0, index), 0, node)\n }\n this.selectedId = node.id\n },\n /** 判断 maybeChild 是否为 node 的后代(防止把容器拖进自己) */\n isDescendant(node: WidgetNode, maybeChildId: string): boolean {\n if (!node.children) return false\n for (const c of node.children) {\n if (c.id === maybeChildId) return true\n if (this.isDescendant(c, maybeChildId)) return true\n }\n return false\n },\n /** 移动已有控件到指定容器 / 根,插入位置 index */\n moveNode(id: string, toParentId: string | null, index: number) {\n if (id === toParentId) return\n const srcNode = findNode(this.widgets, id)\n if (!srcNode) return\n // 不能把节点拖入它自己的后代(否则形成循环);同容器内重排是允许的\n if (toParentId && this.isDescendant(srcNode, toParentId)) return\n const target = toParentId ? findNode(this.widgets, toParentId) : null\n\n // 定位源节点所在的兄弟列表与下标\n const locate = (list: WidgetNode[]): { list: WidgetNode[]; index: number } | null => {\n const i = list.findIndex((n) => n.id === id)\n if (i >= 0) return { list, index: i }\n for (const n of list) {\n if (n.children) {\n const r = locate(n.children)\n if (r) return r\n }\n }\n return null\n }\n const src = locate(this.widgets)\n if (!src) return\n\n // 目标兄弟列表\n let destList: WidgetNode[]\n if (target && getWidgetDef(target.type)?.isContainer) {\n target.children = target.children || []\n destList = target.children\n } else {\n destList = this.widgets\n }\n\n this.commit()\n // 同一列表内移动:源在插入点之前时,先移除源会使目标下标前移一位\n let idx = index\n if (destList === src.list && src.index < index) idx = index - 1\n const [node] = src.list.splice(src.index, 1)\n idx = Math.max(0, Math.min(idx, destList.length))\n destList.splice(idx, 0, node)\n // 栅栏格内保留/初始化「占比」;移出栅栏格则清除\n if (target && target.type === 'grid') {\n const def = (target as { layout?: number }).layout || 24\n // 从别处进入栅栏格 → 取目标栅栏格布局;格内重排 → 保留手动占比\n if (src.list !== destList || node.gridSpan == null) node.gridSpan = def\n } else {\n delete node.gridSpan\n }\n this.selectedId = node.id\n },\n removeWidget(id: string) {\n this.commit()\n removeNode(this.widgets, id)\n if (this.selectedId === id) this.selectedId = null\n },\n moveSibling(id: string, delta: number) {\n const findParent = (list: WidgetNode[]): WidgetNode[] | null => {\n const i = list.findIndex((n) => n.id === id)\n if (i >= 0) return list\n for (const n of list) {\n if (n.children) {\n const r = findParent(n.children)\n if (r) return r\n }\n }\n return null\n }\n const parent = findParent(this.widgets)\n if (!parent) return\n const i = parent.findIndex((n) => n.id === id)\n const j = i + delta\n if (j < 0 || j >= parent.length) return\n this.commit()\n const [item] = parent.splice(i, 1)\n parent.splice(j, 0, item)\n },\n updateNode(id: string, patch: Record<string, unknown>) {\n const node = findNode(this.widgets, id)\n if (!node) return\n Object.assign(node, patch)\n // 子节点整体替换(属性面板传 colnums 等)\n this.commit()\n },\n setDragging(id: string | null) {\n this.draggingId = id\n },\n /** 展开/收起容器(设计器视图操作,不写入撤销历史) */\n setExpanded(id: string, expanded: boolean) {\n const node = findNode(this.widgets, id)\n if (node && 'expanded' in node) node.expanded = expanded\n },\n /** 将 draggingId 控件移动到 targetId(容器)或根 */\n dropTo(targetId: string | null) {\n const dragId = this.draggingId\n if (!dragId) return\n if (dragId === targetId) return\n this.commit()\n const detach = (list: WidgetNode[]): WidgetNode | null => {\n const i = list.findIndex((n) => n.id === dragId)\n if (i >= 0) {\n const [found] = list.splice(i, 1)\n return found\n }\n for (const n of list) {\n if (n.children) {\n const found = detach(n.children)\n if (found) return found\n }\n }\n return null\n }\n const node = detach(this.widgets)\n if (!node) {\n this.draggingId = null\n return\n }\n if (targetId) {\n const target = findNode(this.widgets, targetId)\n if (target && getWidgetDef(target.type)?.isContainer) {\n target.children = target.children || []\n target.children.push(node)\n } else {\n this.widgets.push(node)\n }\n } else {\n this.widgets.push(node)\n }\n this.draggingId = null\n this.selectedId = node.id\n },\n loadSchema(schema: FormSchema) {\n this.formId = schema.formId\n this.dbtable = schema.dbtable\n this.fields = schema.fields\n this.widgets = clone(schema.widgets)\n this.events = schema.events ? clone(schema.events) : { lifecycle: {}, custom: [] }\n this.selectedId = null\n this.selectedForm = false\n this.past = []\n this.future = []\n },\n toSchema(): FormSchema {\n return {\n formId: this.formId,\n dbtable: this.dbtable,\n fields: this.fields,\n widgets: this.widgets,\n events: clone(this.events),\n }\n },\n setFields(fields: FieldMeta[]) {\n this.fields = fields\n },\n },\n})\n","import type { FormSchema } from '@/types'\nimport { mockSchema } from './mock'\n\n/**\n * 接口模块动态配置(四级优先级:props > install options > setApiModule > 默认值)\n */\ninterface ApiConfig {\n baseModule: string\n apiModule: string\n}\nconst DEFAULT: ApiConfig = { baseModule: '', apiModule: 'form-designer' }\nlet runtime: Partial<ApiConfig> = {}\nlet installOptions: Partial<ApiConfig> = {}\n/** props 由调用方在每次请求时传入,优先级最高 */\nlet propsOverride: Partial<ApiConfig> = {}\n\nexport function configureApi(options: Partial<ApiConfig>): void {\n installOptions = { ...installOptions, ...options }\n}\n\nexport function setApiModule(module: string): void {\n runtime.apiModule = module\n}\n\nexport function setBaseModule(module: string): void {\n runtime.baseModule = module\n}\n\nexport function setApiProps(props: Partial<ApiConfig>): void {\n propsOverride = props\n}\n\n/** 计算最终取值(高 -> 低) */\nexport function resolveApiConfig(): ApiConfig {\n return {\n baseModule: propsOverride.baseModule ?? runtime.baseModule ?? installOptions.baseModule ?? DEFAULT.baseModule,\n apiModule: propsOverride.apiModule ?? runtime.apiModule ?? installOptions.apiModule ?? DEFAULT.apiModule,\n }\n}\n\n/** 拼装请求路径:{baseModule}/api/{apiModule}/{action}/{id} */\nexport function buildUrl(action: string, id = ''): string {\n const { baseModule, apiModule } = resolveApiConfig()\n const base = baseModule ? `/${baseModule}` : ''\n return `${base}/api/${apiModule}/${action}${id ? `/${id}` : ''}`\n}\n\n/**\n * 获取表单 JSON Schema(初版 mock,后续替换为真实请求)\n */\nexport async function getSchema(formId: string, props?: Partial<ApiConfig>): Promise<FormSchema> {\n if (props) setApiProps(props)\n const url = buildUrl('getschema', formId)\n // TODO: 对接后端时替换为真实请求:return http.get(url)\n void url\n return JSON.parse(JSON.stringify(mockSchema(formId)))\n}\n\n/**\n * 保存表单 Schema\n */\nexport async function saveSchema(schema: FormSchema, props?: Partial<ApiConfig>): Promise<void> {\n if (props) setApiProps(props)\n const url = buildUrl('saveschema', schema.formId)\n // TODO: 对接后端时替换为真实请求:return http.post(url, schema)\n void url\n void schema\n}\n","import type { FormSchema } from '@/types'\n\n/** 本地存储 key 前缀 */\nconst KEY_PREFIX = 'fd:form:'\n\n/** 生成 GUID(RFC4122 v4),优先使用原生 crypto.randomUUID */\nexport function genGuid(): string {\n if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {\n return crypto.randomUUID()\n }\n // 降级实现\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {\n const r = (Math.random() * 16) | 0\n const v = c === 'x' ? r : (r & 0x3) | 0x8\n return v.toString(16)\n })\n}\n\n/** 将表单 Schema 存至本地(key 为 formId) */\nexport function saveFormToLocal(formId: string, schema: FormSchema): void {\n localStorage.setItem(KEY_PREFIX + formId, JSON.stringify(schema))\n}\n\n/** 从本地读取表单 Schema;不存在或解析失败返回 null */\nexport function loadFormFromLocal(formId: string): FormSchema | null {\n const raw = localStorage.getItem(KEY_PREFIX + formId)\n if (!raw) return null\n try {\n return JSON.parse(raw) as FormSchema\n } catch {\n return null\n }\n}\n","/**\n * 表单事件处理代码片段的安全执行器。\n * handler 为设计态编写的代码字符串,运行态在此沙箱内执行,避免直接 eval 散落各处。\n */\n\n/** 注入 key:自定义事件触发器,运行态组件可通过 inject 调用 */\nexport const INJECT_FIRE_EVENT = 'fdFireEvent'\n\nexport interface HandlerContext {\n /** 表单数据(bindField -> value) */\n formData?: Record<string, unknown>\n /** 触发事件名(自定义事件) */\n event?: string\n /** 变化字段名(onValueChange) */\n field?: string\n /** 变化后的值(onValueChange) */\n value?: unknown\n /** 透传给业务的其他上下文 */\n [key: string]: unknown\n}\n\nexport function runHandler(code: string | undefined, ctx: HandlerContext = {}): unknown {\n if (!code || !code.trim()) return undefined\n try {\n // 以 ctx 为唯一入参,严格模式隔离全局污染\n const fn = new Function('ctx', `\"use strict\";\\n${code}`)\n return fn(ctx)\n } catch (e) {\n console.error('[form-designer] 事件处理函数执行失败:', e)\n return undefined\n }\n}\n\n/**\n * 执行「自定义方法」代码:将代码作为独立 <script> 注入文档执行,\n * 顶层的 function 声明会挂载为 window 上的全局方法,\n * 从而可在其他事件处理代码中直接调用(如 myMethod(ctx))。\n * 脚本同步执行后即移除节点,已挂载的方法不受影响。\n *\n * 注意:不能用 new Function 包裹——函数声明只存在于该函数作用域,不会挂载全局。\n */\nexport function mountGlobalMethods(code: string | undefined): void {\n if (!code || !code.trim() || typeof document === 'undefined') return\n try {\n const script = document.createElement('script')\n script.text = code\n document.head.appendChild(script)\n // 同步执行已完成,移除节点(顶层函数声明已挂至 window)\n script.remove()\n } catch (e) {\n console.error('[form-designer] 自定义方法挂载失败:', e)\n }\n}\n","<script setup lang=\"ts\">\nimport { computed, onMounted, provide, watch } from 'vue'\nimport type { WidgetNode, FormMode, FormEvents, LifecycleHook } from '@/types'\nimport { getWidgetDef } from '@/widgets'\nimport WidgetHost from '@/components/WidgetHost.vue'\nimport { runHandler, mountGlobalMethods, INJECT_FIRE_EVENT } from '@/utils/formEvents'\n\nconst props = defineProps<{\n widgets: WidgetNode[]\n formMode?: FormMode\n formData?: Record<string, unknown>\n /** 表单级事件配置(全局事件),由宿主从 Schema 透传 */\n events?: FormEvents\n /** 表单标识(透传给插槽等需要宿主上下文的控件) */\n formId?: string\n}>()\n\n/** 按控件声明的 visibleModes 做粗粒度显隐控制 */\nconst visibleWidgets = computed(() =>\n props.widgets.filter((node) => {\n const modes = getWidgetDef(node.type)?.visibleModes\n if (!modes || modes.length === 0) return true\n return props.formMode ? modes.includes(props.formMode) : true\n }),\n)\n\n/** 运行指定生命周期钩子 */\nfunction runLifecycle(hook: LifecycleHook): void {\n const code = props.events?.lifecycle[hook]\n runHandler(code, { formData: props.formData, event: hook })\n}\n\n/** 触发自定义事件:执行对应 name 的 handler */\nfunction fireEvent(name: string, payload?: unknown): void {\n const ev = props.events?.custom.find((e) => e.name === name)\n if (!ev) return\n runHandler(ev.handler, { formData: props.formData, event: name, payload })\n}\n\n// 渲染时绑定至对应钩子函数\nprovide(INJECT_FIRE_EVENT, fireEvent)\nonMounted(() => {\n runLifecycle('onLoad')\n runLifecycle('onMounted')\n // 自定义方法:代码中声明的方法挂载至 window,供其他事件处理调用\n mountGlobalMethods(props.events?.lifecycle.custom)\n})\nwatch(\n () => props.formData,\n () => runLifecycle('onValueChange'),\n { deep: true },\n)\n\ndefineExpose({ fireEvent, runLifecycle })\n</script>\n\n<template>\n <div class=\"fd-renderer\">\n <WidgetHost\n v-for=\"node in visibleWidgets\"\n :key=\"node.id\"\n :node=\"node\"\n mode=\"render\"\n :form-mode=\"formMode\"\n :form-data=\"formData\"\n :form-id=\"formId\"\n >\n <!-- 将宿主传入的命名插槽透传给每个控件(插槽控件最终以 <slot> 消费) -->\n <template v-for=\"(_, name) in $slots\" :key=\"name\" #[name]=\"scope\">\n <slot :name=\"name\" v-bind=\"scope || {}\" />\n </template>\n </WidgetHost>\n </div>\n</template>\n\n<style scoped>\n.fd-renderer {\n display: block;\n padding: 1.6rem;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed, nextTick } from 'vue'\nimport { ElTree } from 'element-plus'\nimport 'element-plus/es/components/tree/style/css'\nimport { useDesignerStore } from '@/stores/designer'\nimport { getWidgetDef } from '@/widgets'\nimport type { WidgetNode } from '@/types'\n\ninterface TreeNode {\n id: string\n label: string\n name: string\n sub: string\n children?: TreeNode[]\n}\n\nconst store = useDesignerStore()\n\n/** 控件节点 -> ElTree 节点 */\nfunction toTreeNode(node: WidgetNode): TreeNode {\n const def = getWidgetDef(node.type)\n const label = (node as { label?: string }).label\n const name = def?.title ?? node.type\n return {\n id: node.id,\n label: label ? `${name} · ${label}` : name,\n name,\n sub: label ?? '',\n children: node.children?.map(toTreeNode),\n }\n}\n\nconst treeData = computed<TreeNode[]>(() => store.widgets.map(toTreeNode))\n\n/** 递归统计节点总数 */\nconst totalCount = computed(() => {\n const walk = (list: WidgetNode[]): number =>\n list.reduce((n, x) => n + 1 + walk(x.children ?? []), 0)\n return walk(store.widgets)\n})\n\n/** 点击节点:选中对应控件,并将画布滚动至该组件处 */\nfunction onNodeClick(data: TreeNode) {\n store.select(data.id)\n nextTick(() => {\n document\n .querySelector('.fd-canvas-node.is-selected')\n ?.scrollIntoView({ block: 'nearest' })\n })\n}\n</script>\n\n<template>\n <div class=\"fd-tree\">\n <div class=\"fd-tree-head\">\n <svg class=\"fd-tree-head-icon\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <rect x=\"3\" y=\"3\" width=\"7\" height=\"7\" rx=\"1\" />\n <rect x=\"14\" y=\"3\" width=\"7\" height=\"7\" rx=\"1\" />\n <rect x=\"3\" y=\"14\" width=\"7\" height=\"7\" rx=\"1\" />\n <rect x=\"14\" y=\"14\" width=\"7\" height=\"7\" rx=\"1\" />\n </svg>\n <span class=\"fd-tree-title\">组件树</span>\n <span v-if=\"totalCount\" class=\"fd-tree-count\">{{ totalCount }}</span>\n </div>\n\n <div v-if=\"!totalCount\" class=\"fd-tree-empty\">\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4\" />\n <polyline points=\"17 8 12 3 7 8\" />\n <line x1=\"12\" y1=\"3\" x2=\"12\" y2=\"15\" />\n </svg>\n <span>暂无组件,从左侧拖拽控件到画布</span>\n </div>\n\n <el-tree\n v-else\n class=\"fd-tree-el\"\n :data=\"treeData\"\n node-key=\"id\"\n :current-node-key=\"store.selectedId || ''\"\n highlight-current\n default-expand-all\n show-line\n :expand-on-click-node=\"false\"\n @node-click=\"onNodeClick\"\n >\n <template #default=\"{ data }\">\n <span class=\"fd-tree-name\">{{ data.name }}</span>\n <span v-if=\"data.sub\" class=\"fd-tree-sub\" :title=\"data.sub\">{{ data.sub }}</span>\n </template>\n </el-tree>\n </div>\n</template>\n\n<style scoped>\n.fd-tree {\n padding: 1.2rem;\n height: 100%;\n overflow: auto;\n display: flex;\n flex-direction: column;\n}\n\n/* ===== 头部:图标 + 标题 + 计数 ===== */\n.fd-tree-head {\n display: flex;\n align-items: center;\n gap: 0.8rem;\n padding: 0 0.4rem 0.8rem;\n margin-bottom: 0.8rem;\n border-bottom: 1px solid var(--fd-color-border);\n flex-shrink: 0;\n}\n.fd-tree-head-icon {\n width: 1.6rem;\n height: 1.6rem;\n color: var(--fd-color-primary);\n flex-shrink: 0;\n}\n.fd-tree-title {\n font-weight: 600;\n font-size: 1.5rem;\n}\n.fd-tree-count {\n margin-left: auto;\n padding: 0.1rem 0.7rem;\n border-radius: 1rem;\n font-size: 1.2rem;\n color: var(--fd-color-text-tertiary);\n background: var(--fd-color-info-light);\n}\n\n/* ===== 空状态 ===== */\n.fd-tree-empty {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 0.8rem;\n padding: 4rem 2rem;\n color: var(--fd-color-text-tertiary);\n font-size: 1.3rem;\n text-align: center;\n}\n.fd-tree-empty svg {\n width: 3.2rem;\n height: 3.2rem;\n opacity: 0.6;\n}\n\n/* ===== ElTree:贴合项目主题 ===== */\n.fd-tree-el {\n background: transparent;\n --el-tree-node-hover-bg-color: transparent;\n}\n/* 行高与圆角 */\n.fd-tree-el :deep(.el-tree-node__content) {\n height: auto;\n min-height: 2.8rem;\n border-radius: var(--fd-radius-base);\n padding-left: 0.4rem;\n}\n.fd-tree-el :deep(.el-tree-node__content:hover) {\n background: var(--fd-color-info-light);\n}\n/* 选中态:主题色浅底 + 主题色文字 */\n.fd-tree-el :deep(.el-tree-node.is-current > .el-tree-node__content) {\n background: var(--fd-color-primary-light);\n color: var(--fd-color-primary);\n}\n/* 展开图标配色 */\n.fd-tree-el :deep(.el-tree-node__expand-icon) {\n color: var(--fd-color-text-tertiary);\n}\n.fd-tree-el :deep(.el-tree-node.is-current > .el-tree-node__content .el-tree-node__expand-icon) {\n color: var(--fd-color-primary);\n}\n\n/* ===== 自定义节点内容:名称 + 次级 label ===== */\n.fd-tree-name {\n font-size: 1.3rem;\n}\n.fd-tree-sub {\n margin-left: 0.6rem;\n color: var(--fd-color-text-tertiary);\n font-size: 1.2rem;\n max-width: 12rem;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.el-tree-node.is-current > .el-tree-node__content .fd-tree-sub {\n color: var(--fd-color-primary);\n opacity: 0.75;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed, ref, watch, onMounted, onBeforeUnmount } from 'vue'\nimport { ElInputNumber } from 'element-plus'\nimport 'element-plus/es/components/input-number/style/css'\nimport { useDesignerStore } from '@/stores/designer'\nimport { getSchema } from '@/api'\nimport { genGuid, saveFormToLocal, loadFormFromLocal } from '@/storage/formStorage'\nimport Renderer from '@/components/renderer/Renderer.vue'\nimport ComponentTree from './ComponentTree.vue'\nimport type { WidgetNode } from '@/types'\n\nconst store = useDesignerStore()\n\n/** 暗色主题开关(作用于根元素 data-theme) */\n// const dark = ref(false)\n// function toggleDark() {\n// dark.value = !dark.value\n// document.documentElement.dataset.theme = dark.value ? 'dark' : ''\n// }\n\n/** 弹层控制 */\nconst showPreview = ref(false)\nconst showCode = ref(false)\nconst showTree = ref(false)\nconst showImport = ref(false)\n\n/**\n * 预览区宽度设置(px,270 ~ 1200):\n * 默认值随 templateType 模式——电脑端 1200,移动端 375。\n */\nfunction isMobileTemplate(): boolean {\n const t = new URLSearchParams(window.location.search).get('templateType') || ''\n return t === 'mobile' || t === '2'\n}\nconst previewWidth = ref(isMobileTemplate() ? 375 : 1200)\nfunction clampPreviewWidth() {\n const w = Number(previewWidth.value)\n previewWidth.value = Math.min(1200, Math.max(270, Number.isFinite(w) ? w : 1200))\n}\n\n/** 接口下发的模板类型决定设备比例后,预览宽度重置为对应设备默认值(用户可再手动调整) */\nwatch(\n () => store.device,\n (device) => {\n previewWidth.value = device === 'mobile' ? 375 : 1200\n }\n)\n\n/** 导入弹层:粘贴的 JSON 文本 */\nconst importText = ref('')\n\n/** 导入确认:解析粘贴的 JSON 并覆盖当前表单 */\nfunction onImportConfirm() {\n const text = importText.value.trim()\n if (!text) {\n window.alert('请先粘贴表单 JSON')\n return\n }\n try {\n store.loadSchema(JSON.parse(text))\n } catch {\n window.alert('JSON 解析失败')\n return\n }\n importText.value = ''\n showImport.value = false\n}\n\nconst codeJson = computed(() => JSON.stringify(store.toSchema(), null, 2))\n\n/**\n * 预览用运行态数据:\n * - 顶层字段:值取字段名本身作为占位,不填充「示例xxx」等假数据;\n * - 子表:按 secondtable 生成预览行,每列单元格值取列绑定字段名(col.name);\n * 预览不传 formMode,所有表单内容均展示。\n */\nconst mockFormData = computed<Record<string, unknown>>(() => {\n const data: Record<string, unknown> = {}\n store.fields.forEach((f) => {\n data[f.name] = f.name\n })\n // 递归收集子表控件(含容器嵌套),生成预览行数据\n const collectSubtables = (list: WidgetNode[], out: WidgetNode[]): WidgetNode[] => {\n list.forEach((n) => {\n if (n.type === 'subtable') out.push(n)\n if (n.children?.length) collectSubtables(n.children, out)\n })\n return out\n }\n collectSubtables(store.widgets, []).forEach((node) => {\n if (node.type !== 'subtable' || !node.secondtable) return\n const row: Record<string, unknown> = {}\n ;(node.colnums ?? []).forEach((c) => {\n row[c.name] = c.name\n // 列绑定了链接字段时同步填值,保证预览中链接列按链接渲染(高亮可点)\n if (c.bindLink) row[c.bindLink] = c.bindLink\n })\n data[node.secondtable] = [row]\n })\n return data\n})\n\nasync function onSave() {\n // 保存:已有 id(含由 formId 参数打开)则覆盖;全新表单则生成 GUID\n let id = store.formId\n if (!store.openedWithParam && !id) {\n id = genGuid()\n }\n store.formId = id\n saveFormToLocal(id, store.toSchema())\n store.openedWithParam = true\n window.alert(`已保存(本地)\\nformId: ${id}`)\n}\n\n/** 另存为:始终以新 GUID 存至本地;有 formId 参数时为复制保留原表单,无参数时为新表单 */\nfunction onSaveAs() {\n const id = genGuid()\n store.formId = id\n store.openedWithParam = true\n saveFormToLocal(id, store.toSchema())\n window.alert(`已另存为新表单(本地)\\nformId: ${id}`)\n}\n\nasync function onReload() {\n const local = loadFormFromLocal(store.formId)\n if (local) {\n store.loadSchema(local)\n } else {\n const schema = await getSchema(store.formId)\n store.loadSchema(schema)\n }\n}\n\nfunction onPublish() {\n window.alert('发布成功(mock)')\n}\n\n/** 组件树抽屉:打开时点击抽屉与触发按钮之外的区域关闭(不用全屏遮罩,避免拦截页面滚动) */\nconst treeDrawerRef = ref<HTMLElement | null>(null)\nconst treeBtnRef = ref<HTMLElement | null>(null)\nfunction onDocClick(e: MouseEvent) {\n if (!showTree.value) return\n const target = e.target as Node\n if (treeDrawerRef.value?.contains(target)) return\n if (treeBtnRef.value?.contains(target)) return\n showTree.value = false\n}\nonMounted(() => document.addEventListener('click', onDocClick))\nonBeforeUnmount(() => document.removeEventListener('click', onDocClick))\n</script>\n\n<template>\n <div class=\"fd-toolbar\">\n <div class=\"fd-toolbar-left flex-align-center\">\n <span class=\"fd-toolbar-title\">表单设计器</span>\n <input class=\"fd-toolbar-name\" :value=\"store.formId\" @input=\"store.formId = ($event.target as HTMLInputElement).value\" />\n <!-- 电脑端/移动端比例:由 URL query templateType 决定,此处仅展示当前比例 -->\n <!-- 电脑端/移动端比例:由 URL query templateType 决定,仅显示当前模式标识,不支持手动切换 -->\n <div class=\"fd-device\">\n <button v-if=\"store.device === 'mobile'\" class=\"is-active\" title=\"移动端比例(由 URL 参数 templateType 决定)\">\n <svg class=\"fd-tool-btn-icon\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <rect x=\"5\" y=\"2\" width=\"14\" height=\"20\" rx=\"2\" />\n <line x1=\"12\" y1=\"18\" x2=\"12.01\" y2=\"18\" />\n </svg>\n 移动端\n </button>\n <button v-else class=\"is-active\" title=\"电脑端比例(由 URL 参数 templateType 决定)\">\n <svg class=\"fd-tool-btn-icon\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <rect x=\"2\" y=\"3\" width=\"20\" height=\"14\" rx=\"2\" />\n <line x1=\"8\" y1=\"21\" x2=\"16\" y2=\"21\" />\n <line x1=\"12\" y1=\"17\" x2=\"12\" y2=\"21\" />\n </svg>\n 电脑端\n </button>\n </div>\n </div>\n <div class=\"fd-toolbar-right flex-align-center\">\n <button class=\"fd-tool-btn\" @click=\"showPreview = true\">\n <svg class=\"fd-tool-btn-icon\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z\" />\n <circle cx=\"12\" cy=\"12\" r=\"3\" />\n </svg>\n 预览\n </button>\n <button class=\"fd-tool-btn\" @click=\"showCode = true\">\n <svg class=\"fd-tool-btn-icon\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <polyline points=\"16 18 22 12 16 6\" />\n <polyline points=\"8 6 2 12 8 18\" />\n </svg>\n 查看代码\n </button>\n <button class=\"fd-tool-btn\" @click=\"showImport = true\">\n <svg class=\"fd-tool-btn-icon\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4\" />\n <polyline points=\"17 8 12 3 7 8\" />\n <line x1=\"12\" y1=\"3\" x2=\"12\" y2=\"15\" />\n </svg>\n 导入\n </button>\n <button class=\"fd-tool-btn\" @click=\"onReload\">\n <svg class=\"fd-tool-btn-icon\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <polyline points=\"23 4 23 10 17 10\" />\n <path d=\"M20.49 15a9 9 0 1 1-2.12-9.36L23 10\" />\n </svg>\n 加载\n </button>\n <button class=\"fd-tool-btn\" @click=\"onSave\">\n <svg class=\"fd-tool-btn-icon\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z\" />\n <polyline points=\"17 21 17 13 7 13 7 21\" />\n <polyline points=\"7 3 7 8 15 8\" />\n </svg>\n 保存\n </button>\n <button class=\"fd-tool-btn\" @click=\"onSaveAs\">\n <svg class=\"fd-tool-btn-icon\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <rect x=\"9\" y=\"9\" width=\"13\" height=\"13\" rx=\"2\" />\n <path d=\"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1\" />\n </svg>\n 另存为\n </button>\n <button class=\"fd-tool-btn fd-tool-btn--primary\" @click=\"onPublish\">\n <svg class=\"fd-tool-btn-icon\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <line x1=\"22\" y1=\"2\" x2=\"11\" y2=\"13\" />\n <polygon points=\"22 2 15 22 11 13 2 9 22 2\" />\n </svg>\n 发布\n </button>\n <span class=\"fd-toolbar-divider\"></span>\n <button class=\"fd-tool-btn fd-tool-icon-btn\" :disabled=\"!store.canUndo\" title=\"撤销\" @click=\"store.undo()\">\n <svg class=\"fd-tool-icon\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <polyline points=\"9 14 4 9 9 4\" />\n <path d=\"M20 20v-7a4 4 0 0 0-4-4H4\" />\n </svg>\n </button>\n <button class=\"fd-tool-btn fd-tool-icon-btn\" :disabled=\"!store.canRedo\" title=\"重做\" @click=\"store.redo()\">\n <svg class=\"fd-tool-icon\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <polyline points=\"15 14 20 9 15 4\" />\n <path d=\"M4 20v-7a4 4 0 0 1 4-4h12\" />\n </svg>\n </button>\n <!-- <button class=\"fd-tool-btn\" @click=\"toggleDark\">\n <svg class=\"fd-tool-btn-icon\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z\" />\n </svg>\n 暗色\n </button> -->\n <button ref=\"treeBtnRef\" class=\"fd-tool-btn\" @click=\"showTree = !showTree\">\n <svg class=\"fd-tool-btn-icon\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <line x1=\"8\" y1=\"6\" x2=\"21\" y2=\"6\" />\n <line x1=\"8\" y1=\"12\" x2=\"21\" y2=\"12\" />\n <line x1=\"8\" y1=\"18\" x2=\"21\" y2=\"18\" />\n <line x1=\"3\" y1=\"6\" x2=\"3.01\" y2=\"6\" />\n <line x1=\"3\" y1=\"12\" x2=\"3.01\" y2=\"12\" />\n <line x1=\"3\" y1=\"18\" x2=\"3.01\" y2=\"18\" />\n </svg>\n 组件树\n </button>\n </div>\n\n <!-- 预览弹层 -->\n <Teleport to=\"body\">\n <div v-if=\"showPreview\" class=\"fd-dialog-mask\" @click.self=\"showPreview = false\">\n <div class=\"fd-dialog fd-dialog--preview\">\n <div class=\"fd-dialog-head\">\n <span>预览</span>\n <div class=\"fd-preview-width\">\n <label for=\"fd-preview-width-input\">宽度</label>\n <el-input-number\n id=\"fd-preview-width-input\"\n v-model=\"previewWidth\"\n :min=\"270\"\n :max=\"1200\"\n :step=\"10\"\n size=\"small\"\n controls-position=\"right\"\n @change=\"clampPreviewWidth\"\n />\n <span class=\"fd-preview-width-unit\">px</span>\n </div>\n <button class=\"fd-tool-btn\" @click=\"showPreview = false\">关闭</button>\n </div>\n <div class=\"fd-dialog-body\">\n <div class=\"fd-preview-stage\" :style=\"{ width: previewWidth + 'px' }\">\n <Renderer :widgets=\"store.widgets\" :form-data=\"mockFormData\" />\n </div>\n </div>\n </div>\n </div>\n\n <!-- 查看代码弹层 -->\n <div v-if=\"showCode\" class=\"fd-dialog-mask\" @click.self=\"showCode = false\">\n <div class=\"fd-dialog\">\n <div class=\"fd-dialog-head\">\n <span>JSON Schema</span>\n <button class=\"fd-tool-btn\" @click=\"showCode = false\">关闭</button>\n </div>\n <pre class=\"fd-dialog-code\">{{ codeJson }}</pre>\n </div>\n </div>\n\n <!-- 导入弹层:粘贴 JSON,确认后覆盖当前表单 -->\n <div v-if=\"showImport\" class=\"fd-dialog-mask\" @click.self=\"showImport = false\">\n <div class=\"fd-dialog\">\n <div class=\"fd-dialog-head\">\n <span>导入(粘贴 JSON)</span>\n <button class=\"fd-tool-btn\" @click=\"showImport = false\">取消</button>\n <button class=\"fd-tool-btn fd-tool-btn--primary\" @click=\"onImportConfirm\">确认</button>\n </div>\n <div class=\"fd-dialog-body\">\n <textarea\n v-model=\"importText\"\n class=\"fd-dialog-import-text\"\n placeholder=\"请粘贴表单 JSON(可从「查看代码」复制),确认后将覆盖当前表单\"\n ></textarea>\n </div>\n </div>\n </div>\n\n <!-- 组件树抽屉 -->\n <!-- 组件树抽屉:点击抽屉外区域关闭(document 监听,不拦截页面滚动) -->\n <div v-if=\"showTree\" ref=\"treeDrawerRef\" class=\"fd-tree-drawer\">\n <ComponentTree />\n </div>\n </Teleport>\n </div>\n</template>\n\n<style scoped>\n.fd-toolbar {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 1.2rem;\n height: var(--fd-header-height);\n padding: 0 2rem;\n background: var(--fd-color-bg-panel);\n border-bottom: 1px solid var(--fd-color-border);\n flex-shrink: 0;\n}\n.fd-toolbar-title {\n font-weight: 600;\n font-size: 1.8rem;\n color: var(--fd-color-text);\n white-space: nowrap;\n}\n.fd-toolbar-left {\n gap: 1.6rem;\n}\n.fd-toolbar-divider {\n width: 1px;\n height: 2rem;\n background: var(--fd-color-border);\n flex-shrink: 0;\n}\n.fd-toolbar-name {\n height: 3.2rem;\n width: 16rem;\n padding: 0 1.2rem;\n border: 1px solid transparent;\n border-radius: var(--fd-radius-base);\n background: var(--fd-color-info-light);\n color: var(--fd-color-text-secondary);\n font-size: 1.4rem;\n transition: all var(--fd-transition);\n}\n.fd-toolbar-name:hover {\n background: var(--fd-color-bg-panel);\n border-color: var(--fd-color-primary);\n}\n.fd-toolbar-name:focus {\n outline: none;\n background: var(--fd-color-bg-panel);\n border-color: var(--fd-color-primary);\n box-shadow: 0 0 0 0.2rem rgba(76, 142, 255, 0.2);\n}\n.fd-device {\n display: inline-flex;\n background: var(--fd-color-info-light);\n border-radius: 0.6rem;\n padding: 0.2rem;\n}\n.fd-device button {\n height: 2.8rem;\n display: inline-flex;\n align-items: center;\n gap: 0.4rem;\n padding: 0 1rem;\n border: none;\n background: transparent;\n border-radius: var(--fd-radius-base);\n color: var(--fd-color-text-secondary);\n font-size: 1.3rem;\n /* 仅作比例标识,不支持手动切换 */\n cursor: default;\n white-space: nowrap;\n transition: all var(--fd-transition);\n}\n.fd-device button.is-active {\n background: var(--fd-color-bg-panel);\n color: var(--fd-color-primary);\n box-shadow: var(--fd-shadow-card);\n font-weight: 600;\n}\n.fd-toolbar-right {\n gap: 0.8rem;\n flex-wrap: nowrap;\n overflow-x: auto;\n}\n.fd-tool-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 0.4rem;\n height: 3.4rem;\n padding: 0 1rem;\n border: none;\n border-radius: var(--fd-radius-base);\n background: var(--fd-color-info-light);\n color: #4a4f59;\n font-size: 1.3rem;\n cursor: pointer;\n white-space: nowrap;\n flex-shrink: 0;\n transition: all var(--fd-transition);\n}\n.fd-tool-btn-icon {\n width: 1.4rem;\n height: 1.4rem;\n flex-shrink: 0;\n display: block;\n}\n.fd-tool-btn:hover {\n background: #e8e9eb;\n}\n.fd-tool-btn:disabled {\n opacity: 0.45;\n cursor: not-allowed;\n}\n.fd-tool-btn--primary {\n background: var(--fd-color-primary);\n color: #fff;\n}\n.fd-tool-btn--primary:hover {\n background: var(--fd-color-primary-hover);\n color: #fff;\n}\n.fd-tool-icon-btn {\n width: 3.4rem;\n padding: 0;\n}\n.fd-tool-icon {\n width: 1.8rem;\n height: 1.8rem;\n display: block;\n}\n\n/* 弹层 */\n.fd-dialog-mask {\n position: fixed;\n inset: 0;\n z-index: 100;\n background: rgba(0, 0, 0, 0.45);\n display: flex;\n align-items: center;\n justify-content: center;\n}\n.fd-dialog {\n width: min(86rem, 90vw);\n max-height: 82vh;\n display: flex;\n flex-direction: column;\n background: var(--fd-color-bg-panel);\n border-radius: var(--fd-radius-lg);\n box-shadow: var(--fd-shadow-pop);\n overflow: hidden;\n}\n/* 预览弹层加宽,容纳最大 1200px 的预览区 */\n.fd-dialog--preview {\n width: min(128rem, 94vw);\n}\n/* 预览宽度设置框 */\n.fd-preview-width {\n display: inline-flex;\n align-items: center;\n gap: 0.6rem;\n font-size: 1.3rem;\n font-weight: 400;\n color: var(--fd-color-text-secondary);\n}\n.fd-preview-width :deep(.el-input-number) {\n width: 11rem;\n}\n.fd-preview-width :deep(.el-input-number .el-input__wrapper) {\n background: var(--fd-color-bg);\n box-shadow: 0 0 0 1px var(--fd-color-border) inset;\n}\n.fd-preview-width :deep(.el-input-number .el-input__wrapper:hover) {\n box-shadow: 0 0 0 1px var(--fd-color-border-hover) inset;\n}\n.fd-preview-width :deep(.el-input-number .el-input__wrapper.is-focus) {\n box-shadow: 0 0 0 1px var(--fd-color-primary) inset;\n}\n.fd-preview-width label { white-space: nowrap; }\n.fd-preview-width-unit {\n color: var(--fd-color-text-tertiary);\n}\n/* 预览舞台:CSS 硬限制 270 ~ 1200px,与控件 min/max 双重保险 */\n.fd-preview-stage {\n min-width: 27rem;\n max-width: 120rem;\n margin: 0 auto;\n}\n.fd-dialog-head {\n display: flex;\n align-items: center;\n gap: 1.2rem;\n padding: 1.2rem 1.6rem;\n border-bottom: 1px solid var(--fd-color-border);\n font-weight: 600;\n font-size: 1.5rem;\n}\n.fd-dialog-head span {\n margin-right: auto;\n}\n.fd-dialog-body {\n padding: 1.6rem;\n overflow: auto;\n}\n.fd-dialog-code {\n margin: 0;\n padding: 1.6rem;\n overflow: auto;\n font-size: 1.2rem;\n line-height: 1.6;\n color: var(--fd-color-text);\n}\n.fd-dialog-import-text {\n width: 100%;\n min-height: 32rem;\n padding: 1.2rem;\n border: 1px solid var(--fd-color-border);\n border-radius: var(--fd-radius-base);\n font-size: 1.2rem;\n line-height: 1.6;\n font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace;\n background: var(--fd-color-bg);\n color: var(--fd-color-text);\n resize: vertical;\n}\n\n/* 组件树抽屉 */\n.fd-tree-drawer {\n position: fixed;\n top: 5.6rem;\n right: 0;\n bottom: 0;\n width: 30rem;\n z-index: 90;\n background: var(--fd-color-bg-panel);\n border-left: 1px solid var(--fd-color-border);\n box-shadow: var(--fd-shadow-pop);\n}\n</style>\n","<script setup lang=\"ts\">\nimport { useDesignerStore } from '@/stores/designer'\nimport { getAllWidgetDefs } from '@/widgets'\nimport type { WidgetType } from '@/types'\n\nconst store = useDesignerStore()\nconst defs = getAllWidgetDefs()\n\n/** 控件库分组(与文档控件范围一致) */\nconst groups = [\n {\n title: '基础控件',\n types: ['label', 'text'] as WidgetType[],\n },\n {\n title: '高级控件',\n types: ['subtable'] as WidgetType[],\n },\n {\n title: '布局控件',\n types: ['grid', 'card', 'slot'] as WidgetType[],\n },\n]\n\n/** 类型 -> 图标字符(统一线性风格,禁止 emoji) */\nconst icons: Record<WidgetType, string> = {\n grid: '▦',\n card: '▤',\n slot: '⧉',\n label: 'T',\n text: '¶',\n subtable: '☰',\n}\n\nfunction defOf(type: WidgetType) {\n return defs.find((d) => d.type === type)\n}\n\nfunction onDragStart(e: DragEvent, type: WidgetType) {\n e.dataTransfer?.setData('application/x-fd-new', type)\n if (e.dataTransfer) e.dataTransfer.effectAllowed = 'copy'\n}\n\nfunction onAdd(type: WidgetType) {\n store.addWidget(type)\n}\n</script>\n\n<template>\n <div class=\"fd-palette\">\n <div class=\"fd-palette-title\">控件库</div>\n <div v-for=\"g in groups\" :key=\"g.title\" class=\"fd-palette-group\">\n <div class=\"fd-palette-group-title\">{{ g.title }}</div>\n <template v-for=\"t in g.types\" :key=\"t\">\n <div\n v-if=\"defOf(t)\"\n class=\"fd-palette-item\"\n draggable=\"true\"\n @dragstart=\"onDragStart($event, t)\"\n @click=\"onAdd(t)\"\n >\n <span class=\"fd-palette-icon\">{{ icons[t] }}</span>\n <span>{{ defOf(t)!.title }}</span>\n </div>\n </template>\n </div>\n </div>\n</template>\n\n<style scoped>\n.fd-palette {\n padding: 1.2rem;\n display: flex;\n flex-direction: column;\n gap: 1.2rem;\n overflow: auto;\n height: 100%;\n}\n.fd-palette-title {\n font-weight: 600;\n font-size: 1.4rem;\n color: var(--fd-color-text);\n padding: 0 0.4rem;\n}\n.fd-palette-group {\n display: flex;\n flex-direction: column;\n gap: 0.8rem;\n}\n.fd-palette-group-title {\n font-size: 1.2rem;\n color: var(--fd-color-text-tertiary);\n margin-bottom: 0.2rem;\n padding-left: 0.4rem;\n}\n.fd-palette-item {\n display: flex;\n align-items: center;\n gap: 1rem;\n padding: 1rem 1.2rem;\n border: 1px solid transparent;\n border-radius: var(--fd-radius-base);\n background: var(--fd-color-bg-hover);\n font-size: 1.3rem;\n color: var(--fd-color-text);\n cursor: grab;\n user-select: none;\n transition: all var(--fd-transition);\n}\n.fd-palette-item:hover {\n background: var(--fd-color-primary-bg);\n border-color: var(--fd-color-primary);\n}\n.fd-palette-item:active {\n cursor: grabbing;\n}\n.fd-palette-icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 2.2rem;\n height: 2.2rem;\n border-radius: var(--fd-radius-base);\n background: var(--fd-color-icon-bg);\n color: var(--fd-color-icon);\n font-size: 1.3rem;\n font-weight: 600;\n}\n</style>\n","import type { WidgetNode } from './widget'\n\n/** 字段枚举项 */\nexport interface EnumItem {\n label: string\n value: string\n}\n\n/** 表单生命周期钩子名 */\nexport type LifecycleHook = 'onLoad' | 'onMounted' | 'onValueChange' | 'custom'\n\n/** 各生命周期钩子的展示信息 */\nexport const LIFECYCLE_HOOKS: { key: LifecycleHook; label: string; desc: string }[] = [\n { key: 'onLoad', label: '加载完成', desc: '表单数据就绪后触发' },\n { key: 'onMounted', label: '渲染挂载', desc: '渲染完成并挂载到 DOM 后触发' },\n { key: 'onValueChange', label: '值变化', desc: '任意字段值变化时触发' },\n { key: 'custom', label: '自定义方法', desc: '写入的方法将挂载至全局 window,可在其他事件处理中调用' },\n]\n\n/** 生命周期事件:钩子名 -> 处理代码片段 */\nexport interface FormLifecycleEvents {\n onLoad?: string\n onMounted?: string\n onValueChange?: string\n /** 自定义方法代码:其中声明的方法挂载至 window */\n custom?: string\n}\n\n/** 自定义事件(可供组件选择绑定) */\nexport interface CustomEvent {\n /** 事件标识,组件通过此 name 引用 */\n name: string\n /** 事件显示名 */\n title: string\n /** 事件处理代码片段 */\n handler: string\n}\n\n/** 表单级事件配置 */\nexport interface FormEvents {\n /** 生命周期事件 */\n lifecycle: FormLifecycleEvents\n /** 自定义事件列表 */\n custom: CustomEvent[]\n}\n\n/** 可绑定字段元数据(从 formData 中筛选而来) */\nexport interface FieldMeta {\n /** 字段名 */\n name: string\n /** 字段中文名 */\n label: string\n /** 字段类型 */\n dataType: string\n /** 字段枚举(可选) */\n enums?: EnumItem[]\n}\n\n/** 表单初始化接口返回的结构(mock,后续与后端对齐) */\nexport interface FormSchema {\n /** 表单标识 */\n formId: string\n /**\n * 模板类型:PC = 电脑端 / App = 移动端。\n * 由「获取表单模板」接口下发(设计模板仅根据 formId 获取),\n * 决定设计器画布比例与运行态布局参考;接口未下发时前端回退 URL query。\n */\n templateType?: 'PC' | 'App'\n /** 主表名 */\n dbtable: string\n /** 可绑定字段列表 */\n fields: FieldMeta[]\n /** 控件树 */\n widgets: WidgetNode[]\n /** 表单级事件配置(全局事件) */\n events: FormEvents\n}\n","<script setup lang=\"ts\">\nimport { reactive, defineAsyncComponent } from 'vue'\nimport { useDesignerStore } from '@/stores/designer'\nimport { LIFECYCLE_HOOKS } from '@/types'\n\n/**\n * Monaco 编辑器体积较大,按需异步加载:\n * 仅在用户点击「编写处理函数」弹出编辑弹层时才拉取对应 chunk,避免首屏加载。\n */\nconst CodeEditor = defineAsyncComponent(() => import('./CodeEditor.vue'))\n\nconst store = useDesignerStore()\n\n/** 代码编辑器:触发器 + modal。参照 demo 的 event-handler-trigger / event-handler-editor */\nconst editor = reactive({\n open: false,\n type: '' as 'lifecycle' | 'custom' | '',\n hookKey: '',\n index: -1,\n title: '',\n draft: '',\n})\n\nfunction openLifecycle(h: (typeof LIFECYCLE_HOOKS)[number]) {\n editor.open = true\n editor.type = 'lifecycle'\n editor.hookKey = h.key\n editor.title = `${h.label}(${h.key})`\n editor.draft = store.events.lifecycle[h.key] ?? ''\n}\n\nfunction confirmEditor() {\n if (editor.type === 'lifecycle' && editor.hookKey) {\n store.setLifecycleHook(editor.hookKey as never, editor.draft)\n } else if (editor.type === 'custom' && editor.index >= 0) {\n store.updateCustomEvent(editor.index, { handler: editor.draft } as never)\n }\n editor.open = false\n}\n\nfunction closeEditor() {\n editor.open = false\n}\n</script>\n\n<template>\n <div class=\"fd-form-events\">\n <div class=\"fd-property-title\">表单属性</div>\n <div class=\"fd-form-meta\">\n <span>表单:{{ store.formId }}</span>\n <span>主表:{{ store.dbtable }}</span>\n </div>\n\n <section class=\"fd-events-section\">\n <h4 class=\"fd-events-h\">全局事件 · 生命周期</h4>\n <p class=\"fd-events-tip\">渲染时绑定至对应钩子函数中执行</p>\n <div v-for=\"h in LIFECYCLE_HOOKS\" :key=\"h.key\" class=\"fd-event-row\">\n <div class=\"fd-event-head\">\n <label :title=\"h.desc\">{{ h.label }}</label>\n <code class=\"fd-event-key\">{{ h.key }}</code>\n </div>\n <div\n class=\"fd-event-trigger\"\n @click=\"openLifecycle(h)\"\n :title=\"store.events.lifecycle[h.key] || '点击编写处理函数'\"\n >\n <span v-if=\"store.events.lifecycle[h.key]\" class=\"fd-event-trigger-text\">{{\n store.events.lifecycle[h.key]\n }}</span>\n <span v-else class=\"fd-event-trigger-placeholder\">点击编写</span>\n <span class=\"fd-event-trigger-arrow\">›</span>\n </div>\n </div>\n </section>\n\n <!-- <section class=\"fd-events-section\">\n <div class=\"fd-events-head\">\n <h4 class=\"fd-events-h\">全局事件 · 自定义事件</h4>\n <button class=\"fd-btn fd-btn--primary fd-btn--sm\" @click=\"store.addCustomEvent()\">+ 新增</button>\n </div>\n <p class=\"fd-events-tip\">自定义事件可在运行态被触发执行</p>\n <div v-if=\"store.events.custom.length === 0\" class=\"fd-events-empty\">暂无自定义事件</div>\n <div v-for=\"(ev, i) in store.events.custom\" :key=\"i\" class=\"fd-custom-card\">\n <div class=\"fd-custom-head\">\n <span class=\"fd-custom-index\">#{{ i + 1 }}</span>\n <button class=\"fd-btn fd-btn--danger fd-btn--sm\" @click=\"store.removeCustomEvent(i)\">删除</button>\n </div>\n <div class=\"fd-event-row\">\n <label>事件名(标识)</label>\n <input :value=\"ev.name\" @input=\"onCustom(i, 'name', $event)\" placeholder=\"如 onButtonClick\" />\n </div>\n <div class=\"fd-event-row\">\n <label>显示名</label>\n <input :value=\"ev.title\" @input=\"onCustom(i, 'title', $event)\" placeholder=\"如 点击按钮\" />\n </div>\n <div class=\"fd-event-row\">\n <label>处理代码</label>\n <div\n class=\"fd-event-trigger\"\n @click=\"openCustom(i)\"\n :title=\"ev.handler || '点击编写处理函数'\"\n >\n <span v-if=\"ev.handler\" class=\"fd-event-trigger-text\">{{ ev.handler }}</span>\n <span v-else class=\"fd-event-trigger-placeholder\">点击编写</span>\n <span class=\"fd-event-trigger-arrow\">›</span>\n </div>\n </div>\n </div>\n </section> -->\n\n <!-- 代码编辑弹层:触发器点击后弹出,编写处理函数 -->\n <Teleport to=\"body\">\n <div v-if=\"editor.open\" class=\"fd-dialog-mask\" @click.self=\"closeEditor\">\n <div class=\"fd-dialog\" style=\"max-width: 600px;\">\n <div class=\"fd-dialog-head\">\n <span>编写处理函数 - {{ editor.title }}</span>\n <button class=\"fd-dialog-close\" @click=\"closeEditor\" title=\"关闭\">×</button>\n </div>\n <div class=\"fd-dialog-body\">\n <CodeEditor v-model=\"editor.draft\" language=\"javascript\" />\n </div>\n <div class=\"fd-dialog-foot\">\n <button class=\"fd-btn fd-btn--primary\" @click=\"confirmEditor\">确定</button>\n </div>\n </div>\n </div>\n </Teleport>\n </div>\n</template>\n\n<style scoped>\n.fd-form-events {\n display: flex;\n flex-direction: column;\n gap: 1.6rem;\n}\n.fd-form-meta {\n display: flex;\n flex-direction: column;\n gap: 0.4rem;\n font-size: 1.2rem;\n color: var(--fd-color-text-secondary);\n padding: 0.8rem 1rem;\n background: var(--fd-color-bg);\n border-radius: var(--fd-radius-base);\n}\n.fd-events-section {\n display: flex;\n flex-direction: column;\n gap: 1rem;\n}\n.fd-events-head {\n display: flex;\n align-items: center;\n justify-content: space-between;\n}\n.fd-events-h {\n margin: 0;\n font-size: 1.4rem;\n font-weight: 600;\n}\n.fd-events-tip {\n margin: 0;\n font-size: 1.2rem;\n color: var(--fd-color-text-tertiary);\n}\n.fd-events-empty {\n font-size: 1.3rem;\n color: var(--fd-color-text-placeholder);\n text-align: center;\n padding: 1.2rem;\n border: 1px dashed var(--fd-color-border);\n border-radius: var(--fd-radius-base);\n}\n.fd-event-row {\n display: flex;\n flex-direction: column;\n gap: 0.4rem;\n}\n.fd-event-head {\n display: flex;\n align-items: center;\n gap: 0.8rem;\n}\n.fd-event-row label {\n font-size: 1.3rem;\n color: var(--fd-color-text-secondary);\n}\n.fd-event-key {\n font-size: 1.1rem;\n color: var(--fd-color-primary);\n background: var(--fd-color-primary-light);\n padding: 0.1rem 0.6rem;\n border-radius: var(--fd-radius-base);\n}\n\n/* 触发器:参照 demo .event-handler-trigger —— 展示已有代码或「点击编写」,点击打开弹层 */\n.fd-event-trigger {\n display: flex;\n align-items: center;\n gap: 0.6rem;\n width: 100%;\n min-height: 3.2rem;\n padding: 0 1rem;\n border: 1px solid var(--fd-color-border);\n border-radius: var(--fd-radius-base);\n font-size: 1.3rem;\n background: var(--fd-color-bg-panel);\n cursor: pointer;\n transition: border-color var(--fd-transition), background-color var(--fd-transition);\n overflow: hidden;\n}\n.fd-event-trigger:hover {\n border-color: var(--fd-color-primary);\n background: var(--fd-color-primary-light);\n}\n.fd-event-trigger-text {\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n color: var(--fd-color-text);\n font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace;\n}\n.fd-event-trigger-placeholder {\n flex: 1;\n color: var(--fd-color-text-placeholder);\n}\n.fd-event-trigger-arrow {\n flex-shrink: 0;\n color: var(--fd-color-text-tertiary);\n font-size: 1.8rem;\n line-height: 1;\n}\n\n/* 代码编辑弹层:使用 Monaco 编辑器(CodeEditor.vue) */\n\n.fd-custom-card {\n display: flex;\n flex-direction: column;\n gap: 0.8rem;\n padding: 1.2rem;\n border: 1px solid var(--fd-color-border);\n border-radius: var(--fd-radius-base);\n background: var(--fd-color-bg);\n}\n.fd-custom-head {\n display: flex;\n align-items: center;\n justify-content: space-between;\n}\n.fd-custom-index {\n font-size: 1.3rem;\n font-weight: 600;\n color: var(--fd-color-text-secondary);\n}\n.fd-event-row input {\n width: 100%;\n height: 3.2rem;\n font-size: 1.4rem;\n padding: 0 1rem;\n border: 1px solid var(--fd-color-border);\n border-radius: var(--fd-radius-base);\n background: var(--fd-color-bg-panel);\n color: var(--fd-color-text);\n}\n.fd-event-row input:focus {\n border-color: var(--fd-color-primary);\n outline: none;\n}\n.fd-btn {\n height: 3.2rem;\n padding: 0 1.4rem;\n border: none;\n border-radius: var(--fd-radius-base);\n font-size: 1.3rem;\n cursor: pointer;\n}\n.fd-btn--sm {\n height: 2.6rem;\n padding: 0 1rem;\n font-size: 1.2rem;\n}\n.fd-btn--primary {\n background: var(--fd-color-primary);\n color: #fff;\n}\n.fd-btn--danger {\n background: var(--fd-color-danger-light);\n color: var(--fd-color-danger);\n}\n\n/* 弹层(与项目 .fd-dialog 风格一致,scoped 内自包含) */\n.fd-dialog-mask {\n position: fixed;\n inset: 0;\n z-index: 100;\n background: rgba(0, 0, 0, 0.45);\n display: flex;\n align-items: center;\n justify-content: center;\n}\n.fd-dialog {\n width: min(60rem, 92vw);\n max-height: 82vh;\n display: flex;\n flex-direction: column;\n background: var(--fd-color-bg-panel);\n border-radius: var(--fd-radius-lg);\n box-shadow: var(--fd-shadow-pop);\n overflow: hidden;\n}\n.fd-dialog-head {\n display: flex;\n align-items: center;\n gap: 1.2rem;\n padding: 1.2rem 1.6rem;\n border-bottom: 1px solid var(--fd-color-border);\n font-weight: 600;\n font-size: 1.5rem;\n}\n.fd-dialog-head span {\n margin-right: auto;\n}\n.fd-dialog-close {\n width: 3rem;\n height: 3rem;\n padding: 0;\n font-size: 2rem;\n line-height: 1;\n border: none;\n border-radius: var(--fd-radius-base);\n background: transparent;\n color: var(--fd-color-text-secondary);\n cursor: pointer;\n}\n.fd-dialog-close:hover {\n background: var(--fd-color-bg);\n color: var(--fd-color-text);\n}\n.fd-dialog-body {\n padding: 1.6rem;\n overflow: auto;\n}\n.fd-dialog-foot {\n display: flex;\n justify-content: flex-end;\n gap: 1rem;\n padding: 1.2rem 1.6rem;\n border-top: 1px solid var(--fd-color-border);\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport { useDesignerStore } from '@/stores/designer'\nimport { getWidgetDef } from '@/widgets'\nimport FormEventsPanel from './FormEventsPanel.vue'\n\nconst store = useDesignerStore()\nconst node = computed(() => store.selectedNode)\nconst def = computed(() => (node.value ? getWidgetDef(node.value.type) : undefined))\nconst Panel = computed(() => def.value?.panel)\n\nfunction onUpdate(patch: Record<string, unknown>) {\n if (node.value) store.updateNode(node.value.id, patch)\n}\n\n/** 位于栅栏格内的子节点:可设置占比 */\nconst inGrid = computed(() => node.value != null && node.value.gridSpan != null)\n\nfunction onSpan(e: Event) {\n if (!node.value) return\n const raw = Number((e.target as HTMLInputElement).value)\n const span = Math.min(24, Math.max(1, Number.isFinite(raw) ? Math.round(raw) : 24))\n store.updateNode(node.value.id, { gridSpan: span })\n}\n</script>\n\n<template>\n <div class=\"fd-property\">\n <div class=\"fd-property-title\">属性</div>\n\n <!-- 选中表单本身:表单级属性(全局事件) -->\n <FormEventsPanel v-if=\"store.selectedForm\" />\n\n <!-- 空状态 -->\n <div v-else-if=\"!node\" class=\"fd-property-empty\">\n <span class=\"fd-property-empty-icon\">⚙</span>\n <span>请选择左侧控件<br />或点击画板空白处设置表单属性</span>\n </div>\n\n <!-- 选中控件 -->\n <template v-else>\n <component :is=\"Panel\" v-if=\"Panel\" :node=\"node\" :fields=\"store.fields\" @update=\"onUpdate\" />\n\n <div v-if=\"inGrid\" class=\"fd-property-item\">\n <label>占比</label>\n <input type=\"number\" min=\"1\" max=\"24\" :value=\"node.gridSpan\" @change=\"onSpan\" />\n </div>\n\n <div class=\"fd-property-foot\">\n <span class=\"fd-property-type\">类型:{{ def?.title }}</span>\n <!-- <button class=\"fd-btn fd-btn--danger\" @click=\"store.removeWidget(node.id)\">删除控件</button> -->\n </div>\n </template>\n </div>\n</template>\n\n<style scoped>\n.fd-property { padding: 1.2rem; display: flex; flex-direction: column; gap: 1.2rem; height: 100%; overflow: auto; }\n.fd-property-title { font-weight: 600; font-size: 1.4rem; }\n.fd-property-empty {\n flex: 1;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 1.2rem;\n color: var(--fd-color-text-secondary);\n font-size: 1.3rem;\n text-align: center;\n}\n.fd-property-empty-icon {\n font-size: 3.6rem;\n color: var(--fd-color-border);\n}\n.fd-property-foot { display: flex; align-items: center; justify-content: space-between; margin-top: 1.2rem; padding-top: 1.2rem; border-top: 1px solid var(--fd-color-border); }\n.fd-property-type { font-size: 1.2rem; color: var(--fd-color-text-secondary); }\n.fd-property-item { display: flex; flex-direction: column; gap: 0.4rem; }\n.fd-property-item label { font-size: 1.3rem; color: var(--fd-color-text-secondary); }\n.fd-property-item input,\n.fd-property-item select {\n height: 3.2rem;\n padding: 0 1rem;\n border: 1px solid var(--fd-color-border);\n border-radius: var(--fd-radius-base);\n font-size: 1.4rem;\n background: var(--fd-color-bg-panel);\n}\n.fd-btn { height: 3.2rem; padding: 0 1.4rem; border: none; border-radius: var(--fd-radius-base); font-size: 1.3rem; cursor: pointer; }\n.fd-btn--danger { background: var(--fd-color-danger-light); color: var(--fd-color-danger); }\n</style>\n","<script setup lang=\"ts\">\nimport { computed, ref } from 'vue'\nimport type { WidgetNode, WidgetType } from '@/types'\nimport { useDesignerStore } from '@/stores/designer'\nimport { getWidgetDef } from '@/widgets'\nimport { gridCornerClass } from '@/widgets/grid/corner'\nimport WidgetHost from '@/components/WidgetHost.vue'\n\nconst props = defineProps<{ node: WidgetNode; parentId: string | null; index: number }>()\nconst store = useDesignerStore()\nconst rootEl = ref<HTMLElement | null>(null)\n\n/** 栅栏格内按占据格数跨列;text 控件按对齐方式设置 display */\nconst nodeStyle = computed(() => {\n const styles: Record<string, string> = {}\n if (props.node.gridSpan != null) {\n styles.gridColumn = `span ${props.node.gridSpan}`\n }\n if (props.node.type === 'text') {\n styles.display = (props.node as { display?: string }).display || 'inline-block'\n }\n return Object.keys(styles).length ? styles : undefined\n})\n\nconst isContainer = () => getWidgetDef(props.node.type)?.isContainer\n\n/** 栅栏格内子项圆角定位:结合 gridSpan 计算行首/行尾,仅整体表格四角对应 label 有圆角 */\nfunction gridCorner(child: WidgetNode, index: number): string {\n if (props.node.type !== 'grid') return ''\n const layout = (props.node as { layout?: number }).layout || 24\n return gridCornerClass(child, index, props.node.children || [], layout, store.device === 'mobile')\n}\n\nfunction hasDragData(e: DragEvent): boolean {\n const t = e.dataTransfer\n return !!t && (t.types.includes('application/x-fd-new') || t.types.includes('application/x-fd-move'))\n}\n\nfunction onSelect() {\n store.select(props.node.id)\n}\n\nfunction onDragStart(e: DragEvent) {\n // 阻止冒泡,避免嵌套拖拽时父容器的 dragstart 覆盖来源节点\n e.stopPropagation()\n store.setDragging(props.node.id)\n e.dataTransfer?.setData('application/x-fd-move', props.node.id)\n if (e.dataTransfer) e.dataTransfer.effectAllowed = 'move'\n}\n\nfunction clearAll() {\n store.dragOverId = null\n store.dropContainerId = null\n store.dragBefore = false\n store.setDragging(null)\n}\n\nfunction onDragEnd(e: DragEvent) {\n e.stopPropagation()\n clearAll()\n}\n\nfunction clearIndicator() {\n if (store.dragOverId === props.node.id) store.dragOverId = null\n if (store.dropContainerId === props.node.id) store.dropContainerId = null\n}\n\nfunction onDragOver(e: DragEvent) {\n if (!hasDragData(e)) return\n e.preventDefault()\n e.stopPropagation()\n if (isContainer()) {\n store.dragOverId = null\n store.dragBefore = false\n store.dropContainerId = props.node.id\n } else {\n store.dropContainerId = null\n store.dragOverId = props.node.id\n const el = rootEl.value\n if (el) {\n const rect = el.getBoundingClientRect()\n store.dragBefore = e.clientY - rect.top < rect.height / 2\n }\n }\n}\n\nfunction onDragLeave() {\n clearIndicator()\n}\n\nfunction onDrop(e: DragEvent) {\n if (!hasDragData(e)) return\n e.preventDefault()\n e.stopPropagation()\n const newType = e.dataTransfer?.getData('application/x-fd-new')\n const moveId = e.dataTransfer?.getData('application/x-fd-move')\n if (isContainer()) {\n if (newType) store.addWidget(newType as WidgetType, props.node.id)\n else if (moveId) store.moveNode(moveId, props.node.id, props.node.children?.length ?? 0)\n } else {\n const idx = store.dragBefore ? props.index : props.index + 1\n if (newType) store.addWidget(newType as WidgetType, props.parentId, idx)\n else if (moveId) store.moveNode(moveId, props.parentId, idx)\n }\n store.dragOverId = null\n store.dragBefore = false\n store.dropContainerId = null\n}\n</script>\n\n<template>\n <div\n ref=\"rootEl\"\n class=\"fd-canvas-node\"\n :class=\"[\n `fd-canvas-node--${node.type}`,\n {\n 'is-selected': store.selectedId === node.id,\n 'drop-before': store.dragOverId === node.id && store.dragBefore,\n 'drop-target': store.dropContainerId === node.id,\n 'dragging-source': store.draggingId === node.id,\n },\n ]\"\n :style=\"nodeStyle\"\n draggable=\"true\"\n @mousedown.stop=\"onSelect\"\n @click.stop\n @dragstart=\"onDragStart\"\n @dragend=\"onDragEnd\"\n @dragover=\"onDragOver\"\n @dragleave=\"onDragLeave\"\n @drop=\"onDrop\"\n >\n <div class=\"fd-canvas-node-actions\" @mousedown.stop>\n <span class=\"fd-node-action\" title=\"上移\" @click.stop=\"store.moveSibling(node.id, -1)\">\n <svg class=\"fd-node-icon\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <line x1=\"12\" y1=\"20\" x2=\"12\" y2=\"5\" />\n <polyline points=\"6 11 12 5 18 11\" />\n </svg>\n </span>\n <span class=\"fd-node-action\" title=\"下移\" @click.stop=\"store.moveSibling(node.id, 1)\">\n <svg class=\"fd-node-icon\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <line x1=\"12\" y1=\"4\" x2=\"12\" y2=\"19\" />\n <polyline points=\"6 13 12 19 18 13\" />\n </svg>\n </span>\n <span class=\"fd-node-action delete\" title=\"删除\" @click.stop=\"store.removeWidget(node.id)\">\n <svg class=\"fd-node-icon\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M4 7h16\" />\n <path d=\"M9 7V5.5a1.5 1.5 0 0 1 1.5-1.5h3A1.5 1.5 0 0 1 15 5.5V7\" />\n <path d=\"M6.5 7l1 12.5h9l1-12.5\" />\n <line x1=\"10\" y1=\"11\" x2=\"10\" y2=\"16.5\" />\n <line x1=\"14\" y1=\"11\" x2=\"14\" y2=\"16.5\" />\n </svg>\n </span>\n </div>\n <WidgetHost :node=\"node\" mode=\"design\">\n <template v-if=\"isContainer() && node.children\" #children>\n <CanvasNode\n v-for=\"(child, ci) in node.children\"\n :key=\"child.id\"\n :node=\"child\"\n :parent-id=\"node.id\"\n :index=\"ci\"\n :class=\"gridCorner(child, ci)\"\n />\n <div v-if=\"!node.children || node.children.length === 0\" class=\"fd-canvas-dropzone\">拖拽控件到此容器</div>\n </template>\n </WidgetHost>\n </div>\n</template>\n\n<style scoped>\n.fd-canvas-node {\n position: relative;\n /* margin-bottom: var(--fd-gap-base);\n padding: 1rem 1.2rem; */\n border-radius: var(--fd-radius-base);\n cursor: pointer;\n /* 仅过渡背景/阴影/透明度;拖拽高亮用 box-shadow / ::before,不占布局边框 */\n transition: background-color var(--fd-transition), box-shadow var(--fd-transition), opacity var(--fd-transition);\n}\n.fd-canvas-node:hover {\n background: var(--fd-color-bg-hover);\n}\n/* text 文本控件的 display 由 nodeStyle 内联控制 */\n.fd-canvas-node.is-selected {\n background: var(--fd-color-primary-bg);\n outline: 1px solid var(--fd-color-primary);\n z-index: 1;\n}\n/* 放置位置指示条:绝对定位覆盖在节点上边界,不影响布局 */\n.fd-canvas-node.drop-before::before {\n content: '';\n position: absolute;\n left: 0;\n right: 0;\n top: -0.15rem;\n height: 0.3rem;\n border-radius: 0.15rem;\n background: var(--fd-color-primary);\n z-index: 2;\n}\n.fd-canvas-node.drop-target {\n background: rgba(76, 142, 255, 0.08) !important;\n box-shadow: 0 0 0 1px var(--fd-color-primary), 0 0 0.6rem rgba(76, 142, 255, 0.25);\n}\n.fd-canvas-node.dragging-source {\n opacity: 0.4;\n}\n.fd-canvas-node-actions {\n position: absolute;\n top: 0.6rem;\n right: 0.6rem;\n display: none;\n gap: 0.4rem;\n z-index: 5;\n}\n.fd-canvas-node:hover > .fd-canvas-node-actions {\n display: flex;\n}\n/* 悬停到更深层子节点时,隐藏祖先节点的操作按钮,仅保留最内层当前组件的按钮 */\n.fd-canvas-node:hover:has(.fd-canvas-node:hover) > .fd-canvas-node-actions {\n display: none;\n}\n.fd-node-action {\n width: 2.6rem;\n height: 2.6rem;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--fd-color-bg-panel);\n border: 1px solid var(--fd-color-border);\n border-radius: var(--fd-radius-base);\n cursor: pointer;\n color: var(--fd-color-text-tertiary);\n transition: all var(--fd-transition);\n}\n.fd-node-icon {\n width: 1.4rem;\n height: 1.4rem;\n display: block;\n}\n.fd-node-action:hover {\n background: var(--fd-color-bg-hover);\n border-color: var(--fd-color-border-hover);\n color: var(--fd-color-primary);\n}\n.fd-node-action.delete:hover {\n color: var(--fd-color-danger);\n}\n.fd-canvas-dropzone {\n grid-column: 1 / -1;\n border: 1px dashed var(--fd-color-border);\n border-radius: var(--fd-radius-base);\n padding: 0.8rem;\n text-align: center;\n color: var(--fd-color-text-tertiary);\n font-size: 1.2rem;\n margin-top: 0.6rem;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { onMounted } from 'vue'\nimport { useDesignerStore } from '@/stores/designer'\nimport { getSchema } from '@/api'\nimport { loadFormFromLocal } from '@/storage/formStorage'\nimport Toolbar from './Toolbar.vue'\nimport WidgetPalette from './WidgetPalette.vue'\nimport PropertyPanel from './PropertyPanel.vue'\nimport CanvasNode from './CanvasNode.vue'\n\nconst props = defineProps<{ formId?: string }>()\n\nconst store = useDesignerStore()\n\n/**\n * 模板类型:PC = 电脑端 / App = 移动端。\n * 以接口下发的 templateType 为准(设计模板仅根据 formId 获取),\n * 接口未下发时保留 URL query 兜底值。\n */\nfunction applyTemplateType(templateType?: 'PC' | 'App') {\n if (templateType === 'PC' || templateType === 'App') {\n store.device = templateType === 'App' ? 'mobile' : 'pc'\n }\n}\n\nonMounted(async () => {\n // 电脑端/移动端比例兜底:由 URL query templateType 决定(mobile / 2 = 移动端,其它 = 电脑端)\n const queryType = new URLSearchParams(window.location.search).get('templateType') || ''\n store.device = queryType === 'mobile' || queryType === '2' ? 'mobile' : 'pc'\n\n // formId 参数优先级:prop > 路径参数(?formId=);无则初始化新表单\n const pathFormId = new URLSearchParams(window.location.search).get('formId') || ''\n const fid = props.formId || pathFormId || ''\n if (fid) {\n // 回显:优先本地存储,缺省回退到初始化接口\n const local = loadFormFromLocal(fid)\n if (local) {\n // 控件树回显本地缓存,但可绑定字段枚举始终取最新接口,避免旧缓存导致下拉枚举过期\n const fresh = await getSchema(fid)\n const merged = {\n ...local,\n fields: fresh.fields,\n dbtable: fresh.dbtable,\n templateType: fresh.templateType ?? local.templateType\n }\n applyTemplateType(merged.templateType)\n store.loadSchema(merged)\n } else {\n const schema = await getSchema(fid)\n applyTemplateType(schema.templateType)\n store.loadSchema(schema)\n }\n store.openedWithParam = true\n } else {\n const schema = await getSchema('')\n applyTemplateType(schema.templateType)\n store.loadSchema(schema)\n store.openedWithParam = false\n // 标记为未保存的新表单:formId 置空,保存时再生成 GUID\n store.formId = ''\n }\n})\n\nfunction onCanvasDrop(e: DragEvent) {\n e.preventDefault()\n const newType = e.dataTransfer?.getData('application/x-fd-new')\n const moveId = e.dataTransfer?.getData('application/x-fd-move')\n if (newType) store.addWidget(newType as never, null, store.widgets.length)\n else if (moveId) store.moveNode(moveId, null, store.widgets.length)\n}\n</script>\n\n<template>\n <div class=\"fd-designer\">\n <Toolbar />\n <div class=\"fd-designer-body\">\n <aside class=\"fd-designer-left\">\n <WidgetPalette />\n </aside>\n <main class=\"fd-designer-center\" @dragover.prevent @drop=\"onCanvasDrop\">\n <div\n class=\"fd-canvas\"\n :class=\"{ 'is-mobile': store.device === 'mobile', 'is-selected': store.selectedForm }\"\n @click=\"store.selectForm()\"\n >\n <div v-if=\"store.widgets.length === 0\" class=\"fd-canvas-empty\">\n <span class=\"fd-canvas-empty-icon\">▦</span>\n <span>从左侧拖拽控件到此处</span>\n </div>\n <CanvasNode\n v-for=\"(node, i) in store.widgets\"\n :key=\"node.id\"\n :node=\"node\"\n :parent-id=\"null\"\n :index=\"i\"\n />\n </div>\n </main>\n <aside class=\"fd-designer-right\">\n <PropertyPanel />\n </aside>\n </div>\n </div>\n</template>\n\n<style scoped>\n.fd-designer {\n display: flex;\n flex-direction: column;\n height: 100vh;\n}\n.fd-designer-body {\n flex: 1;\n display: flex;\n min-height: 0;\n}\n.fd-designer-left {\n width: var(--fd-sidebar-width);\n border-right: 1px solid var(--fd-color-border);\n background: var(--fd-color-bg-panel);\n overflow: hidden;\n}\n.fd-designer-center {\n flex: 1;\n padding: 2.4rem;\n overflow: auto;\n background: var(--fd-color-bg);\n}\n.fd-canvas {\n width: 100%;\n max-width: var(--fd-canvas-max);\n min-height: calc(100vh - 16rem);\n margin: 0 auto;\n padding: 1.6rem;\n background: var(--fd-color-bg-panel);\n border-radius: var(--fd-radius-lg);\n box-shadow: var(--fd-shadow-card);\n}\n.fd-canvas.is-mobile {\n max-width: 37.5rem;\n}\n.fd-canvas.is-selected {\n outline: 2px solid var(--fd-color-primary);\n outline-offset: -2px;\n}\n.fd-canvas-empty {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 8rem 2.4rem;\n color: var(--fd-color-text-tertiary);\n}\n.fd-canvas-empty-icon {\n font-size: 4.8rem;\n margin-bottom: 1.6rem;\n color: var(--fd-color-text-placeholder);\n}\n.fd-canvas-empty span:last-child {\n font-size: 1.4rem;\n}\n.fd-designer-right {\n width: var(--fd-property-width);\n border-left: 1px solid var(--fd-color-border);\n background: var(--fd-color-bg-panel);\n}\n</style>\n","import { createApp, h } from 'vue'\nimport type { App } from 'vue'\nimport Renderer from '@/components/renderer/Renderer.vue'\nimport { registerBuiltinWidgets } from '@/widgets'\nimport { configureApi } from '@/api'\nimport type { WidgetNode, FormMode, FormEvents } from '@/types'\n\n/** 渲染表单所需的全部入参(供外部调用方传递) */\nexport interface RenderFormOptions {\n /** 挂载容器(必填)。渲染内容将挂载到该元素内部 */\n container: HTMLElement\n /** 控件节点数组(即表单 schema) */\n widgets: WidgetNode[]\n /** 表单模式:view / start / approval 等,缺省按控件 visibleModes 全显 */\n formMode?: FormMode\n /** 表单初始数据 */\n formData?: Record<string, unknown>\n /** 表单级事件配置(生命周期 + 自定义事件) */\n events?: FormEvents\n /** 表单标识(透传给插槽等需要宿主上下文的控件),可选 */\n formId?: string\n /** 接口模块(apiModule),可选 */\n apiModule?: string\n /** 基础模块(baseModule),可选 */\n baseModule?: string\n}\n\n/** 渲染实例句柄,供外部在挂载后调用 */\nexport interface RenderFormHandle {\n /** 触发指定自定义事件 */\n fireEvent(name: string, payload?: unknown): void\n /** 销毁渲染实例、释放 DOM 与资源 */\n unmount(): void\n}\n\n/**\n * 命令式渲染表单:不依赖页面/组件,由外部传入容器与参数挂载。\n * 返回句柄可触发事件与卸载。\n */\nexport function renderForm(options: RenderFormOptions): RenderFormHandle {\n // 确保内置控件已注册(幂等)\n registerBuiltinWidgets()\n if (options.apiModule || options.baseModule) {\n configureApi({ apiModule: options.apiModule, baseModule: options.baseModule })\n }\n\n // 以 Renderer 为根组件,并通过 ref 拿到其对外暴露的方法\n let exposed: Record<string, (...args: unknown[]) => unknown> | null = null\n const Root = {\n render: () =>\n h(Renderer, {\n widgets: options.widgets,\n formMode: options.formMode,\n formData: options.formData,\n events: options.events,\n formId: options.formId,\n ref: (inst: unknown) => {\n exposed = inst as Record<string, (...args: unknown[]) => unknown>\n },\n }),\n }\n\n const app: App = createApp(Root)\n app.mount(options.container)\n\n return {\n fireEvent: (name, payload) => exposed?.fireEvent?.(name, payload),\n unmount: () => app.unmount(),\n }\n}\n","import type { App } from 'vue'\nimport Designer from '@/components/designer/Designer.vue'\nimport { registerBuiltinWidgets } from '@/widgets'\nimport { configureApi } from '@/api'\n// 全局样式(CSS 变量 / 基础样式):随库产物输出为 dist-lib/style.css\nimport '@/styles/index.css'\n\nexport interface InstallOptions {\n /** 接口模块(apiModule) */\n apiModule?: string\n /** 基础模块(baseModule) */\n baseModule?: string\n}\n\nconst DesignerPlugin = {\n install(app: App, options: InstallOptions = {}) {\n registerBuiltinWidgets()\n if (options.apiModule || options.baseModule) {\n configureApi({ apiModule: options.apiModule, baseModule: options.baseModule })\n }\n app.component('FdDesigner', Designer)\n },\n}\n\nexport default DesignerPlugin\nexport { Designer }\n/** 命令式渲染接口:外部通过 renderForm(options) 挂载,而非页面/组件形式 */\nexport { renderForm } from '@/components/renderer/renderForm'\nexport type { RenderFormOptions, RenderFormHandle } from '@/components/renderer/renderForm'\nexport { registerComponent } from '@/widgets'\nexport { setApiModule, setBaseModule, configureApi } from '@/api'\nexport * from '@/types'\n","<script setup lang=\"ts\">\nimport { ref, onMounted, onBeforeUnmount, watch } from 'vue'\nimport * as monaco from 'monaco-editor'\nimport { javascriptDefaults } from 'monaco-editor/language/typescript/monaco.contribution'\n\nconst props = withDefaults(\n defineProps<{\n modelValue?: string\n language?: string\n }>(),\n { modelValue: '', language: 'javascript' },\n)\n\nconst emit = defineEmits<{ 'update:modelValue': [value: string] }>()\n\nconst container = ref<HTMLDivElement | null>(null)\nlet editor: monaco.editor.IStandaloneCodeEditor | null = null\n\nonMounted(() => {\n if (!container.value) return\n // 处理函数多为运行态 ctx 等上下文变量,关闭语义校验避免误报红线\n javascriptDefaults.setDiagnosticsOptions({\n noSemanticValidation: true,\n noSyntaxValidation: false,\n })\n editor = monaco.editor.create(container.value, {\n value: props.modelValue,\n language: props.language,\n theme: 'vs-dark',\n automaticLayout: true,\n fontSize: 14,\n tabSize: 2,\n minimap: { enabled: false },\n scrollBeyondLastLine: false,\n fontFamily: \"'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace\",\n scrollbar: { verticalScrollbarSize: 8, horizontalScrollbarSize: 8 },\n })\n editor.onDidChangeModelContent(() => {\n emit('update:modelValue', editor?.getValue() ?? '')\n })\n})\n\nwatch(\n () => props.modelValue,\n (val) => {\n if (editor && val !== editor.getValue()) editor.setValue(val ?? '')\n },\n)\n\nwatch(\n () => props.language,\n (lang) => {\n const model = editor?.getModel()\n if (model) monaco.editor.setModelLanguage(model, lang)\n },\n)\n\nonBeforeUnmount(() => {\n editor?.dispose()\n editor = null\n})\n</script>\n\n<template>\n <div ref=\"container\" class=\"fd-code-editor\"></div>\n</template>\n\n<style scoped>\n.fd-code-editor {\n width: 100%;\n height: 32rem;\n border: 1px solid var(--fd-color-border);\n border-radius: var(--fd-radius-base);\n overflow: hidden;\n}\n</style>\n"],"names":["registry","registerComponent","def","getWidgetDef","type","getAllWidgetDefs","createWidget","store","useDesignerStore","_createElementBlock","_normalizeClass","_unref","_createElementVNode","_hoisted_1","_toDisplayString","__props","_normalizeStyle","_Fragment","_createTextVNode","props","isLink","computed","linkUrl","raw","_a","display","designerStore","_mqMobile","ref","_mq","onMounted","e","onUnmounted","isMobile","_hoisted_3","DEFAULT_COLOR","labelDefinition","LabelDesign","LabelRender","emit","__emit","linkFields","f","hexOf","v","onColorChange","onBindFieldChange","val","onBindLinkChange","_openBlock","_hoisted_2","_cache","$event","_hoisted_4","_createVNode","ElSelect","ElOption","_renderList","_createBlock","_hoisted_5","_hoisted_6","_hoisted_7","icon","icons","_resolveDynamicComponent","toggleExpanded","LucideIcon","_withDirectives","_renderSlot","_ctx","_vShow","isWidgetHidden","hiddenMode","status","s","expanded","cardIconNames","cardDefinition","CardDesign","CardRender","iconOpen","selectIcon","ic","_hoisted_9","_hoisted_11","FdSwitch","_hoisted_12","_hoisted_14","slotDefinition","SlotDesign","SlotRender","showTable","c","col","_hoisted_8","cols","readonly","rows","visible","addRow","blank","delRow","idx","cellText","row","name","mergeInfo","list","spans","skipped","ci","enable","start","ri","cur","isMerged","rowspanOf","_hoisted_10","_hoisted_13","_hoisted_15","_hoisted_17","_hoisted_18","_hoisted_19","_hoisted_20","mockSubtables","subtableOptions","getSubtableDef","buildDefaultColumns","i","isFile","mockSchema","formId","template","set","key","value","onSelectSubtable","patch","dialog","reactive","clone","openCol","closeDialog","saveCol","next","toggleCol","addCol","nextTick","delCol","setColor","subtableFields","onBindLink","onTablestyle","onColField","x","opt","_hoisted_16","_Teleport","_hoisted_21","_hoisted_22","_hoisted_23","_hoisted_24","_hoisted_25","_hoisted_27","_hoisted_28","_hoisted_30","_hoisted_32","_hoisted_34","_hoisted_35","_hoisted_36","_hoisted_38","_hoisted_40","_hoisted_41","_hoisted_44","_hoisted_45","_hoisted_48","_hoisted_49","_hoisted_50","_hoisted_51","_hoisted_53","defaultColnums","subtableDefinition","SubtableDesign","SubtableRender","SubtablePanel","Comp","valueOf","bindField","_mergeProps","_createSlots","$slots","_","_withCtx","scope","_normalizeProps","_guardReactiveProps","child","_component_WidgetHost","PC_COLUMNS","gridCornerClass","index","siblings","layout","mobile","total","spanOf","n","flags","span","rowFirst","rowLast","lastRow","isFirstRow","isLastRow","cls","WidgetHost","gridDefinition","GridDesign","GridRender","layoutOptions","applyLayout","children","textDefinition","TextDesign","TextRender","registered","registerBuiltinWidgets","findNode","id","removeNode","defineStore","prev","hook","code","item","parentId","node","parent","maybeChildId","toParentId","srcNode","target","locate","r","src","destList","delta","findParent","j","targetId","dragId","detach","found","schema","fields","DEFAULT","runtime","installOptions","propsOverride","configureApi","options","setApiModule","module","setBaseModule","resolveApiConfig","buildUrl","action","baseModule","apiModule","getSchema","KEY_PREFIX","genGuid","saveFormToLocal","loadFormFromLocal","INJECT_FIRE_EVENT","runHandler","ctx","mountGlobalMethods","script","visibleWidgets","modes","runLifecycle","fireEvent","payload","ev","provide","watch","__expose","toTreeNode","label","treeData","totalCount","walk","onNodeClick","data","ElTree","showPreview","showCode","showTree","showImport","isMobileTemplate","t","previewWidth","clampPreviewWidth","w","device","importText","onImportConfirm","text","codeJson","mockFormData","collectSubtables","out","onSave","onSaveAs","onReload","local","onPublish","treeDrawerRef","treeBtnRef","onDocClick","_b","onBeforeUnmount","ElInputNumber","Renderer","ComponentTree","defs","groups","defOf","d","onDragStart","onAdd","g","LIFECYCLE_HOOKS","CodeEditor","defineAsyncComponent","editor","openLifecycle","h","confirmEditor","closeEditor","Panel","onUpdate","inGrid","onSpan","FormEventsPanel","rootEl","nodeStyle","styles","isContainer","gridCorner","hasDragData","onSelect","clearAll","onDragEnd","clearIndicator","onDragOver","el","rect","onDragLeave","onDrop","newType","moveId","_c","_component_CanvasNode","applyTemplateType","templateType","queryType","pathFormId","fid","fresh","merged","onCanvasDrop","Toolbar","WidgetPalette","CanvasNode","PropertyPanel","renderForm","exposed","Root","inst","app","createApp","DesignerPlugin","Designer","container","javascriptDefaults","monaco","lang","model"],"mappings":"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"}
|