| <template> | 
|   <el-container class="designer-container" @keydown.native.f2="createBaseVue('json')" @keydown.native.f3="createBaseVue('save')"> | 
|     <el-aside width="250px" class="components-list"> | 
|       <sticky :z-index="20" class-name="left-sticky"> | 
|         <el-collapse accordion> | 
|           <el-collapse-item ref="master-table-item" title="主表字段"> | 
|             <template slot="title"> | 
|               <span class="left title">{{ moduleNode.cnName }}</span> | 
|               <el-popover ref="tree-popover" class="right margin-left-30" width="400" trigger="click"> | 
|                 <el-button slot="reference" type="text">选择模块</el-button> | 
|                 <el-scrollbar :noresize="false" :native="false" wrap-class="tree scrollbar-wrap"> | 
|                   <el-tree ref="module-tree" :load="loadModuleNode" :props="moduleProps" lazy @node-click="moduleclick"> | 
|                     <span slot-scope="{ node, data }" class="custom-tree-node"> | 
|                       <template v-if="!node.isLeaf"> | 
|                         <span v-if="node.expanded"> | 
|                           <i class="el-icon-yrt-wenjianjiazhankai"></i> {{ node.label }} | 
|                         </span> | 
|                         <span v-else> | 
|                           <i class="el-icon-yrt-wenjianjia"></i> {{ node.label }} | 
|                         </span> | 
|                       </template> | 
|                       <template v-else> | 
|                         <span> | 
|                           <i class="el-icon-yrt-wenjian1"></i> {{ node.label }} | 
|                         </span> | 
|                       </template> | 
|                     </span> | 
|                   </el-tree> | 
|                 </el-scrollbar> | 
|                 <el-footer style="padding-top:10px;border-top:1px solid #f3f3f3;text-align:right;"> | 
|                   <el-button type="default" @click="$refs['tree-popover'].doClose();">关闭</el-button> | 
|                   <el-button type="primary" @click="treeRefresh">刷新</el-button> | 
|                 </el-footer> | 
|               </el-popover> | 
|             </template> | 
|             <el-scrollbar :noresize="false" :native="false" wrap-class="fields scrollbar-wrap"> | 
|               <draggable :list="fieldComponents" :options="{group:{ name:'people', pull:'clone',put:false},sort:false, ghostClass: 'ghost'}" :move="handleMove" tag="ul" @end="handleMoveEnd" @start="handleMoveStart"> | 
|                 <li v-for="(item, index) in fieldComponents" :key="index" class="form-edit-widget-label"> | 
|                   <a> | 
|                     <i :class="item.icon"></i> | 
|                     <span>{{ item.label }}</span> | 
|                   </a> | 
|                 </li> | 
|               </draggable> | 
|             </el-scrollbar> | 
|           </el-collapse-item> | 
|           <el-collapse-item title="明细字段"> | 
|             <template v-if="detailFields.length"> | 
|               <el-scrollbar :noresize="false" :native="false" wrap-class="fields scrollbar-wrap"> | 
|                 <draggable :list="detailFields" :options="{group:{ name:'people', pull:'clone',put:false},sort:false, ghostClass: 'ghost'}" :move="handleMove" tag="ul" @end="handleMoveEnd" @start="handleMoveStart"> | 
|                   <li v-for="(item, index) in detailFields" :key="index" class="form-edit-widget-label"> | 
|                     <a> | 
|                       <i :class="item.icon"></i> | 
|                       <span>{{ item.label }}</span> | 
|                     </a> | 
|                   </li> | 
|                 </draggable> | 
|               </el-scrollbar> | 
|             </template> | 
|             <template v-else> | 
|               <div class="margin-top-no margin-bottom-20 padding-0-10 color-gray">这里是表单明细字段列表,请在编辑页面中关联子表名</div> | 
|             </template> | 
|           </el-collapse-item> | 
|           <el-collapse-item title="基础字段"> | 
|             <draggable :list="basicComponents" :options="{group:{ name:'people', pull:'clone',put:false},sort:false, ghostClass: 'ghost'}" :move="handleMove" tag="ul" @end="handleMoveEnd" @start="handleMoveStart"> | 
|               <li v-for="(item, index) in basicComponents" :key="index" class="form-edit-widget-label"> | 
|                 <a> | 
|                   <i :class="item.icon"></i> | 
|                   <span>{{ item.label }}</span> | 
|                 </a> | 
|               </li> | 
|             </draggable> | 
|           </el-collapse-item> | 
|           <el-collapse-item title="高级字段"> | 
|             <draggable :list="advanceComponents" :options="{group:{ name:'people', pull:'clone',put:false},sort:false, ghostClass: 'ghost'}" :move="handleMove" tag="ul" @end="handleMoveEnd" @start="handleMoveStart"> | 
|               <li v-for="(item, index) in advanceComponents" :key="index" class="form-edit-widget-label"> | 
|                 <a> | 
|                   <i :class="item.icon"></i> | 
|                   <span>{{ item.label }}</span> | 
|                 </a> | 
|               </li> | 
|             </draggable> | 
|           </el-collapse-item> | 
|           <el-collapse-item title="布局字段"> | 
|             <draggable :list="layoutComponents" :options="{group:{ name:'people', pull:'clone',put:false},sort:false, ghostClass: 'ghost'}" :move="handleMove" tag="ul" @end="handleMoveEnd" @start="handleMoveStart"> | 
|               <li v-for="(item, index) in layoutComponents" :key="index" class="form-edit-widget-label data-grid"> | 
|                 <a> | 
|                   <i :class="item.icon"></i> | 
|                   <span>{{ item.label }}</span> | 
|                 </a> | 
|               </li> | 
|             </draggable> | 
|           </el-collapse-item> | 
|           <el-collapse-item title="按钮设置"> | 
|             <draggable :list="buttonComponents" :options="{group:{ name:'button-group', pull:'clone',put:false},sort:false, ghostClass: 'button-ghost'}" tag="ul"> | 
|               <li v-for="(item, index) in buttonComponents" :key="index" class="form-edit-widget-label data-grid"> | 
|                 <a> | 
|                   <i :class="item.options.icon"></i> | 
|                   <span>{{ item.label }}</span> | 
|                 </a> | 
|               </li> | 
|             </draggable> | 
|           </el-collapse-item> | 
|         </el-collapse> | 
|       </sticky> | 
|     </el-aside> | 
|   | 
|     <el-container class="center-container" direction="vertical"> | 
|       <sticky :z-index="2000" height="40px" class-name="content-tool"> | 
|         <el-tabs v-model="vueDataTabId" class="tabs-nav" @tab-click="vueDataClick" @tab-remove="vueDataRemove" @dblclick.native="vueDataTabDblClick"> | 
|           <template v-for="(tab, index) in vueDataList"> | 
|             <el-tab-pane v-if="index==0" :closable="false" :ref="'tab'+index" :key="index" :name="''+index" :label="(tab.designMode==='user'?'*':'')+tab.label"> | 
|             </el-tab-pane> | 
|             <el-tab-pane v-else :ref="'tab'+index" :key="index" :name="''+index" :label="(tab.designMode==='user'?'*':'')+tab.label" closable> | 
|             </el-tab-pane> | 
|           </template> | 
|         </el-tabs> | 
|   | 
|         <div class="right-tools"> | 
|           <el-button type="text" size="medium" icon="el-icon-yrt-fuzhi2" @click="copeVueData">复制</el-button> | 
|           <el-button type="text" size="medium" icon="el-icon-yrt-reset" @click="handleReset">重置</el-button> | 
|           <el-button type="text" size="medium" icon="el-icon-tickets" @click="handleGenerateJson">查看</el-button> | 
|           <el-button type="text" size="medium" icon="el-icon-yrt-baocun" @click="createBaseVue('save')">保存(F3)</el-button> | 
|           <el-button type="text" size="medium" icon="el-icon-yrt-save" @click="createBaseVue('json')">生成(F2)</el-button> | 
|         </div> | 
|       </sticky> | 
|   | 
|       <div class="content"> | 
|         <el-tabs v-model="editRegionTab" @tab-click="(tab, event)=>{widgetFormSelect=null;configType=tab.name;}"> | 
|           <el-tab-pane label="管理页面" name="ManagerConfig"> | 
|             <div :class="{'widget-empty': widgetFormData.dataListOptions.fields.length == 0}" style="min-height:1200px"> | 
|               <manager-form ref="managerForm" :data="widgetFormData" :select.sync="widgetFormSelect" :config-type.sync="configType" :field-components="fieldComponents"></manager-form> | 
|             </div> | 
|           </el-tab-pane> | 
|           <el-tab-pane label="编辑页面" name="WidgetConfig"> | 
|             <div :class="{'widget-empty': widgetFormData.editorOptions.fields.length == 0}" style="min-height:1200px"> | 
|               <widget-form ref="widgetForm" :data="widgetFormData" :select.sync="widgetFormSelect" :config-type.sync="configType" :detail-fields.sync="detailFields" :field-components="fieldComponents"></widget-form> | 
|             </div> | 
|           </el-tab-pane> | 
|         </el-tabs> | 
|       </div> | 
|     </el-container> | 
|   | 
|     <el-aside class="widget-config-container"> | 
|       <sticky :z-index="20" class-name="left-sticky"> | 
|         <el-container> | 
|           <el-header height="45px"> | 
|             <div :class="{active: configTab=='widget'}" class="config-tab" @click="handleConfigSelect('widget')">字段属性</div> | 
|             <div :class="{active: configTab=='form'}" class="config-tab" @click="handleConfigSelect('form')">表单属性</div> | 
|           </el-header> | 
|           <el-main class="config-content"> | 
|             <el-scrollbar :noresize="false" :native="false" wrap-class="config scrollbar-wrap"> | 
|               <component v-show="configTab=='widget'" :is="configType" :data="widgetFormSelect" :basic-components="basicComponents"></component> | 
|             </el-scrollbar> | 
|             <el-scrollbar :noresize="false" :native="false" wrap-class="config scrollbar-wrap"> | 
|               <form-config v-show="configTab=='form'" :editor-config="widgetFormData.editorOptions.config" :data-options="widgetFormData.dataOptions"></form-config> | 
|             </el-scrollbar> | 
|           </el-main> | 
|         </el-container> | 
|       </sticky> | 
|     </el-aside> | 
|   | 
|     <cus-dialog ref="jsonPreview" :visible="jsonVisible" title="生成JSON并保存Vue文件" width="800px" form @on-close="jsonVisible = false"> | 
|       <div id="jsoneditor" style="height: 400px;width: 100%;">{{ vueData }}</div> | 
|       <template slot="action"> | 
|         <el-button data-clipboard-target=".ace_text-input" @dblclick.native="$message.success('复制成功');">双击复制</el-button> | 
|         <el-button :loading="createLoading" type="primary" data-clipboard-target=".ace_text-input" @click.native="createBaseVue('jsoneditor')">保存并生成Vue文件</el-button> | 
|       </template> | 
|     </cus-dialog> | 
|   | 
|     <cus-dialog ref="codePreview" :visible="codeVisible" title="生成页面" form width="800px" @on-close="codeVisible = false"> | 
|       <div id="codeeditor" style="height: 500px; width: 100%;">{{ htmlTemplate }}</div> | 
|       <template slot="action"> | 
|         <el-button id="closebtn" @click="codeVisible=false">关闭</el-button> | 
|       </template> | 
|     </cus-dialog> | 
|   </el-container> | 
| </template> | 
|   | 
| <script> | 
| import Draggable from 'vuedraggable' | 
| import WidgetConfig from './WidgetConfig' | 
| import ManagerConfig from './ManagerConfig' | 
| import FormConfig from './FormConfig' | 
| import WidgetForm from './WidgetForm' | 
| import ManagerForm from './ManagerForm' | 
| import CusDialog from './CusDialog' | 
| import GenerateForm from './GenerateForm' | 
| // import JSONEditor from 'jsoneditor' | 
| // import 'jsoneditor/dist/jsoneditor.min.css' | 
| import Sticky from '@/components/Sticky' | 
| import Vue from 'vue' | 
| Vue.config.keyCodes.f2 = 113 | 
| Vue.config.keyCodes.f3 = 114 | 
|   | 
| import { | 
|   fieldComponents, | 
|   basicComponents, | 
|   layoutComponents, | 
|   advanceComponents, | 
|   buttonComponents, | 
|   defaultDataListButtons | 
| } from './componentsConfig.js' | 
| import { loadJs } from './util/index.js' | 
| import { generateMixinCode, generateMainCode } from './generateMixinCode.js' | 
|   | 
| export default { | 
|   name: 'sys-dev-tools-ui-designer', | 
|   components: { | 
|     Draggable, | 
|     WidgetConfig, | 
|     ManagerConfig, | 
|     FormConfig, | 
|     WidgetForm, | 
|     ManagerForm, | 
|     CusDialog, | 
|     GenerateForm, | 
|     Sticky | 
|   }, | 
|   data() { | 
|     return { | 
|       fieldComponents, | 
|       basicComponents, | 
|       layoutComponents, | 
|       advanceComponents, | 
|       buttonComponents, | 
|       defaultDataListButtons, | 
|       // 设计模式 | 
|       designMode: 'system', | 
|       // VueData列表All | 
|       vueDataListAll: [], | 
|       // VueData列表 | 
|       vueDataList: [], | 
|       // vue页面ID | 
|       vueDataTabId: '0', | 
|   | 
|       // 明细字段 | 
|       detailFields: [], | 
|   | 
|       // 当前配置参数设置组件 | 
|       configType: 'ManagerConfig', | 
|   | 
|       // 模块tree prop参数配置 | 
|       moduleProps: { | 
|         label: 'cnName', | 
|         // children: "zones", | 
|         isLeaf: function(data, node) { | 
|           return data.hasChild !== 1 | 
|         } | 
|       }, | 
|       // 模块字段信息 | 
|       moduleNode: { | 
|         projectName: null, | 
|         cnName: '【请选择模块】', | 
|         table_Id: 0, | 
|         tableName: null, | 
|         tableView: null, | 
|         dBServer: null, | 
|         dBServerReadOnly: null, | 
|         parentId: null, | 
|         detailName: null, | 
|         idField: null, | 
|         codeRegular: null, | 
|         linkColumn: null, | 
|         sortName: null | 
|       }, | 
|   | 
|       // 设计器数据结构 | 
|       widgetFormData: { | 
|         // 数据加载及保存参数 | 
|         dataOptions: { | 
|           projectName: 'BasicInfo', | 
|           tableView: 'Base_Provider', | 
|           idField: 'provider_Id', | 
|           router: '/basic/asset/provider', | 
|           idValue: 0, | 
|           codeRegular: 'providerCode', // 自动编码字段 | 
|           linkColumn: null, // 链接到弹出编辑窗口的字段 | 
|           menu_Id: 428, | 
|           pageIndex: 1, | 
|           pageSize: 15, | 
|           total: 0, | 
|           sortName: { provider_Id: 'DESC' }, | 
|           showActionField: true // 列表页显示Action列 | 
|         }, | 
|         // 数据管理器对话框参数 | 
|         dataListOptions: { | 
|           // 表格数据 | 
|           data: [], | 
|           // 表格列 | 
|           fields: [], | 
|           // 表格工具栏 | 
|           buttons: [] | 
|         }, | 
|   | 
|         // 编辑器对话框参数 | 
|         editorOptions: { | 
|           fields: [], | 
|           config: { | 
|             labelWidth: '100px', // 标签文字宽度 | 
|             labelPosition: 'right', // 标签位置 | 
|             top: '3vh', // 对话框底部距离 | 
|             width: '1200px', // 对话框宽度 | 
|             visible: false, // 是否显示添加实验室对话框 | 
|             disabled: false, // 是否禁用 | 
|             title: null, // 对话框标题 | 
|             action: 'add', // 接收值为:add、edit | 
|             formInline: false, // 行内表单 | 
|             saveButtonText: '保存' | 
|           } | 
|         } | 
|       }, | 
|   | 
|       // 设计器默认数据结构 | 
|       widgetFormDataDefault: { | 
|         // 数据加载及保存参数 | 
|         dataOptions: { | 
|           projectName: 'BasicInfo', | 
|           tableView: 'Base_Provider', | 
|           idField: 'provider_Id', | 
|           router: '/basic/asset/provider', | 
|           idValue: 0, | 
|           codeRegular: 'providerCode', // 自动编码字段 | 
|           linkColumn: null, // 链接到弹出编辑窗口的字段 | 
|           menu_Id: 428, | 
|           pageIndex: 1, | 
|           pageSize: 15, | 
|           total: 0, | 
|           sortName: { provider_Id: 'DESC' }, | 
|           showActionField: true // 列表页显示Action列 | 
|         }, | 
|         // 数据管理器对话框参数 | 
|         dataListOptions: { | 
|           // 表格数据 | 
|           data: [], | 
|           // 表格列 | 
|           fields: [], | 
|           // 表格工具栏 | 
|           buttons: JSON.parse(JSON.stringify(defaultDataListButtons)) | 
|         }, | 
|   | 
|         // 编辑器对话框参数 | 
|         editorOptions: { | 
|           fields: [], | 
|           config: { | 
|             labelWidth: '100px', // 标签文字宽度 | 
|             formWidth: 'auto', // 表单宽度 | 
|             labelPosition: 'right', // 标签位置 | 
|             top: '3vh', // 对话框底部距离 | 
|             width: '1200px', // 对话框宽度 | 
|             visible: false, // 是否显示添加实验室对话框 | 
|             disabled: false, // 是否禁用 | 
|             title: '资产分类', | 
|             action: 'add', // 接收值为:add、edit | 
|             formInline: false, // 行内表单 | 
|             saveButtonText: '保存' | 
|           } | 
|         } | 
|       }, | 
|       // 设计器类型:管理页面、编辑页面 | 
|       editRegionTab: 'ManagerConfig', | 
|       configTab: 'widget', | 
|       widgetFormSelect: null, // 选中项 | 
|       previewVisible: false, | 
|       jsonVisible: false, | 
|       codeVisible: false, | 
|       remoteFuncs: { | 
|         func_test(resolve) { | 
|           setTimeout(() => { | 
|             const options = [{ id: '1', name: '1111' }, { id: '2', name: '2222' }, { id: '3', name: '3333' }] | 
|   | 
|             resolve(options) | 
|           }, 2000) | 
|         }, | 
|         funcGetToken(resolve) {} | 
|       }, | 
|       widgetModels: {}, | 
|       blank: '', | 
|       htmlTemplate: '', | 
|       vueData: '', // 创建混入文件内容 | 
|       createLoading: false // 创建页面loading | 
|     } | 
|   }, | 
|   computed: { | 
|     currentTabId: function() { | 
|       return parseInt(this.vueDataTabId) | 
|     } | 
|   }, | 
|   watch: { | 
|     widgetFormData: { | 
|       deep: true, | 
|       handler: function(val) { | 
|         var item = this.vueDataList[this.currentTabId] | 
|         if (item) { | 
|           item.vueData = JSON.stringify(val) | 
|         } | 
|       } | 
|     }, | 
|     configType: function(val) {}, | 
|     widgetFormSelect: { | 
|       handler(val) {}, | 
|       deep: true | 
|     } | 
|   }, | 
|   created() { | 
|     // 获取设计模式 | 
|     this.designMode = this.$route.fullPath.indexOf('user') >= 0 ? 'user' : 'system' | 
|   }, | 
|   mounted() { | 
|     loadJs('lib/ace/src/ace.js') | 
|   }, | 
|   activated() { | 
|     this.designMode = this.$route.fullPath.indexOf('user') >= 0 ? 'user' : 'system' | 
|   }, | 
|   methods: { | 
|     handleConfigSelect(value) { | 
|       this.configTab = value | 
|     }, | 
|     handleMoveEnd(evt) { | 
|       // console.log("end", evt); | 
|     }, | 
|     handleMoveStart({ oldIndex }) { | 
|       // console.log("start", oldIndex, this.basicComponents); | 
|     }, | 
|     handleMove() { | 
|       return true | 
|     }, | 
|     // 预览设计 | 
|     handlePreview() { | 
|       this.previewVisible = true | 
|     }, | 
|     // 重置,重新开始设计 | 
|     handleReset() { | 
|       if (!this.moduleNode.tableView) { | 
|         this.$message.error('请选择需要设计的模块!') | 
|         return | 
|       } | 
|       this.$confirm('确定要重置设计,将重新开始设计, 是否继续?', '重置提示', { | 
|         confirmButtonText: '确定', | 
|         cancelButtonText: '取消', | 
|         type: 'warning' | 
|       }) | 
|         .then(() => { | 
|           this.reset() | 
|           this.$message({ | 
|             type: 'success', | 
|             message: '重置成功!' | 
|           }) | 
|         }) | 
|         .catch(() => { | 
|           this.$message({ | 
|             type: 'info', | 
|             message: '已取消重置' | 
|           }) | 
|         }) | 
|     }, | 
|     reset() { | 
|       var data = this.moduleNode | 
|       this.widgetFormData = Object.assign({}, this.widgetFormDataDefault, { | 
|         dataOptions: { | 
|           projectName: data.projectName, | 
|           tableView: data.tableView, | 
|           idField: data.idField, | 
|           router: null, | 
|           idValue: 0, | 
|           codeRegular: data.codeRegular, // 自动编码字段 | 
|           linkColumn: data.linkColumn, // 链接到弹出编辑窗口的字段 | 
|           menu_Id: null, | 
|           pageIndex: 1, | 
|           pageSize: 15, | 
|           total: 0, | 
|           sortName: data.sortName, | 
|           showActionField: true // 列表页显示Action列 | 
|         }, | 
|         // 数据管理器对话框参数 | 
|         dataListOptions: { | 
|           // 表格数据 | 
|           data: [], | 
|           // 表格列 | 
|           fields: [], | 
|           // 表格工具栏 | 
|           buttons: JSON.parse(JSON.stringify(defaultDataListButtons)) | 
|         }, | 
|         // 编辑器对话框参数 | 
|         editorOptions: { | 
|           fields: [], | 
|           config: { | 
|             labelWidth: '100px', // 标签文字宽度 | 
|             labelPosition: 'right', // 标签位置 | 
|             top: '3vh', // 对话框底部距离 | 
|             width: '1200px', // 对话框宽度 | 
|             visible: false, // 是否显示添加实验室对话框 | 
|             disabled: false, // 是否禁用 | 
|             title: null, // 对话框标题 | 
|             action: 'add', // 接收值为:add、edit | 
|             formInline: false, // 行内表单 | 
|             saveButtonText: '保存' | 
|           } | 
|         } | 
|       }) | 
|       // 对话框标题名称 | 
|       this.widgetFormData.editorOptions.config.title = data.cnName | 
|       this.configType = 'WidgetConfig' // 参数设置组件类型 | 
|       this.widgetFormSelect = null // 编辑页面选中项 | 
|     }, | 
|     // 加载模块节点树 | 
|     loadModuleNode(node, resolve) { | 
|       let loading = null | 
|   | 
|       this.$nextTick(() => { | 
|         var where = '' | 
|         if (node.level === 0) { | 
|           where = { parentId: 0 } | 
|   | 
|           var treeEl = this.$refs['module-tree'] | 
|           loading = this.$loading({ | 
|             target: treeEl.$el, | 
|             lock: true, | 
|             text: 'Loading', | 
|             spinner: 'el-icon-loading', | 
|             customClass: 'tree-loading' | 
|           }) | 
|         } else { | 
|           where = { parentId: node.data.table_Id } | 
|         } | 
|   | 
|         var url = '/api/common/loadTreeNode' | 
|         var params = { | 
|           openNodeApi: true, // 启用node api接口 | 
|           folder: 'sys/core', | 
|           dBServer: 'Sys', | 
|           tableName: 'Sys_MvcTableInfo', | 
|           tableView: 'Sys_MvcTableInfo', | 
|           keyName: 'table_Id', | 
|           nodeName: 'cnName', | 
|           fixHasChild: false, | 
|           isBreakWay: false, | 
|           displayBreakWay: false, | 
|           parentName: 'parentId', | 
|           orderBy: { orderNo: 'desc', table_Id: 'asc' }, | 
|           where: where, | 
|           extendColumns: | 
|             'tableName,tableView,dBServer,dBServerReadOnly,detailName,vueData,namespace,keyIDs,codeRegular,linkColumn,sortName,folderName' | 
|         } | 
|         this.common.ajax(url, params, res => { | 
|           if (res.result) { | 
|             resolve(res.data) | 
|           } else { | 
|             this.$message.error(res.msg) | 
|           } | 
|           if (loading) loading.close() | 
|         }) | 
|       }) | 
|     }, | 
|     // 刷新tree | 
|     treeRefresh() { | 
|       this.filterText = '' | 
|       var root = this.$refs['module-tree'].store.root | 
|       while (root.childNodes.length) { | 
|         this.$refs['module-tree'].remove(root.childNodes[0]) | 
|       } | 
|       this.loadModuleNode(root, data => { | 
|         root.doCreateChildren(data) | 
|       }) | 
|     }, | 
|     // 选择模块单击事件 | 
|     moduleclick(data, node, element) { | 
|       if (!node.isLeaf) return | 
|       const namespaces = data.namespace.split('.') | 
|       const folder = namespaces[namespaces.length - 1] + '/' + data.folderName | 
|       let sortName = data.sortName | 
|       try { | 
|         sortName = JSON.parse(sortName) | 
|       } catch (error) { | 
|         sortName = '' + sortName | 
|       } | 
|       this.moduleNode = { | 
|         folder: folder, | 
|         cnName: data.cnName, | 
|         table_Id: data.table_Id, | 
|         tableName: data.tableName, | 
|         tableView: data.tableView, | 
|         dBServer: data.dBServer, | 
|         dBServerReadOnly: data.dBServerReadOnly, | 
|         parentId: data.parentId, | 
|         detailName: data.detailName, | 
|         idField: this.common.caseStyle(data.keyIDs), | 
|         codeRegular: this.common.caseStyle(data.codeRegular), | 
|         linkColumn: this.common.caseStyle(data.linkColumn), | 
|         sortName: sortName, | 
|         searchRowNo: data.searchRowNo, | 
|         vueData: data.vueData | 
|       } | 
|       this.loadVueDataList(this.moduleNode, node, element) | 
|       this.loadModuleFields(this.moduleNode, node, element) | 
|       this.$refs['tree-popover'].doClose() | 
|       var cItem = this.$refs['master-table-item'] | 
|       if (!cItem.isActive) { | 
|         cItem.handleHeaderClick() | 
|       } | 
|     }, | 
|     // 加载VueData列表 | 
|     loadVueDataList(data, node, element) { | 
|       const userInfo = this.common.getUserInfo() | 
|       var where = { table_Id: data.table_Id, userProduct_Id: [0, userInfo.userProduct_Id] } | 
|   | 
|       var url = '/api/common/loadDataList' | 
|       var params = { | 
|         openNodeApi: true, // 启用node api接口 | 
|         folder: 'sys/core', | 
|         tableView: 'Sys_MvcVueData', | 
|         idField: 'vueData_Id', | 
|         idValue: 0, | 
|         menu_Id: 6, | 
|         pageIndex: 1, | 
|         pageSize: 1000, | 
|         total: 0, | 
|         where: where, | 
|         orderBy: { vueData_Id: 'asc' } | 
|       } | 
|   | 
|       this.common.ajax( | 
|         url, | 
|         params, | 
|         res => { | 
|           this.common.showMsg(res) | 
|           if (res.result) { | 
|             this.vueDataList = [] // 清空 | 
|             var dataList = res.data.rows.map((item, index, arr) => { | 
|               var field = { | 
|                 vueData_Id: item.vueData_Id, | 
|                 table_Id: item.table_Id, | 
|                 label: item.vueDataName, | 
|                 vueData: item.vueData, | 
|                 fromVueData_Id: item.fromVueData_Id, | 
|                 userProduct_Id: item.userProduct_Id | 
|               } | 
|               return field | 
|             }) | 
|             this.vueDataListAll = dataList | 
|             // 系统设计 | 
|             if (this.designMode === 'system') { | 
|               // 获取原始所有复制项 | 
|               const otherVueList = this.vueDataListAll.filter(item => item.userProduct_Id === 0) | 
|               this.vueDataList = [ | 
|                 { | 
|                   vueData_Id: 0, // 0表示为主表VueData | 
|                   table_Id: data.table_Id, | 
|                   label: data.cnName, | 
|                   vueData: data.vueData, | 
|                   fromVueData_Id: data.fromVueData_Id, | 
|                   userProduct_Id: data.userProduct_Id, | 
|                   designMode: 'system' | 
|                 } | 
|               ].concat(otherVueList) | 
|             } else { | 
|               // 判断主tab是否已自定义 | 
|               const customVue = this.vueDataListAll.find(item => item.fromVueData_Id === 0) | 
|               if (customVue) { | 
|                 customVue.designMode = 'user' | 
|                 this.vueDataList.push(customVue) | 
|               } else { | 
|                 this.vueDataList = [ | 
|                   { | 
|                     vueData_Id: 0, // 0表示为主表VueData | 
|                     table_Id: data.table_Id, | 
|                     label: data.cnName, | 
|                     vueData: data.vueData, | 
|                     fromVueData_Id: data.fromVueData_Id, | 
|                     userProduct_Id: data.userProduct_Id, | 
|                     designMode: 'system' | 
|                   } | 
|                 ] | 
|               } | 
|               // 获取原始所有复制项 | 
|               const otherVueList = this.vueDataListAll.filter(item => item.userProduct_Id === 0) | 
|               for (const vueInfo of otherVueList) { | 
|                 // 查找是否已经账套自定义 | 
|                 const otherUserVue = this.vueDataListAll.find(item => item.fromVueData_Id === vueInfo.vueData_Id) | 
|                 if (otherUserVue) { | 
|                   otherUserVue.designMode = 'user' | 
|                   this.vueDataList.push(otherUserVue) | 
|                 } else { | 
|                   vueInfo.designMode = 'system' | 
|                   this.vueDataList.push(vueInfo) | 
|                 } | 
|               } | 
|             } | 
|             // 设置当前tab项 | 
|             if (this.vueDataList.length) { | 
|               this.vueDataTabId = '0' | 
|               this.setCurrentVueData(this.vueDataList[0].vueData) | 
|             } | 
|           } | 
|         }, | 
|         true | 
|       ) | 
|     }, | 
|     // 加载模块字段 | 
|     loadModuleFields(data, node, element) { | 
|       var where = { | 
|         table_Id: data.table_Id, | 
|         columnName: { | 
|           operator: '!=', | 
|           value: '分割行' | 
|         }, | 
|         isManagerDataSet: 1 | 
|       } | 
|       debugger | 
|       var url = '/api/common/loadDataList' | 
|       var params = { | 
|         folder: 'sys/core', | 
|         tableView: 'Sys_MvcTableColumn', | 
|         idField: 'columnID', | 
|         idValue: 0, | 
|         menu_Id: 6, | 
|         pageIndex: 1, | 
|         pageSize: 1000, | 
|         total: 0, | 
|         where: where, | 
|         orderBy: { orderNo: 'DESC', columnID: 'ASC' } | 
|       } | 
|   | 
|       this.common.ajax( | 
|         url, | 
|         params, | 
|         res => { | 
|           if (res.result) { | 
|             this.fieldComponents = res.data.rows.map((item, index, arr) => { | 
|               var field = { | 
|                 type: 'input', | 
|                 label: item.columnComment, | 
|                 icon: 'el-icon-yrt-danhangshurukuang', | 
|                 options: { | 
|                   prop: this.common.caseStyle(item.columnName), | 
|                   searchRowNo: item.searchRowNo, | 
|                   width: '100%', | 
|                   noLabel: false, | 
|                   defaultValue: '', | 
|                   required: false, | 
|                   dataType: item.dataType.toLowerCase(), | 
|                   pattern: '', | 
|                   placeholder: '' | 
|                 } | 
|               } | 
|               return field | 
|             }) | 
|           } else { | 
|             this.$message({ | 
|               showClose: true, | 
|               duration: 6000, | 
|               message: res.msg, | 
|               type: 'error' | 
|             }) | 
|           } | 
|         }, | 
|         true | 
|       ) | 
|     }, | 
|     // 生成JSON | 
|     handleGenerateJson() { | 
|       var router = this.widgetFormData.dataOptions.router | 
|   | 
|       this.jsonVisible = true | 
|       if (router) { | 
|         var last = router.lastIndexOf('/') | 
|         if (last === router.length - 1) { | 
|           router = router.substring(0, router.length - 1) | 
|           this.widgetFormData.dataOptions.router = router | 
|         } | 
|       } | 
|       this.vueData = generateMixinCode(this.widgetFormData) | 
|   | 
|       this.$nextTick(() => { | 
|         // eslint-disable-next-line | 
|         const editor = ace.edit('jsoneditor') | 
|         editor.session.setMode('ace/mode/jsx') | 
|       }) | 
|     }, | 
|     // 生成文件 | 
|     createBaseVue(type) { | 
|       if (!this.moduleNode.table_Id) { | 
|         this.$message.error('请选择模块后再执行保存操作!') | 
|         return | 
|       } | 
|       if (type === 'json') { | 
|         var router = this.widgetFormData.dataOptions.router | 
|         var tableView = this.widgetFormData.dataOptions.tableView | 
|         if (!router || !tableView) { | 
|           this.$message.error('请在表单属性里面填写必填属性') | 
|           return | 
|         } | 
|       } | 
|       var vueData = null | 
|       if (type === 'jsoneditor') { | 
|         // eslint-disable-next-line | 
|         const editor = ace.edit('jsoneditor') | 
|         vueData = editor.getSelectedText() | 
|         type = 'json' | 
|       } | 
|   | 
|       var node = this.vueDataList[this.currentTabId] | 
|       // UI布局参数 | 
|       if (!vueData) { | 
|         this.widgetFormData.dataOptions.table_Id = this.moduleNode.table_Id | 
|         this.widgetFormData.dataOptions.vueData_Id = node.vueData_Id // 节点ID | 
|         vueData = JSON.stringify(this.widgetFormData, null, 2) | 
|       } else { | 
|         this.widgetFormData = JSON.parse(vueData) | 
|       } | 
|       if (!vueData) { | 
|         this.$message.error('没有可保存的数据!') | 
|         return | 
|       } | 
|       // 更新节点数据 | 
|       node.vueData = vueData | 
|       const mainCode = generateMainCode(router) | 
|   | 
|       this.createLoading = true | 
|       var url = '/api/sys/mvcVueData/saveBaseVue' | 
|       var params = { | 
|         designMode: this.designMode, // 设计模式:用户自定义、系统 | 
|         noDataSign: true, // 数据不参与签名 | 
|         table_Id: this.moduleNode.table_Id, | 
|         router: this.widgetFormData.dataOptions.router, | 
|         mainCode: mainCode, | 
|         vueData: vueData, | 
|         vueData_Id: node.vueData_Id, | 
|         vueDataName: node.label, | 
|         fromVueData_Id: node.fromVueData_Id, | 
|         userProduct_Id: node.userProduct_Id, | 
|         type: type // 保存方式:保存、生成 | 
|       } | 
|   | 
|       this.common.ajax( | 
|         url, | 
|         params, | 
|         res => { | 
|           if (res.result) { | 
|             this.$message.success(res.msg) | 
|             this.moduleNode.vueData = vueData // 保存数下拉框中的VueData | 
|             if (this.currentTabId === 0) { | 
|               var node = this.$refs['module-tree'].getCurrentNode() | 
|               node.vueData = vueData | 
|             } | 
|             // tab node | 
|             const tabNode = this.vueDataList[this.currentTabId] | 
|             tabNode.vueData_Id = res.data.vueData_Id | 
|             this.jsonVisible = false | 
|           } else { | 
|             this.$message({ | 
|               showClose: true, | 
|               duration: 6000, | 
|               message: res.msg, | 
|               type: 'error' | 
|             }) | 
|           } | 
|           this.createLoading = false | 
|         }, | 
|         true | 
|       ) | 
|     }, | 
|     // vueData Tab点击切换 | 
|     vueDataClick(tab, event) { | 
|       var item = this.vueDataList[this.currentTabId] | 
|       this.setCurrentVueData(item.vueData) | 
|     }, | 
|     // 设置当前VueData | 
|     setCurrentVueData(vueData) { | 
|       var the = this | 
|       if (vueData) { | 
|         this.widgetFormData = JSON.parse(vueData) | 
|         if (!this.widgetFormData.dataListOptions.fields) { | 
|           this.$set(this.widgetFormData.dataListOptions, 'fields', []) | 
|         } | 
|         this.widgetFormSelect = null // 编辑页面选中项 | 
|         // 设置默认选中项 | 
|         if (this.widgetFormData.dataListOptions.fields.length) { | 
|           this.configType = 'ManagerConfig' // 参数设置组件类型 | 
|           this.widgetFormSelect = this.widgetFormData.dataListOptions.fields[0] // 管理页面选中项 | 
|         } | 
|   | 
|         // 转小写,参数 | 
|         const opts = this.widgetFormData.dataOptions | 
|         opts.codeRegular = this.common.caseStyle(opts.codeRegular) | 
|         opts.idField = this.common.caseStyle(opts.idField) | 
|         opts.linkColumn = this.common.caseStyle(opts.linkColumn) | 
|         // 转小写,列表字段 | 
|         this.widgetFormData.dataListOptions.fields.forEach(item => { | 
|           item.prop = this.common.caseStyle(item.prop) | 
|           if (item.keyProp) { | 
|             item.keyProp = this.common.caseStyle(item.keyProp) | 
|           } | 
|         }) | 
|         // 转小写,按钮名字 | 
|         const changeButtons = buttons => { | 
|           buttons.forEach(item => { | 
|             if (item.type === 'button') { | 
|               item.options.authNode = this.common.caseStyle(item.options.authNode) | 
|             } else if (item.type === 'button-group') { | 
|               changeButtons(item.buttons) | 
|             } | 
|           }) | 
|         } | 
|         changeButtons(this.widgetFormData.dataListOptions.buttons) | 
|   | 
|         // 转小写,编辑字段 | 
|         var _caseStyle = function(array) { | 
|           array.forEach(item => { | 
|             if (item.type === 'grid') { | 
|               item.columns.forEach(colItem => { | 
|                 _caseStyle(colItem.fields) | 
|               }) | 
|             } else if (item.type === 'inline-group') { | 
|               _caseStyle(item.fields) | 
|             } else if (item.type === 'detail-grid') { | 
|               item.options.idField = the.common.caseStyle(item.options.idField) | 
|               changeButtons(item.buttons) | 
|               _caseStyle(item.fields) | 
|             } else { | 
|               // 主表 | 
|               if (item.options) { | 
|                 item.options.prop = the.common.caseStyle(item.options.prop) | 
|                 if (item.options.keyProp) { | 
|                   item.options.keyProp = the.common.caseStyle(item.options.keyProp) | 
|                 } | 
|               } else if (item.prop) { | 
|                 // 明细表 | 
|                 item.prop = the.common.caseStyle(item.prop) | 
|                 if (item.keyProp) { | 
|                   item.keyProp = the.common.caseStyle(item.keyProp) | 
|                 } | 
|               } | 
|             } | 
|           }) | 
|         } | 
|         _caseStyle(this.widgetFormData.editorOptions.fields) | 
|       } else { | 
|         this.reset() | 
|       } | 
|     }, | 
|     // 复制VueData | 
|     copeVueData() { | 
|       this.$prompt('请输入模块别名', '提示', { | 
|         confirmButtonText: '确定', | 
|         cancelButtonText: '取消' | 
|       }) | 
|         .then(({ value }) => { | 
|           if (value) { | 
|             var newVueData = JSON.parse(JSON.stringify(this.vueDataList[this.currentTabId])) | 
|             newVueData.label = value | 
|             newVueData.vueData_Id = -1 // -1表示为新增 | 
|             this.vueDataList.push(newVueData) | 
|           } | 
|         }) | 
|         .catch(() => { | 
|           this.$message({ | 
|             type: 'info', | 
|             message: '取消输入' | 
|           }) | 
|         }) | 
|     }, | 
|     // 删除VueData Item | 
|     vueDataRemove(name) { | 
|       this.$confirm('此操作将永久删除该VueData, 是否继续?', '提示', { | 
|         confirmButtonText: '确定', | 
|         cancelButtonText: '取消', | 
|         type: 'warning' | 
|       }) | 
|         .then(() => { | 
|           var index = parseInt(name) | 
|           var vueDataItem = this.vueDataList[index] | 
|           if (vueDataItem.vueData_Id > 0) { | 
|             var url = '/api/sys/mvcVueData/deleteItem' | 
|             var params = { | 
|               vueData_Id: vueDataItem.vueData_Id | 
|             } | 
|             this.common.ajax(url, params, res => { | 
|               this.common.showMsg(res) | 
|               if (res.result) { | 
|                 this.vueDataList.splice(index, 1) | 
|                 this.$message.success('删除成功!') | 
|               } | 
|             }) | 
|           } else if (vueDataItem.vueData_Id === 0) { | 
|             this.$message.error('主VueData不允许删除!') | 
|           } else { | 
|             this.vueDataList.splice(index, 1) | 
|             this.$message.success('删除成功!') | 
|           } | 
|         }) | 
|         .catch(() => { | 
|           this.$message({ | 
|             type: 'info', | 
|             message: '已取消删除' | 
|           }) | 
|         }) | 
|     }, | 
|     // 修改VueData名称 | 
|     vueDataTabDblClick() { | 
|       var vueDataItem = this.vueDataList[this.currentTabId] | 
|       this.$prompt('请输入模块新名称', '提示', { | 
|         confirmButtonText: '确定', | 
|         cancelButtonText: '取消', | 
|         inputValue: vueDataItem.label | 
|       }) | 
|         .then(({ value }) => { | 
|           if (!value) { | 
|             this.$message.error('名称不能为空!') | 
|             return | 
|           } | 
|           if (vueDataItem.vueData_Id > 0) { | 
|             var url = '/api/sys/mvcVueData/updateTitle' | 
|             var params = { | 
|               vueData_Id: vueDataItem.vueData_Id, | 
|               title: value | 
|             } | 
|             this.common.ajax(url, params, res => { | 
|               this.common.showMsg(res) | 
|               vueDataItem.label = value | 
|             }) | 
|           } else { | 
|             vueDataItem.label = value | 
|           } | 
|         }) | 
|         .catch(() => { | 
|           this.$message({ | 
|             type: 'info', | 
|             message: '取消输入' | 
|           }) | 
|         }) | 
|     } | 
|   } | 
| } | 
| </script> | 
|   | 
| <style lang="scss"> | 
| @import './styles/cover.scss'; | 
| @import './styles/index.scss'; | 
| .content { | 
|   /deep/ .el-tabs__header { | 
|     margin: 0 0 2px; | 
|   } | 
| } | 
| </style> |