2021-12-25 19:36:55 +08:00
|
|
|
|
<!--
|
|
|
|
|
/**
|
|
|
|
|
* author: vformAdmin
|
|
|
|
|
* email: vdpadmin@163.com
|
|
|
|
|
* website: https://www.vform666.com
|
|
|
|
|
* date: 2021.08.18
|
|
|
|
|
* remark: 如果要分发VForm源码,需在本文件顶部保留此文件头信息!!
|
|
|
|
|
*/
|
|
|
|
|
-->
|
|
|
|
|
|
|
|
|
|
<template>
|
|
|
|
|
<el-container class="main-container full-height">
|
|
|
|
|
<el-header class="main-header">
|
|
|
|
|
<div class="float-left main-title">
|
|
|
|
|
<img src="../../assets/vform-logo.png" @click="openHome">
|
2022-01-16 15:18:25 +08:00
|
|
|
|
<span class="bold">VForm 3</span> {{i18nt('application.productTitle')}} <span class="version-span">Ver {{vFormVersion}}</span></div>
|
2021-12-25 19:36:55 +08:00
|
|
|
|
<div class="float-right external-link">
|
|
|
|
|
<el-dropdown v-if="showLink('languageMenu')" @command="handleLanguageChanged">
|
2022-01-16 15:18:25 +08:00
|
|
|
|
<span class="el-dropdown-link">{{curLangName}}<svg-icon icon-class="el-arrow-down" /></span>
|
2021-12-25 19:36:55 +08:00
|
|
|
|
<template #dropdown>
|
|
|
|
|
<el-dropdown-menu>
|
|
|
|
|
<el-dropdown-item command="zh-CN">{{i18nt('application.zh-CN')}}</el-dropdown-item>
|
|
|
|
|
<el-dropdown-item command="en-US">{{i18nt('application.en-US')}}</el-dropdown-item>
|
|
|
|
|
</el-dropdown-menu>
|
|
|
|
|
</template>
|
|
|
|
|
</el-dropdown>
|
|
|
|
|
<a v-if="showLink('externalLink')" href="javascript:void(0)" @click="(ev) => openUrl(ev, gitUrl)" target="_blank"><svg-icon icon-class="github" />{{i18nt('application.github')}}</a>
|
|
|
|
|
<a v-if="showLink('externalLink')" href="javascript:void(0)" @click="(ev) => openUrl(ev, docUrl)" target="_blank"><svg-icon icon-class="document" />{{i18nt('application.document')}}</a>
|
|
|
|
|
<a v-if="showLink('externalLink')" href="javascript:void(0)" @click="(ev) => openUrl(ev, chatUrl)" target="_blank">{{i18nt('application.qqGroup')}}</a>
|
|
|
|
|
<a v-if="showLink('externalLink')" href="javascript:void(0)" @click="(ev) => openUrl(ev, subScribeUrl)" target="_blank">
|
|
|
|
|
{{i18nt('application.subscription')}}<i class="el-icon-top-right"></i></a>
|
|
|
|
|
</div>
|
|
|
|
|
</el-header>
|
|
|
|
|
|
|
|
|
|
<el-container>
|
|
|
|
|
<el-aside class="side-panel">
|
|
|
|
|
<widget-panel :designer="designer" />
|
|
|
|
|
</el-aside>
|
|
|
|
|
|
|
|
|
|
<el-container class="center-layout-container">
|
|
|
|
|
<el-header class="toolbar-header">
|
|
|
|
|
<toolbar-panel :designer="designer" ref="toolbarRef">
|
|
|
|
|
<template v-for="(idx, slotName) in $slots" #[slotName]>
|
|
|
|
|
<slot :name="slotName"></slot>
|
|
|
|
|
</template>
|
|
|
|
|
</toolbar-panel>
|
|
|
|
|
</el-header>
|
|
|
|
|
<el-main class="form-widget-main">
|
|
|
|
|
<el-scrollbar class="container-scroll-bar" :style="{height: scrollerHeight}">
|
|
|
|
|
<v-form-widget :designer="designer" :form-config="designer.formConfig">
|
|
|
|
|
</v-form-widget>
|
|
|
|
|
</el-scrollbar>
|
|
|
|
|
</el-main>
|
|
|
|
|
</el-container>
|
|
|
|
|
|
|
|
|
|
<el-aside>
|
2022-01-01 19:15:45 +08:00
|
|
|
|
<setting-panel :designer="designer" :selected-widget="designer.selectedWidget"
|
|
|
|
|
:form-config="designer.formConfig" @edit-event-handler="testEEH" />
|
2021-12-25 19:36:55 +08:00
|
|
|
|
</el-aside>
|
|
|
|
|
</el-container>
|
|
|
|
|
|
|
|
|
|
</el-container>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<script>
|
|
|
|
|
import WidgetPanel from './widget-panel/index'
|
|
|
|
|
import ToolbarPanel from './toolbar-panel/index'
|
|
|
|
|
import SettingPanel from './setting-panel/index'
|
|
|
|
|
import VFormWidget from './form-widget/index'
|
|
|
|
|
import {createDesigner} from "@/components/form-designer/designer"
|
2022-03-08 17:59:10 +08:00
|
|
|
|
import {addWindowResizeHandler, deepClone, getQueryParam, getAllContainerWidgets,
|
|
|
|
|
getAllFieldWidgets} from "@/utils/util"
|
2021-12-25 19:36:55 +08:00
|
|
|
|
import {MOCK_CASE_URL, VARIANT_FORM_VERSION} from "@/utils/config"
|
|
|
|
|
import i18n, { changeLocale } from "@/utils/i18n"
|
2022-01-12 14:09:31 +08:00
|
|
|
|
import axios from 'axios'
|
2022-02-11 17:31:36 +08:00
|
|
|
|
import SvgIcon from "@/components/svg-icon/index"
|
2021-12-25 19:36:55 +08:00
|
|
|
|
|
|
|
|
|
export default {
|
|
|
|
|
name: "VFormDesigner",
|
|
|
|
|
componentName: "VFormDesigner",
|
|
|
|
|
mixins: [i18n],
|
|
|
|
|
components: {
|
2022-01-16 15:18:25 +08:00
|
|
|
|
SvgIcon,
|
2021-12-25 19:36:55 +08:00
|
|
|
|
WidgetPanel,
|
|
|
|
|
ToolbarPanel,
|
|
|
|
|
SettingPanel,
|
|
|
|
|
VFormWidget,
|
|
|
|
|
},
|
|
|
|
|
props: {
|
|
|
|
|
/* 后端字段列表API */
|
|
|
|
|
fieldListApi: {
|
|
|
|
|
type: Object,
|
|
|
|
|
default: null,
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/* 禁止显示的组件名称数组 */
|
|
|
|
|
bannedWidgets: {
|
|
|
|
|
type: Array,
|
|
|
|
|
default: () => []
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
designerConfig: {
|
|
|
|
|
type: Object,
|
|
|
|
|
default: () => {
|
|
|
|
|
return {
|
|
|
|
|
languageMenu: true, //是否显示语言切换菜单
|
|
|
|
|
externalLink: true, //是否显示GitHub、文档等外部链接
|
|
|
|
|
formTemplates: true, //是否显示表单模板
|
|
|
|
|
eventCollapse: true, //是否显示组件事件属性折叠面板
|
|
|
|
|
clearDesignerButton: true, //是否显示清空设计器按钮
|
|
|
|
|
previewFormButton: true, //是否显示预览表单按钮
|
|
|
|
|
importJsonButton: true, //是否显示导入JSON按钮
|
|
|
|
|
exportJsonButton: true, //是否显示导出JSON器按钮
|
|
|
|
|
exportCodeButton: true, //是否显示导出代码按钮
|
|
|
|
|
generateSFCButton: true, //是否显示生成SFC按钮
|
|
|
|
|
|
|
|
|
|
presetCssCode: '', //设计器预设CSS样式代码
|
2022-02-23 10:40:44 +08:00
|
|
|
|
|
|
|
|
|
resetFormJson: false, //是否在设计器初始化时将表单内容重置为空
|
2021-12-25 19:36:55 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
},
|
|
|
|
|
data() {
|
|
|
|
|
return {
|
|
|
|
|
vFormVersion: VARIANT_FORM_VERSION,
|
|
|
|
|
curLangName: '',
|
2022-02-11 17:31:36 +08:00
|
|
|
|
curLocale: '',
|
2021-12-25 19:36:55 +08:00
|
|
|
|
|
|
|
|
|
vsCodeFlag: false,
|
|
|
|
|
caseName: '',
|
|
|
|
|
|
2022-02-11 17:31:36 +08:00
|
|
|
|
docUrl: 'https://www.vform666.com/document3.html',
|
|
|
|
|
gitUrl: 'https://github.com/vform666/variant-form3-vite',
|
2021-12-25 19:36:55 +08:00
|
|
|
|
chatUrl: 'https://www.vform666.com/chat-group.html',
|
|
|
|
|
subScribeUrl: 'https://www.vform666.com/subscribe.html',
|
|
|
|
|
|
|
|
|
|
scrollerHeight: 0,
|
|
|
|
|
|
|
|
|
|
designer: createDesigner(this),
|
|
|
|
|
|
|
|
|
|
fieldList: []
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
provide() {
|
|
|
|
|
return {
|
|
|
|
|
serverFieldList: this.fieldList,
|
|
|
|
|
getDesignerConfig: () => this.designerConfig,
|
|
|
|
|
getBannedWidgets: () => this.bannedWidgets,
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
created() {
|
|
|
|
|
this.vsCodeFlag = getQueryParam('vscode') == 1
|
|
|
|
|
this.caseName = getQueryParam('case')
|
|
|
|
|
},
|
|
|
|
|
mounted() {
|
|
|
|
|
this.initLocale()
|
|
|
|
|
|
|
|
|
|
this.scrollerHeight = window.innerHeight - 56 - 36 + 'px'
|
|
|
|
|
addWindowResizeHandler(() => {
|
|
|
|
|
this.$nextTick(() => {
|
|
|
|
|
this.scrollerHeight = window.innerHeight - 56 - 36 + 'px'
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
this.loadCase()
|
|
|
|
|
|
|
|
|
|
this.loadFieldListFromServer()
|
|
|
|
|
},
|
|
|
|
|
methods: {
|
2022-01-01 19:15:45 +08:00
|
|
|
|
testEEH(eventName, eventParams) {
|
|
|
|
|
console.log('test', eventName)
|
|
|
|
|
console.log('test222222', eventParams)
|
|
|
|
|
},
|
|
|
|
|
|
2021-12-25 19:36:55 +08:00
|
|
|
|
showLink(configName) {
|
|
|
|
|
if (this.designerConfig[configName] === undefined) {
|
|
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return !!this.designerConfig[configName]
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
openHome() {
|
|
|
|
|
if (!!this.vsCodeFlag) {
|
|
|
|
|
const msgObj = {
|
|
|
|
|
cmd: 'openUrl',
|
|
|
|
|
data: {
|
|
|
|
|
url: 'https://www.vform666.com/'
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
window.parent.postMessage(msgObj, '*')
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
openUrl(event, url) {
|
|
|
|
|
if (!!this.vsCodeFlag) {
|
|
|
|
|
const msgObj = {
|
|
|
|
|
cmd: 'openUrl',
|
|
|
|
|
data: {
|
|
|
|
|
url
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
window.parent.postMessage(msgObj, '*')
|
|
|
|
|
} else {
|
|
|
|
|
let aDom = event.currentTarget
|
|
|
|
|
aDom.href = url
|
|
|
|
|
//window.open(url, '_blank') //直接打开新窗口,会被浏览器拦截
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
loadCase() {
|
|
|
|
|
if (!this.caseName) {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
axios.get(MOCK_CASE_URL + this.caseName + '.txt').then(res => {
|
|
|
|
|
if (!!res.data.code) {
|
|
|
|
|
this.$message.error(this.i18nt('designer.hint.sampleLoadedFail'))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.setFormJson(res.data)
|
|
|
|
|
this.$message.success(this.i18nt('designer.hint.sampleLoadedSuccess'))
|
|
|
|
|
}).catch(error => {
|
|
|
|
|
this.$message.error(this.i18nt('designer.hint.sampleLoadedFail') + ':' + error)
|
|
|
|
|
})
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
initLocale() {
|
2022-02-11 17:31:36 +08:00
|
|
|
|
this.curLocale = localStorage.getItem('v_form_locale')
|
2021-12-25 19:36:55 +08:00
|
|
|
|
if (!!this.vsCodeFlag) {
|
2022-02-11 17:31:36 +08:00
|
|
|
|
this.curLocale = this.curLocale || 'en-US'
|
2021-12-25 19:36:55 +08:00
|
|
|
|
} else {
|
2022-02-11 17:31:36 +08:00
|
|
|
|
this.curLocale = this.curLocale || 'zh-CN'
|
2021-12-25 19:36:55 +08:00
|
|
|
|
}
|
2022-02-11 17:31:36 +08:00
|
|
|
|
this.curLangName = this.i18nt('application.' + this.curLocale)
|
|
|
|
|
this.changeLanguage(this.curLocale)
|
2021-12-25 19:36:55 +08:00
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
loadFieldListFromServer() {
|
|
|
|
|
if (!this.fieldListApi) {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-08 17:59:10 +08:00
|
|
|
|
let headers = this.fieldListApi.headers || {}
|
|
|
|
|
axios.get(this.fieldListApi.URL, {'headers': headers}).then(res => {
|
2021-12-25 19:36:55 +08:00
|
|
|
|
let labelKey = this.fieldListApi.labelKey || 'label'
|
|
|
|
|
let nameKey = this.fieldListApi.nameKey || 'name'
|
|
|
|
|
|
2022-03-10 15:41:56 +08:00
|
|
|
|
this.fieldList.splice(0, this.fieldList.length) //清空已有
|
2021-12-25 19:36:55 +08:00
|
|
|
|
res.data.forEach(fieldItem => {
|
|
|
|
|
this.fieldList.push({
|
|
|
|
|
label: fieldItem[labelKey],
|
|
|
|
|
name: fieldItem[nameKey]
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
}).catch(error => {
|
|
|
|
|
this.$message.error(error)
|
|
|
|
|
})
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
handleLanguageChanged(command) {
|
|
|
|
|
this.changeLanguage(command)
|
|
|
|
|
this.curLangName = this.i18nt('application.' + command)
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
changeLanguage(langName) {
|
|
|
|
|
changeLocale(langName)
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
setFormJson(formJson) {
|
|
|
|
|
let modifiedFlag = false
|
|
|
|
|
if (!!formJson) {
|
|
|
|
|
if (typeof formJson === 'string') {
|
|
|
|
|
modifiedFlag = this.designer.loadFormJson( JSON.parse(formJson) )
|
|
|
|
|
} else if (formJson.constructor === Object) {
|
|
|
|
|
modifiedFlag = this.designer.loadFormJson(formJson)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (modifiedFlag) {
|
|
|
|
|
this.designer.emitHistoryChange()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
getFormJson() {
|
|
|
|
|
return {
|
|
|
|
|
widgetList: deepClone(this.designer.widgetList),
|
|
|
|
|
formConfig: deepClone(this.designer.formConfig)
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
clearDesigner() {
|
|
|
|
|
this.$refs.toolbarRef.clearFormWidget()
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 刷新表单设计器
|
|
|
|
|
*/
|
|
|
|
|
refreshDesigner() {
|
|
|
|
|
//this.designer.loadFormJson( this.getFormJson() ) //只有第一次调用生效??
|
|
|
|
|
|
|
|
|
|
let fJson = this.getFormJson()
|
|
|
|
|
this.designer.clearDesigner(true) //不触发历史记录变更
|
|
|
|
|
this.designer.loadFormJson(fJson)
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 预览表单
|
|
|
|
|
*/
|
|
|
|
|
previewForm() {
|
|
|
|
|
this.$refs.toolbarRef.previewForm()
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 导入表单JSON
|
|
|
|
|
*/
|
|
|
|
|
importJson() {
|
|
|
|
|
this.$refs.toolbarRef.importJson()
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 导出表单JSON
|
|
|
|
|
*/
|
|
|
|
|
exportJson() {
|
|
|
|
|
this.$refs.toolbarRef.exportJson()
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 导出Vue/HTML代码
|
|
|
|
|
*/
|
|
|
|
|
exportCode() {
|
|
|
|
|
this.$refs.toolbarRef.exportCode()
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 生成SFC代码
|
|
|
|
|
*/
|
|
|
|
|
generateSFC() {
|
|
|
|
|
this.$refs.toolbarRef.generateSFC()
|
|
|
|
|
},
|
|
|
|
|
|
2022-03-08 17:59:10 +08:00
|
|
|
|
/**
|
|
|
|
|
* 获取所有字段组件
|
|
|
|
|
* @returns {*[]}
|
|
|
|
|
*/
|
|
|
|
|
getFieldWidgets() {
|
|
|
|
|
return getAllFieldWidgets(this.designer.widgetList)
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 获取所有容器组件
|
|
|
|
|
* @returns {*[]}
|
|
|
|
|
*/
|
|
|
|
|
getContainerWidgets() {
|
|
|
|
|
return getAllContainerWidgets(this.designer.widgetList)
|
|
|
|
|
},
|
|
|
|
|
|
2021-12-25 19:36:55 +08:00
|
|
|
|
//TODO: 增加更多方法!!
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
|
|
.el-container.full-height {
|
|
|
|
|
height: 100%;
|
|
|
|
|
overflow-y: hidden;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.el-container.center-layout-container {
|
|
|
|
|
min-width: 680px;
|
|
|
|
|
border-left: 2px dotted #EBEEF5;
|
|
|
|
|
border-right: 2px dotted #EBEEF5;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.el-header.main-header {
|
|
|
|
|
border-bottom: 2px dotted #EBEEF5;
|
|
|
|
|
height: 48px !important;
|
|
|
|
|
line-height: 48px !important;
|
|
|
|
|
min-width: 800px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
div.main-title {
|
|
|
|
|
font-size: 18px;
|
|
|
|
|
color: #242424;
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
justify-items: center;
|
|
|
|
|
|
|
|
|
|
img {
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
width: 36px;
|
|
|
|
|
height: 36px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
span.bold {
|
|
|
|
|
font-size: 20px;
|
|
|
|
|
font-weight: bold;
|
|
|
|
|
margin: 0 6px 0 6px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
span.version-span {
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
color: #101F1C;
|
|
|
|
|
margin-left: 6px;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.float-left {
|
|
|
|
|
float: left;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.float-right {
|
|
|
|
|
float: right;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.el-dropdown-link {
|
|
|
|
|
margin-right: 12px;
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
}
|
|
|
|
|
|
2022-02-03 13:27:31 +08:00
|
|
|
|
div.external-link {
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
|
|
|
|
a {
|
|
|
|
|
font-size: 13px;
|
|
|
|
|
text-decoration: none;
|
|
|
|
|
margin-right: 10px;
|
|
|
|
|
color: #606266;
|
|
|
|
|
}
|
2021-12-25 19:36:55 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.el-header.toolbar-header {
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
border-bottom: 1px dotted #CCCCCC;
|
|
|
|
|
height: 42px !important;
|
|
|
|
|
//line-height: 42px !important;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.el-aside.side-panel {
|
|
|
|
|
width: 260px !important;
|
|
|
|
|
overflow-y: hidden;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.el-main.form-widget-main {
|
|
|
|
|
padding: 0;
|
|
|
|
|
|
|
|
|
|
position: relative;
|
|
|
|
|
overflow-x: hidden;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.container-scroll-bar {
|
|
|
|
|
:deep(.el-scrollbar__wrap), :deep(.el-scrollbar__view) {
|
|
|
|
|
overflow-x: hidden;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
</style>
|