| | |
| | | "@vueup/vue-quill": "1.2.0",
|
| | | "@vueuse/core": "10.11.0",
|
| | | "axios": "0.28.1",
|
| | | "clipboard": "2.0.11",
|
| | | "echarts": "5.5.1",
|
| | | "element-plus": "2.7.6",
|
| | | "file-saver": "2.0.5",
|
| | | "fuse.js": "6.6.2",
|
| | | "js-beautify": "1.14.11",
|
| | | "js-cookie": "3.0.5",
|
| | | "jsencrypt": "3.3.2",
|
| | | "nprogress": "0.2.0",
|
| | |
| | | "splitpanes": "3.1.5",
|
| | | "vue": "3.4.31",
|
| | | "vue-cropper": "1.1.1",
|
| | | "vue-router": "4.4.0"
|
| | | "vue-router": "4.4.0",
|
| | | "vuedraggable": "4.1.0"
|
| | | },
|
| | | "devDependencies": {
|
| | | "@vitejs/plugin-vue": "5.0.5",
|
¶Ô±ÈÐÂÎļþ |
| | |
| | | export const formConf = { |
| | | formRef: 'formRef', |
| | | formModel: 'formData', |
| | | size: 'default', |
| | | labelPosition: 'right', |
| | | labelWidth: 100, |
| | | formRules: 'rules', |
| | | gutter: 15, |
| | | disabled: false, |
| | | span: 24, |
| | | formBtns: true, |
| | | } |
| | | |
| | | export const inputComponents = [ |
| | | { |
| | | label: 'åè¡ææ¬', |
| | | tag: 'el-input', |
| | | tagIcon: 'input', |
| | | type: 'text', |
| | | placeholder: '请è¾å
¥', |
| | | defaultValue: undefined, |
| | | span: 24, |
| | | labelWidth: null, |
| | | style: { width: '100%' }, |
| | | clearable: true, |
| | | prepend: '', |
| | | append: '', |
| | | 'prefix-icon': '', |
| | | 'suffix-icon': '', |
| | | maxlength: null, |
| | | 'show-word-limit': false, |
| | | readonly: false, |
| | | disabled: false, |
| | | required: true, |
| | | regList: [], |
| | | changeTag: true, |
| | | document: 'https://element-plus.org/zh-CN/component/input', |
| | | }, |
| | | { |
| | | label: 'å¤è¡ææ¬', |
| | | tag: 'el-input', |
| | | tagIcon: 'textarea', |
| | | type: 'textarea', |
| | | placeholder: '请è¾å
¥', |
| | | defaultValue: undefined, |
| | | span: 24, |
| | | labelWidth: null, |
| | | autosize: { |
| | | minRows: 4, |
| | | maxRows: 4, |
| | | }, |
| | | style: { width: '100%' }, |
| | | maxlength: null, |
| | | 'show-word-limit': false, |
| | | readonly: false, |
| | | disabled: false, |
| | | required: true, |
| | | regList: [], |
| | | changeTag: true, |
| | | document: 'https://element-plus.org/zh-CN/component/input', |
| | | }, |
| | | { |
| | | label: 'å¯ç ', |
| | | tag: 'el-input', |
| | | tagIcon: 'password', |
| | | type: 'password', |
| | | placeholder: '请è¾å
¥', |
| | | defaultValue: undefined, |
| | | span: 24, |
| | | 'show-password': true, |
| | | labelWidth: null, |
| | | style: { width: '100%' }, |
| | | clearable: true, |
| | | prepend: '', |
| | | append: '', |
| | | 'prefix-icon': '', |
| | | 'suffix-icon': '', |
| | | maxlength: null, |
| | | 'show-word-limit': false, |
| | | readonly: false, |
| | | disabled: false, |
| | | required: true, |
| | | regList: [], |
| | | changeTag: true, |
| | | document: 'https://element-plus.org/zh-CN/component/input', |
| | | }, |
| | | { |
| | | label: '计æ°å¨', |
| | | tag: 'el-input-number', |
| | | tagIcon: 'number', |
| | | placeholder: '', |
| | | defaultValue: undefined, |
| | | span: 24, |
| | | labelWidth: null, |
| | | min: undefined, |
| | | max: undefined, |
| | | step: undefined, |
| | | 'step-strictly': false, |
| | | precision: undefined, |
| | | 'controls-position': '', |
| | | disabled: false, |
| | | required: true, |
| | | regList: [], |
| | | changeTag: true, |
| | | document: 'https://element-plus.org/zh-CN/component/input-number', |
| | | }, |
| | | ] |
| | | |
| | | export const selectComponents = [ |
| | | { |
| | | label: '䏿鿩', |
| | | tag: 'el-select', |
| | | tagIcon: 'select', |
| | | placeholder: 'è¯·éæ©', |
| | | defaultValue: undefined, |
| | | span: 24, |
| | | labelWidth: null, |
| | | style: { width: '100%' }, |
| | | clearable: true, |
| | | disabled: false, |
| | | required: true, |
| | | filterable: false, |
| | | multiple: false, |
| | | options: [ |
| | | { |
| | | label: 'é项ä¸', |
| | | value: 1, |
| | | }, |
| | | { |
| | | label: 'é项äº', |
| | | value: 2, |
| | | }, |
| | | ], |
| | | regList: [], |
| | | changeTag: true, |
| | | document: 'https://element-plus.org/zh-CN/component/select', |
| | | }, |
| | | { |
| | | label: '级èéæ©', |
| | | tag: 'el-cascader', |
| | | tagIcon: 'cascader', |
| | | placeholder: 'è¯·éæ©', |
| | | defaultValue: [], |
| | | span: 24, |
| | | labelWidth: null, |
| | | style: { width: '100%' }, |
| | | props: { |
| | | props: { |
| | | multiple: false, |
| | | }, |
| | | }, |
| | | 'show-all-levels': true, |
| | | disabled: false, |
| | | clearable: true, |
| | | filterable: false, |
| | | required: true, |
| | | options: [ |
| | | { |
| | | id: 1, |
| | | value: 1, |
| | | label: 'é项1', |
| | | children: [ |
| | | { |
| | | id: 2, |
| | | value: 2, |
| | | label: 'é项1-1', |
| | | }, |
| | | ], |
| | | }, |
| | | ], |
| | | dataType: 'dynamic', |
| | | labelKey: 'label', |
| | | valueKey: 'value', |
| | | childrenKey: 'children', |
| | | separator: '/', |
| | | regList: [], |
| | | changeTag: true, |
| | | document: 'https://element-plus.org/zh-CN/component/cascader', |
| | | }, |
| | | { |
| | | label: 'åéæ¡ç»', |
| | | tag: 'el-radio-group', |
| | | tagIcon: 'radio', |
| | | defaultValue: 0, |
| | | span: 24, |
| | | labelWidth: null, |
| | | style: {}, |
| | | optionType: 'default', |
| | | border: false, |
| | | size: 'default', |
| | | disabled: false, |
| | | required: true, |
| | | options: [ |
| | | { |
| | | label: 'é项ä¸', |
| | | value: 1, |
| | | }, |
| | | { |
| | | label: 'é项äº', |
| | | value: 2, |
| | | }, |
| | | ], |
| | | regList: [], |
| | | changeTag: true, |
| | | document: 'https://element-plus.org/zh-CN/component/radio', |
| | | }, |
| | | { |
| | | label: 'å¤éæ¡ç»', |
| | | tag: 'el-checkbox-group', |
| | | tagIcon: 'checkbox', |
| | | defaultValue: [], |
| | | span: 24, |
| | | labelWidth: null, |
| | | style: {}, |
| | | optionType: 'default', |
| | | border: false, |
| | | size: 'default', |
| | | disabled: false, |
| | | required: true, |
| | | options: [ |
| | | { |
| | | label: 'é项ä¸', |
| | | value: 1, |
| | | }, |
| | | { |
| | | label: 'é项äº', |
| | | value: 2, |
| | | }, |
| | | ], |
| | | regList: [], |
| | | changeTag: true, |
| | | document: 'https://element-plus.org/zh-CN/component/checkbox', |
| | | }, |
| | | { |
| | | label: 'å¼å
³', |
| | | tag: 'el-switch', |
| | | tagIcon: 'switch', |
| | | defaultValue: false, |
| | | span: 24, |
| | | labelWidth: null, |
| | | style: {}, |
| | | disabled: false, |
| | | required: true, |
| | | 'active-text': '', |
| | | 'inactive-text': '', |
| | | 'active-color': null, |
| | | 'inactive-color': null, |
| | | 'active-value': true, |
| | | 'inactive-value': false, |
| | | regList: [], |
| | | changeTag: true, |
| | | document: 'https://element-plus.org/zh-CN/component/switch', |
| | | }, |
| | | { |
| | | label: 'æ»å', |
| | | tag: 'el-slider', |
| | | tagIcon: 'slider', |
| | | defaultValue: null, |
| | | span: 24, |
| | | labelWidth: null, |
| | | disabled: false, |
| | | required: true, |
| | | min: 0, |
| | | max: 100, |
| | | step: 1, |
| | | 'show-stops': false, |
| | | range: false, |
| | | regList: [], |
| | | changeTag: true, |
| | | document: 'https://element-plus.org/zh-CN/component/slider', |
| | | }, |
| | | { |
| | | label: 'æ¶é´éæ©', |
| | | tag: 'el-time-picker', |
| | | tagIcon: 'time', |
| | | placeholder: 'è¯·éæ©', |
| | | defaultValue: '', |
| | | span: 24, |
| | | labelWidth: null, |
| | | style: { width: '100%' }, |
| | | disabled: false, |
| | | clearable: true, |
| | | required: true, |
| | | format: 'HH:mm:ss', |
| | | 'value-format': 'HH:mm:ss', |
| | | regList: [], |
| | | changeTag: true, |
| | | document: 'https://element-plus.org/zh-CN/component/time-picker', |
| | | }, |
| | | { |
| | | label: 'æ¶é´èå´', |
| | | tag: 'el-time-picker', |
| | | tagIcon: 'time-range', |
| | | defaultValue: null, |
| | | span: 24, |
| | | labelWidth: null, |
| | | style: { width: '100%' }, |
| | | disabled: false, |
| | | clearable: true, |
| | | required: true, |
| | | 'is-range': true, |
| | | 'range-separator': 'è³', |
| | | 'start-placeholder': 'å¼å§æ¶é´', |
| | | 'end-placeholder': 'ç»ææ¶é´', |
| | | format: 'HH:mm:ss', |
| | | 'value-format': 'HH:mm:ss', |
| | | regList: [], |
| | | changeTag: true, |
| | | document: 'https://element-plus.org/zh-CN/component/time-picker', |
| | | }, |
| | | { |
| | | label: 'æ¥æéæ©', |
| | | tag: 'el-date-picker', |
| | | tagIcon: 'date', |
| | | placeholder: 'è¯·éæ©', |
| | | defaultValue: null, |
| | | type: 'date', |
| | | span: 24, |
| | | labelWidth: null, |
| | | style: { width: '100%' }, |
| | | disabled: false, |
| | | clearable: true, |
| | | required: true, |
| | | format: 'YYYY-MM-DD', |
| | | 'value-format': 'YYYY-MM-DD', |
| | | readonly: false, |
| | | regList: [], |
| | | changeTag: true, |
| | | document: 'https://element-plus.org/zh-CN/component/date-picker', |
| | | }, |
| | | { |
| | | label: 'æ¥æèå´', |
| | | tag: 'el-date-picker', |
| | | tagIcon: 'date-range', |
| | | defaultValue: null, |
| | | span: 24, |
| | | labelWidth: null, |
| | | style: { width: '100%' }, |
| | | type: 'daterange', |
| | | 'range-separator': 'è³', |
| | | 'start-placeholder': 'å¼å§æ¥æ', |
| | | 'end-placeholder': 'ç»ææ¥æ', |
| | | disabled: false, |
| | | clearable: true, |
| | | required: true, |
| | | format: 'YYYY-MM-DD', |
| | | 'value-format': 'YYYY-MM-DD', |
| | | readonly: false, |
| | | regList: [], |
| | | changeTag: true, |
| | | document: 'https://element-plus.org/zh-CN/component/date-picker', |
| | | }, |
| | | { |
| | | label: 'è¯å', |
| | | tag: 'el-rate', |
| | | tagIcon: 'rate', |
| | | defaultValue: 0, |
| | | span: 24, |
| | | labelWidth: null, |
| | | style: {}, |
| | | max: 5, |
| | | 'allow-half': false, |
| | | 'show-text': false, |
| | | 'show-score': false, |
| | | disabled: false, |
| | | required: true, |
| | | regList: [], |
| | | changeTag: true, |
| | | document: 'https://element-plus.org/zh-CN/component/rate', |
| | | }, |
| | | { |
| | | label: 'é¢è²éæ©', |
| | | tag: 'el-color-picker', |
| | | tagIcon: 'color', |
| | | defaultValue: null, |
| | | labelWidth: null, |
| | | 'show-alpha': false, |
| | | 'color-format': '', |
| | | disabled: false, |
| | | required: true, |
| | | size: 'default', |
| | | regList: [], |
| | | changeTag: true, |
| | | document: 'https://element-plus.org/zh-CN/component/color-picker', |
| | | }, |
| | | { |
| | | label: 'ä¸ä¼ ', |
| | | tag: 'el-upload', |
| | | tagIcon: 'upload', |
| | | action: 'https://jsonplaceholder.typicode.com/posts/', |
| | | defaultValue: null, |
| | | labelWidth: null, |
| | | disabled: false, |
| | | required: true, |
| | | accept: '', |
| | | name: 'file', |
| | | 'auto-upload': true, |
| | | showTip: false, |
| | | buttonText: 'ç¹å»ä¸ä¼ ', |
| | | fileSize: 2, |
| | | sizeUnit: 'MB', |
| | | 'list-type': 'text', |
| | | multiple: false, |
| | | regList: [], |
| | | changeTag: true, |
| | | document: 'https://element-plus.org/zh-CN/component/upload', |
| | | tip: 'åªè½ä¸ä¼ ä¸è¶
è¿ 2MB çæä»¶', |
| | | style: { width: '100%' }, |
| | | }, |
| | | ] |
| | | |
| | | export const layoutComponents = [ |
| | | { |
| | | layout: 'rowFormItem', |
| | | tagIcon: 'row', |
| | | type: 'default', |
| | | justify: 'start', |
| | | align: 'top', |
| | | label: 'è¡å®¹å¨', |
| | | layoutTree: true, |
| | | children: [], |
| | | document: 'https://element-plus.org/zh-CN/component/layout', |
| | | }, |
| | | { |
| | | layout: 'colFormItem', |
| | | label: 'æé®', |
| | | changeTag: true, |
| | | labelWidth: null, |
| | | tag: 'el-button', |
| | | tagIcon: 'button', |
| | | span: 24, |
| | | default: 'ä¸»è¦æé®', |
| | | type: 'primary', |
| | | icon: 'Search', |
| | | size: 'default', |
| | | disabled: false, |
| | | document: 'https://element-plus.org/zh-CN/component/button', |
| | | }, |
| | | ] |
| | | |
| | | // ç»ä»¶ruleçè§¦åæ¹å¼ï¼æ è§¦åæ¹å¼çç»ä»¶ä¸çærule |
| | | export const trigger = { |
| | | 'el-input': 'blur', |
| | | 'el-input-number': 'blur', |
| | | 'el-select': 'change', |
| | | 'el-radio-group': 'change', |
| | | 'el-checkbox-group': 'change', |
| | | 'el-cascader': 'change', |
| | | 'el-time-picker': 'change', |
| | | 'el-date-picker': 'change', |
| | | 'el-rate': 'change', |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | const styles = { |
| | | 'el-rate': '.el-rate{display: inline-block; vertical-align: text-top;}', |
| | | 'el-upload': '.el-upload__tip{line-height: 1.2;}' |
| | | } |
| | | |
| | | function addCss(cssList, el) { |
| | | const css = styles[el.tag] |
| | | css && cssList.indexOf(css) === -1 && cssList.push(css) |
| | | if (el.children) { |
| | | el.children.forEach(el2 => addCss(cssList, el2)) |
| | | } |
| | | } |
| | | |
| | | export function makeUpCss(conf) { |
| | | const cssList = [] |
| | | conf.fields.forEach(el => addCss(cssList, el)) |
| | | return cssList.join('\n') |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | export default [ |
| | | { |
| | | layout: 'colFormItem', |
| | | tagIcon: 'input', |
| | | label: 'ææºå·', |
| | | vModel: 'mobile', |
| | | formId: 6, |
| | | tag: 'el-input', |
| | | placeholder: '请è¾å
¥ææºå·', |
| | | defaultValue: '', |
| | | span: 24, |
| | | style: { width: '100%' }, |
| | | clearable: true, |
| | | prepend: '', |
| | | append: '', |
| | | 'prefix-icon': 'Cellphone', |
| | | 'suffix-icon': '', |
| | | maxlength: 11, |
| | | 'show-word-limit': true, |
| | | readonly: false, |
| | | disabled: false, |
| | | required: true, |
| | | changeTag: true, |
| | | regList: [{ |
| | | pattern: '/^1(3|4|5|7|8|9)\\d{9}$/', |
| | | message: 'ææºå·æ ¼å¼é误' |
| | | }] |
| | | } |
| | | ] |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /* eslint-disable max-len */ |
| | | import { trigger } from './config' |
| | | |
| | | let confGlobal |
| | | let someSpanIsNot24 |
| | | |
| | | export function dialogWrapper(str) { |
| | | return `<el-dialog v-model="dialogVisible" @open="onOpen" @close="onClose" title="Dialog Titile"> |
| | | ${str} |
| | | <template #footer> |
| | | <el-button @click="close">åæ¶</el-button> |
| | | <el-button type="primary" @click="handelConfirm">ç¡®å®</el-button> |
| | | </template> |
| | | </el-dialog>` |
| | | } |
| | | |
| | | export function vueTemplate(str) { |
| | | return `<template> |
| | | <div class="app-container"> |
| | | ${str} |
| | | </div> |
| | | </template>` |
| | | } |
| | | |
| | | export function vueScript(str) { |
| | | return `<script setup> |
| | | ${str} |
| | | </script>` |
| | | } |
| | | |
| | | export function cssStyle(cssStr) { |
| | | return `<style> |
| | | ${cssStr} |
| | | </style>` |
| | | } |
| | | |
| | | function buildFormTemplate(conf, child, type) { |
| | | let labelPosition = '' |
| | | if (conf.labelPosition !== 'right') { |
| | | labelPosition = `label-position="${conf.labelPosition}"` |
| | | } |
| | | const disabled = conf.disabled ? `:disabled="${conf.disabled}"` : '' |
| | | let str = `<el-form ref="${conf.formRef}" :model="${conf.formModel}" :rules="${conf.formRules}" size="${conf.size}" ${disabled} label-width="${conf.labelWidth}px" ${labelPosition}> |
| | | ${child} |
| | | ${buildFromBtns(conf, type)} |
| | | </el-form>` |
| | | if (someSpanIsNot24) { |
| | | str = `<el-row :gutter="${conf.gutter}"> |
| | | ${str} |
| | | </el-row>` |
| | | } |
| | | return str |
| | | } |
| | | |
| | | function buildFromBtns(conf, type) { |
| | | let str = '' |
| | | if (conf.formBtns && type === 'file') { |
| | | str = `<el-form-item> |
| | | <el-button type="primary" @click="submitForm">æäº¤</el-button> |
| | | <el-button @click="resetForm">éç½®</el-button> |
| | | </el-form-item>` |
| | | if (someSpanIsNot24) { |
| | | str = `<el-col :span="24"> |
| | | ${str} |
| | | </el-col>` |
| | | } |
| | | } |
| | | return str |
| | | } |
| | | |
| | | // spanä¸ä¸º24çç¨el-colå
裹 |
| | | function colWrapper(element, str) { |
| | | if (someSpanIsNot24 || element.span !== 24) { |
| | | return `<el-col :span="${element.span}"> |
| | | ${str} |
| | | </el-col>` |
| | | } |
| | | return str |
| | | } |
| | | |
| | | const layouts = { |
| | | colFormItem(element) { |
| | | let labelWidth = '' |
| | | if (element.labelWidth && element.labelWidth !== confGlobal.labelWidth) { |
| | | labelWidth = `label-width="${element.labelWidth}px"` |
| | | } |
| | | const required = !trigger[element.tag] && element.required ? 'required' : '' |
| | | const tagDom = tags[element.tag] ? tags[element.tag](element) : null |
| | | let str = `<el-form-item ${labelWidth} label="${element.label}" prop="${element.vModel}" ${required}> |
| | | ${tagDom} |
| | | </el-form-item>` |
| | | str = colWrapper(element, str) |
| | | return str |
| | | }, |
| | | rowFormItem(element) { |
| | | const type = element.type === 'default' ? '' : `type="${element.type}"` |
| | | const justify = element.type === 'default' ? '' : `justify="${element.justify}"` |
| | | const align = element.type === 'default' ? '' : `align="${element.align}"` |
| | | const gutter = element.gutter ? `gutter="${element.gutter}"` : '' |
| | | const children = element.children.map(el => layouts[el.layout](el)) |
| | | let str = `<el-row ${type} ${justify} ${align} ${gutter}> |
| | | ${children.join('\n')} |
| | | </el-row>` |
| | | str = colWrapper(element, str) |
| | | return str |
| | | } |
| | | } |
| | | |
| | | const tags = { |
| | | 'el-button': el => { |
| | | const { |
| | | tag, disabled |
| | | } = attrBuilder(el) |
| | | const type = el.type ? `type="${el.type}"` : '' |
| | | const icon = el.icon ? `icon="${el.icon}"` : '' |
| | | const size = el.size ? `size="${el.size}"` : '' |
| | | let child = buildElButtonChild(el) |
| | | |
| | | if (child) child = `\n${child}\n` // æ¢è¡ |
| | | return `<${el.tag} ${type} ${icon} ${size} ${disabled}>${child}</${el.tag}>` |
| | | }, |
| | | 'el-input': el => { |
| | | const { |
| | | disabled, vModel, clearable, placeholder, width |
| | | } = attrBuilder(el) |
| | | const maxlength = el.maxlength ? `:maxlength="${el.maxlength}"` : '' |
| | | const showWordLimit = el['show-word-limit'] ? 'show-word-limit' : '' |
| | | const readonly = el.readonly ? 'readonly' : '' |
| | | const prefixIcon = el['prefix-icon'] ? `prefix-icon='${el['prefix-icon']}'` : '' |
| | | const suffixIcon = el['suffix-icon'] ? `suffix-icon='${el['suffix-icon']}'` : '' |
| | | const showPassword = el['show-password'] ? 'show-password' : '' |
| | | const type = el.type ? `type="${el.type}"` : '' |
| | | const autosize = el.autosize && el.autosize.minRows |
| | | ? `:autosize="{minRows: ${el.autosize.minRows}, maxRows: ${el.autosize.maxRows}}"` |
| | | : '' |
| | | let child = buildElInputChild(el) |
| | | |
| | | if (child) child = `\n${child}\n` // æ¢è¡ |
| | | return `<${el.tag} ${vModel} ${type} ${placeholder} ${maxlength} ${showWordLimit} ${readonly} ${disabled} ${clearable} ${prefixIcon} ${suffixIcon} ${showPassword} ${autosize} ${width}>${child}</${el.tag}>` |
| | | }, |
| | | 'el-input-number': el => { |
| | | const { disabled, vModel, placeholder } = attrBuilder(el) |
| | | const controlsPosition = el['controls-position'] ? `controls-position=${el['controls-position']}` : '' |
| | | const min = el.min ? `:min='${el.min}'` : '' |
| | | const max = el.max ? `:max='${el.max}'` : '' |
| | | const step = el.step ? `:step='${el.step}'` : '' |
| | | const stepStrictly = el['step-strictly'] ? 'step-strictly' : '' |
| | | const precision = el.precision ? `:precision='${el.precision}'` : '' |
| | | |
| | | return `<${el.tag} ${vModel} ${placeholder} ${step} ${stepStrictly} ${precision} ${controlsPosition} ${min} ${max} ${disabled}></${el.tag}>` |
| | | }, |
| | | 'el-select': el => { |
| | | const { |
| | | disabled, vModel, clearable, placeholder, width |
| | | } = attrBuilder(el) |
| | | const filterable = el.filterable ? 'filterable' : '' |
| | | const multiple = el.multiple ? 'multiple' : '' |
| | | let child = buildElSelectChild(el) |
| | | |
| | | if (child) child = `\n${child}\n` // æ¢è¡ |
| | | return `<${el.tag} ${vModel} ${placeholder} ${disabled} ${multiple} ${filterable} ${clearable} ${width}>${child}</${el.tag}>` |
| | | }, |
| | | 'el-radio-group': el => { |
| | | const { disabled, vModel } = attrBuilder(el) |
| | | const size = `size="${el.size}"` |
| | | let child = buildElRadioGroupChild(el) |
| | | |
| | | if (child) child = `\n${child}\n` // æ¢è¡ |
| | | return `<${el.tag} ${vModel} ${size} ${disabled}>${child}</${el.tag}>` |
| | | }, |
| | | 'el-checkbox-group': el => { |
| | | const { disabled, vModel } = attrBuilder(el) |
| | | const size = `size="${el.size}"` |
| | | const min = el.min ? `:min="${el.min}"` : '' |
| | | const max = el.max ? `:max="${el.max}"` : '' |
| | | let child = buildElCheckboxGroupChild(el) |
| | | |
| | | if (child) child = `\n${child}\n` // æ¢è¡ |
| | | return `<${el.tag} ${vModel} ${min} ${max} ${size} ${disabled}>${child}</${el.tag}>` |
| | | }, |
| | | 'el-switch': el => { |
| | | const { disabled, vModel } = attrBuilder(el) |
| | | const activeText = el['active-text'] ? `active-text="${el['active-text']}"` : '' |
| | | const inactiveText = el['inactive-text'] ? `inactive-text="${el['inactive-text']}"` : '' |
| | | const activeColor = el['active-color'] ? `active-color="${el['active-color']}"` : '' |
| | | const inactiveColor = el['inactive-color'] ? `inactive-color="${el['inactive-color']}"` : '' |
| | | const activeValue = el['active-value'] !== true ? `:active-value='${JSON.stringify(el['active-value'])}'` : '' |
| | | const inactiveValue = el['inactive-value'] !== false ? `:inactive-value='${JSON.stringify(el['inactive-value'])}'` : '' |
| | | |
| | | return `<${el.tag} ${vModel} ${activeText} ${inactiveText} ${activeColor} ${inactiveColor} ${activeValue} ${inactiveValue} ${disabled}></${el.tag}>` |
| | | }, |
| | | 'el-cascader': el => { |
| | | const { |
| | | disabled, vModel, clearable, placeholder, width |
| | | } = attrBuilder(el) |
| | | const options = el.options ? `:options="${el.vModel}Options"` : '' |
| | | const props = el.props ? `:props="${el.vModel}Props"` : '' |
| | | const showAllLevels = el['show-all-levels'] ? '' : ':show-all-levels="false"' |
| | | const filterable = el.filterable ? 'filterable' : '' |
| | | const separator = el.separator === '/' ? '' : `separator="${el.separator}"` |
| | | |
| | | return `<${el.tag} ${vModel} ${options} ${props} ${width} ${showAllLevels} ${placeholder} ${separator} ${filterable} ${clearable} ${disabled}></${el.tag}>` |
| | | }, |
| | | 'el-slider': el => { |
| | | const { disabled, vModel } = attrBuilder(el) |
| | | const min = el.min ? `:min='${el.min}'` : '' |
| | | const max = el.max ? `:max='${el.max}'` : '' |
| | | const step = el.step ? `:step='${el.step}'` : '' |
| | | const range = el.range ? 'range' : '' |
| | | const showStops = el['show-stops'] ? `:show-stops="${el['show-stops']}"` : '' |
| | | |
| | | return `<${el.tag} ${min} ${max} ${step} ${vModel} ${range} ${showStops} ${disabled}></${el.tag}>` |
| | | }, |
| | | 'el-time-picker': el => { |
| | | const { |
| | | disabled, vModel, clearable, placeholder, width |
| | | } = attrBuilder(el) |
| | | const startPlaceholder = el['start-placeholder'] ? `start-placeholder="${el['start-placeholder']}"` : '' |
| | | const endPlaceholder = el['end-placeholder'] ? `end-placeholder="${el['end-placeholder']}"` : '' |
| | | const rangeSeparator = el['range-separator'] ? `range-separator="${el['range-separator']}"` : '' |
| | | const isRange = el['is-range'] ? 'is-range' : '' |
| | | const format = el.format ? `format="${el.format}"` : '' |
| | | const valueFormat = el['value-format'] ? `value-format="${el['value-format']}"` : '' |
| | | const pickerOptions = el['picker-options'] ? `:picker-options='${JSON.stringify(el['picker-options'])}'` : '' |
| | | |
| | | return `<${el.tag} ${vModel} ${isRange} ${format} ${valueFormat} ${pickerOptions} ${width} ${placeholder} ${startPlaceholder} ${endPlaceholder} ${rangeSeparator} ${clearable} ${disabled}></${el.tag}>` |
| | | }, |
| | | 'el-date-picker': el => { |
| | | const { |
| | | disabled, vModel, clearable, placeholder, width |
| | | } = attrBuilder(el) |
| | | const startPlaceholder = el['start-placeholder'] ? `start-placeholder="${el['start-placeholder']}"` : '' |
| | | const endPlaceholder = el['end-placeholder'] ? `end-placeholder="${el['end-placeholder']}"` : '' |
| | | const rangeSeparator = el['range-separator'] ? `range-separator="${el['range-separator']}"` : '' |
| | | const format = el.format ? `format="${el.format}"` : '' |
| | | const valueFormat = el['value-format'] ? `value-format="${el['value-format']}"` : '' |
| | | const type = el.type === 'date' ? '' : `type="${el.type}"` |
| | | const readonly = el.readonly ? 'readonly' : '' |
| | | |
| | | return `<${el.tag} ${type} ${vModel} ${format} ${valueFormat} ${width} ${placeholder} ${startPlaceholder} ${endPlaceholder} ${rangeSeparator} ${clearable} ${readonly} ${disabled}></${el.tag}>` |
| | | }, |
| | | 'el-rate': el => { |
| | | const { disabled, vModel } = attrBuilder(el) |
| | | const max = el.max ? `:max='${el.max}'` : '' |
| | | const allowHalf = el['allow-half'] ? 'allow-half' : '' |
| | | const showText = el['show-text'] ? 'show-text' : '' |
| | | const showScore = el['show-score'] ? 'show-score' : '' |
| | | |
| | | return `<${el.tag} ${vModel} ${allowHalf} ${showText} ${showScore} ${disabled}></${el.tag}>` |
| | | }, |
| | | 'el-color-picker': el => { |
| | | const { disabled, vModel } = attrBuilder(el) |
| | | const size = `size="${el.size}"` |
| | | const showAlpha = el['show-alpha'] ? 'show-alpha' : '' |
| | | const colorFormat = el['color-format'] ? `color-format="${el['color-format']}"` : '' |
| | | |
| | | return `<${el.tag} ${vModel} ${size} ${showAlpha} ${colorFormat} ${disabled}></${el.tag}>` |
| | | }, |
| | | 'el-upload': el => { |
| | | const disabled = el.disabled ? ':disabled=\'true\'' : '' |
| | | const action = el.action ? `:action="${el.vModel}Action"` : '' |
| | | const multiple = el.multiple ? 'multiple' : '' |
| | | const listType = el['list-type'] !== 'text' ? `list-type="${el['list-type']}"` : '' |
| | | const accept = el.accept ? `accept="${el.accept}"` : '' |
| | | const name = el.name !== 'file' ? `name="${el.name}"` : '' |
| | | const autoUpload = el['auto-upload'] === false ? ':auto-upload="false"' : '' |
| | | const beforeUpload = `:before-upload="${el.vModel}BeforeUpload"` |
| | | const fileList = `:file-list="${el.vModel}fileList"` |
| | | const ref = `ref="${el.vModel}"` |
| | | let child = buildElUploadChild(el) |
| | | |
| | | if (child) child = `\n${child}\n` // æ¢è¡ |
| | | return `<${el.tag} ${ref} ${fileList} ${action} ${autoUpload} ${multiple} ${beforeUpload} ${listType} ${accept} ${name} ${disabled}>${child}</${el.tag}>` |
| | | } |
| | | } |
| | | |
| | | function attrBuilder(el) { |
| | | return { |
| | | vModel: `v-model="${confGlobal.formModel}.${el.vModel}"`, |
| | | clearable: el.clearable ? 'clearable' : '', |
| | | placeholder: el.placeholder ? `placeholder="${el.placeholder}"` : '', |
| | | width: el.style && el.style.width ? ':style="{width: \'100%\'}"' : '', |
| | | disabled: el.disabled ? ':disabled=\'true\'' : '' |
| | | } |
| | | } |
| | | |
| | | // el-buttin å级 |
| | | function buildElButtonChild(conf) { |
| | | const children = [] |
| | | if (conf.default) { |
| | | children.push(conf.default) |
| | | } |
| | | return children.join('\n') |
| | | } |
| | | |
| | | // el-input innerHTML |
| | | function buildElInputChild(conf) { |
| | | const children = [] |
| | | if (conf.prepend) { |
| | | children.push(`<template slot="prepend">${conf.prepend}</template>`) |
| | | } |
| | | if (conf.append) { |
| | | children.push(`<template slot="append">${conf.append}</template>`) |
| | | } |
| | | return children.join('\n') |
| | | } |
| | | |
| | | function buildElSelectChild(conf) { |
| | | const children = [] |
| | | if (conf.options && conf.options.length) { |
| | | children.push(`<el-option v-for="(item, index) in ${conf.vModel}Options" :key="index" :label="item.label" :value="item.value" :disabled="item.disabled"></el-option>`) |
| | | } |
| | | return children.join('\n') |
| | | } |
| | | |
| | | function buildElRadioGroupChild(conf) { |
| | | const children = [] |
| | | if (conf.options && conf.options.length) { |
| | | const tag = conf.optionType === 'button' ? 'el-radio-button' : 'el-radio' |
| | | const border = conf.border ? 'border' : '' |
| | | children.push(`<${tag} v-for="(item, index) in ${conf.vModel}Options" :key="index" :label="item.value" :disabled="item.disabled" ${border}>{{item.label}}</${tag}>`) |
| | | } |
| | | return children.join('\n') |
| | | } |
| | | |
| | | function buildElCheckboxGroupChild(conf) { |
| | | const children = [] |
| | | if (conf.options && conf.options.length) { |
| | | const tag = conf.optionType === 'button' ? 'el-checkbox-button' : 'el-checkbox' |
| | | const border = conf.border ? 'border' : '' |
| | | children.push(`<${tag} v-for="(item, index) in ${conf.vModel}Options" :key="index" :label="item.value" :disabled="item.disabled" ${border}>{{item.label}}</${tag}>`) |
| | | } |
| | | return children.join('\n') |
| | | } |
| | | |
| | | function buildElUploadChild(conf) { |
| | | const list = [] |
| | | if (conf['list-type'] === 'picture-card') list.push('<i class="el-icon-plus"></i>') |
| | | else list.push(`<el-button size="small" type="primary" icon="el-icon-upload">${conf.buttonText}</el-button>`) |
| | | if (conf.showTip) list.push(`<div slot="tip" class="el-upload__tip">åªè½ä¸ä¼ ä¸è¶
è¿ ${conf.fileSize}${conf.sizeUnit} ç${conf.accept}æä»¶</div>`) |
| | | return list.join('\n') |
| | | } |
| | | |
| | | export function makeUpHtml(conf, type) { |
| | | const htmlList = [] |
| | | confGlobal = conf |
| | | someSpanIsNot24 = conf.fields.some(item => item.span !== 24) |
| | | conf.fields.forEach(el => { |
| | | htmlList.push(layouts[el.layout](el)) |
| | | }) |
| | | const htmlStr = htmlList.join('\n') |
| | | |
| | | let temp = buildFormTemplate(conf, htmlStr, type) |
| | | if (type === 'dialog') { |
| | | temp = dialogWrapper(temp) |
| | | } |
| | | confGlobal = null |
| | | return temp |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | ["platform-eleme","eleme","delete-solid","delete","s-tools","setting","user-solid","user","phone","phone-outline","more","more-outline","star-on","star-off","s-goods","goods","warning","warning-outline","question","info","remove","circle-plus","success","error","zoom-in","zoom-out","remove-outline","circle-plus-outline","circle-check","circle-close","s-help","help","minus","plus","check","close","picture","picture-outline","picture-outline-round","upload","upload2","download","camera-solid","camera","video-camera-solid","video-camera","message-solid","bell","s-cooperation","s-order","s-platform","s-fold","s-unfold","s-operation","s-promotion","s-home","s-release","s-ticket","s-management","s-open","s-shop","s-marketing","s-flag","s-comment","s-finance","s-claim","s-custom","s-opportunity","s-data","s-check","s-grid","menu","share","d-caret","caret-left","caret-right","caret-bottom","caret-top","bottom-left","bottom-right","back","right","bottom","top","top-left","top-right","arrow-left","arrow-right","arrow-down","arrow-up","d-arrow-left","d-arrow-right","video-pause","video-play","refresh","refresh-right","refresh-left","finished","sort","sort-up","sort-down","rank","loading","view","c-scale-to-original","date","edit","edit-outline","folder","folder-opened","folder-add","folder-remove","folder-delete","folder-checked","tickets","document-remove","document-delete","document-copy","document-checked","document","document-add","printer","paperclip","takeaway-box","search","monitor","attract","mobile","scissors","umbrella","headset","brush","mouse","coordinate","magic-stick","reading","data-line","data-board","pie-chart","data-analysis","collection-tag","film","suitcase","suitcase-1","receiving","collection","files","notebook-1","notebook-2","toilet-paper","office-building","school","table-lamp","house","no-smoking","smoking","shopping-cart-full","shopping-cart-1","shopping-cart-2","shopping-bag-1","shopping-bag-2","sold-out","sell","present","box","bank-card","money","coin","wallet","discount","price-tag","news","guide","male","female","thumb","cpu","link","connection","open","turn-off","set-up","chat-round","chat-line-round","chat-square","chat-dot-round","chat-dot-square","chat-line-square","message","postcard","position","turn-off-microphone","microphone","close-notification","bangzhu","time","odometer","crop","aim","switch-button","full-screen","copy-document","mic","stopwatch","medal-1","medal","trophy","trophy-1","first-aid-kit","discover","place","location","location-outline","location-information","add-location","delete-location","map-location","alarm-clock","timer","watch-1","watch","lock","unlock","key","service","mobile-phone","bicycle","truck","ship","basketball","football","soccer","baseball","wind-power","light-rain","lightning","heavy-rain","sunrise","sunrise-1","sunset","sunny","cloudy","partly-cloudy","cloudy-and-sunny","moon","moon-night","dish","dish-1","food","chicken","fork-spoon","knife-fork","burger","tableware","sugar","dessert","ice-cream","hot-water","water-cup","coffee-cup","cold-drink","goblet","goblet-full","goblet-square","goblet-square-full","refrigerator","grape","watermelon","cherry","apple","pear","orange","coffee","ice-tea","ice-drink","milk-tea","potato-strips","lollipop","ice-cream-square","ice-cream-round"] |
¶Ô±ÈÐÂÎļþ |
| | |
| | | import { titleCase } from '@/utils/index' |
| | | import { trigger } from './config' |
| | | // æä»¶å¤§å°è®¾ç½® |
| | | const units = { |
| | | KB: '1024', |
| | | MB: '1024 / 1024', |
| | | GB: '1024 / 1024 / 1024', |
| | | } |
| | | /** |
| | | * @name: çæjséè¦çæ°æ® |
| | | * @description: çæjséè¦çæ°æ® |
| | | * @param {*} conf |
| | | * @param {*} type å¼¹çªæè¡¨å |
| | | * @return {*} |
| | | */ |
| | | export function makeUpJs(conf, type) { |
| | | conf = JSON.parse(JSON.stringify(conf)) |
| | | const dataList = [] |
| | | const ruleList = [] |
| | | const optionsList = [] |
| | | const propsList = [] |
| | | const methodList = [] |
| | | const uploadVarList = [] |
| | | |
| | | conf.fields.forEach((el) => { |
| | | buildAttributes( |
| | | el, |
| | | dataList, |
| | | ruleList, |
| | | optionsList, |
| | | methodList, |
| | | propsList, |
| | | uploadVarList |
| | | ) |
| | | }) |
| | | |
| | | const script = buildexport( |
| | | conf, |
| | | type, |
| | | dataList.join('\n'), |
| | | ruleList.join('\n'), |
| | | optionsList.join('\n'), |
| | | uploadVarList.join('\n'), |
| | | propsList.join('\n'), |
| | | methodList.join('\n') |
| | | ) |
| | | |
| | | return script |
| | | } |
| | | /** |
| | | * @name: çæåæ° |
| | | * @description: çæåæ°ï¼å
æ¬è¡¨åæ°æ®è¡¨åéªè¯æ°æ®ï¼å¤ééé¡¹æ°æ®ï¼ä¸ä¼ æ°æ®ç |
| | | * @return {*} |
| | | */ |
| | | function buildAttributes( |
| | | el, |
| | | dataList, |
| | | ruleList, |
| | | optionsList, |
| | | methodList, |
| | | propsList, |
| | | uploadVarList |
| | | ){ |
| | | buildData(el, dataList) |
| | | buildRules(el, ruleList) |
| | | |
| | | if (el.options && el.options.length) { |
| | | buildOptions(el, optionsList) |
| | | if (el.dataType === 'dynamic') { |
| | | const model = `${el.vModel}Options` |
| | | const options = titleCase(model) |
| | | buildOptionMethod(`get${options}`, model, methodList) |
| | | } |
| | | } |
| | | |
| | | if (el.props && el.props.props) { |
| | | buildProps(el, propsList) |
| | | } |
| | | |
| | | if (el.action && el.tag === 'el-upload') { |
| | | uploadVarList.push( |
| | | ` |
| | | // ä¸ä¼ 请æ±è·¯å¾ |
| | | const ${el.vModel}Action = ref('${el.action}') |
| | | // ä¸ä¼ æä»¶å表 |
| | | const ${el.vModel}fileList = ref([])` |
| | | ) |
| | | methodList.push(buildBeforeUpload(el)) |
| | | if (!el['auto-upload']) { |
| | | methodList.push(buildSubmitUpload(el)) |
| | | } |
| | | } |
| | | |
| | | if (el.children) { |
| | | el.children.forEach((el2) => { |
| | | buildAttributes( |
| | | el2, |
| | | dataList, |
| | | ruleList, |
| | | optionsList, |
| | | methodList, |
| | | propsList, |
| | | uploadVarList |
| | | ) |
| | | }) |
| | | } |
| | | } |
| | | /** |
| | | * @name: çæè¡¨åæ°æ®formData |
| | | * @description: çæè¡¨åæ°æ®formData |
| | | * @param {*} conf |
| | | * @param {*} dataList æ°æ®å表 |
| | | * @return {*} |
| | | */ |
| | | function buildData(conf, dataList) { |
| | | if (conf.vModel === undefined) return |
| | | let defaultValue |
| | | if (typeof conf.defaultValue === 'string' && !conf.multiple) { |
| | | defaultValue = `'${conf.defaultValue}'` |
| | | } else { |
| | | defaultValue = `${JSON.stringify(conf.defaultValue)}` |
| | | } |
| | | dataList.push(`${conf.vModel}: ${defaultValue},`) |
| | | } |
| | | /** |
| | | * @name: çæè¡¨åéªè¯æ°æ®rule |
| | | * @description: çæè¡¨åéªè¯æ°æ®rule |
| | | * @param {*} conf |
| | | * @param {*} ruleList éªè¯æ°æ®å表 |
| | | * @return {*} |
| | | */ |
| | | function buildRules(conf, ruleList) { |
| | | if (conf.vModel === undefined) return |
| | | const rules = [] |
| | | if (trigger[conf.tag]) { |
| | | if (conf.required) { |
| | | const type = Array.isArray(conf.defaultValue) ? "type: 'array'," : '' |
| | | let message = Array.isArray(conf.defaultValue) |
| | | ? `请è³å°éæ©ä¸ä¸ª${conf.vModel}` |
| | | : conf.placeholder |
| | | if (message === undefined) message = `${conf.label}ä¸è½ä¸ºç©º` |
| | | rules.push( |
| | | `{ required: true, ${type} message: '${message}', trigger: '${ |
| | | trigger[conf.tag] |
| | | }' }` |
| | | ) |
| | | } |
| | | if (conf.regList && Array.isArray(conf.regList)) { |
| | | conf.regList.forEach((item) => { |
| | | if (item.pattern) { |
| | | rules.push( |
| | | `{ pattern: new RegExp(${item.pattern}), message: '${ |
| | | item.message |
| | | }', trigger: '${trigger[conf.tag]}' }` |
| | | ) |
| | | } |
| | | }) |
| | | } |
| | | ruleList.push(`${conf.vModel}: [${rules.join(',')}],`) |
| | | } |
| | | } |
| | | /** |
| | | * @name: çæéé¡¹æ°æ® |
| | | * @description: çæéé¡¹æ°æ®ï¼åéå¤é䏿ç |
| | | * @param {*} conf |
| | | * @param {*} optionsList éé¡¹æ°æ®å表 |
| | | * @return {*} |
| | | */ |
| | | function buildOptions(conf, optionsList) { |
| | | if (conf.vModel === undefined) return |
| | | if (conf.dataType === 'dynamic') { |
| | | conf.options = [] |
| | | } |
| | | const str = `const ${conf.vModel}Options = ref(${JSON.stringify(conf.options)})` |
| | | optionsList.push(str) |
| | | } |
| | | /** |
| | | * @name: çææ¹æ³ |
| | | * @description: çææ¹æ³ |
| | | * @param {*} methodName æ¹æ³å |
| | | * @param {*} model |
| | | * @param {*} methodList æ¹æ³å表 |
| | | * @return {*} |
| | | */ |
| | | function buildOptionMethod(methodName, model, methodList) { |
| | | const str = `function ${methodName}() { |
| | | // TODO å起请æ±è·åæ°æ® |
| | | ${model}.value |
| | | }` |
| | | methodList.push(str) |
| | | } |
| | | /** |
| | | * @name: çæè¡¨åç»ä»¶éè¦çprops设置 |
| | | * @description: çæè¡¨åç»ä»¶éè¦çprops设置ï¼å¦ï¼çº§èç»ä»¶ |
| | | * @param {*} conf |
| | | * @param {*} propsList |
| | | * @return {*} |
| | | */ |
| | | function buildProps(conf, propsList) { |
| | | if (conf.dataType === 'dynamic') { |
| | | conf.valueKey !== 'value' && (conf.props.props.value = conf.valueKey) |
| | | conf.labelKey !== 'label' && (conf.props.props.label = conf.labelKey) |
| | | conf.childrenKey !== 'children' && |
| | | (conf.props.props.children = conf.childrenKey) |
| | | } |
| | | const str = ` |
| | | // props设置 |
| | | const ${conf.vModel}Props = ref(${JSON.stringify(conf.props.props)})` |
| | | propsList.push(str) |
| | | } |
| | | /** |
| | | * @name: çæä¸ä¼ ç»ä»¶çç¸å
³å
容 |
| | | * @description: çæä¸ä¼ ç»ä»¶çç¸å
³å
容 |
| | | * @param {*} conf |
| | | * @return {*} |
| | | */ |
| | | function buildBeforeUpload(conf) { |
| | | const unitNum = units[conf.sizeUnit] |
| | | let rightSizeCode = '' |
| | | let acceptCode = '' |
| | | const returnList = [] |
| | | if (conf.fileSize) { |
| | | rightSizeCode = `let isRightSize = file.size / ${unitNum} < ${conf.fileSize} |
| | | if(!isRightSize){ |
| | | proxy.$modal.msgError('æä»¶å¤§å°è¶
è¿ ${conf.fileSize}${conf.sizeUnit}') |
| | | }` |
| | | returnList.push('isRightSize') |
| | | } |
| | | if (conf.accept) { |
| | | acceptCode = `let isAccept = new RegExp('${conf.accept}').test(file.type) |
| | | if(!isAccept){ |
| | | proxy.$modal.msgError('åºè¯¥éæ©${conf.accept}ç±»åçæä»¶') |
| | | }` |
| | | returnList.push('isAccept') |
| | | } |
| | | const str = ` |
| | | /** |
| | | * @name: ä¸ä¼ ä¹åçæä»¶å¤æ |
| | | * @description: ä¸ä¼ ä¹åçæä»¶å¤æï¼å¤ææä»¶å¤§å°æä»¶ç±»åç |
| | | * @param {*} file |
| | | * @return {*} |
| | | */ |
| | | function ${conf.vModel}BeforeUpload(file) { |
| | | ${rightSizeCode} |
| | | ${acceptCode} |
| | | return ${returnList.join('&&')} |
| | | }` |
| | | return returnList.length ? str : '' |
| | | } |
| | | /** |
| | | * @name: çææäº¤è¡¨åæ¹æ³ |
| | | * @description: çææäº¤è¡¨åæ¹æ³ |
| | | * @param {Object} conf vModel 表åref |
| | | * @return {*} |
| | | */ |
| | | function buildSubmitUpload(conf) { |
| | | const str = `function submitUpload() { |
| | | this.$refs['${conf.vModel}'].submit() |
| | | }` |
| | | return str |
| | | } |
| | | /** |
| | | * @name: ç»è£
js代ç |
| | | * @description: ç»è£
jsä»£ç æ¹æ³ |
| | | * @return {*} |
| | | */ |
| | | function buildexport( |
| | | conf, |
| | | type, |
| | | data, |
| | | rules, |
| | | selectOptions, |
| | | uploadVar, |
| | | props, |
| | | methods |
| | | ) { |
| | | let str = ` |
| | | const { proxy } = getCurrentInstance() |
| | | const ${conf.formRef} = ref() |
| | | const data = reactive({ |
| | | ${conf.formModel}: { |
| | | ${data} |
| | | }, |
| | | ${conf.formRules}: { |
| | | ${rules} |
| | | } |
| | | }) |
| | | |
| | | const {${conf.formModel}, ${conf.formRules}} = toRefs(data) |
| | | |
| | | ${selectOptions} |
| | | |
| | | ${uploadVar} |
| | | |
| | | ${props} |
| | | |
| | | ${methods} |
| | | ` |
| | | |
| | | if(type === 'dialog') { |
| | | str += ` |
| | | // å¼¹çªè®¾ç½® |
| | | const dialogVisible = defineModel() |
| | | // å¼¹çªç¡®è®¤åè° |
| | | const emit = defineEmits(['confirm']) |
| | | /** |
| | | * @name: å¼¹çªæå¼åæ§è¡ |
| | | * @description: å¼¹çªæå¼åæ§è¡æ¹æ³ |
| | | * @return {*} |
| | | */ |
| | | function onOpen(){ |
| | | |
| | | } |
| | | /** |
| | | * @name: å¼¹çªå
³éæ¶æ§è¡ |
| | | * @description: å¼¹çªå
³éæ¹æ³ï¼é置表å |
| | | * @return {*} |
| | | */ |
| | | function onClose(){ |
| | | ${conf.formRef}.value.resetFields() |
| | | } |
| | | /** |
| | | * @name: å¼¹çªåæ¶ |
| | | * @description: å¼¹çªåæ¶æ¹æ³ |
| | | * @return {*} |
| | | */ |
| | | function close(){ |
| | | dialogVisible.value = false |
| | | } |
| | | /** |
| | | * @name: å¼¹çªè¡¨åæäº¤ |
| | | * @description: å¼¹çªè¡¨åæäº¤æ¹æ³ |
| | | * @return {*} |
| | | */ |
| | | function handelConfirm(){ |
| | | ${conf.formRef}.value.validate((valid) => { |
| | | if (!valid) return |
| | | // TODO æäº¤è¡¨å |
| | | |
| | | close() |
| | | // åè°ç¶çº§ç»ä»¶ |
| | | emit('confirm') |
| | | }) |
| | | } |
| | | ` |
| | | } else { |
| | | str += ` |
| | | /** |
| | | * @name: 表åæäº¤ |
| | | * @description: 表åæäº¤æ¹æ³ |
| | | * @return {*} |
| | | */ |
| | | function submitForm() { |
| | | ${conf.formRef}.value.validate((valid) => { |
| | | if (!valid) return |
| | | // TODO æäº¤è¡¨å |
| | | }) |
| | | } |
| | | /** |
| | | * @name: 表åéç½® |
| | | * @description: 表åéç½®æ¹æ³ |
| | | * @return {*} |
| | | */ |
| | | function resetForm() { |
| | | ${conf.formRef}.value.resetFields() |
| | | } |
| | | ` |
| | | } |
| | | return str |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | import { defineComponent, h } from 'vue' |
| | | import { makeMap } from '@/utils/index' |
| | | |
| | | const isAttr = makeMap( |
| | | 'accept,accept-charset,accesskey,action,align,alt,async,autocomplete,' + |
| | | 'autofocus,autoplay,autosave,bgcolor,border,buffered,challenge,charset,' + |
| | | 'checked,cite,class,code,codebase,color,cols,colspan,content,http-equiv,' + |
| | | 'name,contenteditable,contextmenu,controls,coords,data,datetime,default,' + |
| | | 'defer,dir,dirname,disabled,download,draggable,dropzone,enctype,method,for,' + |
| | | 'form,formaction,headers,height,hidden,high,href,hreflang,http-equiv,' + |
| | | 'icon,id,ismap,itemprop,keytype,kind,label,lang,language,list,loop,low,' + |
| | | 'manifest,max,maxlength,media,method,GET,POST,min,multiple,email,file,' + |
| | | 'muted,name,novalidate,open,optimum,pattern,ping,placeholder,poster,' + |
| | | 'preload,radiogroup,readonly,rel,required,reversed,rows,rowspan,sandbox,' + |
| | | 'scope,scoped,seamless,selected,shape,size,type,text,password,sizes,span,' + |
| | | 'spellcheck,src,srcdoc,srclang,srcset,start,step,style,summary,tabindex,' + |
| | | 'target,title,type,usemap,value,width,wrap' + 'prefix-icon' |
| | | ) |
| | | const isNotProps = makeMap( |
| | | 'layout,prepend,regList,tag,document,changeTag,defaultValue' |
| | | ) |
| | | |
| | | function useVModel(props, emit) { |
| | | return { |
| | | modelValue: props.defaultValue, |
| | | 'onUpdate:modelValue': (val) => emit('update:modelValue', val), |
| | | } |
| | | } |
| | | const componentChild = { |
| | | 'el-button': { |
| | | default(h, conf, key) { |
| | | return conf[key] |
| | | }, |
| | | }, |
| | | 'el-select': { |
| | | options(h, conf, key) { |
| | | return conf.options.map(item => h(resolveComponent('el-option'), { |
| | | label: item.label, |
| | | value: item.value, |
| | | })) |
| | | } |
| | | }, |
| | | 'el-radio-group': { |
| | | options(h, conf, key) { |
| | | return conf.optionType === 'button' ? conf.options.map(item => h(resolveComponent('el-checkbox-button'), { |
| | | label: item.value, |
| | | }, () => item.label)) : conf.options.map(item => h(resolveComponent('el-radio'), { |
| | | label: item.value, |
| | | border: conf.border, |
| | | }, () => item.label)) |
| | | } |
| | | }, |
| | | 'el-checkbox-group': { |
| | | options(h, conf, key) { |
| | | return conf.optionType === 'button' ? conf.options.map(item => h(resolveComponent('el-checkbox-button'), { |
| | | label: item.value, |
| | | }, () => item.label)) : conf.options.map(item => h(resolveComponent('el-checkbox'), { |
| | | label: item.value, |
| | | border: conf.border, |
| | | }, () => item.label)) |
| | | } |
| | | }, |
| | | 'el-upload': { |
| | | 'list-type': (h, conf, key) => { |
| | | const option = {} |
| | | // if (conf.showTip) { |
| | | // tip = h('div', { |
| | | // class: "el-upload__tip" |
| | | // }, () => 'åªè½ä¸ä¼ ä¸è¶
è¿' + conf.fileSize + conf.sizeUnit + 'ç' + conf.accept + 'æä»¶') |
| | | // } |
| | | if (conf['list-type'] === 'picture-card') { |
| | | return h(resolveComponent('el-icon'), option, () => h(resolveComponent('Plus'))) |
| | | } else { |
| | | // option.size = "small" |
| | | option.type = "primary" |
| | | option.icon = "Upload" |
| | | return h(resolveComponent('el-button'), option, () => conf.buttonText) |
| | | } |
| | | }, |
| | | |
| | | } |
| | | } |
| | | const componentSlot = { |
| | | 'el-upload': { |
| | | 'tip': (h, conf, key) => { |
| | | if (conf.showTip) { |
| | | return () => h('div', { |
| | | class: "el-upload__tip" |
| | | }, 'åªè½ä¸ä¼ ä¸è¶
è¿' + conf.fileSize + conf.sizeUnit + 'ç' + conf.accept + 'æä»¶') |
| | | } |
| | | }, |
| | | } |
| | | } |
| | | export default defineComponent({ |
| | | |
| | | // ä½¿ç¨ render 彿° |
| | | render() { |
| | | const dataObject = { |
| | | attrs: {}, |
| | | props: {}, |
| | | on: {}, |
| | | style: {} |
| | | } |
| | | const confClone = JSON.parse(JSON.stringify(this.conf)) |
| | | const children = [] |
| | | const slot = {} |
| | | const childObjs = componentChild[confClone.tag] |
| | | if (childObjs) { |
| | | Object.keys(childObjs).forEach(key => { |
| | | const childFunc = childObjs[key] |
| | | if (confClone[key]) { |
| | | children.push(childFunc(h, confClone, key)) |
| | | } |
| | | }) |
| | | } |
| | | const slotObjs = componentSlot[confClone.tag] |
| | | if (slotObjs) { |
| | | Object.keys(slotObjs).forEach(key => { |
| | | const childFunc = slotObjs[key] |
| | | if (confClone[key]) { |
| | | slot[key] = childFunc(h, confClone, key) |
| | | } |
| | | }) |
| | | } |
| | | Object.keys(confClone).forEach(key => { |
| | | const val = confClone[key] |
| | | if (dataObject[key]) { |
| | | dataObject[key] = val |
| | | } else if (isAttr(key)) { |
| | | dataObject.attrs[key] = val |
| | | } else if (!isNotProps(key)) { |
| | | dataObject.props[key] = val |
| | | } |
| | | }) |
| | | if(children.length > 0){ |
| | | slot.default = () => children |
| | | } |
| | | |
| | | return h(resolveComponent(this.conf.tag), |
| | | { |
| | | modelValue: this.$attrs.modelValue, |
| | | ...dataObject.props, |
| | | ...dataObject.attrs, |
| | | style: { |
| | | ...dataObject.style |
| | | }, |
| | | } |
| | | , slot ?? null) |
| | | }, |
| | | props: { |
| | | conf: { |
| | | type: Object, |
| | | required: true, |
| | | }, |
| | | } |
| | | }) |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <el-dialog v-model="open" width="500px" title="éæ©çæç±»å" @open="onOpen" @close="onClose"> |
| | | <el-form ref="codeTypeForm" :model="formData" :rules="rules" label-width="100px"> |
| | | <el-form-item label="çæç±»å" prop="type"> |
| | | <el-radio-group v-model="formData.type"> |
| | | <el-radio-button v-for="(item, index) in typeOptions" :key="index" :label="item.value"> |
| | | {{ item.label }} |
| | | </el-radio-button> |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | <el-form-item v-if="showFileName" label="æä»¶å" prop="fileName"> |
| | | <el-input v-model="formData.fileName" placeholder="请è¾å
¥æä»¶å" clearable /> |
| | | </el-form-item> |
| | | </el-form> |
| | | |
| | | <template #footer> |
| | | <el-button @click="onClose">åæ¶</el-button> |
| | | <el-button type="primary" @click="handelConfirm">ç¡®å®</el-button> |
| | | </template> |
| | | </el-dialog> |
| | | </template> |
| | | |
| | | <script setup> |
| | | const open = defineModel() |
| | | const props = defineProps({ |
| | | showFileName: Boolean |
| | | }) |
| | | const emit = defineEmits(['confirm']) |
| | | const formData = ref({ |
| | | fileName: undefined, |
| | | type: 'file' |
| | | }) |
| | | const codeTypeForm = ref() |
| | | const rules = { |
| | | fileName: [{ |
| | | required: true, |
| | | message: '请è¾å
¥æä»¶å', |
| | | trigger: 'blur' |
| | | }], |
| | | type: [{ |
| | | required: true, |
| | | message: 'çæç±»åä¸è½ä¸ºç©º', |
| | | trigger: 'change' |
| | | }] |
| | | } |
| | | const typeOptions = ref([ |
| | | { |
| | | label: '页é¢', |
| | | value: 'file' |
| | | }, |
| | | { |
| | | label: 'å¼¹çª', |
| | | value: 'dialog' |
| | | } |
| | | ]) |
| | | function onOpen() { |
| | | if (props.showFileName) { |
| | | formData.value.fileName = `${+new Date()}.vue` |
| | | } |
| | | } |
| | | function onClose() { |
| | | open.value = false |
| | | } |
| | | function handelConfirm() { |
| | | codeTypeForm.value.validate(valid => { |
| | | if (!valid) return |
| | | emit('confirm', { ...formData.value }) |
| | | onClose() |
| | | }) |
| | | } |
| | | </script> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <el-col :span="element.span" :class="className" @click.stop="activeItem(element)"> |
| | | <el-form-item :label="element.label" :label-width="element.labelWidth ? element.labelWidth + 'px' : null" |
| | | :required="element.required" v-if="element.layout === 'colFormItem'"> |
| | | <render :key="element.tag" :conf="element" v-model="element.defaultValue" /> |
| | | </el-form-item> |
| | | <el-row :gutter="element.gutter" :class="element.class" @click.stop="activeItem(element)" v-else> |
| | | <span class="component-name"> {{ element.componentName }} </span> |
| | | <draggable group="componentsGroup" :animation="340" :list="element.children" class="drag-wrapper" item-key="label" |
| | | ref="draggableItemRef" :component-data="getComponentData()"> |
| | | <template #item="scoped"> |
| | | <draggable-item :key="scoped.element.renderKey" :drawing-list="element.children" :element="scoped.element" |
| | | :index="index" :active-id="activeId" :form-conf="formConf" @activeItem="activeItem(scoped.element)" |
| | | @copyItem="copyItem(scoped.element, element.children)" |
| | | @deleteItem="deleteItem(scoped.index, element.children)" /> |
| | | </template> |
| | | </draggable> |
| | | </el-row> |
| | | <span class="drawing-item-copy" title="å¤å¶" @click.stop="copyItem(element)"> |
| | | <el-icon><CopyDocument /></el-icon> |
| | | </span> |
| | | <span class="drawing-item-delete" title="å é¤" @click.stop="deleteItem(index)"> |
| | | <el-icon><Delete /></el-icon> |
| | | </span> |
| | | </el-col> |
| | | </template> |
| | | <script setup name="DraggableItem"> |
| | | import draggable from "vuedraggable/dist/vuedraggable.common"; |
| | | import render from '@/utils/generator/render' |
| | | |
| | | const props = defineProps({ |
| | | element: Object, |
| | | index: Number, |
| | | drawingList: Array, |
| | | activeId: { |
| | | type: [String, Number] |
| | | }, |
| | | formConf: Object |
| | | }) |
| | | const className = ref('') |
| | | const draggableItemRef = ref(null) |
| | | const emits = defineEmits(['activeItem', 'copyItem', 'deleteItem']) |
| | | |
| | | function activeItem(item) { |
| | | emits('activeItem', item) |
| | | } |
| | | function copyItem(item, parent) { |
| | | emits('copyItem', item, parent ?? props.drawingList) |
| | | } |
| | | function deleteItem(item, parent) { |
| | | emits('deleteItem', item, parent ?? props.drawingList) |
| | | } |
| | | |
| | | function getComponentData() { |
| | | return { |
| | | gutter: props.element.gutter, |
| | | justify: props.element.justify, |
| | | align: props.element.align |
| | | } |
| | | } |
| | | |
| | | watch(() => props.activeId, (val) => { |
| | | className.value = (props.element.layout === 'rowFormItem' ? 'drawing-row-item' : 'drawing-item') + (val === props.element.formId ? ' active-from-item' : '') |
| | | if (props.formConf.unFocusedComponentBorder) { |
| | | className.value += ' unfocus-bordered' |
| | | } |
| | | }, { immediate: true }) |
| | | </script> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="icon-dialog"> |
| | | <el-dialog v-model="value" width="980px" :close-on-click-modal="false" :modal-append-to-body="false" @open="onOpen" |
| | | @close="onClose"> |
| | | <template #header="{ close, titleId, titleClass }"> |
| | | 鿩徿 |
| | | <el-input v-model="key" size="small" :style="{ width: '260px' }" placeholder="请è¾å
¥å¾æ åç§°" prefix-icon="Search" |
| | | clearable /> |
| | | </template> |
| | | <ul class="icon-ul"> |
| | | <li v-for="icon in iconList" :key="icon" :class="active === icon ? 'active-item' : ''" @click="onSelect(icon)"> |
| | | <div> |
| | | <el-icon :size="30"> |
| | | <component :is="icon" /> |
| | | </el-icon> |
| | | <div>{{ icon }}</div> |
| | | </div> |
| | | </li> |
| | | </ul> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | <script setup> |
| | | import * as ElementPlusIconsVue from '@element-plus/icons-vue' |
| | | import { watch } from 'vue' |
| | | |
| | | const iconList = ref([]) |
| | | const originList = [] |
| | | const key = ref('') |
| | | const active = ref('') |
| | | const emit = defineEmits(['select']) |
| | | const value = defineModel() |
| | | for (const [key] of Object.entries(ElementPlusIconsVue)) { |
| | | iconList.value.push(key) |
| | | originList.push(key) |
| | | } |
| | | |
| | | function onOpen() { } |
| | | function onClose() { } |
| | | function onSelect(icon) { |
| | | active.value = icon |
| | | emit('select', icon) |
| | | value.value = false |
| | | } |
| | | |
| | | watch(key, (val) => { |
| | | if (val) { |
| | | iconList.value = originList.filter(name => name.indexOf(val) > -1) |
| | | } else { |
| | | iconList.value = originList |
| | | } |
| | | }) |
| | | </script> |
| | | <style lang="scss" scoped> |
| | | .icon-ul { |
| | | margin: 0; |
| | | padding: 0; |
| | | font-size: 0; |
| | | |
| | | li { |
| | | list-style-type: none; |
| | | text-align: center; |
| | | font-size: 14px; |
| | | display: inline-flex; |
| | | width: 16.66%; |
| | | box-sizing: border-box; |
| | | height: 108px; |
| | | padding: 6px 6px 6px 6px; |
| | | cursor: pointer; |
| | | overflow: hidden; |
| | | align-items: center; |
| | | justify-content: center; |
| | | |
| | | &:hover { |
| | | background: #f2f2f2; |
| | | } |
| | | |
| | | &.active-item { |
| | | background: #e1f3fb; |
| | | color: #7a6df0 |
| | | } |
| | | |
| | | i { |
| | | font-size: 30px; |
| | | line-height: 50px; |
| | | margin-bottom: 10px; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .icon-dialog { |
| | | :deep() { |
| | | .el-dialog { |
| | | border-radius: 8px; |
| | | margin-bottom: 0; |
| | | margin-top: 4vh !important; |
| | | display: flex; |
| | | flex-direction: column; |
| | | max-height: 92vh; |
| | | overflow: hidden; |
| | | box-sizing: border-box; |
| | | |
| | | .el-dialog__header { |
| | | padding-top: 14px; |
| | | } |
| | | |
| | | .el-dialog__body { |
| | | margin: 0 20px 20px 20px; |
| | | padding: 0; |
| | | overflow: auto; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | </style> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="right-board"> |
| | | <el-tabs v-model="currentTab" stretch class="center-tabs"> |
| | | <el-tab-pane label="ç»ä»¶å±æ§" name="field" /> |
| | | <el-tab-pane label="表å屿§" name="form" /> |
| | | </el-tabs> |
| | | <div class="field-box"> |
| | | <a class="document-link" target="_blank" :href="documentLink" title="æ¥çç»ä»¶ææ¡£"> |
| | | <el-icon> |
| | | <Link /> |
| | | </el-icon> |
| | | </a> |
| | | <el-scrollbar class="right-scrollbar"> |
| | | <!-- ç»ä»¶å±æ§ --> |
| | | <el-form v-show="currentTab === 'field' && showField" size="default" label-width="90px" label-position="top" |
| | | style=""> |
| | | <el-form-item v-if="activeData.changeTag" label="ç»ä»¶ç±»å"> |
| | | <el-select v-model="activeData.tagIcon" placeholder="è¯·éæ©ç»ä»¶ç±»å" :style="{ width: '100%' }" @change="tagChange"> |
| | | <el-option-group v-for="group in tagList" :key="group.label" :label="group.label"> |
| | | <el-option v-for="item in group.options" :key="item.label" :label="item.label" :value="item.tagIcon"> |
| | | <svg-icon class="node-icon" :icon-class="item.tagIcon" style="margin-right: 10px;" /> |
| | | <span> {{ item.label }}</span> |
| | | </el-option> |
| | | </el-option-group> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item v-if="activeData.vModel !== undefined" label="åæ®µå"> |
| | | <el-input v-model="activeData.vModel" placeholder="请è¾å
¥å段åï¼v-modelï¼" /> |
| | | </el-form-item> |
| | | <el-form-item v-if="activeData.componentName !== undefined" label="ç»ä»¶å"> |
| | | {{ activeData.componentName }} |
| | | </el-form-item> |
| | | <el-form-item v-if="activeData.label !== undefined" label="æ é¢"> |
| | | <el-input v-model="activeData.label" placeholder="请è¾å
¥æ é¢" /> |
| | | </el-form-item> |
| | | <el-form-item v-if="activeData.placeholder !== undefined" label="å ä½æç¤º"> |
| | | <el-input v-model="activeData.placeholder" placeholder="请è¾å
¥å ä½æç¤º" /> |
| | | </el-form-item> |
| | | <el-form-item v-if="activeData['start-placeholder'] !== undefined" label="å¼å§å ä½"> |
| | | <el-input v-model="activeData['start-placeholder']" placeholder="请è¾å
¥å ä½æç¤º" /> |
| | | </el-form-item> |
| | | <el-form-item v-if="activeData['end-placeholder'] !== undefined" label="ç»æå ä½"> |
| | | <el-input v-model="activeData['end-placeholder']" placeholder="请è¾å
¥å ä½æç¤º" /> |
| | | </el-form-item> |
| | | <el-form-item v-if="activeData.span !== undefined" label="表åæ
æ ¼"> |
| | | <el-slider v-model="activeData.span" :max="24" :min="1" :marks="{ 12: '' }" @change="spanChange" /> |
| | | </el-form-item> |
| | | <el-form-item v-if="activeData.layout === 'rowFormItem'" label="æ
æ ¼é´é"> |
| | | <el-input-number v-model="activeData.gutter" :min="0" placeholder="æ
æ ¼é´é" /> |
| | | </el-form-item> |
| | | |
| | | <el-form-item v-if="activeData.justify !== undefined" label="æ°´å¹³æå"> |
| | | <el-select v-model="activeData.justify" placeholder="è¯·éæ©æ°´å¹³æå" :style="{ width: '100%' }"> |
| | | <el-option v-for="(item, index) in justifyOptions" :key="index" :label="item.label" :value="item.value" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item v-if="activeData.align !== undefined" label="åç´æå"> |
| | | <el-radio-group v-model="activeData.align"> |
| | | <el-radio-button label="top" /> |
| | | <el-radio-button label="middle" /> |
| | | <el-radio-button label="bottom" /> |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | <el-form-item v-if="activeData.labelWidth !== undefined" label="æ ç¾å®½åº¦"> |
| | | <el-input v-model.number="activeData.labelWidth" type="number" placeholder="请è¾å
¥æ ç¾å®½åº¦" /> |
| | | </el-form-item> |
| | | <el-form-item v-if="activeData.style && activeData.style.width !== undefined" label="ç»ä»¶å®½åº¦"> |
| | | <el-input v-model="activeData.style.width" placeholder="请è¾å
¥ç»ä»¶å®½åº¦" clearable /> |
| | | </el-form-item> |
| | | <el-form-item v-if="activeData.vModel !== undefined" label="é»è®¤å¼"> |
| | | <el-input :value="setDefaultValue(activeData.defaultValue)" placeholder="请è¾å
¥é»è®¤å¼" |
| | | @input="onDefaultValueInput" /> |
| | | </el-form-item> |
| | | <el-form-item v-if="activeData.tag === 'el-checkbox-group'" label="è³å°åºé"> |
| | | <el-input-number :value="activeData.min" :min="0" placeholder="è³å°åºé" |
| | | @input="$set(activeData, 'min', $event ? $event : undefined)" /> |
| | | </el-form-item> |
| | | <el-form-item v-if="activeData.tag === 'el-checkbox-group'" label="æå¤å¯é"> |
| | | <el-input-number :value="activeData.max" :min="0" placeholder="æå¤å¯é" |
| | | @input="$set(activeData, 'max', $event ? $event : undefined)" /> |
| | | </el-form-item> |
| | | <el-form-item v-if="activeData.prepend !== undefined" label="åç¼"> |
| | | <el-input v-model="activeData.prepend" placeholder="请è¾å
¥åç¼" /> |
| | | </el-form-item> |
| | | <el-form-item v-if="activeData.append !== undefined" label="åç¼"> |
| | | <el-input v-model="activeData.append" placeholder="请è¾å
¥åç¼" /> |
| | | </el-form-item> |
| | | <el-form-item v-if="activeData['prefix-icon'] !== undefined" label="å徿 "> |
| | | <el-input v-model="activeData['prefix-icon']" placeholder="请è¾å
¥å徿 åç§°"> |
| | | <template #append> |
| | | <el-button icon="Pointer" @click="openIconsDialog('prefix-icon')"> |
| | | éæ© |
| | | </el-button> |
| | | </template> |
| | | </el-input> |
| | | </el-form-item> |
| | | <el-form-item v-if="activeData['suffix-icon'] !== undefined" label="å徿 "> |
| | | <el-input v-model="activeData['suffix-icon']" placeholder="请è¾å
¥å徿 åç§°"> |
| | | <template #append> |
| | | <el-button icon="Pointer" @click="openIconsDialog('suffix-icon')"> |
| | | éæ© |
| | | </el-button> |
| | | </template> |
| | | </el-input> |
| | | </el-form-item> |
| | | <el-form-item v-if="activeData.tag === 'el-cascader'" label="é项åé符"> |
| | | <el-input v-model="activeData.separator" placeholder="请è¾å
¥é项åé符" /> |
| | | </el-form-item> |
| | | <el-form-item v-if="activeData.autosize !== undefined" label="æå°è¡æ°"> |
| | | <el-input-number v-model="activeData.autosize.minRows" :min="1" placeholder="æå°è¡æ°" /> |
| | | </el-form-item> |
| | | <el-form-item v-if="activeData.autosize !== undefined" label="æå¤§è¡æ°"> |
| | | <el-input-number v-model="activeData.autosize.maxRows" :min="1" placeholder="æå¤§è¡æ°" /> |
| | | </el-form-item> |
| | | <el-form-item v-if="activeData.min !== undefined" label="æå°å¼"> |
| | | <el-input-number v-model="activeData.min" placeholder="æå°å¼" /> |
| | | </el-form-item> |
| | | <el-form-item v-if="activeData.max !== undefined" label="æå¤§å¼"> |
| | | <el-input-number v-model="activeData.max" placeholder="æå¤§å¼" /> |
| | | </el-form-item> |
| | | <el-form-item v-if="activeData.step !== undefined" label="æ¥é¿"> |
| | | <el-input-number v-model="activeData.step" placeholder="æ¥æ°" /> |
| | | </el-form-item> |
| | | <el-form-item v-if="activeData.tag === 'el-input-number'" label="精度"> |
| | | <el-input-number v-model="activeData.precision" :min="0" placeholder="精度" /> |
| | | </el-form-item> |
| | | <el-form-item v-if="activeData.tag === 'el-input-number'" label="æé®ä½ç½®"> |
| | | <el-radio-group v-model="activeData['controls-position']"> |
| | | <el-radio-button label=""> |
| | | é»è®¤ |
| | | </el-radio-button> |
| | | <el-radio-button label="right"> |
| | | å³ä¾§ |
| | | </el-radio-button> |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | <el-form-item v-if="activeData.maxlength !== undefined" label="æå¤è¾å
¥"> |
| | | <el-input v-model="activeData.maxlength" placeholder="请è¾å
¥å符é¿åº¦"> |
| | | <template slot="append"> |
| | | 个å符 |
| | | </template> |
| | | </el-input> |
| | | </el-form-item> |
| | | <el-form-item v-if="activeData['active-text'] !== undefined" label="å¼å¯æç¤º"> |
| | | <el-input v-model="activeData['active-text']" placeholder="请è¾å
¥å¼å¯æç¤º" /> |
| | | </el-form-item> |
| | | <el-form-item v-if="activeData['inactive-text'] !== undefined" label="å
³éæç¤º"> |
| | | <el-input v-model="activeData['inactive-text']" placeholder="请è¾å
¥å
³éæç¤º" /> |
| | | </el-form-item> |
| | | <el-form-item v-if="activeData['active-value'] !== undefined" label="å¼å¯å¼"> |
| | | <el-input :value="setDefaultValue(activeData['active-value'])" placeholder="请è¾å
¥å¼å¯å¼" |
| | | @input="onSwitchValueInput($event, 'active-value')" /> |
| | | </el-form-item> |
| | | <el-form-item v-if="activeData['inactive-value'] !== undefined" label="å
³éå¼"> |
| | | <el-input :value="setDefaultValue(activeData['inactive-value'])" placeholder="请è¾å
¥å
³éå¼" |
| | | @input="onSwitchValueInput($event, 'inactive-value')" /> |
| | | </el-form-item> |
| | | <el-form-item v-if="activeData.type !== undefined && 'el-date-picker' === activeData.tag" label="æ¶é´ç±»å"> |
| | | <el-select v-model="activeData.type" placeholder="è¯·éæ©æ¶é´ç±»å" :style="{ width: '100%' }" |
| | | @change="dateTypeChange"> |
| | | <el-option v-for="(item, index) in dateOptions" :key="index" :label="item.label" :value="item.value" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item v-if="activeData.name !== undefined" label="æä»¶å段å"> |
| | | <el-input v-model="activeData.name" placeholder="请è¾å
¥ä¸ä¼ æä»¶å段å" /> |
| | | </el-form-item> |
| | | <el-form-item v-if="activeData.accept !== undefined" label="æä»¶ç±»å"> |
| | | <el-select v-model="activeData.accept" placeholder="è¯·éæ©æä»¶ç±»å" :style="{ width: '100%' }" clearable> |
| | | <el-option label="å¾ç" value="image/*" /> |
| | | <el-option label="è§é¢" value="video/*" /> |
| | | <el-option label="é³é¢" value="audio/*" /> |
| | | <el-option label="excel" value=".xls,.xlsx" /> |
| | | <el-option label="word" value=".doc,.docx" /> |
| | | <el-option label="pdf" value=".pdf" /> |
| | | <el-option label="txt" value=".txt" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item v-if="activeData.fileSize !== undefined" label="æä»¶å¤§å°"> |
| | | <el-input v-model.number="activeData.fileSize" placeholder="请è¾å
¥æä»¶å¤§å°"> |
| | | <el-select slot="append" v-model="activeData.sizeUnit" :style="{ width: '66px' }"> |
| | | <el-option label="KB" value="KB" /> |
| | | <el-option label="MB" value="MB" /> |
| | | <el-option label="GB" value="GB" /> |
| | | </el-select> |
| | | </el-input> |
| | | </el-form-item> |
| | | <el-form-item v-if="activeData.action !== undefined" label="ä¸ä¼ å°å"> |
| | | <el-input v-model="activeData.action" placeholder="请è¾å
¥ä¸ä¼ å°å" clearable /> |
| | | </el-form-item> |
| | | <el-form-item v-if="activeData['list-type'] !== undefined" label="å表类å"> |
| | | <el-radio-group v-model="activeData['list-type']" size="small"> |
| | | <el-radio-button label="text"> |
| | | text |
| | | </el-radio-button> |
| | | <el-radio-button label="picture"> |
| | | picture |
| | | </el-radio-button> |
| | | <el-radio-button label="picture-card"> |
| | | picture-card |
| | | </el-radio-button> |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | <el-form-item v-if="activeData.buttonText !== undefined" v-show="'picture-card' !== activeData['list-type']" |
| | | label="æé®æå"> |
| | | <el-input v-model="activeData.buttonText" placeholder="请è¾å
¥æé®æå" /> |
| | | </el-form-item> |
| | | <el-form-item v-if="activeData['range-separator'] !== undefined" label="åé符"> |
| | | <el-input v-model="activeData['range-separator']" placeholder="请è¾å
¥åé符" /> |
| | | </el-form-item> |
| | | <el-form-item v-if="activeData['picker-options'] !== undefined" label="æ¶é´æ®µ"> |
| | | <el-input v-model="activeData['picker-options'].selectableRange" placeholder="请è¾å
¥æ¶é´æ®µ" /> |
| | | </el-form-item> |
| | | <el-form-item v-if="activeData.format !== undefined" label="æ¶é´æ ¼å¼"> |
| | | <el-input :value="activeData.format" placeholder="请è¾å
¥æ¶é´æ ¼å¼" @input="setTimeValue($event)" /> |
| | | </el-form-item> |
| | | <template v-if="['el-checkbox-group', 'el-radio-group', 'el-select'].indexOf(activeData.tag) > -1"> |
| | | <el-divider>é项</el-divider> |
| | | <draggable :list="activeData.options" :animation="340" group="selectItem" handle=".option-drag" |
| | | item-key="label"> |
| | | <template #item="{ element, index }"> |
| | | <div :key="index" class="select-item"> |
| | | <div class="select-line-icon option-drag"> |
| | | <i class="el-icon-s-operation" /> |
| | | </div> |
| | | <el-input v-model="element.label" placeholder="é项å" size="small" /> |
| | | <el-input placeholder="é项å¼" size="small" :value="element.value" |
| | | @input="setOptionValue(element, $event)" /> |
| | | <div class="close-btn select-line-icon" @click="activeData.options.splice(index, 1)"> |
| | | <el-icon> |
| | | <Remove /> |
| | | </el-icon> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | </draggable> |
| | | <div> |
| | | <el-button icon="CirclePlus" style="margin-left: 8px; margin-top: 10px;" text bg type="primary" |
| | | @click="addSelectItem"> |
| | | æ·»å é项 |
| | | </el-button> |
| | | </div> |
| | | <el-divider /> |
| | | </template> |
| | | |
| | | <template v-if="['el-cascader'].indexOf(activeData.tag) > -1"> |
| | | <el-divider>é项</el-divider> |
| | | <el-form-item label="æ°æ®ç±»å"> |
| | | <el-radio-group v-model="activeData.dataType" size="small"> |
| | | <el-radio-button label="dynamic"> |
| | | å¨ææ°æ® |
| | | </el-radio-button> |
| | | <el-radio-button label="static"> |
| | | éææ°æ® |
| | | </el-radio-button> |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | |
| | | <template v-if="activeData.dataType === 'dynamic'"> |
| | | <el-form-item label="æ ç¾é®å"> |
| | | <el-input v-model="activeData.labelKey" placeholder="请è¾å
¥æ ç¾é®å" /> |
| | | </el-form-item> |
| | | <el-form-item label="å¼é®å"> |
| | | <el-input v-model="activeData.valueKey" placeholder="请è¾å
¥å¼é®å" /> |
| | | </el-form-item> |
| | | <el-form-item label="å级é®å"> |
| | | <el-input v-model="activeData.childrenKey" placeholder="请è¾å
¥å级é®å" /> |
| | | </el-form-item> |
| | | </template> |
| | | |
| | | <el-tree v-if="activeData.dataType === 'static'" draggable :data="activeData.options" node-key="id" |
| | | :expand-on-click-node="false" :render-content="renderContent" /> |
| | | <div v-if="activeData.dataType === 'static'"> |
| | | <el-button icon="CirclePlus" style="margin-left: 0; margin-top: 10px;" type="primary" text bg |
| | | @click="addTreeItem"> |
| | | æ·»å ç¶çº§ |
| | | </el-button> |
| | | </div> |
| | | <el-divider /> |
| | | </template> |
| | | |
| | | <el-form-item v-if="activeData.optionType !== undefined" label="éé¡¹æ ·å¼"> |
| | | <el-radio-group v-model="activeData.optionType"> |
| | | <el-radio-button label="default"> |
| | | é»è®¤ |
| | | </el-radio-button> |
| | | <el-radio-button label="button"> |
| | | æé® |
| | | </el-radio-button> |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | <el-form-item v-if="activeData['active-color'] !== undefined" label="å¼å¯é¢è²"> |
| | | <el-color-picker v-model="activeData['active-color']" /> |
| | | </el-form-item> |
| | | <el-form-item v-if="activeData['inactive-color'] !== undefined" label="å
³éé¢è²"> |
| | | <el-color-picker v-model="activeData['inactive-color']" /> |
| | | </el-form-item> |
| | | |
| | | <el-form-item v-if="activeData['allow-half'] !== undefined" label="å
许åé"> |
| | | <el-switch v-model="activeData['allow-half']" /> |
| | | </el-form-item> |
| | | <el-form-item v-if="activeData['show-text'] !== undefined" label="è¾
婿å"> |
| | | <el-switch v-model="activeData['show-text']" @change="rateTextChange" /> |
| | | </el-form-item> |
| | | <el-form-item v-if="activeData['show-score'] !== undefined" label="æ¾ç¤ºåæ°"> |
| | | <el-switch v-model="activeData['show-score']" @change="rateScoreChange" /> |
| | | </el-form-item> |
| | | <el-form-item v-if="activeData['show-stops'] !== undefined" label="æ¾ç¤ºé´æç¹"> |
| | | <el-switch v-model="activeData['show-stops']" /> |
| | | </el-form-item> |
| | | <el-form-item v-if="activeData.range !== undefined" label="èå´éæ©"> |
| | | <el-switch v-model="activeData.range" @change="rangeChange" /> |
| | | </el-form-item> |
| | | <el-form-item v-if="activeData.border !== undefined && activeData.optionType === 'default'" label="æ¯å¦å¸¦è¾¹æ¡"> |
| | | <el-switch v-model="activeData.border" /> |
| | | </el-form-item> |
| | | <el-form-item v-if="activeData.tag === 'el-color-picker'" label="é¢è²æ ¼å¼"> |
| | | <el-select v-model="activeData['color-format']" placeholder="è¯·éæ©é¢è²æ ¼å¼" :style="{ width: '100%' }" |
| | | @change="colorFormatChange"> |
| | | <el-option v-for="(item, index) in colorFormatOptions" :key="index" :label="item.label" |
| | | :value="item.value" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item v-if="activeData.size !== undefined && |
| | | (activeData.optionType === 'button' || |
| | | activeData.border || |
| | | activeData.tag === 'el-color-picker')" label="é项尺寸"> |
| | | <el-radio-group v-model="activeData.size"> |
| | | <el-radio-button label="large"> |
| | | è¾å¤§ |
| | | </el-radio-button> |
| | | <el-radio-button label="default"> |
| | | é»è®¤ |
| | | </el-radio-button> |
| | | <el-radio-button label="small"> |
| | | è¾å° |
| | | </el-radio-button> |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | <el-form-item v-if="activeData['show-word-limit'] !== undefined" label="è¾å
¥ç»è®¡"> |
| | | <el-switch v-model="activeData['show-word-limit']" /> |
| | | </el-form-item> |
| | | <el-form-item v-if="activeData.tag === 'el-input-number'" label="ä¸¥æ ¼æ¥æ°"> |
| | | <el-switch v-model="activeData['step-strictly']" /> |
| | | </el-form-item> |
| | | <el-form-item v-if="activeData.tag === 'el-cascader'" label="æ¯å¦å¤é"> |
| | | <el-switch v-model="activeData.props.props.multiple" /> |
| | | </el-form-item> |
| | | <el-form-item v-if="activeData.tag === 'el-cascader'" label="å±ç¤ºå
¨è·¯å¾"> |
| | | <el-switch v-model="activeData['show-all-levels']" /> |
| | | </el-form-item> |
| | | <el-form-item v-if="activeData.tag === 'el-cascader'" label="å¯å¦çé"> |
| | | <el-switch v-model="activeData.filterable" /> |
| | | </el-form-item> |
| | | <el-form-item v-if="activeData.clearable !== undefined" label="è½å¦æ¸
空"> |
| | | <el-switch v-model="activeData.clearable" /> |
| | | </el-form-item> |
| | | <el-form-item v-if="activeData.showTip !== undefined" label="æ¾ç¤ºæç¤º"> |
| | | <el-switch v-model="activeData.showTip" /> |
| | | </el-form-item> |
| | | <el-form-item v-if="activeData.multiple !== undefined" label="å¤éæä»¶"> |
| | | <el-switch v-model="activeData.multiple" /> |
| | | </el-form-item> |
| | | <el-form-item v-if="activeData['auto-upload'] !== undefined" label="èªå¨ä¸ä¼ "> |
| | | <el-switch v-model="activeData['auto-upload']" /> |
| | | </el-form-item> |
| | | <el-form-item v-if="activeData.readonly !== undefined" label="æ¯å¦åªè¯»"> |
| | | <el-switch v-model="activeData.readonly" /> |
| | | </el-form-item> |
| | | <el-form-item v-if="activeData.disabled !== undefined" label="æ¯å¦ç¦ç¨"> |
| | | <el-switch v-model="activeData.disabled" /> |
| | | </el-form-item> |
| | | <el-form-item v-if="activeData.tag === 'el-select'" label="æ¯å¦å¯æç´¢"> |
| | | <el-switch v-model="activeData.filterable" /> |
| | | </el-form-item> |
| | | <el-form-item v-if="activeData.tag === 'el-select'" label="æ¯å¦å¤é"> |
| | | <el-switch v-model="activeData.multiple" @change="multipleChange" /> |
| | | </el-form-item> |
| | | <el-form-item v-if="activeData.required !== undefined" label="æ¯å¦å¿
å¡«"> |
| | | <el-switch v-model="activeData.required" /> |
| | | </el-form-item> |
| | | |
| | | <template v-if="activeData.layoutTree"> |
| | | <el-divider>å¸å±ç»ææ </el-divider> |
| | | <el-tree :data="[activeData]" :props="layoutTreeProps" node-key="renderKey" default-expand-all draggable> |
| | | <template #default="{ node, data }"> |
| | | <span class="node-label"> |
| | | <svg-icon class="node-icon" :icon-class="data.tagIcon" style="margin-right: 5px;" /> |
| | | {{ node.label }} |
| | | </span> |
| | | </template> |
| | | </el-tree> |
| | | </template> |
| | | |
| | | <template v-if="activeData.layout === 'colFormItem'"> |
| | | <el-divider>æ£åæ ¡éª</el-divider> |
| | | <div v-for="(item, index) in activeData.regList" :key="index" class="reg-item"> |
| | | <span class="close-btn" @click="activeData.regList.splice(index, 1)"> |
| | | <el-icon> |
| | | <Close /> |
| | | </el-icon> |
| | | </span> |
| | | <el-form-item label="表达å¼"> |
| | | <el-input v-model="item.pattern" placeholder="请è¾å
¥æ£å" /> |
| | | </el-form-item> |
| | | <el-form-item label="é误æç¤º" style="margin-bottom:0"> |
| | | <el-input v-model="item.message" placeholder="请è¾å
¥é误æç¤º" /> |
| | | </el-form-item> |
| | | </div> |
| | | <div> |
| | | <el-button icon="CirclePlus" style="margin-left: 0; margin-top: 10px;" type="primary" text bg |
| | | @click="addReg"> |
| | | æ·»å è§å |
| | | </el-button> |
| | | </div> |
| | | </template> |
| | | </el-form> |
| | | <!-- 表å屿§ --> |
| | | <el-form v-show="currentTab === 'form'" label-width="90px" label-position="top"> |
| | | <el-form-item label="表åå"> |
| | | <el-input v-model="formConf.formRef" placeholder="请è¾å
¥è¡¨ååï¼refï¼" /> |
| | | </el-form-item> |
| | | <el-form-item label="è¡¨åæ¨¡å"> |
| | | <el-input v-model="formConf.formModel" placeholder="请è¾å
¥æ°æ®æ¨¡å" /> |
| | | </el-form-item> |
| | | <el-form-item label="æ ¡éªæ¨¡å"> |
| | | <el-input v-model="formConf.formRules" placeholder="请è¾å
¥æ ¡éªæ¨¡å" /> |
| | | </el-form-item> |
| | | <el-form-item label="表å尺寸"> |
| | | <el-radio-group v-model="formConf.size"> |
| | | <el-radio-button label="large"> |
| | | è¾å¤§ |
| | | </el-radio-button> |
| | | <el-radio-button label="default"> |
| | | é»è®¤ |
| | | </el-radio-button> |
| | | <el-radio-button label="small"> |
| | | è¾å° |
| | | </el-radio-button> |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | <el-form-item label="æ ç¾å¯¹é½"> |
| | | <el-radio-group v-model="formConf.labelPosition"> |
| | | <el-radio-button label="left"> |
| | | å·¦å¯¹é½ |
| | | </el-radio-button> |
| | | <el-radio-button label="right"> |
| | | å³å¯¹é½ |
| | | </el-radio-button> |
| | | <el-radio-button label="top"> |
| | | é¡¶é¨å¯¹é½ |
| | | </el-radio-button> |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | <el-form-item label="æ ç¾å®½åº¦"> |
| | | <el-input-number v-model="formConf.labelWidth" placeholder="æ ç¾å®½åº¦" /> |
| | | </el-form-item> |
| | | <el-form-item label="æ
æ ¼é´é"> |
| | | <el-input-number v-model="formConf.gutter" :min="0" placeholder="æ
æ ¼é´é" /> |
| | | </el-form-item> |
| | | <el-form-item label="ç¦ç¨è¡¨å"> |
| | | <el-switch v-model="formConf.disabled" /> |
| | | </el-form-item> |
| | | <el-form-item label="表åæé®"> |
| | | <el-switch v-model="formConf.formBtns" /> |
| | | </el-form-item> |
| | | <el-form-item label="æ¾ç¤ºæªéä¸ç»ä»¶è¾¹æ¡"> |
| | | <el-switch v-model="formConf.unFocusedComponentBorder" /> |
| | | </el-form-item> |
| | | </el-form> |
| | | </el-scrollbar> |
| | | </div> |
| | | <icons-dialog v-model="iconsVisible" :current="activeData[currentIconModel]" @select="setIcon" /> |
| | | <treeNode-dialog v-model="dialogVisible" @commit="addNode" /> |
| | | |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import draggable from "vuedraggable/dist/vuedraggable.common" |
| | | import { isNumberStr } from '@/utils/index' |
| | | import IconsDialog from './IconsDialog' |
| | | import TreeNodeDialog from './TreeNodeDialog' |
| | | import { inputComponents, selectComponents } from '@/utils/generator/config' |
| | | |
| | | const { proxy } = getCurrentInstance() |
| | | const dateTimeFormat = { |
| | | date: 'YYYY-MM-DD', |
| | | week: 'YYYY 第 ww å¨', |
| | | month: 'YYYY-MM', |
| | | year: 'YYYY', |
| | | datetime: 'YYYY-MM-DD HH:mm:ss', |
| | | daterange: 'YYYY-MM-DD', |
| | | monthrange: 'YYYY-MM', |
| | | datetimerange: 'YYYY-MM-DD HH:mm:ss' |
| | | } |
| | | const props = defineProps({ |
| | | showField: Boolean, |
| | | activeData: Object, |
| | | formConf: Object |
| | | }) |
| | | |
| | | const data = reactive({ |
| | | currentTab: 'field', |
| | | currentNode: null, |
| | | dialogVisible: false, |
| | | iconsVisible: false, |
| | | currentIconModel: null, |
| | | dateTypeOptions: [ |
| | | { |
| | | label: 'æ¥(date)', |
| | | value: 'date' |
| | | }, |
| | | { |
| | | label: 'å¨(week)', |
| | | value: 'week' |
| | | }, |
| | | { |
| | | label: 'æ(month)', |
| | | value: 'month' |
| | | }, |
| | | { |
| | | label: 'å¹´(year)', |
| | | value: 'year' |
| | | }, |
| | | { |
| | | label: 'æ¥ææ¶é´(datetime)', |
| | | value: 'datetime' |
| | | } |
| | | ], |
| | | dateRangeTypeOptions: [ |
| | | { |
| | | label: 'æ¥æèå´(daterange)', |
| | | value: 'daterange' |
| | | }, |
| | | { |
| | | label: 'æèå´(monthrange)', |
| | | value: 'monthrange' |
| | | }, |
| | | { |
| | | label: 'æ¥ææ¶é´èå´(datetimerange)', |
| | | value: 'datetimerange' |
| | | } |
| | | ], |
| | | colorFormatOptions: [ |
| | | { |
| | | label: 'hex', |
| | | value: 'hex' |
| | | }, |
| | | { |
| | | label: 'rgb', |
| | | value: 'rgb' |
| | | }, |
| | | { |
| | | label: 'rgba', |
| | | value: 'rgba' |
| | | }, |
| | | { |
| | | label: 'hsv', |
| | | value: 'hsv' |
| | | }, |
| | | { |
| | | label: 'hsl', |
| | | value: 'hsl' |
| | | } |
| | | ], |
| | | justifyOptions: [ |
| | | { |
| | | label: 'start', |
| | | value: 'start' |
| | | }, |
| | | { |
| | | label: 'end', |
| | | value: 'end' |
| | | }, |
| | | { |
| | | label: 'center', |
| | | value: 'center' |
| | | }, |
| | | { |
| | | label: 'space-around', |
| | | value: 'space-around' |
| | | }, |
| | | { |
| | | label: 'space-between', |
| | | value: 'space-between' |
| | | } |
| | | ], |
| | | layoutTreeProps: { |
| | | label(data, node) { |
| | | return data.componentName || `${data.label}: ${data.vModel}` |
| | | } |
| | | } |
| | | }) |
| | | |
| | | const { currentTab, currentNode, dialogVisible, iconsVisible, currentIconModel, dateTypeOptions, dateRangeTypeOptions, colorFormatOptions, justifyOptions, layoutTreeProps } = toRefs(data) |
| | | |
| | | const documentLink = computed(() => props.activeData.document || 'https://element-plus.org/zh-CN/guide/installation') |
| | | |
| | | const dateOptions = computed(() => { |
| | | if (props.activeData.type !== undefined && props.activeData.tag === 'el-date-picker') { |
| | | if (props.activeData['start-placeholder'] === undefined) { |
| | | return dateTypeOptions.value |
| | | } |
| | | return dateRangeTypeOptions.value |
| | | } |
| | | return [] |
| | | }) |
| | | |
| | | const tagList = ref([ |
| | | { |
| | | label: 'è¾å
¥åç»ä»¶', |
| | | options: inputComponents |
| | | }, |
| | | { |
| | | label: 'éæ©åç»ä»¶', |
| | | options: selectComponents |
| | | } |
| | | ]) |
| | | |
| | | const emit = defineEmits(['tag-change']) |
| | | |
| | | function addReg() { |
| | | props.activeData.regList.push({ |
| | | pattern: '', |
| | | message: '' |
| | | }) |
| | | } |
| | | function addSelectItem() { |
| | | props.activeData.options.push({ |
| | | label: '', |
| | | value: '' |
| | | }) |
| | | } |
| | | |
| | | function addTreeItem() { |
| | | ++proxy.idGlobal |
| | | dialogVisible.value = true |
| | | currentNode.value = props.activeData.options |
| | | } |
| | | |
| | | function renderContent(h, { node, data, store }) { |
| | | return h('div', { |
| | | class: "custom-tree-node" |
| | | }, [ |
| | | h('span', node.label), |
| | | h('span', { |
| | | class: "node-operation" |
| | | }, [ |
| | | h(resolveComponent('el-link'), { |
| | | type: "primary", |
| | | icon: "Plus", |
| | | underline: false, |
| | | onClick: () => { |
| | | append(data) |
| | | |
| | | } |
| | | }), |
| | | h(resolveComponent('el-link'), { |
| | | type: "danger", |
| | | icon: "Delete", |
| | | underline: false, |
| | | style: "margin-left: 5px;", |
| | | onClick: () => { |
| | | remove(node, data) |
| | | } |
| | | }) |
| | | ]) |
| | | ]) |
| | | } |
| | | function append(data) { |
| | | if (!data.children) { |
| | | data.children = [] |
| | | } |
| | | dialogVisible.value = true |
| | | currentNode.value = data.children |
| | | } |
| | | function remove(node, data) { |
| | | const { parent } = node |
| | | const children = parent.data.children || parent.data |
| | | const index = children.findIndex(d => d.id === data.id) |
| | | children.splice(index, 1) |
| | | } |
| | | function addNode(data) { |
| | | currentNode.value.push(data) |
| | | } |
| | | |
| | | function setOptionValue(item, val) { |
| | | item.value = isNumberStr(val) ? +val : val |
| | | } |
| | | function setDefaultValue(val) { |
| | | if (Array.isArray(val)) { |
| | | return val.join(',') |
| | | } |
| | | if (['string', 'number'].indexOf(val) > -1) { |
| | | return val |
| | | } |
| | | if (typeof val === 'boolean') { |
| | | return `${val}` |
| | | } |
| | | return val |
| | | } |
| | | |
| | | function onDefaultValueInput(str) { |
| | | if (Array.isArray(props.activeData.defaultValue)) { |
| | | // æ°ç» |
| | | props.activeData.defaultValue = str.split(',').map(val => (isNumberStr(val) ? +val : val)) |
| | | } else if (['true', 'false'].indexOf(str) > -1) { |
| | | // å¸å° |
| | | props.activeData.defaultValue = JSON.parse(str) |
| | | } else { |
| | | // åç¬¦ä¸²åæ°å |
| | | props.activeData.defaultValue = isNumberStr(str) ? +str : str |
| | | } |
| | | } |
| | | |
| | | function onSwitchValueInput(val, name) { |
| | | if (['true', 'false'].indexOf(val) > -1) { |
| | | props.activeData[name] = JSON.parse(val) |
| | | } else { |
| | | props.activeData[name] = isNumberStr(val) ? +val : val |
| | | } |
| | | } |
| | | |
| | | function setTimeValue(val, type) { |
| | | const valueFormat = type === 'week' ? dateTimeFormat.date : val |
| | | props.activeData.defaultValue = null |
| | | props.activeData['value-format'] = valueFormat |
| | | props.activeData.format = val |
| | | } |
| | | |
| | | function spanChange(val) { |
| | | props.formConf.span = val |
| | | } |
| | | |
| | | function multipleChange(val) { |
| | | props.activeData.defaultValue = val ? [] : '' |
| | | } |
| | | |
| | | function dateTypeChange(val) { |
| | | setTimeValue(dateTimeFormat[val], val) |
| | | } |
| | | |
| | | function rangeChange(val) { |
| | | props.activeData.defaultValue = val ? [props.activeData.min, props.activeData.max] : props.activeData.min |
| | | } |
| | | |
| | | function rateTextChange(val) { |
| | | if (val) props.activeData['show-score'] = false |
| | | } |
| | | |
| | | function rateScoreChange(val) { |
| | | if (val) props.activeData['show-text'] = false |
| | | } |
| | | |
| | | function colorFormatChange(val) { |
| | | props.activeData.defaultValue = null |
| | | props.activeData['show-alpha'] = val.indexOf('a') > -1 |
| | | props.activeData.renderKey = +new Date() // æ´æ°renderKey,éæ°æ¸²æè¯¥ç»ä»¶ |
| | | } |
| | | |
| | | function openIconsDialog(model) { |
| | | iconsVisible.value = true |
| | | currentIconModel.value = model |
| | | } |
| | | |
| | | function setIcon(val) { |
| | | props.activeData[currentIconModel.value] = val |
| | | } |
| | | |
| | | function tagChange(tagIcon) { |
| | | let target = inputComponents.find(item => item.tagIcon === tagIcon) |
| | | if (!target) target = selectComponents.find(item => item.tagIcon === tagIcon) |
| | | emit('tag-change', target) |
| | | } |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .right-board { |
| | | width: 350px; |
| | | position: absolute; |
| | | right: 0; |
| | | top: 0; |
| | | padding-top: 3px; |
| | | |
| | | &:deep() { |
| | | .el-tabs__header { |
| | | margin: 0; |
| | | } |
| | | |
| | | .el-input-group__append .el-button { |
| | | display: inline-flex; |
| | | } |
| | | } |
| | | |
| | | .field-box { |
| | | position: relative; |
| | | height: calc(100vh - 50px - 40px - 42px); |
| | | box-sizing: border-box; |
| | | overflow: hidden; |
| | | } |
| | | |
| | | .el-scrollbar { |
| | | height: 100%; |
| | | |
| | | &:deep() { |
| | | .el-scrollbar__view { |
| | | padding: 30px 20px; |
| | | } |
| | | |
| | | } |
| | | } |
| | | } |
| | | |
| | | .reg-item { |
| | | padding: 12px 6px; |
| | | background: var(--el-border-color-extra-light); |
| | | position: relative; |
| | | border-radius: 4px; |
| | | |
| | | .close-btn { |
| | | position: absolute; |
| | | right: -6px; |
| | | top: -6px; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | width: 16px; |
| | | height: 16px; |
| | | line-height: 16px; |
| | | background: rgba(0, 0, 0, .2); |
| | | border-radius: 50%; |
| | | color: #fff; |
| | | z-index: 1; |
| | | cursor: pointer; |
| | | font-size: 12px; |
| | | } |
| | | } |
| | | |
| | | .select-item { |
| | | display: flex; |
| | | border: 1px dashed #fff; |
| | | box-sizing: border-box; |
| | | |
| | | & .close-btn { |
| | | cursor: pointer; |
| | | color: #f56c6c; |
| | | } |
| | | |
| | | & .el-input+.el-input { |
| | | margin-left: 4px; |
| | | } |
| | | } |
| | | |
| | | .select-item+.select-item { |
| | | margin-top: 4px; |
| | | } |
| | | |
| | | .select-item.sortable-chosen { |
| | | border: 1px dashed #409eff; |
| | | } |
| | | |
| | | .select-line-icon { |
| | | line-height: 32px; |
| | | font-size: 22px; |
| | | padding: 0 4px; |
| | | color: #777; |
| | | } |
| | | |
| | | .option-drag { |
| | | cursor: move; |
| | | } |
| | | |
| | | .time-range { |
| | | .el-date-editor { |
| | | width: 227px; |
| | | } |
| | | |
| | | :deep() { |
| | | .el-icon-time { |
| | | display: none; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .document-link { |
| | | position: absolute; |
| | | display: flex; |
| | | width: 26px; |
| | | height: 26px; |
| | | top: 0; |
| | | left: 0; |
| | | cursor: pointer; |
| | | background: #409eff; |
| | | z-index: 1; |
| | | border-radius: 0 0 6px 0; |
| | | justify-content: center; |
| | | align-items: center; |
| | | color: #fff; |
| | | font-size: 18px; |
| | | } |
| | | |
| | | .node-label { |
| | | font-size: 14px; |
| | | } |
| | | |
| | | .node-icon { |
| | | color: #bebfc3; |
| | | } |
| | | |
| | | .custom-tree-node { |
| | | flex: 1; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: space-between; |
| | | font-size: 14px; |
| | | padding-right: 8px; |
| | | } |
| | | </style> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div> |
| | | <el-dialog title="æ·»å é项" v-model="open" width="800px" :close-on-click-modal="false" :modal-append-to-body="false" |
| | | @open="onOpen" @close="onClose"> |
| | | <el-form ref="treeNodeForm" :model="formData" :rules="rules" label-width="100px"> |
| | | <el-col :span="24"> |
| | | <el-form-item label="é项å" prop="label"> |
| | | <el-input v-model="formData.label" placeholder="请è¾å
¥é项å" clearable /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="24"> |
| | | <el-form-item label="é项å¼" prop="value"> |
| | | <el-input v-model="formData.value" placeholder="请è¾å
¥é项å¼" clearable> |
| | | <template #append> |
| | | <el-select v-model="dataType" :style="{ width: '100px' }"> |
| | | <el-option v-for="(item, index) in dataTypeOptions" :key="index" :label="item.label" :value="item.value" |
| | | :disabled="item.disabled" /> |
| | | </el-select> |
| | | </template> |
| | | |
| | | </el-input> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-form> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button type="primary" @click="handelConfirm">ç¡® å®</el-button> |
| | | <el-button @click="onClose">å æ¶</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | <script setup> |
| | | const open = defineModel() |
| | | const emit = defineEmits(['confirm']) |
| | | const formData = ref({ |
| | | label: undefined, |
| | | value: undefined |
| | | }) |
| | | const rules = { |
| | | label: [ |
| | | { |
| | | required: true, |
| | | message: '请è¾å
¥é项å', |
| | | trigger: 'blur' |
| | | } |
| | | ], |
| | | value: [ |
| | | { |
| | | required: true, |
| | | message: '请è¾å
¥é项å¼', |
| | | trigger: 'blur' |
| | | } |
| | | ] |
| | | } |
| | | const dataType = ref('string') |
| | | const dataTypeOptions = ref([ |
| | | { |
| | | label: 'å符串', |
| | | value: 'string' |
| | | }, |
| | | { |
| | | label: 'æ°å', |
| | | value: 'number' |
| | | } |
| | | ]) |
| | | const id = ref(100) |
| | | const treeNodeForm = ref() |
| | | |
| | | function onOpen() { |
| | | formData.value = { |
| | | label: undefined, |
| | | value: undefined |
| | | } |
| | | } |
| | | |
| | | function onClose() { |
| | | open.value = false |
| | | } |
| | | |
| | | function handelConfirm() { |
| | | treeNodeForm.value.validate(valid => { |
| | | if (!valid) return |
| | | if (dataType.value === 'number') { |
| | | formData.value.value = parseFloat(formData.value.value) |
| | | } |
| | | formData.value.id = id.value++ |
| | | emit('commit', formData.value) |
| | | onClose() |
| | | }) |
| | | } |
| | | </script> |
| | |
| | | <template>
|
| | | <div> 表åæå»º <svg-icon icon-class="build" /> </div>
|
| | | </template> |
| | | <div class="container">
|
| | | <div class="left-board">
|
| | | <div class="logo-wrapper">
|
| | | <div class="logo">
|
| | | <img :src="logo" alt="logo"> Form Generator
|
| | | </div>
|
| | | </div>
|
| | | <el-scrollbar class="left-scrollbar">
|
| | | <div class="components-list">
|
| | | <div class="components-title">
|
| | | <svg-icon icon-class="component" />è¾å
¥åç»ä»¶
|
| | | </div>
|
| | | <draggable class="components-draggable" :list="inputComponents"
|
| | | :group="{ name: 'componentsGroup', pull: 'clone', put: false }" :clone="cloneComponent"
|
| | | draggable=".components-item" :sort="false" @end="onEnd" item-key="label">
|
| | | <template #item="{ element, index }">
|
| | | <div :key="index" class="components-item" @click="addComponent(element)">
|
| | | <div class="components-body">
|
| | | <svg-icon :icon-class="element.tagIcon" />
|
| | | {{ element.label }}
|
| | | </div>
|
| | | </div>
|
| | | </template>
|
| | | </draggable>
|
| | | <div class="components-title">
|
| | | <svg-icon icon-class="component" />éæ©åç»ä»¶
|
| | | </div>
|
| | | <draggable class="components-draggable" :list="selectComponents"
|
| | | :group="{ name: 'componentsGroup', pull: 'clone', put: false }" :clone="cloneComponent"
|
| | | draggable=".components-item" :sort="false" @end="onEnd" item-key="label">
|
| | | <template #item="{ element, index }">
|
| | | <div :key="index" class="components-item" @click="addComponent(element)">
|
| | | <div class="components-body">
|
| | | <svg-icon :icon-class="element.tagIcon" />
|
| | | {{ element.label }}
|
| | | </div>
|
| | | </div>
|
| | | </template>
|
| | | </draggable>
|
| | | <div class="components-title">
|
| | | <svg-icon icon-class="component" /> å¸å±åç»ä»¶
|
| | | </div>
|
| | | <draggable class="components-draggable" :list="layoutComponents"
|
| | | :group="{ name: 'componentsGroup', pull: 'clone', put: false }" :clone="cloneComponent"
|
| | | draggable=".components-item" :sort="false" @end="onEnd" item-key="label">
|
| | | <template #item="{ element, index }">
|
| | | <div :key="index" class="components-item" @click="addComponent(element)">
|
| | | <div class="components-body">
|
| | | <svg-icon :icon-class="element.tagIcon" />
|
| | | {{ element.label }}
|
| | | </div>
|
| | | </div>
|
| | | </template>
|
| | | </draggable>
|
| | | </div>
|
| | | </el-scrollbar>
|
| | | </div>
|
| | | <div class="center-board">
|
| | | <div class="action-bar">
|
| | | <el-button icon="Download" type="primary" text @click="download">
|
| | | 导åºvueæä»¶
|
| | | </el-button>
|
| | | <el-button class="copy-btn-main" icon="DocumentCopy" type="primary" text @click="copy">
|
| | | å¤å¶ä»£ç
|
| | | </el-button>
|
| | | <el-button class="delete-btn" icon="Delete" text @click="empty" type="danger">
|
| | | æ¸
空
|
| | | </el-button>
|
| | | </div>
|
| | | <el-scrollbar class="center-scrollbar">
|
| | | <el-row class="center-board-row" :gutter="formConf.gutter">
|
| | | <el-form :size="formConf.size" :label-position="formConf.labelPosition" :disabled="formConf.disabled"
|
| | | :label-width="formConf.labelWidth + 'px'">
|
| | | <draggable class="drawing-board" :list="drawingList" :animation="340" group="componentsGroup"
|
| | | item-key="label">
|
| | | <template #item="{ element, index }">
|
| | | <draggable-item :key="element.renderKey" :drawing-list="drawingList" :element="element" :index="index"
|
| | | :active-id="activeId" :form-conf="formConf" @activeItem="activeFormItem" @copyItem="drawingItemCopy"
|
| | | @deleteItem="drawingItemDelete" />
|
| | | </template>
|
| | | </draggable>
|
| | | <div v-show="!drawingList.length" class="empty-info">
|
| | | ä»å·¦ä¾§æå
¥æç¹éç»ä»¶è¿è¡è¡¨å设计
|
| | | </div>
|
| | | </el-form>
|
| | | </el-row>
|
| | | </el-scrollbar>
|
| | | </div>
|
| | | <right-panel :active-data="activeData" :form-conf="formConf" :show-field="!!drawingList.length"
|
| | | @tag-change="tagChange" />
|
| | |
|
| | | <code-type-dialog v-model="dialogVisible" title="éæ©çæç±»å" :showFileName="showFileName" @confirm="generate" />
|
| | | <input id="copyNode" type="hidden">
|
| | | </div>
|
| | | </template>
|
| | |
|
| | | <script setup>
|
| | | import draggable from "vuedraggable/dist/vuedraggable.common"
|
| | | import ClipboardJS from 'clipboard'
|
| | | import beautifier from 'js-beautify'
|
| | | import logo from '@/assets/logo/logo.png'
|
| | | import { inputComponents, selectComponents, layoutComponents, formConf as formConfData } from '@/utils/generator/config'
|
| | | import { beautifierConf } from '@/utils/index'
|
| | | import drawingDefalut from '@/utils/generator/drawingDefalut'
|
| | | import { makeUpHtml, vueTemplate, vueScript, cssStyle } from '@/utils/generator/html'
|
| | | import { makeUpJs } from '@/utils/generator/js'
|
| | | import { makeUpCss } from '@/utils/generator/css'
|
| | | import Download from '@/plugins/download'
|
| | | import { ElNotification } from 'element-plus'
|
| | | import DraggableItem from './DraggableItem'
|
| | | import RightPanel from './RightPanel'
|
| | | import CodeTypeDialog from './CodeTypeDialog'
|
| | | import { onMounted, watch } from 'vue'
|
| | |
|
| | | const drawingList = ref(drawingDefalut)
|
| | | const { proxy } = getCurrentInstance()
|
| | | const dialogVisible = ref(false)
|
| | | const showFileName = ref(false)
|
| | | const operationType = ref('')
|
| | | const idGlobal = ref(100)
|
| | | const activeData = ref(drawingDefalut[0])
|
| | | const activeId = ref(drawingDefalut[0].formId)
|
| | | const generateConf = ref(null)
|
| | | const formData = ref({})
|
| | | const formConf = ref(formConfData)
|
| | | let oldActiveId
|
| | | let tempActiveData
|
| | |
|
| | | function activeFormItem(element) {
|
| | | activeData.value = element
|
| | | activeId.value = element.formId
|
| | | }
|
| | | function copy() {
|
| | | dialogVisible.value = true
|
| | | showFileName.value = false
|
| | | operationType.value = 'copy'
|
| | | }
|
| | | function download() {
|
| | | dialogVisible.value = true
|
| | | showFileName.value = true
|
| | | operationType.value = 'download'
|
| | | }
|
| | | function empty() {
|
| | | proxy.$modal.confirm('ç¡®å®è¦æ¸
空ææç»ä»¶åï¼', 'æç¤º', { type: 'warning' }).then(() => {
|
| | | idGlobal.value = 100
|
| | | drawingList.value = []
|
| | | }
|
| | | )
|
| | | }
|
| | |
|
| | | function onEnd(obj, a) {
|
| | | if (obj.from !== obj.to) {
|
| | | activeData.value = tempActiveData
|
| | | activeId.value = idGlobal.value
|
| | | }
|
| | | }
|
| | |
|
| | | function addComponent(item) {
|
| | | const clone = cloneComponent(item)
|
| | | drawingList.value.push(clone)
|
| | | activeFormItem(clone)
|
| | | }
|
| | |
|
| | | function cloneComponent(origin) {
|
| | | const clone = JSON.parse(JSON.stringify(origin))
|
| | | clone.formId = ++idGlobal.value
|
| | | clone.span = formConf.value.span
|
| | | clone.renderKey = +new Date() // æ¹årenderKeyåå¯ä»¥å®ç°å¼ºå¶æ´æ°ç»ä»¶
|
| | | if (!clone.layout) clone.layout = 'colFormItem'
|
| | | if (clone.layout === 'colFormItem') {
|
| | | clone.vModel = `field${idGlobal.value}`
|
| | | clone.placeholder !== undefined && (clone.placeholder += clone.label)
|
| | | tempActiveData = clone
|
| | | } else if (clone.layout === 'rowFormItem') {
|
| | | delete clone.label
|
| | | clone.componentName = `row${idGlobal.value}`
|
| | | clone.gutter = formConf.value.gutter
|
| | | tempActiveData = clone
|
| | | }
|
| | | return tempActiveData
|
| | | }
|
| | |
|
| | | function drawingItemCopy(item, parent) {
|
| | | let clone = JSON.parse(JSON.stringify(item))
|
| | | clone = createIdAndKey(clone)
|
| | | parent.push(clone)
|
| | | activeFormItem(clone)
|
| | | }
|
| | |
|
| | |
|
| | | function createIdAndKey(item) {
|
| | | item.formId = ++idGlobal.value
|
| | | item.renderKey = +new Date()
|
| | | if (item.layout === 'colFormItem') {
|
| | | item.vModel = `field${idGlobal.value}`
|
| | | } else if (item.layout === 'rowFormItem') {
|
| | | item.componentName = `row${idGlobal.value}`
|
| | | }
|
| | | if (Array.isArray(item.children)) {
|
| | | item.children = item.children.map(childItem => createIdAndKey(childItem))
|
| | | }
|
| | | return item
|
| | | }
|
| | |
|
| | | function drawingItemDelete(index, parent) {
|
| | | parent.splice(index, 1)
|
| | | nextTick(() => {
|
| | | const len = drawingList.value.length
|
| | | if (len) {
|
| | | activeFormItem(drawingList.value[len - 1])
|
| | | }
|
| | | })
|
| | | }
|
| | |
|
| | | function tagChange(newTag) {
|
| | | newTag = cloneComponent(newTag)
|
| | | newTag.vModel = activeData.value.vModel
|
| | | newTag.formId = activeId.value
|
| | | newTag.span = activeData.value.span
|
| | | delete activeData.value.tag
|
| | | delete activeData.value.tagIcon
|
| | | delete activeData.value.document
|
| | | Object.keys(newTag).forEach(key => {
|
| | | if (activeData.value[key] !== undefined
|
| | | && typeof activeData.value[key] === typeof newTag[key]) {
|
| | | newTag[key] = activeData.value[key]
|
| | | }
|
| | | })
|
| | | activeData.value = newTag
|
| | | updateDrawingList(newTag, drawingList.value)
|
| | | }
|
| | |
|
| | |
|
| | | function updateDrawingList(newTag, list) {
|
| | | const index = list.findIndex(item => item.formId === activeId.value)
|
| | | if (index > -1) {
|
| | | list.splice(index, 1, newTag)
|
| | | } else {
|
| | | list.forEach(item => {
|
| | | if (Array.isArray(item.children)) updateDrawingList(newTag, item.children)
|
| | | })
|
| | | }
|
| | | }
|
| | | function generate(data) {
|
| | | generateConf.value = data
|
| | | nextTick(() => {
|
| | | switch (operationType.value) {
|
| | | case 'copy':
|
| | | execCopy(data)
|
| | | break
|
| | | case 'download':
|
| | | execDownload(data)
|
| | | break
|
| | | default:
|
| | | break
|
| | | }
|
| | | })
|
| | | }
|
| | |
|
| | | function execDownload(data) {
|
| | | const codeStr = generateCode()
|
| | | const blob = new Blob([codeStr], { type: 'text/plain;charset=utf-8' })
|
| | | Download.saveAs(blob, data.fileName)
|
| | | }
|
| | |
|
| | | function execCopy(data) {
|
| | | document.getElementById('copyNode').click()
|
| | | }
|
| | | function AssembleFormData() {
|
| | | formData.value = { fields: JSON.parse(JSON.stringify(drawingList.value)), ...formConf.value }
|
| | | }
|
| | | function generateCode() {
|
| | | const { type } = generateConf.value
|
| | | AssembleFormData()
|
| | | const script = vueScript(makeUpJs(formData.value, type))
|
| | | const html = vueTemplate(makeUpHtml(formData.value, type))
|
| | | const css = cssStyle(makeUpCss(formData.value))
|
| | | return beautifier.html(html + script + css, beautifierConf.html)
|
| | | }
|
| | | watch(() => activeData.value.label, (val, oldVal) => {
|
| | | if (
|
| | | activeData.value.placeholder === undefined
|
| | | || !activeData.value.tag
|
| | | || oldActiveId !== activeId.value
|
| | | ) {
|
| | | return
|
| | | }
|
| | | activeData.value.placeholder = activeData.value.placeholder.replace(oldVal, '') + val
|
| | | })
|
| | | watch(activeId, (val) => {
|
| | | oldActiveId = val
|
| | | }, { immediate: true })
|
| | |
|
| | | onMounted(() => {
|
| | | const clipboard = new ClipboardJS('#copyNode', {
|
| | | text: trigger => {
|
| | | const codeStr = generateCode()
|
| | | ElNotification({ title: 'æå', message: '代ç å·²å¤å¶å°åªåæ¿ï¼å¯ç²è´´ã', type: 'success' })
|
| | | return codeStr
|
| | | }
|
| | | })
|
| | | clipboard.on('error', e => {
|
| | | proxy.$modal.msgError('代ç å¤å¶å¤±è´¥')
|
| | | })
|
| | | })
|
| | | </script>
|
| | |
|
| | | <style lang='scss'>
|
| | | $lighterBlue: #409EFF;
|
| | |
|
| | | .container {
|
| | | position: relative;
|
| | | width: 100%;
|
| | | background-color: var(--el-bg-color-overlay);
|
| | | height: calc(100vh - 50px - 40px);
|
| | | overflow: hidden;
|
| | |
|
| | | .left-board {
|
| | | width: 260px;
|
| | | position: absolute;
|
| | | left: 0;
|
| | | top: 0;
|
| | | height: calc(100vh - 50px - 40px);
|
| | |
|
| | | .logo-wrapper {
|
| | | position: relative;
|
| | | height: 42px;
|
| | | border-bottom: 1px solid var(--el-border-color-extra-light);
|
| | | box-sizing: border-box;
|
| | |
|
| | | .logo {
|
| | | position: absolute;
|
| | | left: 12px;
|
| | | top: 6px;
|
| | | line-height: 30px;
|
| | | color: #00afff;
|
| | | font-weight: 600;
|
| | | font-size: 17px;
|
| | | white-space: nowrap;
|
| | |
|
| | | >img {
|
| | | width: 30px;
|
| | | height: 30px;
|
| | | vertical-align: top;
|
| | | }
|
| | |
|
| | | .github {
|
| | | display: inline-block;
|
| | | vertical-align: sub;
|
| | | margin-left: 15px;
|
| | |
|
| | | >img {
|
| | | height: 22px;
|
| | | }
|
| | | }
|
| | | }
|
| | | }
|
| | |
|
| | | .left-scrollbar {
|
| | | .el-scrollbar__wrap {
|
| | | box-sizing: border-box;
|
| | | overflow-x: hidden !important;
|
| | | margin-bottom: 0 !important;
|
| | |
|
| | | .components-list {
|
| | | padding: 8px;
|
| | | box-sizing: border-box;
|
| | | height: 100%;
|
| | |
|
| | | .components-title {
|
| | | font-size: 14px;
|
| | | // color: #222;
|
| | | margin: 6px 2px;
|
| | |
|
| | | .svg-icon {
|
| | | // color: #666;
|
| | | font-size: 18px;
|
| | | margin-right: 5px;
|
| | | }
|
| | | }
|
| | |
|
| | | .components-draggable {
|
| | | padding-bottom: 20px;
|
| | |
|
| | | .components-item {
|
| | | display: inline-block;
|
| | | width: 48%;
|
| | | margin: 1%;
|
| | | transition: transform 0ms !important;
|
| | |
|
| | | .components-body {
|
| | | padding: 8px 10px;
|
| | | background: var(--el-border-color-extra-light);
|
| | | font-size: 12px;
|
| | | cursor: move;
|
| | | border: 1px dashed var(--el-border-color-extra-light);
|
| | | border-radius: 3px;
|
| | |
|
| | | .svg-icon {
|
| | | // color: #777;
|
| | | font-size: 15px;
|
| | | margin-right: 5px;
|
| | | }
|
| | |
|
| | | &:hover {
|
| | | border: 1px dashed #787be8;
|
| | | color: #787be8;
|
| | |
|
| | | .svg-icon {
|
| | | color: #787be8;
|
| | | }
|
| | | }
|
| | | }
|
| | | }
|
| | | }
|
| | |
|
| | |
|
| | | }
|
| | | }
|
| | | }
|
| | | }
|
| | |
|
| | | .center-board {
|
| | | height: calc(100vh - 50px - 40px);
|
| | | width: auto;
|
| | | margin: 0 350px 0 260px;
|
| | | box-sizing: border-box;
|
| | |
|
| | | .action-bar {
|
| | | position: relative;
|
| | | height: 42px;
|
| | | padding: 0 15px;
|
| | | box-sizing: border-box;
|
| | | ;
|
| | | border: 1px solid var(--el-border-color-extra-light);
|
| | | border-top: none;
|
| | | border-left: none;
|
| | | display: flex;
|
| | | align-items: center;
|
| | | justify-content: flex-end;
|
| | |
|
| | | u .delete-btn {
|
| | | color: #F56C6C;
|
| | | }
|
| | | }
|
| | |
|
| | | .center-scrollbar {
|
| | | height: calc(100vh - 50px - 40px - 42px);
|
| | | overflow: hidden;
|
| | | border-left: 1px solid var(--el-border-color-extra-light);
|
| | | border-right: 1px solid var(--el-border-color-extra-light);
|
| | | box-sizing: border-box;
|
| | |
|
| | | .el-scrollbar__view {
|
| | | overflow-x: hidden;
|
| | | }
|
| | |
|
| | | .center-board-row {
|
| | | padding: 12px 12px 15px 12px;
|
| | | box-sizing: border-box;
|
| | |
|
| | | &>.el-form {
|
| | | // 69 = 12+15+42
|
| | | height: calc(100vh - 50px - 40px - 69px);
|
| | | flex: 1;
|
| | |
|
| | | .drawing-board {
|
| | | height: 100%;
|
| | | position: relative;
|
| | |
|
| | | .components-body {
|
| | | padding: 0;
|
| | | margin: 0;
|
| | | font-size: 0;
|
| | | }
|
| | |
|
| | | .sortable-ghost {
|
| | | position: relative;
|
| | | display: block;
|
| | | overflow: hidden;
|
| | |
|
| | | &::before {
|
| | | content: " ";
|
| | | position: absolute;
|
| | | left: 0;
|
| | | right: 0;
|
| | | top: 0;
|
| | | height: 3px;
|
| | | background: rgb(89, 89, 223);
|
| | | z-index: 2;
|
| | | }
|
| | | }
|
| | |
|
| | | .components-item.sortable-ghost {
|
| | | width: 100%;
|
| | | height: 60px;
|
| | | background: var(--el-border-color-extra-light);
|
| | | }
|
| | |
|
| | | .active-from-item {
|
| | | &>.el-form-item {
|
| | | background: var(--el-border-color-extra-light);
|
| | | border-radius: 6px;
|
| | | }
|
| | |
|
| | | &>.drawing-item-copy,
|
| | | &>.drawing-item-delete {
|
| | | display: initial;
|
| | | }
|
| | |
|
| | | &>.component-name {
|
| | | color: $lighterBlue;
|
| | | }
|
| | |
|
| | | .el-input__wrapper {
|
| | | box-shadow: 0 0 0 1px var(--el-input-hover-border-color) inset;
|
| | | }
|
| | | }
|
| | |
|
| | | .el-form-item {
|
| | | margin-bottom: 15px;
|
| | | }
|
| | | }
|
| | |
|
| | | .drawing-item {
|
| | | position: relative;
|
| | | cursor: move;
|
| | |
|
| | | &.unfocus-bordered:not(.activeFromItem)>div:first-child {
|
| | | border: 1px dashed #ccc;
|
| | | }
|
| | |
|
| | | .el-form-item {
|
| | | padding: 12px 10px;
|
| | | }
|
| | | }
|
| | |
|
| | | .drawing-row-item {
|
| | | position: relative;
|
| | | cursor: move;
|
| | | box-sizing: border-box;
|
| | | border: 1px dashed #ccc;
|
| | | border-radius: 3px;
|
| | | padding: 0 2px;
|
| | | margin-bottom: 15px;
|
| | |
|
| | | .drawing-row-item {
|
| | | margin-bottom: 2px;
|
| | | }
|
| | |
|
| | | .el-col {
|
| | | margin-top: 22px;
|
| | | }
|
| | |
|
| | | .el-form-item {
|
| | | margin-bottom: 0;
|
| | | }
|
| | |
|
| | | .drag-wrapper {
|
| | | min-height: 80px;
|
| | | flex: 1;
|
| | | display: flex;
|
| | | flex-wrap: wrap;
|
| | | }
|
| | |
|
| | | &.active-from-item {
|
| | | border: 1px dashed $lighterBlue;
|
| | | }
|
| | |
|
| | | .component-name {
|
| | | position: absolute;
|
| | | top: 0;
|
| | | left: 0;
|
| | | font-size: 12px;
|
| | | color: #bbb;
|
| | | display: inline-block;
|
| | | padding: 0 6px;
|
| | | }
|
| | | }
|
| | |
|
| | | .drawing-item,
|
| | | .drawing-row-item {
|
| | | &:hover {
|
| | | &>.el-form-item {
|
| | | background: var(--el-border-color-extra-light);
|
| | | border-radius: 6px;
|
| | | }
|
| | |
|
| | | &>.drawing-item-copy,
|
| | | &>.drawing-item-delete {
|
| | | display: initial;
|
| | | }
|
| | | }
|
| | |
|
| | | &>.drawing-item-copy,
|
| | | &>.drawing-item-delete {
|
| | | display: none;
|
| | | position: absolute;
|
| | | top: -10px;
|
| | | width: 22px;
|
| | | height: 22px;
|
| | | line-height: 22px;
|
| | | text-align: center;
|
| | | border-radius: 50%;
|
| | | font-size: 12px;
|
| | | border: 1px solid;
|
| | | cursor: pointer;
|
| | | z-index: 1;
|
| | | }
|
| | |
|
| | | &>.drawing-item-copy {
|
| | | right: 56px;
|
| | | border-color: $lighterBlue;
|
| | | color: $lighterBlue;
|
| | | background: #fff;
|
| | |
|
| | | &:hover {
|
| | | background: $lighterBlue;
|
| | | color: #fff;
|
| | | }
|
| | | }
|
| | |
|
| | | &>.drawing-item-delete {
|
| | | right: 24px;
|
| | | border-color: #F56C6C;
|
| | | color: #F56C6C;
|
| | | background: #fff;
|
| | |
|
| | | &:hover {
|
| | | background: #F56C6C;
|
| | | color: #fff;
|
| | | }
|
| | | }
|
| | | }
|
| | |
|
| | | .empty-info {
|
| | | position: absolute;
|
| | | top: 46%;
|
| | | left: 0;
|
| | | right: 0;
|
| | | text-align: center;
|
| | | font-size: 18px;
|
| | | color: #ccb1ea;
|
| | | letter-spacing: 4px;
|
| | | }
|
| | |
|
| | | }
|
| | | }
|
| | | }
|
| | | }
|
| | | }
|
| | | </style>
|