z-certificate-editor 1.0.3 → 1.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/style.css +1047 -0
- package/dist/z-certificate-editor.es.js +2128 -0
- package/dist/z-certificate-editor.es.js.map +1 -0
- package/dist/z-certificate-editor.umd.js +2131 -0
- package/dist/z-certificate-editor.umd.js.map +1 -0
- package/package.json +9 -3
- package/dist/assets/index-CujE4kZ0.js +0 -17
- package/dist/assets/index-j3Ih4QMK.css +0 -1
- package/dist/index.html +0 -13
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"z-certificate-editor.es.js","sources":["../src/utils/templateManager.js","../src/components/DesignPanel.vue","../src/utils/fieldManager.js","../src/components/CanvasArea.vue","../src/components/FieldDialog.vue","../src/components/PropertiesPanel.vue","../src/components/FieldDataPanel.vue","../src/components/CertificatePreview.vue","../src/components/CertificateEditor.vue"],"sourcesContent":["// 预设模板\r\nexport const PRESET_TEMPLATES = [\r\n {\r\n id: 'vertical-1',\r\n name: '竖版模板1',\r\n type: 'vertical',\r\n width: 972,\r\n height: 1378,\r\n background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',\r\n description: '经典竖版证书模板'\r\n },\r\n {\r\n id: 'vertical-2',\r\n name: '竖版模板2',\r\n type: 'vertical',\r\n width: 972,\r\n height: 1378,\r\n background: 'linear-gradient(135deg, #f093fb 0%, #f5576c 100%)',\r\n description: '优雅竖版证书模板'\r\n },\r\n {\r\n id: 'vertical-3',\r\n name: '竖版模板3',\r\n type: 'vertical',\r\n width: 972,\r\n height: 1378,\r\n background: 'linear-gradient(135deg, #4facfe 0%, #00f2fe 100%)',\r\n description: '现代竖版证书模板'\r\n },\r\n {\r\n id: 'horizontal-1',\r\n name: '横版模板1',\r\n type: 'horizontal',\r\n width: 1303,\r\n height: 897,\r\n background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',\r\n description: '经典横版证书模板'\r\n },\r\n {\r\n id: 'horizontal-2',\r\n name: '横版模板2',\r\n type: 'horizontal',\r\n width: 1303,\r\n height: 897,\r\n background: 'linear-gradient(135deg, #f093fb 0%, #f5576c 100%)',\r\n description: '优雅横版证书模板'\r\n },\r\n {\r\n id: 'horizontal-3',\r\n name: '横版模板3',\r\n type: 'horizontal',\r\n width: 1303,\r\n height: 897,\r\n background: 'linear-gradient(135deg, #4facfe 0%, #00f2fe 100%)',\r\n description: '现代横版证书模板'\r\n }\r\n]\r\n\r\n// 验证图片文件\r\nexport const validateImageFile = (file) => {\r\n const allowedTypes = ['image/jpeg', 'image/jpg', 'image/png']\r\n const maxSize = 2 * 1024 * 1024 // 2MB\r\n \r\n if (!allowedTypes.includes(file.type)) {\r\n return { valid: false, error: '只支持 JPG、JPEG、PNG 格式的图片' }\r\n }\r\n \r\n if (file.size > maxSize) {\r\n return { valid: false, error: '图片大小不能超过 2MB' }\r\n }\r\n \r\n return { valid: true }\r\n}\r\n\r\n// 将文件转换为Base64\r\nexport const fileToBase64 = (file) => {\r\n return new Promise((resolve, reject) => {\r\n const reader = new FileReader()\r\n reader.onload = () => resolve(reader.result)\r\n reader.onerror = reject\r\n reader.readAsDataURL(file)\r\n })\r\n}\r\n\r\n// 获取模板尺寸建议\r\nexport const getTemplateSizeSuggestion = (type) => {\r\n if (type === 'vertical') {\r\n return { width: 972, height: 1378 }\r\n } else {\r\n return { width: 1303, height: 897 }\r\n }\r\n}\r\n","<template>\r\n <div class=\"design-panel\">\r\n <div class=\"panel-tabs\">\r\n <div \r\n class=\"tab-item\" \r\n :class=\"{ active: activeTab === 'elements' }\"\r\n @click=\"activeTab = 'elements'\"\r\n >\r\n 设计元素\r\n </div>\r\n <div \r\n class=\"tab-item\" \r\n :class=\"{ active: activeTab === 'templates' }\"\r\n @click=\"activeTab = 'templates'\"\r\n >\r\n 底图模板\r\n </div>\r\n </div>\r\n \r\n <div class=\"panel-content\">\r\n <!-- 设计元素 -->\r\n <div v-if=\"activeTab === 'elements'\" class=\"elements-section\">\r\n <div class=\"elements-grid\">\r\n <div class=\"element-item\" @click=\"$emit('add-element', 'text')\">\r\n <div class=\"element-icon\">📝</div>\r\n <div class=\"element-label\">短文本</div>\r\n </div>\r\n <div class=\"element-item\" @click=\"$emit('add-element', 'longtext')\">\r\n <div class=\"element-icon\">📄</div>\r\n <div class=\"element-label\">长文本</div>\r\n </div>\r\n <div class=\"element-item\" @click=\"$emit('add-element', 'image')\">\r\n <div class=\"element-icon\">🖼️</div>\r\n <div class=\"element-label\">图片</div>\r\n </div>\r\n <div class=\"element-item\" @click=\"$emit('add-element', 'qrcode')\">\r\n <div class=\"element-icon\">🔲</div>\r\n <div class=\"element-label\">二维码</div>\r\n </div>\r\n </div>\r\n </div>\r\n \r\n <!-- 底图模板 -->\r\n <div v-if=\"activeTab === 'templates'\" class=\"templates-section\">\r\n <div class=\"upload-section\">\r\n <input\r\n ref=\"fileInputRef\"\r\n type=\"file\"\r\n accept=\"image/jpeg,image/jpg,image/png\"\r\n @change=\"handleFileUpload\"\r\n style=\"display: none\"\r\n />\r\n <button class=\"upload-btn\" @click=\"triggerUpload\">\r\n <span>📁</span>\r\n <span>上传模板</span>\r\n </button>\r\n <div class=\"upload-hint\">\r\n 支持:jpg、jpeg、png 小于2M<br>\r\n 建议尺寸:{{ templateType === 'vertical' ? '972 x 1378' : '1303 x 897' }}\r\n </div>\r\n </div>\r\n \r\n <div class=\"template-type-switch\">\r\n <button \r\n class=\"switch-btn\" \r\n :class=\"{ active: templateType === 'vertical' }\"\r\n @click=\"templateType = 'vertical'\"\r\n >\r\n 竖版\r\n </button>\r\n <button \r\n class=\"switch-btn\" \r\n :class=\"{ active: templateType === 'horizontal' }\"\r\n @click=\"templateType = 'horizontal'\"\r\n >\r\n 横版\r\n </button>\r\n </div>\r\n \r\n <div class=\"templates-list\">\r\n <div\r\n v-for=\"template in filteredTemplates\"\r\n :key=\"template.id\"\r\n class=\"template-item\"\r\n @click=\"handleSelectTemplate(template)\"\r\n >\r\n <div class=\"template-preview\" :style=\"{ background: template.background }\"></div>\r\n <div class=\"template-name\">{{ template.name }}</div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</template>\r\n\r\n<script setup>\r\nimport { ref, computed } from 'vue'\r\nimport { PRESET_TEMPLATES, validateImageFile, fileToBase64, getTemplateSizeSuggestion } from '../utils/templateManager.js'\r\n\r\nconst emit = defineEmits(['add-element', 'select-template', 'upload-template'])\r\n\r\nconst activeTab = ref('elements')\r\nconst templateType = ref('vertical')\r\nconst fileInputRef = ref(null)\r\n\r\nconst filteredTemplates = computed(() => {\r\n return PRESET_TEMPLATES.filter(t => t.type === templateType.value)\r\n})\r\n\r\nconst handleSelectTemplate = (template) => {\r\n emit('select-template', template)\r\n}\r\n\r\nconst triggerUpload = () => {\r\n fileInputRef.value?.click()\r\n}\r\n\r\nconst handleFileUpload = async (event) => {\r\n const file = event.target.files?.[0]\r\n if (!file) return\r\n \r\n const validation = validateImageFile(file)\r\n if (!validation.valid) {\r\n alert(validation.error)\r\n return\r\n }\r\n \r\n try {\r\n const base64 = await fileToBase64(file)\r\n const suggestion = getTemplateSizeSuggestion(templateType.value)\r\n \r\n const customTemplate = {\r\n id: `custom-${Date.now()}`,\r\n name: '自定义模板',\r\n type: templateType.value,\r\n width: suggestion.width,\r\n height: suggestion.height,\r\n background: base64,\r\n description: '自定义上传的模板'\r\n }\r\n \r\n emit('upload-template', customTemplate)\r\n } catch (error) {\r\n alert('上传失败,请重试')\r\n console.error(error)\r\n }\r\n \r\n // 重置input\r\n if (fileInputRef.value) {\r\n fileInputRef.value.value = ''\r\n }\r\n}\r\n</script>\r\n\r\n<style scoped>\r\n.design-panel {\r\n display: flex;\r\n flex-direction: column;\r\n height: 100%;\r\n background: #fff;\r\n}\r\n\r\n.panel-tabs {\r\n display: flex;\r\n border-bottom: 1px solid #e0e0e0;\r\n background: #fafafa;\r\n}\r\n\r\n.tab-item {\r\n flex: 1;\r\n padding: 12px;\r\n text-align: center;\r\n cursor: pointer;\r\n font-size: 14px;\r\n color: #666;\r\n border-bottom: 2px solid transparent;\r\n transition: all 0.3s;\r\n}\r\n\r\n.tab-item:hover {\r\n color: #1890ff;\r\n background: #f0f0f0;\r\n}\r\n\r\n.tab-item.active {\r\n color: #1890ff;\r\n border-bottom-color: #1890ff;\r\n background: #fff;\r\n font-weight: 500;\r\n}\r\n\r\n.panel-content {\r\n flex: 1;\r\n overflow-y: auto;\r\n padding: 16px;\r\n}\r\n\r\n.elements-section {\r\n width: 100%;\r\n}\r\n\r\n.elements-grid {\r\n display: grid;\r\n grid-template-columns: repeat(2, 1fr);\r\n gap: 12px;\r\n}\r\n\r\n.element-item {\r\n display: flex;\r\n flex-direction: column;\r\n align-items: center;\r\n justify-content: center;\r\n padding: 16px;\r\n border: 1px solid #e0e0e0;\r\n border-radius: 4px;\r\n cursor: pointer;\r\n transition: all 0.3s;\r\n background: #fff;\r\n}\r\n\r\n.element-item:hover {\r\n border-color: #1890ff;\r\n background: #f0f7ff;\r\n transform: translateY(-2px);\r\n box-shadow: 0 2px 8px rgba(24, 144, 255, 0.2);\r\n}\r\n\r\n.element-icon {\r\n font-size: 32px;\r\n margin-bottom: 8px;\r\n}\r\n\r\n.element-label {\r\n font-size: 12px;\r\n color: #333;\r\n}\r\n\r\n.templates-section {\r\n width: 100%;\r\n}\r\n\r\n.upload-section {\r\n padding: 16px;\r\n border: 1px dashed #d9d9d9;\r\n border-radius: 4px;\r\n text-align: center;\r\n background: #fafafa;\r\n margin-bottom: 16px;\r\n}\r\n\r\n.template-type-switch {\r\n display: flex;\r\n gap: 8px;\r\n margin-bottom: 16px;\r\n padding: 4px;\r\n background: #f5f5f5;\r\n border-radius: 4px;\r\n}\r\n\r\n.switch-btn {\r\n flex: 1;\r\n padding: 6px 12px;\r\n border: none;\r\n background: transparent;\r\n color: #666;\r\n border-radius: 4px;\r\n cursor: pointer;\r\n font-size: 14px;\r\n transition: all 0.3s;\r\n}\r\n\r\n.switch-btn.active {\r\n background: #fff;\r\n color: #1890ff;\r\n font-weight: 500;\r\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);\r\n}\r\n\r\n.templates-list {\r\n display: flex;\r\n flex-direction: column;\r\n gap: 12px;\r\n margin-bottom: 16px;\r\n}\r\n\r\n.template-item {\r\n border: 1px solid #e0e0e0;\r\n border-radius: 4px;\r\n overflow: hidden;\r\n cursor: pointer;\r\n transition: all 0.3s;\r\n background: #fff;\r\n}\r\n\r\n.template-item:hover {\r\n border-color: #1890ff;\r\n box-shadow: 0 2px 8px rgba(24, 144, 255, 0.2);\r\n}\r\n\r\n.template-preview {\r\n width: 100%;\r\n height: 120px;\r\n background: #f5f5f5;\r\n}\r\n\r\n.template-name {\r\n padding: 8px 12px;\r\n font-size: 13px;\r\n color: #333;\r\n text-align: center;\r\n background: #fff;\r\n}\r\n\r\n.upload-btn {\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n gap: 6px;\r\n width: 100%;\r\n padding: 8px 16px;\r\n border: 1px solid #d9d9d9;\r\n background: #fff;\r\n color: #333;\r\n border-radius: 4px;\r\n cursor: pointer;\r\n font-size: 14px;\r\n transition: all 0.3s;\r\n margin-bottom: 8px;\r\n}\r\n\r\n.upload-btn:hover {\r\n border-color: #1890ff;\r\n color: #1890ff;\r\n}\r\n\r\n.upload-hint {\r\n font-size: 11px;\r\n color: #999;\r\n line-height: 1.5;\r\n}\r\n</style>\r\n","// 系统字段定义\r\nexport const SYSTEM_FIELDS = [\r\n {\r\n key: 'name',\r\n label: '姓名',\r\n placeholder: '{{姓名}}',\r\n category: '基本信息',\r\n description: '证书持有人的姓名'\r\n },\r\n {\r\n key: 'gender',\r\n label: '性别称呼',\r\n placeholder: '{{性别称呼}}',\r\n category: '基本信息',\r\n description: '先生/女士'\r\n },\r\n {\r\n key: 'examName',\r\n label: '考试名称',\r\n placeholder: '{{考试名称}}',\r\n category: '考试信息',\r\n description: '参加的考试名称'\r\n },\r\n {\r\n key: 'score',\r\n label: '成绩',\r\n placeholder: '{{成绩}}',\r\n category: '考试信息',\r\n description: '考试成绩'\r\n },\r\n {\r\n key: 'scoreLevel',\r\n label: '成绩等级',\r\n placeholder: '{{成绩等级}}',\r\n category: '考试信息',\r\n description: '成绩等级(如:优秀、良好、合格等)'\r\n },\r\n {\r\n key: 'certificateNumber',\r\n label: '证书编号',\r\n placeholder: '{{证书编号}}',\r\n category: '证书信息',\r\n description: '证书的唯一编号'\r\n },\r\n {\r\n key: 'validityPeriod',\r\n label: '有效期',\r\n placeholder: '{{有效期}}',\r\n category: '证书信息',\r\n description: '证书的有效期限'\r\n },\r\n {\r\n key: 'issueDate',\r\n label: '颁发日期',\r\n placeholder: '{{颁发日期}}',\r\n category: '证书信息',\r\n description: '证书颁发的日期'\r\n },\r\n {\r\n key: 'organization',\r\n label: '颁发机构',\r\n placeholder: '{{颁发机构}}',\r\n category: '证书信息',\r\n description: '颁发证书的机构名称'\r\n },\r\n {\r\n key: 'idNumber',\r\n label: '身份证号',\r\n placeholder: '{{身份证号}}',\r\n category: '基本信息',\r\n description: '身份证号码'\r\n },\r\n {\r\n key: 'phone',\r\n label: '联系电话',\r\n placeholder: '{{联系电话}}',\r\n category: '基本信息',\r\n description: '联系电话'\r\n },\r\n {\r\n key: 'email',\r\n label: '电子邮箱',\r\n placeholder: '{{电子邮箱}}',\r\n category: '基本信息',\r\n description: '电子邮箱地址'\r\n },\r\n {\r\n key: 'account',\r\n label: '账号',\r\n placeholder: '{{账号}}',\r\n category: '基本信息',\r\n description: '用户账号'\r\n },\r\n {\r\n key: 'examScore',\r\n label: '考试得分',\r\n placeholder: '{{考试得分}}',\r\n category: '考试信息',\r\n description: '考试得分'\r\n },\r\n {\r\n key: 'issueDateMonth',\r\n label: '颁证时间(月)',\r\n placeholder: '{{颁证时间(月)}}',\r\n category: '证书信息',\r\n description: '证书颁发的月份'\r\n },\r\n {\r\n key: 'issueDateDay',\r\n label: '颁证时间(日)',\r\n placeholder: '{{颁证时间(日)}}',\r\n category: '证书信息',\r\n description: '证书颁发的日期'\r\n }\r\n]\r\n\r\n// 按分类组织字段\r\nexport const FIELDS_BY_CATEGORY = SYSTEM_FIELDS.reduce((acc, field) => {\r\n if (!acc[field.category]) {\r\n acc[field.category] = []\r\n }\r\n acc[field.category].push(field)\r\n return acc\r\n}, {})\r\n\r\n// 根据key获取字段\r\nexport const getFieldByKey = (key) => {\r\n return SYSTEM_FIELDS.find(field => field.key === key)\r\n}\r\n\r\n// 根据key获取占位符\r\nexport const getPlaceholderByKey = (key) => {\r\n const field = getFieldByKey(key)\r\n return field ? field.placeholder : `{{${key}}}`\r\n}\r\n\r\n// 替换文本中的字段占位符\r\nexport const replaceFields = (text, fieldData = {}) => {\r\n if (!text) return ''\r\n \r\n let result = text\r\n SYSTEM_FIELDS.forEach(field => {\r\n const placeholder = field.placeholder\r\n const value = fieldData[field.key] || field.placeholder\r\n // 使用全局替换\r\n const regex = new RegExp(placeholder.replace(/[{}]/g, '\\\\$&'), 'g')\r\n result = result.replace(regex, value)\r\n })\r\n \r\n return result\r\n}\r\n\r\n// 提取文本中的所有字段占位符\r\nexport const extractFields = (text) => {\r\n if (!text) return []\r\n \r\n const fields = []\r\n SYSTEM_FIELDS.forEach(field => {\r\n if (text.includes(field.placeholder)) {\r\n fields.push(field)\r\n }\r\n })\r\n \r\n return fields\r\n}\r\n\r\n// 检查文本是否包含字段占位符\r\nexport const hasFields = (text) => {\r\n if (!text) return false\r\n return SYSTEM_FIELDS.some(field => text.includes(field.placeholder))\r\n}\r\n\r\n// 默认字段数据(用于预览)\r\nexport const DEFAULT_FIELD_DATA = {\r\n name: '张三',\r\n gender: '先生',\r\n examName: '计算机应用能力考试',\r\n score: '95',\r\n scoreLevel: '优秀',\r\n certificateNumber: 'CERT-2024-001234',\r\n validityPeriod: '2024-01-01 至 2027-01-01',\r\n issueDate: '2024-01-01',\r\n organization: '考试认证中心',\r\n idNumber: '110101199001011234',\r\n phone: '13800138000',\r\n email: 'zhangsan@example.com',\r\n account: 'user001',\r\n examScore: '95',\r\n issueDateMonth: '01',\r\n issueDateDay: '01'\r\n}\r\n","<template>\r\n <div class=\"canvas-area\">\r\n <div \r\n class=\"certificate-canvas\" \r\n ref=\"canvasRef\"\r\n :style=\"getCanvasStyle()\"\r\n >\r\n <!-- 默认边框(仅在没有选择底图模板时显示) -->\r\n <div v-if=\"!props.template || !props.template.background\" class=\"certificate-border\"></div>\r\n\r\n <!-- 可编辑元素 -->\r\n <div\r\n v-for=\"element in elements\"\r\n :key=\"element.id\"\r\n :class=\"['editable-element', element.type, { selected: selectedElement?.id === element.id }]\"\r\n :style=\"getElementStyle(element)\"\r\n @click.stop=\"$emit('select-element', element)\"\r\n @mousedown=\"handleMouseDown($event, element)\"\r\n >\r\n <!-- 文本元素 -->\r\n <div v-if=\"element.type === 'text' || element.type === 'longtext'\" class=\"text-content\">\r\n <span v-html=\"renderTextWithFields(element.content)\"></span>\r\n </div>\r\n \r\n <!-- 图片元素 -->\r\n <div v-else-if=\"element.type === 'image'\" class=\"image-element\">\r\n <img\r\n v-if=\"getImageSrc(element)\"\r\n :src=\"getImageSrc(element)\"\r\n alt=\"图片\"\r\n class=\"element-image\"\r\n />\r\n <div v-else class=\"image-placeholder\">\r\n <span>🖼️ 请设置图片</span>\r\n </div>\r\n </div>\r\n \r\n <!-- 二维码元素 -->\r\n <div v-else-if=\"element.type === 'qrcode'\" class=\"qrcode-element\">\r\n <img\r\n v-if=\"getQrcodeContent(element) && isImageUrl(getQrcodeContent(element))\"\r\n :src=\"getQrcodeContent(element)\"\r\n alt=\"二维码\"\r\n class=\"element-image\"\r\n />\r\n <div v-else-if=\"getQrcodeContent(element)\" class=\"qrcode-content\">\r\n <div class=\"qrcode-placeholder-text\">二维码</div>\r\n <div class=\"qrcode-info\">{{ getQrcodeContent(element) }}</div>\r\n </div>\r\n <div v-else class=\"qrcode-placeholder\">\r\n <span>🔲 请设置二维码</span>\r\n </div>\r\n </div>\r\n \r\n <!-- 调整大小控制点 -->\r\n <div v-if=\"selectedElement?.id === element.id\" class=\"resize-handles\">\r\n <div class=\"handle handle-nw\" @mousedown.stop=\"handleResizeStart($event, element, 'nw')\"></div>\r\n <div class=\"handle handle-ne\" @mousedown.stop=\"handleResizeStart($event, element, 'ne')\"></div>\r\n <div class=\"handle handle-sw\" @mousedown.stop=\"handleResizeStart($event, element, 'sw')\"></div>\r\n <div class=\"handle handle-se\" @mousedown.stop=\"handleResizeStart($event, element, 'se')\"></div>\r\n </div>\r\n \r\n <!-- 删除按钮 -->\r\n <button\r\n v-if=\"selectedElement?.id === element.id\"\r\n class=\"delete-btn\"\r\n @click.stop=\"$emit('delete-element', element.id)\"\r\n >\r\n ×\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n</template>\r\n\r\n<script setup>\r\nimport { ref, onMounted, onUnmounted } from 'vue'\r\nimport { SYSTEM_FIELDS } from '../utils/fieldManager.js'\r\n\r\nconst props = defineProps({\r\n elements: {\r\n type: Array,\r\n default: () => []\r\n },\r\n selectedElement: {\r\n type: Object,\r\n default: null\r\n },\r\n fieldData: {\r\n type: Object,\r\n default: () => ({})\r\n },\r\n template: {\r\n type: Object,\r\n default: null\r\n },\r\n systemFields: {\r\n type: Array,\r\n default: () => SYSTEM_FIELDS\r\n }\r\n})\r\n\r\nconst emit = defineEmits(['select-element', 'update-element', 'delete-element'])\r\n\r\n// 渲染文本,替换字段占位符\r\nconst renderTextWithFields = (text) => {\r\n if (!text) return ''\r\n \r\n const fieldData = props.fieldData || {}\r\n let result = text\r\n \r\n props.systemFields.forEach(field => {\r\n const placeholder = field.placeholder\r\n const value = fieldData[field.key] || placeholder\r\n \r\n if (fieldData[field.key]) {\r\n const regex = new RegExp(placeholder.replace(/[{}]/g, '\\\\$&'), 'g')\r\n result = result.replace(regex, `<span class=\"field-value\">${value}</span>`)\r\n } else {\r\n const regex = new RegExp(placeholder.replace(/[{}]/g, '\\\\$&'), 'g')\r\n result = result.replace(regex, `<span class=\"field-placeholder-highlight\">${placeholder}</span>`)\r\n }\r\n })\r\n \r\n return result\r\n}\r\n\r\n// 获取图片源\r\nconst getImageSrc = (element) => {\r\n if (!element) return null\r\n \r\n if (element.imageSource === 'field') {\r\n // 关联字段,从fieldData中获取\r\n const fieldKey = element.imageField\r\n if (fieldKey && props.fieldData && props.fieldData[fieldKey]) {\r\n return props.fieldData[fieldKey]\r\n }\r\n return null\r\n } else {\r\n // URL输入\r\n return element.imageUrl || null\r\n }\r\n}\r\n\r\n// 获取二维码内容(与图片使用相同的逻辑)\r\nconst getQrcodeContent = (element) => {\r\n if (!element) return null\r\n \r\n if (element.qrcodeSource === 'field') {\r\n // 关联字段,从fieldData中获取\r\n const fieldKey = element.qrcodeField\r\n if (fieldKey && props.fieldData && props.fieldData[fieldKey]) {\r\n return props.fieldData[fieldKey]\r\n }\r\n return null\r\n } else {\r\n // URL输入或文本内容\r\n return element.qrcodeContent || null\r\n }\r\n}\r\n\r\n// 判断是否为图片URL\r\nconst isImageUrl = (url) => {\r\n if (!url) return false\r\n // 检查是否是base64图片\r\n if (url.startsWith('data:image/')) return true\r\n // 检查是否是http/https图片URL\r\n if (url.startsWith('http://') || url.startsWith('https://')) {\r\n // 检查是否是图片文件扩展名\r\n const imageExtensions = ['.jpg', '.jpeg', '.png', '.gif', '.webp', '.svg', '.bmp']\r\n const lowerUrl = url.toLowerCase()\r\n return imageExtensions.some(ext => lowerUrl.includes(ext))\r\n }\r\n return false\r\n}\r\n\r\n// 获取画布样式\r\nconst getCanvasStyle = () => {\r\n const baseStyle = {}\r\n \r\n if (props.template) {\r\n baseStyle.width = `${props.template.width}px`\r\n baseStyle.minHeight = `${props.template.height}px`\r\n } else {\r\n baseStyle.width = '800px'\r\n baseStyle.minHeight = '1000px'\r\n }\r\n \r\n // 将背景直接应用到画布\r\n if (props.template && props.template.background) {\r\n if (props.template.background.startsWith('data:') || props.template.background.startsWith('http')) {\r\n baseStyle.backgroundImage = `url(${props.template.background})`\r\n baseStyle.backgroundSize = '100% 100%'\r\n baseStyle.backgroundPosition = 'center'\r\n baseStyle.backgroundRepeat = 'no-repeat'\r\n } else {\r\n baseStyle.background = props.template.background\r\n baseStyle.backgroundSize = '100% 100%'\r\n baseStyle.backgroundPosition = 'center'\r\n baseStyle.backgroundRepeat = 'no-repeat'\r\n }\r\n }\r\n \r\n return baseStyle\r\n}\r\n\r\nconst canvasRef = ref(null)\r\nconst isDragging = ref(false)\r\nconst isResizing = ref(false)\r\nconst dragStart = ref({ x: 0, y: 0 })\r\nconst resizeStart = ref({ x: 0, y: 0, width: 0, height: 0 })\r\nconst currentElement = ref(null)\r\nconst resizeDirection = ref('')\r\n\r\nconst getElementStyle = (element) => {\r\n const baseStyle = {\r\n position: 'absolute',\r\n left: `${element.x}px`,\r\n top: `${element.y}px`,\r\n width: `${element.width}px`,\r\n minHeight: `${element.height}px`\r\n }\r\n \r\n if (element.type === 'text' || element.type === 'longtext') {\r\n return {\r\n ...baseStyle,\r\n fontSize: `${element.style?.fontSize || 18}px`,\r\n fontFamily: element.style?.fontFamily || '方正书宋简体',\r\n fontWeight: element.style?.fontWeight || 'normal',\r\n fontStyle: element.style?.fontStyle || 'normal',\r\n textDecoration: element.style?.textDecoration || 'none',\r\n color: element.style?.color || '#000000',\r\n textAlign: element.style?.textAlign || 'left',\r\n lineHeight: element.style?.lineHeight || 1.2\r\n }\r\n }\r\n \r\n return baseStyle\r\n}\r\n\r\nconst handleMouseDown = (e, element) => {\r\n if (e.target.closest('.handle') || e.target.closest('.delete-btn')) {\r\n return\r\n }\r\n \r\n isDragging.value = true\r\n currentElement.value = element\r\n dragStart.value = {\r\n x: e.clientX - element.x,\r\n y: e.clientY - element.y\r\n }\r\n \r\n document.addEventListener('mousemove', handleMouseMove)\r\n document.addEventListener('mouseup', handleMouseUp)\r\n}\r\n\r\nconst handleMouseMove = (e) => {\r\n if (isDragging.value && currentElement.value) {\r\n const newX = e.clientX - dragStart.value.x\r\n const newY = e.clientY - dragStart.value.y\r\n \r\n const updatedElement = {\r\n ...currentElement.value,\r\n x: Math.max(0, newX),\r\n y: Math.max(0, newY)\r\n }\r\n \r\n emit('update-element', updatedElement)\r\n } else if (isResizing.value && currentElement.value) {\r\n const deltaX = e.clientX - resizeStart.value.x\r\n const deltaY = e.clientY - resizeStart.value.y\r\n \r\n let newWidth = resizeStart.value.width\r\n let newHeight = resizeStart.value.height\r\n let newX = currentElement.value.x\r\n let newY = currentElement.value.y\r\n \r\n if (resizeDirection.value.includes('e')) {\r\n newWidth = Math.max(50, resizeStart.value.width + deltaX)\r\n }\r\n if (resizeDirection.value.includes('w')) {\r\n newWidth = Math.max(50, resizeStart.value.width - deltaX)\r\n newX = currentElement.value.x + (resizeStart.value.width - newWidth)\r\n }\r\n if (resizeDirection.value.includes('s')) {\r\n newHeight = Math.max(30, resizeStart.value.height + deltaY)\r\n }\r\n if (resizeDirection.value.includes('n')) {\r\n newHeight = Math.max(30, resizeStart.value.height - deltaY)\r\n newY = currentElement.value.y + (resizeStart.value.height - newHeight)\r\n }\r\n \r\n const updatedElement = {\r\n ...currentElement.value,\r\n x: newX,\r\n y: newY,\r\n width: newWidth,\r\n height: newHeight\r\n }\r\n \r\n emit('update-element', updatedElement)\r\n }\r\n}\r\n\r\nconst handleMouseUp = () => {\r\n isDragging.value = false\r\n isResizing.value = false\r\n currentElement.value = null\r\n resizeDirection.value = ''\r\n \r\n document.removeEventListener('mousemove', handleMouseMove)\r\n document.removeEventListener('mouseup', handleMouseUp)\r\n}\r\n\r\nconst handleResizeStart = (e, element, direction) => {\r\n e.stopPropagation()\r\n isResizing.value = true\r\n currentElement.value = element\r\n resizeDirection.value = direction\r\n resizeStart.value = {\r\n x: e.clientX,\r\n y: e.clientY,\r\n width: element.width,\r\n height: element.height\r\n }\r\n \r\n document.addEventListener('mousemove', handleMouseMove)\r\n document.addEventListener('mouseup', handleMouseUp)\r\n}\r\n\r\nonUnmounted(() => {\r\n document.removeEventListener('mousemove', handleMouseMove)\r\n document.removeEventListener('mouseup', handleMouseUp)\r\n})\r\n</script>\r\n\r\n<style scoped>\r\n.canvas-area {\r\n width: 100%;\r\n height: 100%;\r\n overflow: auto;\r\n background: #f0f0f0;\r\n display: flex;\r\n justify-content: center;\r\n align-items: flex-start;\r\n padding: 40px 20px;\r\n}\r\n\r\n.certificate-canvas {\r\n position: relative;\r\n width: 800px;\r\n min-height: 1000px;\r\n background: #fff;\r\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);\r\n padding: 60px 50px;\r\n}\r\n\r\n.certificate-border {\r\n position: absolute;\r\n top: 0;\r\n left: 0;\r\n right: 0;\r\n bottom: 0;\r\n border: 12px solid #1890ff;\r\n background-image: \r\n repeating-linear-gradient(\r\n 0deg,\r\n transparent,\r\n transparent 2px,\r\n rgba(255, 255, 255, 0.1) 2px,\r\n rgba(255, 255, 255, 0.1) 4px\r\n ),\r\n repeating-linear-gradient(\r\n 90deg,\r\n transparent,\r\n transparent 2px,\r\n rgba(255, 255, 255, 0.1) 2px,\r\n rgba(255, 255, 255, 0.1) 4px\r\n );\r\n background-size: 20px 20px;\r\n box-shadow: \r\n inset 0 0 0 2px rgba(255, 255, 255, 0.3),\r\n inset 0 0 0 4px #1890ff,\r\n inset 0 0 0 6px rgba(255, 255, 255, 0.3);\r\n}\r\n\r\n.editable-element {\r\n position: absolute;\r\n border: 1px dashed #ccc;\r\n cursor: move;\r\n min-width: 50px;\r\n min-height: 30px;\r\n padding: 4px;\r\n}\r\n\r\n.editable-element.selected {\r\n border-color: #1890ff;\r\n border-width: 2px;\r\n background: rgba(24, 144, 255, 0.05);\r\n}\r\n\r\n.editable-element.text,\r\n.editable-element.longtext {\r\n border: 1px dashed #999;\r\n}\r\n\r\n.editable-element.text.selected,\r\n.editable-element.longtext.selected {\r\n border-color: #1890ff;\r\n border-width: 2px;\r\n}\r\n\r\n.text-content {\r\n width: 100%;\r\n height: 100%;\r\n word-wrap: break-word;\r\n white-space: pre-wrap;\r\n padding: 2px;\r\n min-height: 20px;\r\n}\r\n\r\n.field-placeholder-highlight {\r\n background: #e6f7ff;\r\n color: #1890ff;\r\n padding: 2px 4px;\r\n border-radius: 2px;\r\n font-weight: 500;\r\n}\r\n\r\n.field-value {\r\n color: #52c41a;\r\n font-weight: 500;\r\n}\r\n\r\n.image-placeholder,\r\n.qrcode-placeholder {\r\n width: 100%;\r\n height: 100%;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n background: #f5f5f5;\r\n border: 1px dashed #ccc;\r\n color: #999;\r\n}\r\n\r\n.image-element,\r\n.qrcode-element {\r\n width: 100%;\r\n height: 100%;\r\n overflow: hidden;\r\n}\r\n\r\n.element-image {\r\n width: 100%;\r\n height: 100%;\r\n object-fit: contain;\r\n display: block;\r\n}\r\n\r\n.qrcode-content {\r\n width: 100%;\r\n height: 100%;\r\n display: flex;\r\n flex-direction: column;\r\n align-items: center;\r\n justify-content: center;\r\n background: #f5f5f5;\r\n border: 1px dashed #ccc;\r\n padding: 8px;\r\n}\r\n\r\n.qrcode-placeholder-text {\r\n font-size: 12px;\r\n color: #999;\r\n margin-bottom: 4px;\r\n}\r\n\r\n.qrcode-info {\r\n font-size: 10px;\r\n color: #666;\r\n word-break: break-all;\r\n text-align: center;\r\n}\r\n\r\n.resize-handles {\r\n position: absolute;\r\n top: -4px;\r\n left: -4px;\r\n right: -4px;\r\n bottom: -4px;\r\n pointer-events: none;\r\n}\r\n\r\n.handle {\r\n position: absolute;\r\n width: 8px;\r\n height: 8px;\r\n background: #1890ff;\r\n border: 1px solid #fff;\r\n pointer-events: all;\r\n cursor: nwse-resize;\r\n}\r\n\r\n.handle-nw {\r\n top: -4px;\r\n left: -4px;\r\n cursor: nwse-resize;\r\n}\r\n\r\n.handle-ne {\r\n top: -4px;\r\n right: -4px;\r\n cursor: nesw-resize;\r\n}\r\n\r\n.handle-sw {\r\n bottom: -4px;\r\n left: -4px;\r\n cursor: nesw-resize;\r\n}\r\n\r\n.handle-se {\r\n bottom: -4px;\r\n right: -4px;\r\n cursor: nwse-resize;\r\n}\r\n\r\n.delete-btn {\r\n position: absolute;\r\n top: -12px;\r\n right: -12px;\r\n width: 24px;\r\n height: 24px;\r\n border-radius: 50%;\r\n background: #ff4d4f;\r\n color: #fff;\r\n border: none;\r\n cursor: pointer;\r\n font-size: 18px;\r\n line-height: 1;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);\r\n}\r\n\r\n.delete-btn:hover {\r\n background: #ff7875;\r\n}\r\n</style>\r\n","<template>\r\n <div v-if=\"visible\" class=\"field-dialog-overlay\" @click.self=\"handleClose\">\r\n <div class=\"field-dialog\">\r\n <div class=\"dialog-header\">\r\n <h3>选择字段</h3>\r\n <button class=\"close-btn\" @click=\"handleClose\">×</button>\r\n </div>\r\n \r\n <div class=\"dialog-content\">\r\n <div class=\"search-box\">\r\n <input \r\n type=\"text\" \r\n v-model=\"searchText\"\r\n placeholder=\"搜索字段...\"\r\n class=\"search-input\"\r\n @input=\"handleSearch\"\r\n />\r\n </div>\r\n \r\n <div class=\"table-container\">\r\n <table class=\"fields-table\">\r\n <thead>\r\n <tr>\r\n <th>系统字段</th>\r\n <th>操作</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr\r\n v-for=\"field in paginatedFields\"\r\n :key=\"field.key\"\r\n class=\"field-row\"\r\n >\r\n <td class=\"field-name\">{{ field.label }}</td>\r\n <td class=\"field-action\">\r\n <button \r\n class=\"select-btn\"\r\n @click=\"handleSelectField(field)\"\r\n >\r\n 选择\r\n </button>\r\n </td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n \r\n <!-- 分页 -->\r\n <div class=\"pagination\" v-if=\"totalPages > 1\">\r\n <button \r\n class=\"page-btn\"\r\n :disabled=\"currentPage === 1\"\r\n @click=\"goToPage(currentPage - 1)\"\r\n >\r\n <\r\n </button>\r\n <button\r\n v-for=\"page in totalPages\"\r\n :key=\"page\"\r\n class=\"page-btn\"\r\n :class=\"{ active: page === currentPage }\"\r\n @click=\"goToPage(page)\"\r\n >\r\n {{ page }}\r\n </button>\r\n <button \r\n class=\"page-btn\"\r\n :disabled=\"currentPage === totalPages\"\r\n @click=\"goToPage(currentPage + 1)\"\r\n >\r\n >\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</template>\r\n\r\n<script setup>\r\nimport { ref, computed } from 'vue'\r\nimport { SYSTEM_FIELDS } from '../utils/fieldManager.js'\r\n\r\nconst props = defineProps({\r\n visible: {\r\n type: Boolean,\r\n default: false\r\n },\r\n currentText: {\r\n type: String,\r\n default: ''\r\n },\r\n selectionStart: {\r\n type: Number,\r\n default: 0\r\n },\r\n selectionEnd: {\r\n type: Number,\r\n default: 0\r\n },\r\n systemFields: {\r\n type: Array,\r\n default: () => SYSTEM_FIELDS\r\n }\r\n})\r\n\r\nconst emit = defineEmits(['close', 'insert'])\r\n\r\nconst searchText = ref('')\r\nconst currentPage = ref(1)\r\nconst pageSize = 10\r\n\r\n// 过滤后的字段列表\r\nconst filteredFields = computed(() => {\r\n if (!searchText.value.trim()) {\r\n return props.systemFields\r\n }\r\n \r\n const searchLower = searchText.value.toLowerCase()\r\n return props.systemFields.filter(field => \r\n field.label.toLowerCase().includes(searchLower) ||\r\n field.key.toLowerCase().includes(searchLower) ||\r\n (field.description && field.description.toLowerCase().includes(searchLower))\r\n )\r\n})\r\n\r\n// 总页数\r\nconst totalPages = computed(() => {\r\n return Math.ceil(filteredFields.value.length / pageSize)\r\n})\r\n\r\n// 当前页的字段\r\nconst paginatedFields = computed(() => {\r\n const start = (currentPage.value - 1) * pageSize\r\n const end = start + pageSize\r\n return filteredFields.value.slice(start, end)\r\n})\r\n\r\n// 搜索时重置到第一页\r\nconst handleSearch = () => {\r\n currentPage.value = 1\r\n}\r\n\r\n// 跳转到指定页\r\nconst goToPage = (page) => {\r\n if (page >= 1 && page <= totalPages.value) {\r\n currentPage.value = page\r\n }\r\n}\r\n\r\n// 选择字段并立即插入\r\nconst handleSelectField = (field) => {\r\n emit('insert', [field])\r\n // 不关闭对话框,允许继续选择其他字段\r\n}\r\n\r\n// 关闭对话框\r\nconst handleClose = () => {\r\n searchText.value = ''\r\n currentPage.value = 1\r\n emit('close')\r\n}\r\n</script>\r\n\r\n<style scoped>\r\n.field-dialog-overlay {\r\n position: fixed;\r\n top: 0;\r\n left: 0;\r\n right: 0;\r\n bottom: 0;\r\n background: rgba(0, 0, 0, 0.5);\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n z-index: 1000;\r\n}\r\n\r\n.field-dialog {\r\n background: #fff;\r\n border-radius: 8px;\r\n width: 600px;\r\n max-height: 80vh;\r\n display: flex;\r\n flex-direction: column;\r\n box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);\r\n}\r\n\r\n.dialog-header {\r\n display: flex;\r\n justify-content: space-between;\r\n align-items: center;\r\n padding: 16px 20px;\r\n border-bottom: 1px solid #e0e0e0;\r\n}\r\n\r\n.dialog-header h3 {\r\n font-size: 18px;\r\n font-weight: 500;\r\n color: #333;\r\n margin: 0;\r\n}\r\n\r\n.close-btn {\r\n width: 32px;\r\n height: 32px;\r\n border: none;\r\n background: transparent;\r\n font-size: 24px;\r\n color: #999;\r\n cursor: pointer;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n border-radius: 4px;\r\n transition: all 0.3s;\r\n}\r\n\r\n.close-btn:hover {\r\n background: #f5f5f5;\r\n color: #333;\r\n}\r\n\r\n.dialog-content {\r\n flex: 1;\r\n display: flex;\r\n flex-direction: column;\r\n padding: 20px;\r\n overflow: hidden;\r\n}\r\n\r\n.search-box {\r\n margin-bottom: 16px;\r\n}\r\n\r\n.search-input {\r\n width: 100%;\r\n padding: 8px 12px;\r\n border: 1px solid #d9d9d9;\r\n border-radius: 4px;\r\n font-size: 14px;\r\n}\r\n\r\n.search-input:focus {\r\n outline: none;\r\n border-color: #1890ff;\r\n}\r\n\r\n.table-container {\r\n flex: 1;\r\n overflow-y: auto;\r\n border: 1px solid #e0e0e0;\r\n border-radius: 4px;\r\n}\r\n\r\n.fields-table {\r\n width: 100%;\r\n border-collapse: collapse;\r\n background: #fff;\r\n}\r\n\r\n.fields-table thead {\r\n background: #fafafa;\r\n position: sticky;\r\n top: 0;\r\n z-index: 10;\r\n}\r\n\r\n.fields-table th {\r\n padding: 12px 16px;\r\n text-align: left;\r\n font-size: 14px;\r\n font-weight: 500;\r\n color: #333;\r\n border-bottom: 1px solid #e0e0e0;\r\n}\r\n\r\n.fields-table th:first-child {\r\n width: 70%;\r\n}\r\n\r\n.fields-table th:last-child {\r\n width: 30%;\r\n text-align: center;\r\n}\r\n\r\n.fields-table tbody tr {\r\n border-bottom: 1px solid #f0f0f0;\r\n transition: background 0.2s;\r\n}\r\n\r\n.fields-table tbody tr:hover {\r\n background: #fafafa;\r\n}\r\n\r\n.fields-table tbody tr:last-child {\r\n border-bottom: none;\r\n}\r\n\r\n.field-row {\r\n cursor: pointer;\r\n}\r\n\r\n.field-name {\r\n padding: 12px 16px;\r\n font-size: 14px;\r\n color: #333;\r\n}\r\n\r\n.field-action {\r\n padding: 12px 16px;\r\n text-align: center;\r\n}\r\n\r\n.select-btn {\r\n padding: 4px 16px;\r\n border: 1px solid #1890ff;\r\n background: #fff;\r\n color: #1890ff;\r\n border-radius: 4px;\r\n font-size: 14px;\r\n cursor: pointer;\r\n transition: all 0.3s;\r\n}\r\n\r\n.select-btn:hover {\r\n background: #1890ff;\r\n color: #fff;\r\n}\r\n\r\n.pagination {\r\n display: flex;\r\n justify-content: center;\r\n align-items: center;\r\n gap: 8px;\r\n margin-top: 16px;\r\n padding-top: 16px;\r\n border-top: 1px solid #e0e0e0;\r\n}\r\n\r\n.page-btn {\r\n min-width: 32px;\r\n height: 32px;\r\n padding: 0 8px;\r\n border: 1px solid #d9d9d9;\r\n background: #fff;\r\n color: #333;\r\n border-radius: 4px;\r\n font-size: 14px;\r\n cursor: pointer;\r\n transition: all 0.3s;\r\n}\r\n\r\n.page-btn:hover:not(:disabled) {\r\n border-color: #1890ff;\r\n color: #1890ff;\r\n}\r\n\r\n.page-btn.active {\r\n background: #1890ff;\r\n border-color: #1890ff;\r\n color: #fff;\r\n}\r\n\r\n.page-btn:disabled {\r\n opacity: 0.5;\r\n cursor: not-allowed;\r\n}\r\n</style>\r\n","<template>\r\n <div class=\"properties-panel\">\r\n <div class=\"panel-header\">\r\n <h3>属性设置</h3>\r\n </div>\r\n \r\n <div class=\"panel-content\">\r\n <!-- 文本/长文本内容编辑 -->\r\n <div v-if=\"element.type === 'text' || element.type === 'longtext'\" class=\"content-section\">\r\n <div class=\"form-group\">\r\n <label class=\"form-label\">内容</label>\r\n <div class=\"content-input-wrapper\">\r\n <textarea\r\n ref=\"contentTextareaRef\"\r\n v-model=\"localContent\"\r\n @input=\"handleContentChange\"\r\n @focus=\"handleTextareaFocus\"\r\n :rows=\"element.type === 'longtext' ? 6 : 3\"\r\n class=\"content-textarea\"\r\n ></textarea>\r\n <button class=\"insert-field-btn\" @click=\"showFieldDialog = true\">\r\n <span>+</span>\r\n <span>在内容中关联系统字段</span>\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n \r\n <!-- 文本样式设置 -->\r\n <div v-if=\"element.type === 'text' || element.type === 'longtext'\" class=\"style-section\">\r\n <div class=\"section-title\">文本样式</div>\r\n \r\n <div class=\"form-group\">\r\n <label class=\"form-label\">字体大小</label>\r\n <select v-model.number=\"localStyle.fontSize\" @change=\"updateElement\" class=\"form-select\">\r\n <option :value=\"12\">12px</option>\r\n <option :value=\"14\">14px</option>\r\n <option :value=\"16\">16px</option>\r\n <option :value=\"18\">18px</option>\r\n <option :value=\"20\">20px</option>\r\n <option :value=\"24\">24px</option>\r\n <option :value=\"28\">28px</option>\r\n <option :value=\"32\">32px</option>\r\n <option :value=\"36\">36px</option>\r\n <option :value=\"48\">48px</option>\r\n </select>\r\n </div>\r\n \r\n <div class=\"form-group\">\r\n <label class=\"form-label\">字体</label>\r\n <select v-model=\"localStyle.fontFamily\" @change=\"updateElement\" class=\"form-select\">\r\n <option value=\"方正书宋简体\">方正书宋简体</option>\r\n <option value=\"微软雅黑\">微软雅黑</option>\r\n <option value=\"宋体\">宋体</option>\r\n <option value=\"黑体\">黑体</option>\r\n <option value=\"Arial\">Arial</option>\r\n </select>\r\n </div>\r\n \r\n <div class=\"form-group\">\r\n <label class=\"form-label\">文字样式</label>\r\n <div class=\"style-buttons\">\r\n <button \r\n :class=\"['style-btn', { active: localStyle.fontWeight === 'bold' }]\"\r\n @click=\"toggleStyle('fontWeight', 'bold', 'normal')\"\r\n >\r\n <strong>B</strong>\r\n </button>\r\n <button \r\n :class=\"['style-btn', { active: localStyle.fontStyle === 'italic' }]\"\r\n @click=\"toggleStyle('fontStyle', 'italic', 'normal')\"\r\n >\r\n <em>I</em>\r\n </button>\r\n <button \r\n :class=\"['style-btn', { active: localStyle.textDecoration === 'underline' }]\"\r\n @click=\"toggleStyle('textDecoration', 'underline', 'none')\"\r\n >\r\n <u>U</u>\r\n </button>\r\n </div>\r\n </div>\r\n \r\n <div class=\"form-group\">\r\n <label class=\"form-label\">颜色</label>\r\n <input \r\n type=\"color\" \r\n v-model=\"localStyle.color\" \r\n @change=\"updateElement\"\r\n class=\"color-input\"\r\n />\r\n </div>\r\n \r\n <div class=\"form-group\">\r\n <label class=\"form-label\">对齐方式</label>\r\n <div class=\"align-buttons\">\r\n <button \r\n :class=\"['align-btn', { active: localStyle.textAlign === 'left' }]\"\r\n @click=\"setAlign('left')\"\r\n >\r\n 左对齐\r\n </button>\r\n <button \r\n :class=\"['align-btn', { active: localStyle.textAlign === 'center' }]\"\r\n @click=\"setAlign('center')\"\r\n >\r\n 居中\r\n </button>\r\n <button \r\n :class=\"['align-btn', { active: localStyle.textAlign === 'right' }]\"\r\n @click=\"setAlign('right')\"\r\n >\r\n 右对齐\r\n </button>\r\n </div>\r\n </div>\r\n \r\n <div class=\"form-group\">\r\n <label class=\"form-label\">行高</label>\r\n <input \r\n type=\"number\" \r\n v-model.number=\"localStyle.lineHeight\" \r\n @input=\"updateElement\"\r\n step=\"0.1\"\r\n min=\"0.5\"\r\n max=\"3\"\r\n class=\"form-input\"\r\n />\r\n </div>\r\n </div>\r\n \r\n <!-- 图片设置 -->\r\n <div v-if=\"element.type === 'image'\" class=\"image-section\">\r\n <div class=\"section-title\">图片设置</div>\r\n \r\n <div class=\"form-group\">\r\n <label class=\"form-label\">图片来源</label>\r\n <div class=\"radio-group\">\r\n <label class=\"radio-label\">\r\n <input \r\n type=\"radio\" \r\n value=\"url\" \r\n v-model=\"localImageSource\"\r\n @change=\"handleImageSourceChange\"\r\n />\r\n <span>URL</span>\r\n </label>\r\n <label class=\"radio-label\">\r\n <input \r\n type=\"radio\" \r\n value=\"field\" \r\n v-model=\"localImageSource\"\r\n @change=\"handleImageSourceChange\"\r\n />\r\n <span>关联字段</span>\r\n </label>\r\n </div>\r\n </div>\r\n \r\n <div v-if=\"localImageSource === 'url'\" class=\"form-group\">\r\n <label class=\"form-label\">图片URL</label>\r\n <div class=\"image-upload-wrapper\">\r\n <input\r\n ref=\"imageFileInputRef\"\r\n type=\"file\"\r\n accept=\"image/jpeg,image/jpg,image/png\"\r\n @change=\"handleImageUpload\"\r\n style=\"display: none\"\r\n />\r\n <button class=\"upload-btn\" @click=\"triggerImageUpload\">\r\n <span>📁</span>\r\n <span>本地上传</span>\r\n </button>\r\n <input \r\n type=\"text\" \r\n v-model=\"localImageUrl\" \r\n @input=\"updateElement\"\r\n placeholder=\"请输入图片URL\"\r\n class=\"image-url-input\"\r\n />\r\n <button v-if=\"localImageUrl\" class=\"remove-btn\" @click=\"removeImage\">移除</button>\r\n </div>\r\n <div v-if=\"localImageUrl\" class=\"image-preview\">\r\n <img :src=\"localImageUrl\" alt=\"预览\" />\r\n </div>\r\n </div>\r\n \r\n <div v-if=\"localImageSource === 'field'\" class=\"form-group\">\r\n <label class=\"form-label\">关联字段</label>\r\n <select v-model=\"localImageField\" @change=\"updateElement\" class=\"form-select\">\r\n <option value=\"\">请选择字段</option>\r\n <option value=\"avatar\">头像 (avatar)</option>\r\n <option value=\"photo\">照片 (photo)</option>\r\n <option value=\"headImage\">头像图片 (headImage)</option>\r\n <option v-for=\"field in systemFields\" :key=\"field.key\" :value=\"field.key\">\r\n {{ field.label }} ({{ field.placeholder }})\r\n </option>\r\n </select>\r\n <div v-if=\"localImageField\" class=\"field-preview\">\r\n 字段: {{ getFieldLabel(localImageField) }}\r\n </div>\r\n </div>\r\n </div>\r\n \r\n <!-- 二维码设置 -->\r\n <div v-if=\"element.type === 'qrcode'\" class=\"qrcode-section\">\r\n <div class=\"section-title\">二维码设置</div>\r\n \r\n <div class=\"form-group\">\r\n <label class=\"form-label\">二维码来源</label>\r\n <div class=\"radio-group\">\r\n <label class=\"radio-label\">\r\n <input \r\n type=\"radio\" \r\n value=\"url\" \r\n v-model=\"localQrcodeSource\"\r\n @change=\"handleQrcodeSourceChange\"\r\n />\r\n <span>URL/内容</span>\r\n </label>\r\n <label class=\"radio-label\">\r\n <input \r\n type=\"radio\" \r\n value=\"field\" \r\n v-model=\"localQrcodeSource\"\r\n @change=\"handleQrcodeSourceChange\"\r\n />\r\n <span>关联字段</span>\r\n </label>\r\n </div>\r\n </div>\r\n \r\n <div v-if=\"localQrcodeSource === 'url'\" class=\"form-group\">\r\n <label class=\"form-label\">二维码内容/图片URL</label>\r\n <div class=\"qrcode-upload-wrapper\">\r\n <input\r\n ref=\"qrcodeFileInputRef\"\r\n type=\"file\"\r\n accept=\"image/jpeg,image/jpg,image/png\"\r\n @change=\"handleQrcodeUpload\"\r\n style=\"display: none\"\r\n />\r\n <button class=\"upload-btn\" @click=\"triggerQrcodeUpload\">\r\n <span>📁</span>\r\n <span>本地上传</span>\r\n </button>\r\n <input \r\n type=\"text\" \r\n v-model=\"localQrcodeContent\" \r\n @input=\"updateElement\"\r\n placeholder=\"请输入二维码内容或图片URL\"\r\n class=\"qrcode-input\"\r\n />\r\n <button v-if=\"localQrcodeContent\" class=\"remove-btn\" @click=\"removeQrcode\">移除</button>\r\n </div>\r\n <div v-if=\"localQrcodeContent && isImageUrl(localQrcodeContent)\" class=\"qrcode-preview\">\r\n <img :src=\"localQrcodeContent\" alt=\"预览\" />\r\n </div>\r\n </div>\r\n \r\n <div v-if=\"localQrcodeSource === 'field'\" class=\"form-group\">\r\n <label class=\"form-label\">关联字段</label>\r\n <select v-model=\"localQrcodeField\" @change=\"updateElement\" class=\"form-select\">\r\n <option value=\"\">请选择字段</option>\r\n <option value=\"certificateNumber\">证书编号 (certificateNumber)</option>\r\n <option value=\"idNumber\">身份证号 (idNumber)</option>\r\n <option value=\"url\">链接地址 (url)</option>\r\n <option value=\"examName\">考试名称 (examName)</option>\r\n <option v-for=\"field in systemFields\" :key=\"field.key\" :value=\"field.key\">\r\n {{ field.label }} ({{ field.placeholder }})\r\n </option>\r\n </select>\r\n <div v-if=\"localQrcodeField\" class=\"field-preview\">\r\n 字段: {{ getFieldLabel(localQrcodeField) }}\r\n </div>\r\n </div>\r\n </div>\r\n \r\n <!-- 位置和尺寸 -->\r\n <div class=\"position-section\">\r\n <div class=\"section-title\">位置和尺寸</div>\r\n \r\n <div class=\"form-row\">\r\n <div class=\"form-group\">\r\n <label class=\"form-label\">X</label>\r\n <input \r\n type=\"number\" \r\n v-model.number=\"element.x\" \r\n @input=\"updateElement\"\r\n class=\"form-input\"\r\n />\r\n </div>\r\n <div class=\"form-group\">\r\n <label class=\"form-label\">Y</label>\r\n <input \r\n type=\"number\" \r\n v-model.number=\"element.y\" \r\n @input=\"updateElement\"\r\n class=\"form-input\"\r\n />\r\n </div>\r\n </div>\r\n \r\n <div class=\"form-row\">\r\n <div class=\"form-group\">\r\n <label class=\"form-label\">宽度</label>\r\n <input \r\n type=\"number\" \r\n v-model.number=\"element.width\" \r\n @input=\"updateElement\"\r\n class=\"form-input\"\r\n />\r\n </div>\r\n <div class=\"form-group\">\r\n <label class=\"form-label\">高度</label>\r\n <input \r\n type=\"number\" \r\n v-model.number=\"element.height\" \r\n @input=\"updateElement\"\r\n class=\"form-input\"\r\n />\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n \r\n <!-- 字段选择对话框 -->\r\n <FieldDialog\r\n :visible=\"showFieldDialog\"\r\n :current-text=\"localContent\"\r\n :selection-start=\"selectionStart\"\r\n :selection-end=\"selectionEnd\"\r\n :system-fields=\"systemFields\"\r\n @close=\"showFieldDialog = false\"\r\n @insert=\"handleInsertField\"\r\n />\r\n </div>\r\n</template>\r\n\r\n<script setup>\r\nimport { ref, watch, computed } from 'vue'\r\nimport FieldDialog from './FieldDialog.vue'\r\nimport { SYSTEM_FIELDS, getFieldByKey } from '../utils/fieldManager.js'\r\nimport { validateImageFile, fileToBase64 } from '../utils/templateManager.js'\r\n\r\nconst props = defineProps({\r\n element: {\r\n type: Object,\r\n required: true\r\n },\r\n systemFields: {\r\n type: Array,\r\n default: () => SYSTEM_FIELDS\r\n }\r\n})\r\n\r\nconst emit = defineEmits(['update-element'])\r\n\r\n// 本地状态\r\nconst localContent = ref('')\r\nconst localStyle = ref({})\r\nconst localImageSource = ref('url')\r\nconst localImageUrl = ref('')\r\nconst localImageField = ref('')\r\nconst localQrcodeSource = ref('url')\r\nconst localQrcodeContent = ref('')\r\nconst localQrcodeField = ref('')\r\nconst showFieldDialog = ref(false)\r\nconst selectionStart = ref(0)\r\nconst selectionEnd = ref(0)\r\nconst contentTextareaRef = ref(null)\r\nconst imageFileInputRef = ref(null)\r\nconst qrcodeFileInputRef = ref(null)\r\n\r\n// 初始化本地状态\r\nconst initLocalState = () => {\r\n localContent.value = props.element.content || ''\r\n localStyle.value = { ...props.element.style } || {}\r\n \r\n if (props.element.type === 'image') {\r\n localImageSource.value = props.element.imageSource || 'url'\r\n localImageUrl.value = props.element.imageUrl || ''\r\n localImageField.value = props.element.imageField || ''\r\n }\r\n \r\n if (props.element.type === 'qrcode') {\r\n localQrcodeSource.value = props.element.qrcodeSource || 'url'\r\n localQrcodeContent.value = props.element.qrcodeContent || ''\r\n localQrcodeField.value = props.element.qrcodeField || ''\r\n }\r\n}\r\n\r\n// 监听element变化\r\nwatch(() => props.element, initLocalState, { immediate: true, deep: true })\r\n\r\n// 更新元素\r\nconst updateElement = () => {\r\n const updated = { ...props.element }\r\n \r\n if (props.element.type === 'text' || props.element.type === 'longtext') {\r\n updated.content = localContent.value\r\n updated.style = { ...localStyle.value }\r\n }\r\n \r\n if (props.element.type === 'image') {\r\n updated.imageSource = localImageSource.value\r\n updated.imageUrl = localImageUrl.value\r\n updated.imageField = localImageField.value\r\n }\r\n \r\n if (props.element.type === 'qrcode') {\r\n updated.qrcodeSource = localQrcodeSource.value\r\n updated.qrcodeContent = localQrcodeContent.value\r\n updated.qrcodeField = localQrcodeField.value\r\n }\r\n \r\n emit('update-element', updated)\r\n}\r\n\r\nconst handleContentChange = () => {\r\n updateElement()\r\n}\r\n\r\nconst handleTextareaFocus = (e) => {\r\n selectionStart.value = e.target.selectionStart\r\n selectionEnd.value = e.target.selectionEnd\r\n}\r\n\r\nconst handleInsertField = (fields) => {\r\n if (fields.length > 0) {\r\n const field = fields[0]\r\n const textarea = contentTextareaRef.value\r\n if (textarea) {\r\n const start = selectionStart.value\r\n const end = selectionEnd.value\r\n const text = localContent.value\r\n const newText = text.substring(0, start) + field.placeholder + text.substring(end)\r\n localContent.value = newText\r\n \r\n // 设置光标位置\r\n setTimeout(() => {\r\n const newPos = start + field.placeholder.length\r\n textarea.setSelectionRange(newPos, newPos)\r\n textarea.focus()\r\n }, 0)\r\n \r\n updateElement()\r\n }\r\n }\r\n}\r\n\r\nconst toggleStyle = (property, value1, value2) => {\r\n localStyle.value[property] = localStyle.value[property] === value1 ? value2 : value1\r\n updateElement()\r\n}\r\n\r\nconst setAlign = (align) => {\r\n localStyle.value.textAlign = align\r\n updateElement()\r\n}\r\n\r\nconst handleImageSourceChange = () => {\r\n updateElement()\r\n}\r\n\r\nconst triggerImageUpload = () => {\r\n imageFileInputRef.value?.click()\r\n}\r\n\r\nconst handleImageUpload = async (event) => {\r\n const file = event.target.files?.[0]\r\n if (!file) return\r\n \r\n const validation = validateImageFile(file)\r\n if (!validation.valid) {\r\n alert(validation.error)\r\n return\r\n }\r\n \r\n try {\r\n const base64 = await fileToBase64(file)\r\n localImageUrl.value = base64\r\n localImageSource.value = 'url'\r\n updateElement()\r\n } catch (error) {\r\n alert('上传失败,请重试')\r\n console.error(error)\r\n }\r\n \r\n if (imageFileInputRef.value) {\r\n imageFileInputRef.value.value = ''\r\n }\r\n}\r\n\r\nconst removeImage = () => {\r\n localImageUrl.value = ''\r\n updateElement()\r\n}\r\n\r\nconst handleQrcodeSourceChange = () => {\r\n updateElement()\r\n}\r\n\r\nconst triggerQrcodeUpload = () => {\r\n qrcodeFileInputRef.value?.click()\r\n}\r\n\r\nconst handleQrcodeUpload = async (event) => {\r\n const file = event.target.files?.[0]\r\n if (!file) return\r\n \r\n const validation = validateImageFile(file)\r\n if (!validation.valid) {\r\n alert(validation.error)\r\n return\r\n }\r\n \r\n try {\r\n const base64 = await fileToBase64(file)\r\n localQrcodeContent.value = base64\r\n localQrcodeSource.value = 'url'\r\n updateElement()\r\n } catch (error) {\r\n alert('上传失败,请重试')\r\n console.error(error)\r\n }\r\n \r\n if (qrcodeFileInputRef.value) {\r\n qrcodeFileInputRef.value.value = ''\r\n }\r\n}\r\n\r\nconst removeQrcode = () => {\r\n localQrcodeContent.value = ''\r\n updateElement()\r\n}\r\n\r\nconst getFieldLabel = (key) => {\r\n // 首先在传入的 systemFields 中查找\r\n const field = props.systemFields.find(f => f.key === key)\r\n if (field) return field.label\r\n \r\n // 如果没找到,尝试使用默认的系统字段\r\n const defaultField = getFieldByKey(key)\r\n return defaultField ? defaultField.label : key\r\n}\r\n\r\nconst isImageUrl = (url) => {\r\n if (!url) return false\r\n if (url.startsWith('data:image/')) return true\r\n if (url.startsWith('http://') || url.startsWith('https://')) {\r\n const imageExtensions = ['.jpg', '.jpeg', '.png', '.gif', '.webp', '.svg', '.bmp']\r\n const lowerUrl = url.toLowerCase()\r\n return imageExtensions.some(ext => lowerUrl.includes(ext))\r\n }\r\n return false\r\n}\r\n</script>\r\n\r\n<style scoped>\r\n.properties-panel {\r\n display: flex;\r\n flex-direction: column;\r\n height: 100%;\r\n background: #fff;\r\n}\r\n\r\n.panel-header {\r\n padding: 12px 16px;\r\n border-bottom: 1px solid #e0e0e0;\r\n}\r\n\r\n.panel-header h3 {\r\n font-size: 14px;\r\n font-weight: 500;\r\n color: #333;\r\n margin: 0;\r\n}\r\n\r\n.panel-content {\r\n flex: 1;\r\n overflow-y: auto;\r\n padding: 16px;\r\n}\r\n\r\n.section-title {\r\n font-size: 13px;\r\n font-weight: 500;\r\n color: #666;\r\n margin-bottom: 12px;\r\n padding-bottom: 8px;\r\n border-bottom: 1px solid #f0f0f0;\r\n}\r\n\r\n.form-group {\r\n margin-bottom: 16px;\r\n}\r\n\r\n.form-label {\r\n display: block;\r\n font-size: 12px;\r\n color: #666;\r\n margin-bottom: 6px;\r\n}\r\n\r\n.form-input,\r\n.form-select {\r\n width: 100%;\r\n padding: 6px 10px;\r\n border: 1px solid #d9d9d9;\r\n border-radius: 4px;\r\n font-size: 13px;\r\n}\r\n\r\n.form-input:focus,\r\n.form-select:focus {\r\n outline: none;\r\n border-color: #1890ff;\r\n}\r\n\r\n.content-input-wrapper {\r\n display: flex;\r\n flex-direction: column;\r\n gap: 8px;\r\n}\r\n\r\n.content-textarea {\r\n width: 100%;\r\n padding: 8px;\r\n border: 1px solid #d9d9d9;\r\n border-radius: 4px;\r\n font-size: 13px;\r\n resize: vertical;\r\n}\r\n\r\n.content-textarea:focus {\r\n outline: none;\r\n border-color: #1890ff;\r\n}\r\n\r\n.insert-field-btn {\r\n display: flex;\r\n align-items: center;\r\n gap: 4px;\r\n padding: 6px 12px;\r\n border: 1px solid #d9d9d9;\r\n background: #fff;\r\n color: #666;\r\n border-radius: 4px;\r\n font-size: 12px;\r\n cursor: pointer;\r\n transition: all 0.3s;\r\n}\r\n\r\n.insert-field-btn:hover {\r\n border-color: #1890ff;\r\n color: #1890ff;\r\n}\r\n\r\n.style-buttons {\r\n display: flex;\r\n gap: 8px;\r\n}\r\n\r\n.style-btn {\r\n width: 32px;\r\n height: 32px;\r\n border: 1px solid #d9d9d9;\r\n background: #fff;\r\n border-radius: 4px;\r\n cursor: pointer;\r\n font-size: 14px;\r\n transition: all 0.3s;\r\n}\r\n\r\n.style-btn:hover {\r\n border-color: #1890ff;\r\n}\r\n\r\n.style-btn.active {\r\n background: #1890ff;\r\n border-color: #1890ff;\r\n color: #fff;\r\n}\r\n\r\n.color-input {\r\n width: 100%;\r\n height: 32px;\r\n border: 1px solid #d9d9d9;\r\n border-radius: 4px;\r\n cursor: pointer;\r\n}\r\n\r\n.align-buttons {\r\n display: flex;\r\n gap: 8px;\r\n}\r\n\r\n.align-btn {\r\n flex: 1;\r\n padding: 6px 12px;\r\n border: 1px solid #d9d9d9;\r\n background: #fff;\r\n border-radius: 4px;\r\n font-size: 12px;\r\n cursor: pointer;\r\n transition: all 0.3s;\r\n}\r\n\r\n.align-btn:hover {\r\n border-color: #1890ff;\r\n}\r\n\r\n.align-btn.active {\r\n background: #1890ff;\r\n border-color: #1890ff;\r\n color: #fff;\r\n}\r\n\r\n.radio-group {\r\n display: flex;\r\n gap: 16px;\r\n}\r\n\r\n.radio-label {\r\n display: flex;\r\n align-items: center;\r\n gap: 6px;\r\n font-size: 13px;\r\n cursor: pointer;\r\n}\r\n\r\n.image-upload-wrapper,\r\n.qrcode-upload-wrapper {\r\n display: flex;\r\n flex-direction: column;\r\n gap: 8px;\r\n}\r\n\r\n.upload-btn {\r\n width: 100%;\r\n padding: 10px 16px;\r\n border: 2px solid #1890ff;\r\n background: #1890ff;\r\n color: #fff;\r\n border-radius: 4px;\r\n font-size: 14px;\r\n font-weight: 500;\r\n cursor: pointer;\r\n transition: all 0.3s;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n gap: 6px;\r\n}\r\n\r\n.upload-btn:hover {\r\n background: #40a9ff;\r\n border-color: #40a9ff;\r\n box-shadow: 0 2px 8px rgba(24, 144, 255, 0.3);\r\n}\r\n\r\n.upload-btn:active {\r\n background: #096dd9;\r\n border-color: #096dd9;\r\n}\r\n\r\n.image-url-input,\r\n.qrcode-input {\r\n width: 100%;\r\n padding: 6px 10px;\r\n border: 1px solid #d9d9d9;\r\n border-radius: 4px;\r\n font-size: 13px;\r\n}\r\n\r\n.image-url-input:focus,\r\n.qrcode-input:focus {\r\n outline: none;\r\n border-color: #1890ff;\r\n}\r\n\r\n.remove-btn {\r\n padding: 4px 12px;\r\n border: 1px solid #ff4d4f;\r\n background: #fff;\r\n color: #ff4d4f;\r\n border-radius: 4px;\r\n font-size: 12px;\r\n cursor: pointer;\r\n transition: all 0.3s;\r\n align-self: flex-start;\r\n}\r\n\r\n.remove-btn:hover {\r\n background: #ff4d4f;\r\n color: #fff;\r\n}\r\n\r\n.image-preview,\r\n.qrcode-preview {\r\n margin-top: 8px;\r\n padding: 8px;\r\n border: 1px solid #e0e0e0;\r\n border-radius: 4px;\r\n background: #fafafa;\r\n}\r\n\r\n.image-preview img,\r\n.qrcode-preview img {\r\n max-width: 100%;\r\n max-height: 200px;\r\n display: block;\r\n}\r\n\r\n.field-preview {\r\n margin-top: 8px;\r\n padding: 6px 10px;\r\n background: #f0f7ff;\r\n border: 1px solid #d6e4ff;\r\n border-radius: 4px;\r\n font-size: 12px;\r\n color: #1890ff;\r\n}\r\n\r\n.form-row {\r\n display: grid;\r\n grid-template-columns: 1fr 1fr;\r\n gap: 12px;\r\n}\r\n</style>\r\n","<template>\r\n <div class=\"field-data-panel\">\r\n <div class=\"panel-header\">\r\n <h3>字段数据</h3>\r\n <button class=\"reset-btn\" @click=\"resetData\">重置</button>\r\n </div>\r\n \r\n <div class=\"panel-content\">\r\n <div \r\n v-for=\"(fields, category) in fieldsByCategory\"\r\n :key=\"category\"\r\n class=\"field-category\"\r\n >\r\n <div class=\"category-title\">{{ category }}</div>\r\n <div class=\"fields-list\">\r\n <div\r\n v-for=\"field in fields\"\r\n :key=\"field.key\"\r\n class=\"field-item\"\r\n >\r\n <label class=\"field-label\">{{ field.label }}</label>\r\n <input\r\n v-model=\"localFieldData[field.key]\"\r\n @input=\"updateFieldData\"\r\n type=\"text\"\r\n class=\"field-input\"\r\n :placeholder=\"field.placeholder\"\r\n />\r\n <div class=\"field-hint\">{{ field.description }}</div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</template>\r\n\r\n<script setup>\r\nimport { ref, watch, computed } from 'vue'\r\nimport { FIELDS_BY_CATEGORY, DEFAULT_FIELD_DATA } from '../utils/fieldManager.js'\r\n\r\nconst props = defineProps({\r\n fieldData: {\r\n type: Object,\r\n default: () => ({})\r\n }\r\n})\r\n\r\nconst emit = defineEmits(['update-field-data'])\r\n\r\nconst localFieldData = ref({ ...props.fieldData })\r\n\r\nconst fieldsByCategory = computed(() => FIELDS_BY_CATEGORY)\r\n\r\nwatch(() => props.fieldData, (newData) => {\r\n localFieldData.value = { ...newData }\r\n}, { deep: true })\r\n\r\nconst updateFieldData = () => {\r\n emit('update-field-data', { ...localFieldData.value })\r\n}\r\n\r\nconst resetData = () => {\r\n localFieldData.value = { ...DEFAULT_FIELD_DATA }\r\n updateFieldData()\r\n}\r\n</script>\r\n\r\n<style scoped>\r\n.field-data-panel {\r\n display: flex;\r\n flex-direction: column;\r\n height: 100%;\r\n background: #fff;\r\n border-top: 1px solid #e0e0e0;\r\n}\r\n\r\n.panel-header {\r\n display: flex;\r\n justify-content: space-between;\r\n align-items: center;\r\n padding: 12px 16px;\r\n border-bottom: 1px solid #e0e0e0;\r\n}\r\n\r\n.panel-header h3 {\r\n font-size: 14px;\r\n font-weight: 500;\r\n color: #333;\r\n margin: 0;\r\n}\r\n\r\n.reset-btn {\r\n padding: 4px 12px;\r\n border: 1px solid #d9d9d9;\r\n background: #fff;\r\n border-radius: 4px;\r\n font-size: 12px;\r\n color: #666;\r\n cursor: pointer;\r\n}\r\n\r\n.reset-btn:hover {\r\n border-color: #1890ff;\r\n color: #1890ff;\r\n}\r\n\r\n.panel-content {\r\n flex: 1;\r\n overflow-y: auto;\r\n padding: 16px;\r\n}\r\n\r\n.field-category {\r\n margin-bottom: 24px;\r\n}\r\n\r\n.category-title {\r\n font-size: 13px;\r\n font-weight: 500;\r\n color: #666;\r\n margin-bottom: 12px;\r\n padding-bottom: 8px;\r\n border-bottom: 1px solid #f0f0f0;\r\n}\r\n\r\n.fields-list {\r\n display: flex;\r\n flex-direction: column;\r\n gap: 16px;\r\n}\r\n\r\n.field-item {\r\n display: flex;\r\n flex-direction: column;\r\n gap: 6px;\r\n}\r\n\r\n.field-label {\r\n font-size: 13px;\r\n color: #333;\r\n font-weight: 500;\r\n}\r\n\r\n.field-input {\r\n padding: 6px 10px;\r\n border: 1px solid #d9d9d9;\r\n border-radius: 4px;\r\n font-size: 13px;\r\n}\r\n\r\n.field-input:focus {\r\n outline: none;\r\n border-color: #1890ff;\r\n}\r\n\r\n.field-hint {\r\n font-size: 11px;\r\n color: #999;\r\n}\r\n</style>\r\n","<template>\r\n <div v-if=\"visible\" class=\"preview-overlay\" @click.self=\"handleClose\">\r\n <div class=\"preview-dialog\">\r\n <div class=\"preview-header\">\r\n <h3>证书预览</h3>\r\n <button class=\"close-btn\" @click=\"handleClose\">×</button>\r\n </div>\r\n \r\n <div class=\"preview-content\">\r\n <div class=\"preview-canvas-wrapper\">\r\n <div \r\n class=\"preview-canvas\" \r\n :style=\"getCanvasStyle()\"\r\n >\r\n <!-- 可编辑元素 -->\r\n <div\r\n v-for=\"element in elements\"\r\n :key=\"element.id\"\r\n :class=\"['preview-element', element.type]\"\r\n :style=\"getElementStyle(element)\"\r\n >\r\n <!-- 文本元素 -->\r\n <div v-if=\"element.type === 'text' || element.type === 'longtext'\" class=\"preview-text-content\">\r\n <span v-html=\"renderTextWithFields(element.content)\"></span>\r\n </div>\r\n \r\n <!-- 图片元素 -->\r\n <div v-else-if=\"element.type === 'image'\" class=\"preview-image-element\">\r\n <img\r\n v-if=\"getImageSrc(element)\"\r\n :src=\"getImageSrc(element)\"\r\n alt=\"图片\"\r\n class=\"preview-element-image\"\r\n />\r\n </div>\r\n \r\n <!-- 二维码元素 -->\r\n <div v-else-if=\"element.type === 'qrcode'\" class=\"preview-qrcode-element\">\r\n <img\r\n v-if=\"getQrcodeContent(element) && isImageUrl(getQrcodeContent(element))\"\r\n :src=\"getQrcodeContent(element)\"\r\n alt=\"二维码\"\r\n class=\"preview-element-image\"\r\n />\r\n <div v-else-if=\"getQrcodeContent(element)\" class=\"preview-qrcode-text\">\r\n {{ getQrcodeContent(element) }}\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</template>\r\n\r\n<script setup>\r\nimport { computed } from 'vue'\r\nimport { SYSTEM_FIELDS } from '../utils/fieldManager.js'\r\n\r\nconst props = defineProps({\r\n visible: {\r\n type: Boolean,\r\n default: false\r\n },\r\n elements: {\r\n type: Array,\r\n default: () => []\r\n },\r\n template: {\r\n type: Object,\r\n default: null\r\n },\r\n fieldData: {\r\n type: Object,\r\n default: () => ({})\r\n },\r\n systemFields: {\r\n type: Array,\r\n default: () => SYSTEM_FIELDS\r\n }\r\n})\r\n\r\nconst emit = defineEmits(['close'])\r\n\r\nconst handleClose = () => {\r\n emit('close')\r\n}\r\n\r\n// 获取画布样式\r\nconst getCanvasStyle = () => {\r\n const baseStyle = {}\r\n \r\n if (props.template) {\r\n baseStyle.width = `${props.template.width}px`\r\n baseStyle.height = `${props.template.height}px`\r\n } else {\r\n baseStyle.width = '800px'\r\n baseStyle.height = '1000px'\r\n }\r\n \r\n // 将背景直接应用到画布\r\n if (props.template && props.template.background) {\r\n if (props.template.background.startsWith('data:') || props.template.background.startsWith('http')) {\r\n baseStyle.backgroundImage = `url(${props.template.background})`\r\n baseStyle.backgroundSize = '100% 100%'\r\n baseStyle.backgroundPosition = 'center'\r\n baseStyle.backgroundRepeat = 'no-repeat'\r\n } else {\r\n baseStyle.background = props.template.background\r\n baseStyle.backgroundSize = '100% 100%'\r\n baseStyle.backgroundPosition = 'center'\r\n baseStyle.backgroundRepeat = 'no-repeat'\r\n }\r\n }\r\n \r\n return baseStyle\r\n}\r\n\r\n// 获取元素样式\r\nconst getElementStyle = (element) => {\r\n const baseStyle = {\r\n position: 'absolute',\r\n left: `${element.x}px`,\r\n top: `${element.y}px`,\r\n width: `${element.width}px`,\r\n minHeight: `${element.height}px`\r\n }\r\n \r\n if (element.type === 'text' || element.type === 'longtext') {\r\n return {\r\n ...baseStyle,\r\n fontSize: `${element.style?.fontSize || 18}px`,\r\n fontFamily: element.style?.fontFamily || '方正书宋简体',\r\n fontWeight: element.style?.fontWeight || 'normal',\r\n fontStyle: element.style?.fontStyle || 'normal',\r\n textDecoration: element.style?.textDecoration || 'none',\r\n color: element.style?.color || '#000000',\r\n textAlign: element.style?.textAlign || 'left',\r\n lineHeight: element.style?.lineHeight || 1.2\r\n }\r\n }\r\n \r\n return baseStyle\r\n}\r\n\r\n// 渲染文本,替换字段占位符\r\nconst renderTextWithFields = (text) => {\r\n if (!text) return ''\r\n \r\n const fieldData = props.fieldData || {}\r\n let result = text\r\n \r\n props.systemFields.forEach(field => {\r\n const placeholder = field.placeholder\r\n const value = fieldData[field.key] || placeholder\r\n \r\n const regex = new RegExp(placeholder.replace(/[{}]/g, '\\\\$&'), 'g')\r\n result = result.replace(regex, value)\r\n })\r\n \r\n return result\r\n}\r\n\r\n// 获取图片源\r\nconst getImageSrc = (element) => {\r\n if (!element) return null\r\n \r\n if (element.imageSource === 'field') {\r\n const fieldKey = element.imageField\r\n if (fieldKey && props.fieldData && props.fieldData[fieldKey]) {\r\n return props.fieldData[fieldKey]\r\n }\r\n return null\r\n } else {\r\n return element.imageUrl || null\r\n }\r\n}\r\n\r\n// 获取二维码内容\r\nconst getQrcodeContent = (element) => {\r\n if (!element) return null\r\n \r\n if (element.qrcodeSource === 'field') {\r\n const fieldKey = element.qrcodeField\r\n if (fieldKey && props.fieldData && props.fieldData[fieldKey]) {\r\n return props.fieldData[fieldKey]\r\n }\r\n return null\r\n } else {\r\n return element.qrcodeContent || null\r\n }\r\n}\r\n\r\n// 判断是否为图片URL\r\nconst isImageUrl = (url) => {\r\n if (!url) return false\r\n if (url.startsWith('data:image/')) return true\r\n if (url.startsWith('http://') || url.startsWith('https://')) {\r\n const imageExtensions = ['.jpg', '.jpeg', '.png', '.gif', '.webp', '.svg', '.bmp']\r\n const lowerUrl = url.toLowerCase()\r\n return imageExtensions.some(ext => lowerUrl.includes(ext))\r\n }\r\n return false\r\n}\r\n</script>\r\n\r\n<style scoped>\r\n.preview-overlay {\r\n position: fixed;\r\n top: 0;\r\n left: 0;\r\n right: 0;\r\n bottom: 0;\r\n background: rgba(0, 0, 0, 0.7);\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n z-index: 2000;\r\n}\r\n\r\n.preview-dialog {\r\n background: #fff;\r\n border-radius: 8px;\r\n width: 90%;\r\n max-width: 1200px;\r\n max-height: 90vh;\r\n display: flex;\r\n flex-direction: column;\r\n box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);\r\n}\r\n\r\n.preview-header {\r\n display: flex;\r\n justify-content: space-between;\r\n align-items: center;\r\n padding: 16px 20px;\r\n border-bottom: 1px solid #e0e0e0;\r\n}\r\n\r\n.preview-header h3 {\r\n font-size: 18px;\r\n font-weight: 500;\r\n color: #333;\r\n margin: 0;\r\n}\r\n\r\n.close-btn {\r\n width: 32px;\r\n height: 32px;\r\n border: none;\r\n background: transparent;\r\n font-size: 24px;\r\n color: #999;\r\n cursor: pointer;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n border-radius: 4px;\r\n transition: all 0.3s;\r\n}\r\n\r\n.close-btn:hover {\r\n background: #f5f5f5;\r\n color: #333;\r\n}\r\n\r\n.preview-content {\r\n flex: 1;\r\n overflow: auto;\r\n padding: 40px;\r\n display: flex;\r\n justify-content: center;\r\n align-items: flex-start;\r\n background: #f5f5f5;\r\n}\r\n\r\n.preview-canvas-wrapper {\r\n display: flex;\r\n justify-content: center;\r\n align-items: flex-start;\r\n}\r\n\r\n.preview-canvas {\r\n background: #fff;\r\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);\r\n position: relative;\r\n padding: 60px 50px;\r\n}\r\n\r\n.preview-element {\r\n position: absolute;\r\n}\r\n\r\n.preview-text-content {\r\n width: 100%;\r\n height: 100%;\r\n word-wrap: break-word;\r\n white-space: pre-wrap;\r\n}\r\n\r\n.preview-image-element,\r\n.preview-qrcode-element {\r\n width: 100%;\r\n height: 100%;\r\n overflow: hidden;\r\n}\r\n\r\n.preview-element-image {\r\n width: 100%;\r\n height: 100%;\r\n object-fit: contain;\r\n display: block;\r\n}\r\n\r\n.preview-qrcode-text {\r\n width: 100%;\r\n height: 100%;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n background: #f5f5f5;\r\n border: 1px solid #e0e0e0;\r\n font-size: 12px;\r\n color: #666;\r\n word-break: break-all;\r\n padding: 8px;\r\n}\r\n</style>\r\n","<template>\r\n <div class=\"certificate-editor\">\r\n <!-- 顶部工具栏 -->\r\n <div class=\"toolbar\">\r\n <button class=\"toolbar-btn preview-btn\" @click=\"showPreview = true\">\r\n <span>👁️</span>\r\n <span>预览</span>\r\n </button>\r\n <button class=\"toolbar-btn save-btn\" @click=\"handleSave\">\r\n <span>💾</span>\r\n <span>保存</span>\r\n </button>\r\n </div>\r\n \r\n <!-- 主要内容区域 -->\r\n <div class=\"certificate-editor-content\">\r\n <!-- 左侧设计元素面板 -->\r\n <DesignPanel \r\n @add-element=\"handleAddElement\"\r\n @select-template=\"handleSelectTemplate\"\r\n @upload-template=\"handleUploadTemplate\"\r\n class=\"left-panel\"\r\n />\r\n \r\n <!-- 中间画布 -->\r\n <CanvasArea \r\n :elements=\"elements\"\r\n :selected-element=\"selectedElement\"\r\n :field-data=\"fieldData\"\r\n :template=\"currentTemplate\"\r\n :system-fields=\"systemFields\"\r\n @select-element=\"handleSelectElement\"\r\n @update-element=\"handleUpdateElement\"\r\n @delete-element=\"handleDeleteElement\"\r\n class=\"canvas-area\"\r\n />\r\n \r\n <!-- 右侧属性面板 -->\r\n <div class=\"right-panel\">\r\n <PropertiesPanel \r\n v-if=\"selectedElement\"\r\n :element=\"selectedElement\"\r\n :system-fields=\"systemFields\"\r\n @update-element=\"handleUpdateElement\"\r\n class=\"properties-section\"\r\n />\r\n <FieldDataPanel\r\n :field-data=\"fieldData\"\r\n @update-field-data=\"handleUpdateFieldData\"\r\n class=\"field-data-section\"\r\n />\r\n </div>\r\n </div>\r\n \r\n <!-- 预览对话框 -->\r\n <CertificatePreview\r\n :visible=\"showPreview\"\r\n :elements=\"elements\"\r\n :template=\"currentTemplate\"\r\n :field-data=\"fieldData\"\r\n :system-fields=\"systemFields\"\r\n @close=\"showPreview = false\"\r\n />\r\n </div>\r\n</template>\r\n\r\n<script setup>\r\nimport { ref, onMounted } from 'vue'\r\nimport DesignPanel from './DesignPanel.vue'\r\nimport CanvasArea from './CanvasArea.vue'\r\nimport PropertiesPanel from './PropertiesPanel.vue'\r\nimport FieldDataPanel from './FieldDataPanel.vue'\r\nimport CertificatePreview from './CertificatePreview.vue'\r\nimport { PRESET_TEMPLATES } from '../utils/templateManager.js'\r\nimport { SYSTEM_FIELDS } from '../utils/fieldManager.js'\r\n\r\n// 接收系统字段参数,如果没有传入则使用默认的系统字段\r\nconst props = defineProps({\r\n systemFields: {\r\n type: Array,\r\n default: () => SYSTEM_FIELDS\r\n }\r\n})\r\n\r\n// 定义事件\r\nconst emit = defineEmits(['save'])\r\n\r\nconst elements = ref([])\r\nconst selectedElement = ref(null)\r\nconst fieldData = ref({})\r\nconst showPreview = ref(false)\r\n// 默认使用竖版第一个模板\r\nconst currentTemplate = ref(PRESET_TEMPLATES.find(t => t.type === 'vertical') || PRESET_TEMPLATES[0])\r\n\r\n// 初始化示例数据\r\nonMounted(() => {\r\n elements.value = [\r\n {\r\n id: 1,\r\n type: 'text',\r\n x: 115,\r\n y: 466,\r\n width: 698,\r\n height: 29,\r\n content: '{{姓名}} ({{性别称呼}})',\r\n style: {\r\n fontSize: 18,\r\n fontFamily: '方正书宋简体',\r\n fontWeight: 'normal',\r\n fontStyle: 'normal',\r\n textDecoration: 'none',\r\n color: '#000000',\r\n textAlign: 'left',\r\n lineHeight: 1.2\r\n }\r\n },\r\n {\r\n id: 2,\r\n type: 'longtext',\r\n x: 115,\r\n y: 520,\r\n width: 698,\r\n height: 80,\r\n content: '您参加了\"{{考试名称}}\"考试,成绩: {{成绩等级}},经审定,准予颁发考试证书!',\r\n style: {\r\n fontSize: 18,\r\n fontFamily: '方正书宋简体',\r\n fontWeight: 'normal',\r\n fontStyle: 'normal',\r\n textDecoration: 'none',\r\n color: '#000000',\r\n textAlign: 'left',\r\n lineHeight: 1.2\r\n }\r\n },\r\n {\r\n id: 3,\r\n type: 'text',\r\n x: 115,\r\n y: 620,\r\n width: 698,\r\n height: 29,\r\n content: '证书编号: {{证书编号}}',\r\n style: {\r\n fontSize: 18,\r\n fontFamily: '方正书宋简体',\r\n fontWeight: 'normal',\r\n fontStyle: 'normal',\r\n textDecoration: 'none',\r\n color: '#000000',\r\n textAlign: 'left',\r\n lineHeight: 1.2\r\n }\r\n },\r\n {\r\n id: 4,\r\n type: 'text',\r\n x: 115,\r\n y: 660,\r\n width: 698,\r\n height: 29,\r\n content: '有效期: {{有效期}}',\r\n style: {\r\n fontSize: 18,\r\n fontFamily: '方正书宋简体',\r\n fontWeight: 'normal',\r\n fontStyle: 'normal',\r\n textDecoration: 'none',\r\n color: '#000000',\r\n textAlign: 'left',\r\n lineHeight: 1.2\r\n }\r\n }\r\n ]\r\n})\r\n\r\nconst handleAddElement = (type) => {\r\n const newElement = {\r\n id: Date.now(),\r\n type,\r\n x: 100,\r\n y: 100,\r\n width: type === 'text' ? 200 : type === 'qrcode' ? 100 : 150,\r\n height: type === 'text' ? 50 : type === 'qrcode' ? 100 : 150,\r\n content: type === 'text' ? '新文本' : '',\r\n style: {\r\n fontSize: 18,\r\n fontFamily: '方正书宋简体',\r\n fontWeight: 'normal',\r\n fontStyle: 'normal',\r\n textDecoration: 'none',\r\n color: '#000000',\r\n textAlign: 'left',\r\n lineHeight: 1.2\r\n }\r\n }\r\n \r\n // 图片元素初始化\r\n if (type === 'image') {\r\n newElement.imageSource = 'url'\r\n newElement.imageUrl = ''\r\n newElement.imageField = ''\r\n }\r\n \r\n // 二维码元素初始化(与图片使用相同的逻辑)\r\n if (type === 'qrcode') {\r\n newElement.qrcodeSource = 'url'\r\n newElement.qrcodeContent = ''\r\n newElement.qrcodeField = ''\r\n }\r\n \r\n elements.value.push(newElement)\r\n selectedElement.value = newElement\r\n}\r\n\r\nconst handleSelectElement = (element) => {\r\n selectedElement.value = element\r\n}\r\n\r\nconst handleUpdateElement = (updatedElement) => {\r\n const index = elements.value.findIndex(el => el.id === updatedElement.id)\r\n if (index !== -1) {\r\n elements.value[index] = { ...updatedElement }\r\n selectedElement.value = elements.value[index]\r\n }\r\n}\r\n\r\nconst handleDeleteElement = (elementId) => {\r\n elements.value = elements.value.filter(el => el.id !== elementId)\r\n if (selectedElement.value?.id === elementId) {\r\n selectedElement.value = null\r\n }\r\n}\r\n\r\nconst handleUpdateFieldData = (newFieldData) => {\r\n fieldData.value = { ...newFieldData }\r\n}\r\n\r\nconst handleSelectTemplate = (template) => {\r\n currentTemplate.value = template\r\n}\r\n\r\nconst handleUploadTemplate = (template) => {\r\n currentTemplate.value = template\r\n}\r\n\r\n// 获取证书配置数据\r\nconst getCertificateData = () => {\r\n return {\r\n template: currentTemplate.value,\r\n elements: elements.value,\r\n fieldData: fieldData.value,\r\n timestamp: new Date().toISOString()\r\n }\r\n}\r\n\r\n// 保存证书配置\r\nconst handleSave = () => {\r\n const certificateConfig = getCertificateData()\r\n \r\n // 输出到控制台(保留原有功能)\r\n console.log('=== 证书配置数据 ===')\r\n console.log(JSON.stringify(certificateConfig, null, 2))\r\n console.log('==================')\r\n \r\n // 触发 save 事件,将数据传递给父组件\r\n emit('save', certificateConfig)\r\n \r\n alert('证书配置已保存,数据已传递给父组件')\r\n}\r\n\r\n// 暴露方法给父组件调用\r\ndefineExpose({\r\n getCertificateData\r\n})\r\n</script>\r\n\r\n<style scoped>\r\n.certificate-editor {\r\n display: flex;\r\n flex-direction: column;\r\n width: 100%;\r\n height: 100%;\r\n background: #f5f5f5;\r\n}\r\n\r\n.toolbar {\r\n display: flex;\r\n align-items: center;\r\n gap: 12px;\r\n padding: 12px 20px;\r\n background: #fff;\r\n border-bottom: 1px solid #e0e0e0;\r\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);\r\n flex-shrink: 0;\r\n}\r\n\r\n.toolbar-btn {\r\n display: flex;\r\n align-items: center;\r\n gap: 6px;\r\n padding: 8px 16px;\r\n border: 1px solid #d9d9d9;\r\n background: #fff;\r\n color: #333;\r\n border-radius: 4px;\r\n cursor: pointer;\r\n font-size: 14px;\r\n transition: all 0.3s;\r\n}\r\n\r\n.toolbar-btn:hover {\r\n border-color: #1890ff;\r\n color: #1890ff;\r\n}\r\n\r\n.toolbar-btn.preview-btn:hover {\r\n background: #e6f7ff;\r\n border-color: #1890ff;\r\n}\r\n\r\n.toolbar-btn.save-btn:hover {\r\n background: #f6ffed;\r\n border-color: #52c41a;\r\n color: #52c41a;\r\n}\r\n\r\n.certificate-editor-content {\r\n display: flex;\r\n flex: 1;\r\n min-height: 0;\r\n overflow: hidden;\r\n}\r\n\r\n.left-panel {\r\n width: 280px;\r\n background: #fff;\r\n border-right: 1px solid #e0e0e0;\r\n overflow-y: auto;\r\n}\r\n\r\n.canvas-area {\r\n flex: 1;\r\n overflow: auto;\r\n display: flex;\r\n justify-content: center;\r\n align-items: flex-start;\r\n padding: 20px;\r\n}\r\n\r\n.right-panel {\r\n width: 350px;\r\n background: #fff;\r\n border-left: 1px solid #e0e0e0;\r\n display: flex;\r\n flex-direction: column;\r\n overflow: hidden;\r\n}\r\n\r\n.properties-section {\r\n flex: 1;\r\n overflow-y: auto;\r\n border-bottom: 1px solid #e0e0e0;\r\n}\r\n\r\n.field-data-section {\r\n height: 300px;\r\n overflow-y: auto;\r\n}\r\n</style>\r\n"],"names":["_openBlock","_createElementBlock","_hoisted_1","_createElementVNode","_hoisted_2","_normalizeClass","_hoisted_3","_hoisted_4","_hoisted_5","$emit","_hoisted_6","_hoisted_7","_hoisted_8","_createTextVNode","_hoisted_9","_hoisted_10","_Fragment","_renderList","_normalizeStyle","_hoisted_12","_toDisplayString","_withModifiers","_hoisted_11","_hoisted_13","_hoisted_14","_hoisted_19","_vModelSelect","_vModelText","_createVNode","_createBlock"],"mappings":"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"}
|