<template> <a-config-provider :locale="locale"> <div class="form-designer-container-9136076486841527"> <k-header v-if="showHead" :title="title" /> <!-- 操作区域 start --> <operatingArea v-if="toolbarsTop" :showToolbarsText="showToolbarsText" :toolbars="toolbars" @handleSave="handleSave" @handlePreview="handlePreview" @handleOpenImportJsonModal="handleOpenImportJsonModal" @handleOpenCodeModal="handleOpenCodeModal" @handleOpenJsonModal="handleOpenJsonModal" @handleReset="handleReset" @handleClose="handleClose" @handleUndo="handleUndo" @handleRedo="handleRedo" :recordList="recordList" :redoList="redoList" > <template slot="left-action"> <slot name="left-action"></slot> </template> <template slot="right-action"> <slot name="right-action"></slot> </template> </operatingArea> <!-- 操作区域 end --> <div class="content" :class="{ 'show-head': showHead, 'toolbars-top': toolbarsTop, 'show-head-and-toolbars-top': toolbarsTop && showHead }" > <!-- 左侧控件区域 start --> <aside class="left"> <a-collapse @change="collapseChange" :defaultActiveKey="collapseDefaultActiveKey"> <!-- 基础控件 start --> <a-collapse-panel v-if="basicsArray.length > 0" header="基础控件" key="1"> <collapseItem :list="basicsArray" @generateKey="generateKey" @handleListPush="handleListPush" @start="handleStart" /> </a-collapse-panel> <!-- 基础控件 end --> <!-- 自定义控件 start --> <a-collapse-panel v-if="customComponents.list.length > 0" :header="customComponents.title" key="3" > <collapseItem :list="customComponents.list" @generateKey="generateKey" @handleListPush="handleListPush" @start="handleStart" /> </a-collapse-panel> <!-- 自定义控件 end --> <!-- 布局控件 start --> <a-collapse-panel v-if="layoutArray.length > 0" header="布局控件" key="4"> <collapseItem :list="layoutArray" @generateKey="generateKey" @handleListPush="handleListPush" @start="handleStart" /> </a-collapse-panel> <!-- 布局控件 end --> </a-collapse> </aside> <!-- 左侧控件区域 end --> <!-- 中间面板区域 start --> <section> <!-- 操作区域 start --> <operatingArea v-if="!toolbarsTop" :showToolbarsText="showToolbarsText" :toolbars="toolbars" @handleSave="handleSave" @handlePreview="handlePreview" @handleOpenImportJsonModal="handleOpenImportJsonModal" @handleOpenCodeModal="handleOpenCodeModal" @handleOpenJsonModal="handleOpenJsonModal" @handleReset="handleReset" @handleClose="handleClose" @handleUndo="handleUndo" @handleRedo="handleRedo" @handleQuery="handleQuery" :recordList="recordList" :redoList="redoList" > <template slot="left-action"> <slot name="left-action"></slot> </template> <template slot="right-action"> <slot name="right-action"></slot> </template> </operatingArea> <!-- 操作区域 end --> <k-form-component-panel :class="{ 'no-toolbars-top': !toolbarsTop }" :data="data" :selectItem="selectItem" :noModel="noModel" :hideModel="hideModel" :startType="startType" ref="KFCP" @handleSetSelectItem="handleSetSelectItem" /> <!-- 操作区域 start --> <k-json-modal ref="jsonModal" /> <k-code-modal ref="codeModal" /> <importJsonModal ref="importJsonModal" /> <previewModal ref="previewModal" /> <!-- 查询弹框 --> <queryModal ref="queryModal" /> <!-- 同表多个表单先择弹框 --> <selectTbTableInfoModal ref="selectTbTableInfoModal"/> </section> <!-- 中间面板区域 end --> <!-- 右侧控件属性区域 start --> <aside class="right"> <a-tabs :activeKey="activeKey" @change="changeTab" :tabBarStyle="{ margin: 0 }"> <a-tab-pane :key="1" tab="表单属性设置"> <formProperties :config="data.config" :formData="formData" :previewOptions="previewOptions" /> </a-tab-pane> <a-tab-pane :key="2" tab="控件属性设置"> <formItemProperties class="form-item-properties" :selectItem="selectItem" :hideModel="hideModel" :tableColumnList="tableColumnList" /> </a-tab-pane> </a-tabs> </aside> <!-- 右侧控件属性区域 end --> </div> <!-- <k-footer /> --> </div> </a-config-provider> </template> <script> /* * author kcz * date 2019-11-20 * description 表单设计器 */ import kHeader from "./module/header"; import operatingArea from "./module/operatingArea"; // import kFooter from "./module/footer"; import kFormComponentPanel from "./module/formComponentPanel"; import kJsonModal from "./module/jsonModal"; import kCodeModal from "./module/codeModal"; import collapseItem from "./module/collapseItem"; import importJsonModal from "./module/importJsonModal"; import queryModal from "./module/queryModal"; import selectTbTableInfoModal from "./module/selectTbTableInfoModal"; import previewModal from "../KFormPreview/index.vue"; import zhCN from "ant-design-vue/lib/locale-provider/zh_CN"; import { Revoke } from "../core/revoke"; import { basicsList, layoutList, customComponents } from "./config/formItemsConfig"; import formItemProperties from "./module/formItemProperties"; import formProperties from "./module/formProperties"; import { getFormByBusinessTable, getTableColumnList } from "../api/api"; export default { name: "KFormDesign", props: { title: { type: String, default: "表单设计器" }, showHead: { type: Boolean, default: true }, hideResetHint: { type: Boolean, default: false }, toolbarsTop: { type: Boolean, default: false }, toolbars: { type: Array, default: () => [ "save", "preview", "importJson", "exportJson", "exportCode", "reset", "close", "undo", "redo" ] }, showToolbarsText: { type: Boolean, default: false }, fields: { type: Array, default: () => [ "input", "textarea", "number", "select", "checkbox", "radio", "date", "time", "rate", "slider", "uploadFile", "uploadImg", "cascader", "treeSelect", "batch", "selectInputList", "editor", "switch", "button", "alert", "text", "html", "divider", "card", "tabs", "grid", "table" ] }, hideModel: { // 隐藏数据字段 type: Boolean, default: false } }, data() { return { tableColumnList:[],//数据表字段集合 formData: {}, //表单数据 locale: zhCN, customComponents, activeKey: 1, updateTime: 0, updateRecordTime: 0, startType: "", revoke: null, recordList: [], redoList: [], noModel: [ "button", "divider", "card", "grid", "tabs", "table", "alert", "text", "html" ], data: { list: [], config: { layout: "horizontal", labelCol: { xs: 4, sm: 4, md: 4, lg: 4, xl: 4, xxl: 4 }, labelWidth: 100, labelLayout: "flex", wrapperCol: { xs: 18, sm: 18, md: 18, lg: 18, xl: 18, xxl: 18 }, hideRequiredMark: false, customStyle: "" } }, previewOptions: { width: 850 }, selectItem: { key: "" } }; }, components: { kHeader, // kFooter, operatingArea, collapseItem, kJsonModal, kCodeModal, importJsonModal, previewModal, kFormComponentPanel, formItemProperties, formProperties, queryModal, selectTbTableInfoModal }, watch: { data: { handler(e) { this.$nextTick(() => { this.revoke.push(e); }); }, deep: true, immediate: true } }, computed: { basicsArray() { // 计算需要显示的基础字段 return basicsList.filter(item => this.fields.includes(item.type)); }, layoutArray() { // 计算需要显示的布局字段 return layoutList.filter(item => this.fields.includes(item.type)); }, collapseDefaultActiveKey() { // 计算当前展开的控件列表 const defaultActiveKey = window.localStorage.getItem( "collapseDefaultActiveKey" ); if (defaultActiveKey) { return defaultActiveKey.split(","); } else { return ["1"]; } } }, methods: { generateKey(list, index) { // 生成key值 const key = list[index].type + "_" + new Date().getTime(); this.$set(list, index, { ...list[index], key, model: key }); if (this.noModel.includes(list[index].type)) { // 删除不需要的model属性 delete list[index].model; } }, handleListPush(item) { if(this.formData.businessTable){ // 双击控件按钮push到list // 生成key值 if (!this.selectItem.key) { // 在没有选择表单时,将数据push到this.data.list const key = item.type + "_" + new Date().getTime(); item = { ...item, key, model: key, }; if (this.noModel.includes(item.type)) { // 删除不需要的model属性 delete item.model; } const itemString = JSON.stringify(item); const record = JSON.parse(itemString); // 删除icon及compoent属性 delete record.icon; delete record.component; this.data.list.push(record); this.handleSetSelectItem(record); return false; } this.$refs.KFCP.handleCopy(false, item); }else{ this.$message.error("请先选择表单属性中的关联数据表") } }, handleOpenJsonModal() { // 打开json预览模态框 this.$refs.jsonModal.jsonData = this.data; this.$refs.jsonModal.formData = this.formData; this.$refs.jsonModal.visible = true; }, handleOpenCodeModal() { // 打开代码预览模态框 this.$refs.codeModal.jsonData = this.data; this.$refs.codeModal.visible = true; }, handleOpenImportJsonModal() { // 打开json预览模态框 this.$refs.importJsonModal.jsonData = this.data; this.$refs.importJsonModal.handleSetSelectItem = this.handleSetSelectItem; this.$refs.importJsonModal.visible = true; }, handlePreview() { // 打开预览模态框 this.$refs.previewModal.jsonData = this.data; this.$refs.previewModal.previewWidth = this.previewOptions.width; this.$refs.previewModal.visible = true; }, handleQuery() { // 打开查询模态框 this.$refs.queryModal.jsonData = this.data; this.$refs.queryModal.formData = this.formData; // this.$refs.queryModal.previewWidth = this.previewOptions.width; this.$refs.queryModal.visible = true; }, handleReset() { // 清空 if (this.hideResetHint) { this.formData = {}; this.$refs.queryModal.formData = {}; this.tableColumnList=[]; // 不显示提示直接清空 this.resetData(); return; } this.$confirm({ title: "警告", content: "是否确认清空内容?", okText: "是", okType: "danger", cancelText: "否", onOk: () => { this.resetData(); } }); }, resetData() { this.data = { list: [], config: { layout: "horizontal", labelCol: { xs: 4, sm: 4, md: 4, lg: 4, xl: 4, xxl: 4 }, labelWidth: 100, labelLayout: "flex", wrapperCol: { xs: 18, sm: 18, md: 18, lg: 18, xl: 18, xxl: 18 }, hideRequiredMark: false, customStyle: "" } }; this.handleSetSelectItem({ key: "" }); this.$message.success("已清空"); }, handleSetSelectItem(record) { // 操作间隔不能低于100毫秒 const newTime = new Date().getTime(); if (newTime - this.updateTime < 100) { return false; } this.updateTime = newTime; // 设置selectItem的值 this.selectItem = record; ///获取表字段的下拉数据 //判断字段下拉数据是否有集合 if(!this.tableColumnList||this.tableColumnList.length<=0){//没有则查询 //获取表字段下拉数据接口 getTableColumnList(this.formData.businessTable).then(res=>{ this.tableColumnList=res.data.result;//表字段下拉数据 }); } // 判断是否选中控件,如果选中则弹出属性面板,否则关闭属性面板 if (record.key) { this.startType = record.type; this.changeTab(2); } else { this.changeTab(1); } }, /** * @description: 切换属性设置面板 * @param {*} * @return {*} */ changeTab(e) { this.activeKey = e; }, /** * @Author: kcz * @description: 遍历json结构,获取所有字段 * @param {*} * @return {*} Array */ getFieldSchema() { const fields = []; const traverse = array => { array.forEach(element => { if (element.type === "grid" || element.type === "tabs") { // 栅格布局 element.columns.forEach(item => { traverse(item.list); }); } else if (element.type === "card") { // 卡片布局 traverse(element.list); } else if (element.type === "batch") { // 动态表格内复制 traverse(element.list); } else if (element.type === "table") { // 表格布局 element.trs.forEach(item => { item.tds.forEach(val => { traverse(val.list); }); }); } else { if (element.model) { fields.push(element); } } }); }; traverse(this.data.list); return fields; }, handleSetData(data) { // 用于父组件赋值 try { if (typeof data !== "object") { return false; } else { this.data = data; // 导入json数据后,需要清除已选择key this.handleSetSelectItem({ key: "" }); } return true; } catch (error) { console.error(error); return false; } }, collapseChange(val) { // 点击collapse时,保存当前collapse状态 window.localStorage.setItem("collapseDefaultActiveKey", val); }, handleStart(type) { this.startType = type; }, /** * @description: 撤销 * @param {*} * @return {*} */ handleUndo() { const record = this.revoke.undo(); if (!record) { return false; } this.data = record; this.handleSetSelectItem({ key: "" }); }, /** * @description: 重做 * @param {*} * @return {*} */ handleRedo() { const record = this.revoke.redo(); if (!record) { return false; } this.data = record; }, handleSave() { // 保存函数 this.$emit("save", JSON.stringify(this.data)); }, getValue() { // 获取数据 return this.data; }, handleClose() { this.$emit("close"); } }, created() { this.revoke = new Revoke(); this.recordList = this.revoke.recordList; this.redoList = this.revoke.redoList; console.log(this.$route.query.tableName); //判断是否有接收到表明 if (this.$route.query.tableName) { //有则根据表明查询表单json以及相关数据 getFormByBusinessTable(this.$route.query.tableName).then(res => { if (res.data.success) { if(res.data.result.tbTableInfoList!=null&&res.data.result.tbTableInfoList.length>1){ // 打开查询模态框 // this.$refs.queryModal.jsonData = this.data; // this.$refs.queryModal.formData = this.formData; // this.$refs.queryModal.previewWidth = this.previewOptions.width; this.$refs.selectTbTableInfoModal.visible = true; this.$refs.selectTbTableInfoModal.dataSource=res.data.result.tbTableInfoList; this.$refs.selectTbTableInfoModal.jsonData = this.data;//表单json this.$refs.selectTbTableInfoModal.formData = this.formData;//表单相关字段数据 }else{ //获取Json字符串装json格式 const editorJsonData = res.data.result.jsonContent; const jsonData = {}; //获取json展示的数据 jsonData.list = editorJsonData.list; jsonData.config = editorJsonData.config; jsonData.config.layout = editorJsonData.config.layout; this.data = jsonData; //当前填写数据存储,用于其他页面获取 this.formData.businessTable = this.$route.query.tableName; //数据库表明 this.formData.text = res.data.result.text; //表单标题 // this.$message.success("查询成功"); } } else { this.$message.error(res.data.message); } }); } } }; //根据表名称获取表字段与表说明 // function getTableColumnListShow(item,formData){ // getTableColumnList(formData.businessTable).then(res=>{ // if(res.data.success){ // item.tableList=res.data.result; // } // }); // item.tableList=[ // {columnName:"123",columnComment:"123"} // ] // } </script>