You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

418 lines
16 KiB

5 years ago
<template>
<div class="container">
5 years ago
<div class="left-board">
<el-row>
<el-col :offset="1" :span="2">
<el-button size="mini" round @click="$router.back(-1)">
5 years ago
<i class="el-icon-arrow-left"/>
返回
</el-button>
5 years ago
</el-col>
<el-col :span="2" :offset="5">
<el-button size="mini" round @click="$router.back(-1)">
<i class="el-icon-arrow-left"/>
发布
</el-button>
</el-col>
</el-row>
5 years ago
<el-scrollbar class="left-scrollbar">
<div class="components-list">
<div v-for="(item, listIndex) in leftComponents" :key="listIndex">
<div class="components-title">
<svg-icon name="component"/>
{{ item.title }}
</div>
<draggable
class="components-draggable"
:list="item.list"
:group="{ name: 'componentsGroup', pull: 'clone', put: false }"
:clone="cloneComponent"
draggable=".components-item"
:sort="false"
@end="onEnd"
>
<div
v-for="(element, index) in item.list"
:key="index"
class="components-item"
@click="addComponent(element)"
>
<div class="components-body">
<svg-icon :name="element.__config__.tagIcon"/>
{{ element.__config__.label }}
</div>
</div>
</draggable>
</div>
</div>
</el-scrollbar>
</div>
<div class="center-board">
5 years ago
<el-row type="flex" align="middle" justify="justify">
<el-col :span="18" :offset="6">
<el-menu default-active="1" style="background-color: transparent" mode="horizontal">
<el-menu-item index="1">编辑</el-menu-item>
<el-menu-item index="2">外观</el-menu-item>
<el-menu-item index="3">设置</el-menu-item>
<el-menu-item index="4">发布</el-menu-item>
<el-menu-item index="5">统计</el-menu-item>
</el-menu>
</el-col>
</el-row>
5 years ago
<el-scrollbar class="center-scrollbar">
5 years ago
<el-row class="center-board-row" :gutter="formConf.gutter">
<el-row type="flex" justify="center" align="middle">
<el-col :span="20" style="text-align: center">
5 years ago
<h4 class="form-name-text" contenteditable="true"
@blur="(event)=>{
formConf.title=event.target.innerText;
this.saveProjectInfo()}">
5 years ago
{{formConf.title}}</h4>
</el-col>
</el-row>
<el-row type="flex" justify="center" align="middle">
<el-col :span="20" style="text-align: center">
5 years ago
<p class="form-name-text" contenteditable="true"
@blur="(event)=>{
formConf.description=event.target.innerText;
this.saveProjectInfo()}">
{{formConf.description}}
</p>
</el-col>
</el-row>
<el-divider></el-divider>
5 years ago
<el-form
:size="formConf.size"
:label-position="formConf.labelPosition"
:disabled="formConf.disabled"
:label-width="formConf.labelWidth + 'px'"
>
5 years ago
<draggable class="drawing-board" :list="drawingList" :animation="340" group="componentsGroup" @end="onItemEnd">
5 years ago
<draggable-item
v-for="(item, index) in drawingList"
:key="item.renderKey"
:drawing-list="drawingList"
:current-item="item"
:index="index"
:active-id="activeId"
:form-conf="formConf"
@activeItem="activeFormItem"
@changeLabel="changeLabel"
@copyItem="drawingItemCopy"
@deleteItem="drawingItemDelete"
/>
</draggable>
<div v-show="!drawingList.length" class="empty-info">
从左侧拖入或点选组件进行表单设计
</div>
</el-form>
</el-row>
5 years ago
</el-scrollbar>
5 years ago
</div>
<right-panel
v-if="activeData"
5 years ago
:active-data="activeData"
:form-conf="formConf"
:show-field="!!drawingList.length"
@tag-change="tagChange"
@data-change="updateProjectItemInfo"
5 years ago
/>
</div>
</template>
<script>
import draggable from 'vuedraggable'
import {debounce} from 'throttle-debounce'
import render from '@/components/render/render'
import RightPanel from './RightPanel'
5 years ago
import {
5 years ago
inputComponents, selectComponents, formConf
5 years ago
} from '@/components/generator/config'
import {
exportDefault, beautifierConf, isNumberStr, titleCase, deepClone
} from '@/utils/index'
5 years ago
import {formItemConvertData} from '@/utils/convert'
5 years ago
import drawingDefalut from '@/components/generator/drawingDefalut'
import DraggableItem from './DraggableItem'
import {
getDrawingList, saveDrawingList, getIdGlobal, saveIdGlobal, getFormConf
} from '@/utils/db'
let beautifier
const emptyActiveData = {
style: {},
autosize: {}
}
let oldActiveId
let tempActiveData
5 years ago
let drawingListInDB
let formConfInDB
let idGlobal
5 years ago
export default {
components: {
draggable,
render,
RightPanel,
DraggableItem
},
data() {
return {
idGlobal,
formConf,
inputComponents,
selectComponents,
labelWidth: 100,
drawingList: drawingDefalut,
drawingData: {},
5 years ago
activeId: drawingDefalut.length != 0 ? drawingDefalut[0].formId : 0,
5 years ago
formData: {},
dialogVisible: false,
generateConf: null,
showFileName: false,
5 years ago
activeData: drawingDefalut ? drawingDefalut[0] : null,
5 years ago
saveDrawingListDebounce: debounce(340, saveDrawingList),
saveIdGlobalDebounce: debounce(340, saveIdGlobal),
5 years ago
projectKey: '',
5 years ago
leftComponents: [
{
title: '输入型组件',
list: inputComponents
},
{
title: '选择型组件',
list: selectComponents
}
]
}
},
computed: {},
watch: {
// eslint-disable-next-line func-names
'activeData.__config__.label': function(val, oldVal) {
if (
this.activeData.placeholder === undefined
|| !this.activeData.__config__.tag
|| oldActiveId !== this.activeId
) {
return
}
this.activeData.placeholder = this.activeData.placeholder.replace(oldVal, '') + val
},
activeId: {
handler(val) {
oldActiveId = val
},
immediate: true
},
drawingList: {
handler(val) {
5 years ago
this.saveDrawingListDebounce(val, this.projectKey)
5 years ago
if (val.length === 0) this.idGlobal = 100
},
deep: true
},
idGlobal: {
handler(val) {
if (val) {
this.saveIdGlobalDebounce(val, this.projectKey)
}
5 years ago
},
immediate: true
}
},
mounted() {
5 years ago
//项目key
let projectKey = this.$route.query.key
//表单内容 如果表单为空 使用默认表单
drawingListInDB = getDrawingList(projectKey)
5 years ago
if (Array.isArray(drawingListInDB) && drawingListInDB.length > 0) {
this.drawingList = drawingListInDB
} else {
this.drawingList = drawingDefalut
}
5 years ago
if (this.drawingList.length) {
this.activeFormItem(this.drawingList[0])
5 years ago
}
//获取表单配置
// formConfInDB = getFormConf(projectKey)
// if (formConfInDB) {
// this.formConf = formConfInDB
// }
//获取后台数据
this.$api.get(`/project/query/${projectKey}`).then(res => {
this.formConf.title = res.data.name
this.formConf.description = res.data.describe
})
5 years ago
//全局组件Id
if (getIdGlobal(projectKey)) {
this.idGlobal = getIdGlobal(projectKey)
5 years ago
}
this.projectKey = projectKey
5 years ago
},
methods: {
5 years ago
saveProjectInfo: debounce(430, true, function() {
this.$api.post('/project/update', {
'key': this.projectKey,
'name': this.formConf.title,
'describe': this.formConf.description
}).then((res) => {
})
}),
updateProjectItemInfo(val) {
5 years ago
let data = formItemConvertData(val, this.projectKey)
this.$api.post('/project/item/update', data).then((res) => {
})
},
deleteProjectItemInfo(val) {
console.log(val)
5 years ago
let data = formItemConvertData(val, this.projectKey)
this.$api.post('/project/item/delete', data).then((res) => {
})
},
5 years ago
saveProjectItemInfo(item) {
let params = formItemConvertData(item, this.projectKey)
this.$api.post('/project/item/create', params).then(res => {
item.sort = res.data.sort
})
},
5 years ago
activeFormItem(currentItem) {
this.activeData = currentItem
this.activeId = currentItem.__config__.formId
},
changeLabel(currentItem, value) {
console.log(currentItem)
console.log(value)
},
onEnd(obj) {
if (obj.from !== obj.to) {
this.activeData = tempActiveData
this.activeId = this.idGlobal
}
},
5 years ago
onItemEnd(obj){
console.log(obj)
let params={'projectKey':this.projectKey}
if(this.drawingList[obj.newIndex-1]){
let sort1=this.drawingList[obj.newIndex-1].sort
params.beforePosition=sort1
}
if(this.drawingList[obj.newIndex+1]){
let sort2= this.drawingList[obj.newIndex+1].sort
params.afterPosition=sort2
}
params.formItemId=this.drawingList[obj.newIndex].__config__.formId
this.$api.post('/project/item/sort', params).then(res => {
this.drawingList[obj.newIndex].sort = res.data.sort
})
},
5 years ago
addComponent(item) {
const clone = this.cloneComponent(item)
this.drawingList.push(clone)
this.activeFormItem(clone)
},
5 years ago
cloneComponent(origin,save=true) {
5 years ago
const clone = deepClone(origin)
const config = clone.__config__
config.span = this.formConf.span // 生成代码时,会根据span做精简判断
this.createIdAndKey(clone)
clone.placeholder !== undefined && (clone.placeholder += config.label)
tempActiveData = clone
5 years ago
if(save){
this.saveProjectItemInfo(clone)
}
5 years ago
return tempActiveData
},
createIdAndKey(item) {
const config = item.__config__
config.formId = ++this.idGlobal
config.renderKey = `${config.formId}${+new Date()}` // 改变renderKey后可以实现强制更新组件
if (config.layout === 'colFormItem') {
item.__vModel__ = `field${this.idGlobal}`
} else if (config.layout === 'rowFormItem') {
config.componentName = `row${this.idGlobal}`
!Array.isArray(config.children) && (config.children = [])
delete config.label // rowFormItem无需配置label属性
}
if (Array.isArray(config.children)) {
config.children = config.children.map(childItem => this.createIdAndKey(childItem))
}
return item
},
empty() {
this.$confirm('确定要清空所有组件吗?', '提示', {type: 'warning'})
.then(
() => {
this.drawingList = []
this.idGlobal = 100
}
)
},
drawingItemCopy(item, list) {
let clone = deepClone(item)
clone = this.createIdAndKey(clone)
list.push(clone)
this.activeFormItem(clone)
this.saveProjectItemInfo(clone)
5 years ago
},
drawingItemDelete(index, list) {
5 years ago
let item = list[index]
5 years ago
list.splice(index, 1)
this.$nextTick(() => {
const len = this.drawingList.length
if (len) {
this.activeFormItem(this.drawingList[len - 1])
}
})
this.deleteProjectItemInfo(item)
5 years ago
},
tagChange(newTag) {
5 years ago
newTag = this.cloneComponent(newTag,false)
5 years ago
const config = newTag.__config__
newTag.__vModel__ = this.activeData.__vModel__
5 years ago
newTag.sort=this.activeData.sort
5 years ago
config.formId = this.activeId
config.span = this.activeData.__config__.span
this.activeData.__config__.tag = config.tag
this.activeData.__config__.tagIcon = config.tagIcon
this.activeData.__config__.document = config.document
5 years ago
this.activeData.typeId=newTag.typeId
5 years ago
if (typeof this.activeData.__config__.defaultValue === typeof config.defaultValue) {
config.defaultValue = this.activeData.__config__.defaultValue
}
Object.keys(newTag)
.forEach(key => {
if (this.activeData[key] !== undefined) {
newTag[key] = this.activeData[key]
}
})
this.activeData = newTag
5 years ago
this.updateProjectItemInfo(newTag)
5 years ago
this.updateDrawingList(newTag, this.drawingList)
},
updateDrawingList(newTag, list) {
const index = list.findIndex(item => item.__config__.formId === this.activeId)
if (index > -1) {
list.splice(index, 1, newTag)
} else {
list.forEach(item => {
if (Array.isArray(item.__config__.children)) this.updateDrawingList(newTag, item.__config__.children)
})
}
}
}
}
</script>
5 years ago
<style lang='scss'>
5 years ago
@import '@/assets/styles/home';
@import '@/assets/styles/index';
5 years ago
</style>