| <template> | 
|   <div class="widget-form-container"> | 
|     <el-form :label-position="data.config.labelPosition" :inline="data.config.formInline" :style="{width:(data.config.formWidth || 'auto')}"> | 
|   | 
|       <draggable v-model="data.fields" :options="{group:'people', ghostClass: 'ghost'}" class="widget-form-list form-region" @end="handleMoveEnd" @add="handleWidgetAdd"> | 
|   | 
|         <template v-for="(element, index) in data.fields"> | 
|           <template v-if="element.type === 'grid'"> | 
|             <div v-if="element && element.key" :key="element.key" class="widget-grid-container data-grid" style="position: relative;"> | 
|               <el-row :justify="element.options.justify" :align="element.options.align" :class="{active: selectWidget && selectWidget.key === element.key}" :gutter="element.options.gutter ? element.options.gutter : 0" class="widget-grid" type="flex" @click.native="handleSelectWidget(index)"> | 
|                 <el-col v-for="(col, colIndex) in element.columns" :key="colIndex" :span="col.span ? col.span : 0"> | 
|                   <div style="border: 1px dashed #999;"> | 
|                     <draggable v-model="col.fields" :options="{group:'people', ghostClass: 'ghost'}" class="widget-form-list grid-list" filter="widget-grid-container" @end="handleMoveEnd" @add="handleWidgetColAdd($event, element, colIndex)"> | 
|                       <widget-form-item v-for="(el, i) in col.fields" v-if="el.key" :key="el.key" :element="el" :select.sync="selectWidget" :config-type.sync="currentConfigType" :index="i" :fields="col.fields"></widget-form-item> | 
|                     </draggable> | 
|                   </div> | 
|                 </el-col> | 
|               </el-row> | 
|               <el-button v-if="selectWidget && selectWidget.key === element.key" title="删除" style="bottom: -20px;" circle plain type="danger" class="widget-action-delete" @click.stop="handleWidgetDelete(index)"> | 
|                 <i class="el-icon-yrt-shanchu2"></i> | 
|               </el-button> | 
|             </div> | 
|           </template> | 
|           <template v-else-if="element.type === 'splitter-group'"> | 
|             <div v-if="element && element.key" :key="element.key" class="widget-grid-container splitter-group" style="position: relative;"> | 
|               <div :class="{active: selectWidget && selectWidget.key === element.key}" class="widget-grid" @click="handleSelectWidget(index)"> | 
|                 <div style="border: 1px dashed #999;"> | 
|                   <div class="splitter-title"> | 
|                     {{ element.label }} | 
|                   </div> | 
|                 </div> | 
|               </div> | 
|               <el-button v-if="selectWidget && selectWidget.key === element.key" title="删除" style="bottom: -20px;" class="widget-action-delete" circle plain type="danger" @click.stop="handleWidgetDelete(index)"> | 
|                 <i class="el-icon-yrt-shanchu2"></i> | 
|               </el-button> | 
|             </div> | 
|           </template> | 
|           <template v-else> | 
|             <widget-form-item v-if="element && element.key" :key="element.key" :element="element" :select.sync="selectWidget" :config-type.sync="currentConfigType" :index="index" :fields="data.fields"></widget-form-item> | 
|           </template> | 
|         </template> | 
|   | 
|       </draggable> | 
|     </el-form> | 
|   </div> | 
| </template> | 
|   | 
| <script> | 
| import Draggable from 'vuedraggable' | 
| import WidgetFormItem from './WidgetFormItem' | 
| import WidgetFormItemInline from './WidgetFormItemInline' | 
|   | 
| export default { | 
|   components: { | 
|     Draggable, | 
|     WidgetFormItem, | 
|     WidgetFormItemInline | 
|   }, | 
|   props: { | 
|     data: { | 
|       type: Object, | 
|       default: () => { | 
|         return {} | 
|       } | 
|     }, | 
|     select: { | 
|       type: Object, | 
|       default: () => { | 
|         return {} | 
|       } | 
|     }, | 
|     configType: { | 
|       type: String, | 
|       default: null | 
|     }, | 
|     detailFields: { | 
|       type: Array, | 
|       default: () => { | 
|         return [] | 
|       } | 
|     } | 
|   }, | 
|   data() { | 
|     return { | 
|       selectWidget: this.select | 
|     } | 
|   }, | 
|   computed: { | 
|     currentConfigType: { | 
|       get: function() { | 
|         return this.configType | 
|       }, | 
|       set: function(val) { | 
|         this.$emit('update:configType', val) | 
|       } | 
|     }, | 
|     // 当前选中明细列表 | 
|     currentDetailFields: { | 
|       get: function() { | 
|         return this.detailFields | 
|       }, | 
|       set: function(val) { | 
|         this.$emit('update:detailFields', val) | 
|       } | 
|     } | 
|   }, | 
|   watch: { | 
|     select(val) { | 
|       this.selectWidget = val | 
|     }, | 
|     selectWidget: { | 
|       handler(val) { | 
|         this.$emit('update:select', val) | 
|       }, | 
|       deep: true | 
|     } | 
|   }, | 
|   methods: { | 
|     handleMoveEnd({ newIndex, oldIndex }) { | 
|       // console.log('index', newIndex, oldIndex) | 
|     }, | 
|     handleMoveStart({ oldIndex }) { | 
|       // console.log("start", oldIndex, this.basicComponents); | 
|     }, | 
|     handleSelectWidget(index) { | 
|       // console.log(index, '#####') | 
|       this.selectWidget = this.data.fields[index] | 
|       this.currentConfigType = 'WidgetConfig' | 
|     }, | 
|     handleWidgetAdd(evt) { | 
|       const newIndex = evt.newIndex | 
|       // console.log(to) | 
|   | 
|       // 为拖拽到容器的元素添加唯一 key | 
|       const key = Date.parse(new Date()) + '_' + Math.ceil(Math.random() * 99999) | 
|       this.$set(this.data.fields, newIndex, { | 
|         ...this.data.fields[newIndex], | 
|         options: { | 
|           ...this.data.fields[newIndex].options, | 
|           remoteFunc: 'func_' + key | 
|         }, | 
|         key, | 
|         rules: [] | 
|       }) | 
|       delete this.data.fields[newIndex].icon | 
|   | 
|       if (this.data.fields[newIndex].type === 'radio' || this.data.fields[newIndex].type === 'checkbox') { | 
|         this.$set(this.data.fields, newIndex, { | 
|           ...this.data.fields[newIndex], | 
|           options: { | 
|             ...this.data.fields[newIndex].options, | 
|             options: this.data.fields[newIndex].options.options.map(item => ({ | 
|               ...item | 
|             })) | 
|           } | 
|         }) | 
|       } else if (this.data.fields[newIndex].type === 'detail-grid') { | 
|         this.data.fields[newIndex].subTableView = null // 关联子表 | 
|         this.$set(this.data.fields[newIndex], 'buttons', [ | 
|           { | 
|             type: 'button-group', | 
|             label: '按钮组', | 
|             buttons: [ | 
|               { | 
|                 type: 'button', | 
|                 label: '新建', | 
|                 options: { | 
|                   icon: 'el-icon-plus', | 
|                   type: 'primary', | 
|                   authNode: 'add' | 
|                 }, | 
|                 key: 'detail_add' | 
|               }, | 
|               { | 
|                 type: 'button', | 
|                 label: '删除', | 
|                 options: { | 
|                   icon: 'el-icon-yrt-shanchu2', | 
|                   type: 'primary', | 
|                   authNode: 'delete' | 
|                 }, | 
|                 key: 'detail_delete' | 
|               } | 
|             ], | 
|             options: { | 
|               icon: 'el-icon-yrt-anniuzu' | 
|             } | 
|           } | 
|         ]) | 
|   | 
|         // delete this.data.fields[newIndex].options; | 
|         delete this.data.fields[newIndex].rules | 
|       } else if (this.data.fields[newIndex].type === 'grid') { | 
|         this.$set(this.data.fields, newIndex, { | 
|           ...this.data.fields[newIndex], | 
|           columns: this.data.fields[newIndex].columns.map(item => ({ ...item })) | 
|         }) | 
|         delete this.data.fields[newIndex].rules | 
|       } | 
|   | 
|       this.currentConfigType = 'WidgetConfig' | 
|       this.selectWidget = this.data.fields[newIndex] | 
|     }, | 
|     handleWidgetColAdd($event, row, colIndex) { | 
|       // console.log('coladd', $event, row, colIndex) | 
|       const newIndex = $event.newIndex | 
|       const oldIndex = $event.oldIndex | 
|       const item = $event.item | 
|   | 
|       // 防止布局元素的嵌套拖拽 | 
|       if (item.className.indexOf('data-grid') >= 0) { | 
|         // 如果是列表中拖拽的元素需要还原到原来位置 | 
|         item.tagName === 'DIV' && this.data.fields.splice(oldIndex, 0, row.columns[colIndex].fields[newIndex]) | 
|   | 
|         row.columns[colIndex].fields.splice(newIndex, 1) | 
|   | 
|         return false | 
|       } | 
|   | 
|       // console.log('from', item) | 
|   | 
|       const key = Date.parse(new Date()) + '_' + Math.ceil(Math.random() * 99999) | 
|   | 
|       this.$set(row.columns[colIndex].fields, newIndex, { | 
|         ...row.columns[colIndex].fields[newIndex], | 
|         options: { | 
|           ...row.columns[colIndex].fields[newIndex].options, | 
|           remoteFunc: 'func_' + key | 
|         }, | 
|         key, | 
|         // 绑定键值 | 
|         model: row.columns[colIndex].fields[newIndex].type + '_' + key, | 
|         rules: [] | 
|       }) | 
|   | 
|       if (row.columns[colIndex].fields[newIndex].type === 'radio' || row.columns[colIndex].fields[newIndex].type === 'checkbox') { | 
|         this.$set(row.columns[colIndex].fields, newIndex, { | 
|           ...row.columns[colIndex].fields[newIndex], | 
|           options: { | 
|             ...row.columns[colIndex].fields[newIndex].options, | 
|             options: row.columns[colIndex].fields[newIndex].options.options.map(item => ({ | 
|               ...item | 
|             })) | 
|           } | 
|         }) | 
|       } | 
|       delete row.columns[colIndex].fields[newIndex].icon | 
|   | 
|       this.currentConfigType = 'WidgetConfig' | 
|       this.selectWidget = row.columns[colIndex].fields[newIndex] | 
|     }, | 
|     handleWidgetDelete(index) { | 
|       if (this.data.fields.length - 1 === index) { | 
|         if (index === 0) { | 
|           this.selectWidget = {} | 
|         } else { | 
|           this.selectWidget = this.data.fields[index - 1] | 
|         } | 
|       } else { | 
|         this.selectWidget = this.data.fields[index + 1] | 
|       } | 
|   | 
|       this.$nextTick(() => { | 
|         this.data.fields.splice(index, 1) | 
|       }) | 
|     }, | 
|     // 行内布局 | 
|     handleWidgetInlineAdd($event, row) { | 
|       // console.log('coladd', $event, row, colIndex) | 
|       const newIndex = $event.newIndex | 
|       const oldIndex = $event.oldIndex | 
|       const item = $event.item | 
|   | 
|       // 防止布局元素的嵌套拖拽 | 
|       if (item.className.indexOf('inline-group') >= 0) { | 
|         // 如果是列表中拖拽的元素需要还原到原来位置 | 
|         item.tagName === 'DIV' && this.data.fields.splice(oldIndex, 0, row.fields[newIndex]) | 
|   | 
|         row.fields.splice(newIndex, 1) | 
|   | 
|         return false | 
|       } | 
|   | 
|       // console.log('from', item) | 
|   | 
|       const key = Date.parse(new Date()) + '_' + Math.ceil(Math.random() * 99999) | 
|   | 
|       this.$set(row.fields, newIndex, { | 
|         ...row.fields[newIndex], | 
|         options: { | 
|           ...row.fields[newIndex].options | 
|         }, | 
|         key, | 
|         rules: [] | 
|       }) | 
|   | 
|       if (row.fields[newIndex].type === 'radio' || row.fields[newIndex].type === 'checkbox') { | 
|         this.$set(row.fields, newIndex, { | 
|           ...row.fields[newIndex], | 
|           options: { | 
|             ...row.fields[newIndex].options, | 
|             options: row.fields[newIndex].options.options.map(item => ({ | 
|               ...item | 
|             })) | 
|           } | 
|         }) | 
|       } | 
|       delete row.fields[newIndex].icon | 
|   | 
|       this.currentConfigType = 'WidgetConfig' | 
|       this.selectWidget = row.fields[newIndex] | 
|     }, | 
|     // 明细布局 | 
|     handleWidgetDetailAdd($event, row) { | 
|       // console.log('coladd', $event, row, colIndex) | 
|       const newIndex = $event.newIndex | 
|       const oldIndex = $event.oldIndex | 
|       const item = $event.item | 
|   | 
|       // 防止布局元素的嵌套拖拽 | 
|       if (item.className.indexOf('detail-grid') >= 0) { | 
|         // 如果是列表中拖拽的元素需要还原到原来位置 | 
|         item.tagName === 'DIV' && this.data.fields.splice(oldIndex, 0, row.fields[newIndex]) | 
|   | 
|         row.fields.splice(newIndex, 1) | 
|   | 
|         return false | 
|       } | 
|   | 
|       const key = Date.parse(new Date()) + '_' + Math.ceil(Math.random() * 99999) | 
|   | 
|       var field = row.fields[newIndex] | 
|       this.$set(row.fields, newIndex, { | 
|         prop: field.options.prop, | 
|         label: field.label, | 
|         dataType: field.options.dataType, | 
|         sortable: false, | 
|         hidden: false, | 
|         isQuickSearch: false, | 
|         key, | 
|         headerAlign: 'center', | 
|         align: 'left' | 
|       }) | 
|   | 
|       if (row.fields[newIndex].type === 'radio' || row.fields[newIndex].type === 'checkbox') { | 
|         this.$set(row.fields, newIndex, { | 
|           ...row.fields[newIndex], | 
|           options: { | 
|             ...row.fields[newIndex].options, | 
|             options: row.fields[newIndex].options.options.map(item => ({ | 
|               ...item | 
|             })) | 
|           } | 
|         }) | 
|       } | 
|       delete row.fields[newIndex].icon | 
|   | 
|       this.currentConfigType = 'ManagerConfig' | 
|       this.selectWidget = row.fields[newIndex] | 
|     }, | 
|     // 显示明细字段列表 | 
|     showDetailField() { | 
|       if (!this.selectWidget.subTableView) { | 
|         this.$message.warning('请设置关联子表名称') | 
|         return | 
|       } | 
|       this.loadModuleFields() | 
|     }, | 
|     // 加载模块字段 | 
|     loadModuleFields() { | 
|       var the = this | 
|       var where = "TableView='" + this.selectWidget.subTableView + "'" | 
|       debugger | 
|       var url = '/api/common/loadDataList' | 
|       var params = { | 
|         projectName: 'Rattan.Sys', | 
|         tableView: 'Sys_MvcTableColumn', | 
|         idField: 'ColumnID', | 
|         idValue: 0, | 
|         menu_Id: 6, | 
|         pageIndex: 1, | 
|         pageSize: 1000, | 
|         total: 0, | 
|         where: where, | 
|         SortName: 'OrderNo DESC, ColumnID' | 
|       } | 
|   | 
|       the.common.ajax( | 
|         url, | 
|         params, | 
|         res => { | 
|           if (res.result) { | 
|             var fields = res.data.rows.map((item, index, arr) => { | 
|               var field = { | 
|                 type: 'input', | 
|                 label: item.ColumnComment, | 
|                 icon: 'el-icon-yrt-danhangshurukuang', | 
|                 options: { | 
|                   prop: item.ColumnName, | 
|                   width: '100%', | 
|                   noLabel: false, | 
|                   defaultValue: '', | 
|                   required: false, | 
|                   dataType: item.DataType.toLowerCase(), | 
|                   pattern: '', | 
|                   placeholder: '' | 
|                 } | 
|               } | 
|               return field | 
|             }) | 
|             the.currentDetailFields = fields | 
|             // 找到明细主键 | 
|             var keyField = res.data.rows.find(item => { | 
|               return item.FieldAttribute === 'Key' | 
|             }) | 
|             if (keyField) { | 
|               this.$set(this.selectWidget.options, 'idField', keyField.ColumnName) | 
|             } | 
|           } else { | 
|             the.$message({ | 
|               showClose: true, | 
|               duration: 6000, | 
|               message: res.Msg, | 
|               type: 'error' | 
|             }) | 
|           } | 
|         }, | 
|         true | 
|       ) | 
|     }, | 
|     // 下来选择器参数 | 
|     selectOptions(newField, dropdown_Id, keyProp) { | 
|       const randNum = Math.ceil(Math.random() * 99999) | 
|       const key = Date.parse(new Date()) + '_' + randNum | 
|       const params = { | 
|         type: 'select', | 
|         label: newField.label, | 
|         options: { | 
|           width: '280px', | 
|           defaultValue: '', | 
|           multiple: false, | 
|           disabled: false, | 
|           clearable: false, | 
|           placeholder: '', | 
|           required: false, | 
|           showLabel: true, | 
|           noLabel: false, | 
|           options: [ | 
|             { | 
|               value: '下拉框1' | 
|             }, | 
|             { | 
|               value: '下拉框2' | 
|             }, | 
|             { | 
|               value: '下拉框3' | 
|             } | 
|           ], | 
|           remote: 'bindDropdown', | 
|           remoteOptions: [], | 
|           dropdown_Id: dropdown_Id, | 
|           props: { | 
|             value: 'value', | 
|             label: 'label' | 
|           }, | 
|           remoteFunc: '', | 
|           prop: newField.options.prop, | 
|           dataType: newField.options.dataType | 
|         }, | 
|         key: key | 
|       } | 
|       if (keyProp) { | 
|         params.options.keyProp = keyProp | 
|       } | 
|       return params | 
|     }, | 
|     // 向fields集合中添加字段 | 
|     addField(fields, field, width) { | 
|       const newIndex = fields.length | 
|       // 为拖拽到容器的元素添加唯一 key | 
|       const randNum = Math.ceil(Math.random() * 99999) | 
|       const key = Date.parse(new Date()) + '_' + randNum | 
|       this.$set(fields, newIndex, { | 
|         ...field, | 
|         options: { | 
|           ...field.options, | 
|           remoteFunc: 'func_' + key | 
|         }, | 
|         key, | 
|         rules: [] | 
|       }) | 
|   | 
|       var newField = fields[newIndex] | 
|       switch (newField.options.dataType) { | 
|         case 'datetime': | 
|           newField.type = 'date' | 
|           break | 
|       } | 
|       switch (newField.options.prop) { | 
|         case 'Enable': | 
|           fields[newIndex] = { | 
|             type: 'switch', | 
|             label: newField.label, | 
|             options: { | 
|               defaultValue: false, | 
|               required: false, | 
|               disabled: false, | 
|               noLabel: false, | 
|               prop: newField.options.label, | 
|               dataType: newField.options.dataType, | 
|               'active-value': 1, | 
|               'inactive-value': 0 | 
|             }, | 
|             key: key | 
|           } | 
|           break | 
|         case 'UserTrueName': | 
|           fields[newIndex] = this.selectOptions(newField, 22, 'User_Id') | 
|           break | 
|         case 'ConsignorName': | 
|           fields[newIndex] = this.selectOptions(newField, 797, 'Consignor_Id') | 
|           break | 
|         case 'StorageName': | 
|           fields[newIndex] = this.selectOptions(newField, 31, 'Storage_Id') | 
|           break | 
|         case 'ExpressCorpName': | 
|           fields[newIndex] = this.selectOptions(newField, 568, 'ExpressCorp_Id') | 
|           break | 
|         case 'ExpressCorpType': | 
|           fields[newIndex] = this.selectOptions(newField, 502, null) | 
|           break | 
|         case 'Creator': | 
|         case 'CreateDate': | 
|         case 'Modifier': | 
|         case 'ModifyDate': | 
|           newField.options.readonly = true | 
|           break | 
|         case 'Remark': | 
|           fields[newIndex].type = 'textarea' | 
|           fields[newIndex].options.width = '420px' | 
|           break | 
|       } | 
|       if (fields[newIndex].type !== 'switch') { | 
|         fields[newIndex].options.width = width || '100%' | 
|       } | 
|       delete fields[newIndex].icon | 
|     } | 
|   } | 
| } | 
| </script> |