lex-xin hace 3 años
padre
commit
6c8732bef5

+ 445 - 445
src/components/VueFormMaking/components/Container.vue

@@ -1,445 +1,445 @@
-<template>
-  <el-container class="fm2-container">
-    <el-main class="fm2-main">
-      <el-container>
-        <el-aside width="250px">
-          <div class="components-list">
-            <template v-if="basicFields.length">
-              <div class="widget-cate">{{ $t('fm.components.basic.title') }}</div>
-              <draggable
-                tag="ul"
-                :list="basicComponents"
-                v-bind="{group:{ name:'people', pull:'clone',put:false},sort:false, ghostClass: 'ghost'}"
-                :move="handleMove"
-                @end="handleMoveEnd"
-                @start="handleMoveStart"
-              >
-                <template v-for="(item, index) in basicComponents">
-                  <li v-if="basicFields.indexOf(item.type)>=0" :key="index" class="form-edit-widget-label" :class="{'no-put': item.type == 'divider'}">
-                    <a>
-                      <i class="icon iconfont" :class="item.icon" />
-                      <span>{{ item.name }}</span>
-                    </a>
-                  </li>
-                </template>
-
-              </draggable>
-            </template>
-
-            <template v-if="advanceFields.length">
-              <div class="widget-cate">{{ $t('fm.components.advance.title') }}</div>
-              <draggable
-                tag="ul"
-                :list="advanceComponents"
-                v-bind="{group:{ name:'people', pull:'clone',put:false},sort:false, ghostClass: 'ghost'}"
-                :move="handleMove"
-                @end="handleMoveEnd"
-                @start="handleMoveStart"
-              >
-                <template v-for="(item, index) in advanceComponents">
-                  <li v-if="advanceFields.indexOf(item.type) >= 0" :key="index" class="form-edit-widget-label" :class="{'no-put': item.type == 'table'}">
-                    <a>
-                      <i class="icon iconfont" :class="item.icon" />
-                      <span>{{ item.name }}</span>
-                    </a>
-                  </li>
-                </template>
-
-              </draggable>
-            </template>
-
-            <template v-if="layoutFields.length">
-              <div class="widget-cate">{{ $t('fm.components.layout.title') }}</div>
-              <draggable
-                tag="ul"
-                :list="layoutComponents"
-                v-bind="{group:{ name:'people', pull:'clone',put:false},sort:false, ghostClass: 'ghost'}"
-                :move="handleMove"
-                @end="handleMoveEnd"
-                @start="handleMoveStart"
-              >
-                <template v-for="(item, index) in layoutComponents">
-                  <li v-if="layoutFields.indexOf(item.type) >=0" :key="index" class="form-edit-widget-label no-put">
-                    <a>
-                      <i class="icon iconfont" :class="item.icon" />
-                      <span>{{ item.name }}</span>
-                    </a>
-                  </li>
-                </template>
-
-              </draggable>
-            </template>
-
-          </div>
-
-        </el-aside>
-        <el-container class="center-container" direction="vertical">
-          <el-header class="btn-bar" style="height: 45px;">
-            <slot name="action" />
-            <el-button v-if="upload" type="text" size="medium" icon="el-icon-upload2" @click="handleUpload">{{ $t('fm.actions.import') }}</el-button>
-            <el-button v-if="clearable" type="text" size="medium" icon="el-icon-delete" @click="handleClear">{{ $t('fm.actions.clear') }}</el-button>
-            <el-button v-if="preview" type="text" size="medium" icon="el-icon-view" @click="handlePreview">{{ $t('fm.actions.preview') }}</el-button>
-            <el-button v-if="generateJson" type="text" size="medium" icon="el-icon-tickets" @click="handleGenerateJson">{{ $t('fm.actions.json') }}</el-button>
-            <el-button v-if="generateCode" type="text" size="medium" icon="el-icon-document" @click="handleGenerateCode">{{ $t('fm.actions.code') }}</el-button>
-          </el-header>
-          <el-main :class="{'widget-empty': widgetForm.list.length == 0}">
-
-            <widget-form v-if="!resetJson" ref="widgetForm" :data="widgetForm" :select.sync="widgetFormSelect" />
-          </el-main>
-        </el-container>
-
-        <el-aside class="widget-config-container" style="width: 305px;">
-          <el-container>
-            <el-header height="45px">
-              <div class="config-tab" style="width: 100%;" :class="{active: configTab=='widget'}" @click="handleConfigSelect('widget')">{{ $t('fm.config.widget.title') }}</div>
-              <!-- <div class="config-tab" :class="{active: configTab=='form'}" @click="handleConfigSelect('form')">{{ $t('fm.config.form.title') }}</div> -->
-            </el-header>
-            <el-main class="config-content">
-              <widget-config v-if="widgetFormSelect!==null" v-show="configTab=='widget'" :form="widgetForm" :data="widgetFormSelect" />
-              <!-- <form-config v-show="configTab=='form'" :data="widgetForm.config" /> -->
-            </el-main>
-          </el-container>
-
-        </el-aside>
-
-        <cus-dialog
-          ref="widgetPreview"
-          :visible="previewVisible"
-          width="1000px"
-          form
-          @on-close="previewVisible = false"
-        >
-          <generate-form
-            v-if="previewVisible"
-            ref="generateForm"
-            insite="true"
-            :data="widgetForm"
-            :value="widgetModels"
-            :remote="remoteFuncs"
-            @on-change="handleDataChange"
-          >
-
-            <template slot-scope="scope">
-              Width <el-input v-model="scope.model.blank.width" style="width: 100px" />
-              Height <el-input v-model="scope.model.blank.height" style="width: 100px" />
-            </template>
-          </generate-form>
-
-          <template slot="action">
-            <el-button type="primary" @click="handleTest">{{ $t('fm.actions.getData') }}</el-button>
-            <el-button @click="handleReset">{{ $t('fm.actions.reset') }}</el-button>
-          </template>
-        </cus-dialog>
-
-        <cus-dialog
-          ref="uploadJson"
-          :visible="uploadVisible"
-          width="800px"
-          form
-          @on-close="uploadVisible = false"
-          @on-submit="handleUploadJson"
-        >
-          <el-alert type="info" :title="$t('fm.description.uploadJsonInfo')" />
-          <div id="uploadeditor" style="height: 400px;width: 100%;">{{ jsonEg }}</div>
-        </cus-dialog>
-
-        <cus-dialog
-          ref="jsonPreview"
-          :visible="jsonVisible"
-          width="800px"
-          form
-          @on-close="jsonVisible = false"
-        >
-
-          <div id="jsoneditor" style="height: 400px;width: 100%;">{{ jsonTemplate }}</div>
-
-          <template slot="action">
-            <el-button type="primary" class="json-btn" :data-clipboard-text="jsonCopyValue">{{ $t('fm.actions.copyData') }}</el-button>
-          </template>
-        </cus-dialog>
-
-        <cus-dialog
-          ref="codePreview"
-          :visible="codeVisible"
-          width="800px"
-          form
-          :action="false"
-          @on-close="codeVisible = false"
-        >
-          <div id="codeeditor" style="height: 500px; width: 100%;">{{ htmlTemplate }}</div>
-        </cus-dialog>
-      </el-container>
-    </el-main>
-    <el-footer height="30px" style="font-weight: 600;">Powered by <a target="_blank" href="http://www.fdevops.com">fdevops</a></el-footer>
-  </el-container>
-
-</template>
-
-<script>
-import Draggable from 'vuedraggable'
-import WidgetConfig from './WidgetConfig'
-// import FormConfig from './FormConfig'
-import WidgetForm from './WidgetForm'
-import CusDialog from './CusDialog'
-import GenerateForm from './GenerateForm'
-import Clipboard from 'clipboard'
-import { basicComponents, layoutComponents, advanceComponents } from './componentsConfig.js'
-import request from '../util/request.js'
-import generateCode from './generateCode.js'
-
-var ace = require('ace-builds/src-noconflict/ace')
-ace.config.set('basePath', '/lib/ace')
-ace.config.set('modePath', '/lib/ace')
-ace.config.set('themePath', '/lib/ace')
-window.define = window.define || ace.define
-window.require = window.require || ace.require
-
-export default {
-  name: 'FmMakingForm',
-  components: {
-    Draggable,
-    WidgetConfig,
-    // FormConfig,
-    WidgetForm,
-    CusDialog,
-    GenerateForm
-  },
-  props: {
-    preview: {
-      type: Boolean,
-      default: false
-    },
-    generateCode: {
-      type: Boolean,
-      default: false
-    },
-    generateJson: {
-      type: Boolean,
-      default: false
-    },
-    upload: {
-      type: Boolean,
-      default: false
-    },
-    clearable: {
-      type: Boolean,
-      default: false
-    },
-    basicFields: {
-      type: Array,
-      default: () => ['input', 'textarea', 'number', 'radio', 'checkbox', 'time', 'date', 'rate', 'color', 'select', 'switch', 'slider', 'text', 'organ', 'school']
-    },
-    advanceFields: {
-      type: Array,
-      default: () => ['blank', 'imgupload', 'editor', 'cascader']
-    },
-    layoutFields: {
-      type: Array,
-      default: () => ['grid', 'divider']
-    }
-  },
-  data() {
-    return {
-      basicComponents,
-      layoutComponents,
-      advanceComponents,
-      resetJson: false,
-      widgetForm: {
-        list: [],
-        config: {
-          labelWidth: 100,
-          labelPosition: 'right',
-          size: 'small'
-        }
-      },
-      configTab: 'widget',
-      widgetFormSelect: null,
-      previewVisible: false,
-      jsonVisible: false,
-      codeVisible: false,
-      uploadVisible: 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) {
-          request.get('http://tools-server.xiaoyaoji.cn/api/uptoken').then(res => {
-            resolve(res.uptoken)
-          })
-        },
-        upload_callback(response, file, fileList) {
-        }
-      },
-      widgetModels: {},
-      blank: '',
-      htmlTemplate: '',
-      jsonTemplate: '',
-      uploadEditor: null,
-      jsonCopyValue: '',
-      jsonClipboard: null,
-      jsonEg: `{
-  "list": [],
-  "config": {
-    "labelWidth": 100,
-    "labelPosition": "top",
-    "size": "small"
-  }
-}`
-    }
-  },
-  watch: {
-    widgetForm: {
-      deep: true,
-      handler: function(val) {
-      }
-    },
-    '$lang': function(val) {
-      this._loadComponents()
-    }
-  },
-  mounted() {
-    this._loadComponents()
-  },
-  methods: {
-    _loadComponents() {
-      this.basicComponents = this.basicComponents.map(item => {
-        return {
-          ...item,
-          name: this.$t(`fm.components.fields.${item.type}`)
-        }
-      })
-      this.advanceComponents = this.advanceComponents.map(item => {
-        return {
-          ...item,
-          name: this.$t(`fm.components.fields.${item.type}`)
-        }
-      })
-      this.layoutComponents = this.layoutComponents.map(item => {
-        return {
-          ...item,
-          name: this.$t(`fm.components.fields.${item.type}`)
-        }
-      })
-    },
-    handleConfigSelect(value) {
-      this.configTab = value
-    },
-    handleMoveEnd(evt) {
-    },
-    handleMoveStart({ oldIndex }) {
-    },
-    handleMove() {
-      return true
-    },
-    handlePreview() {
-      this.previewVisible = true
-    },
-    handleTest() {
-      this.$refs.generateForm.getData().then(data => {
-        this.$alert(data, '').catch(e => {})
-        this.$refs.widgetPreview.end()
-      }).catch(e => {
-        this.$refs.widgetPreview.end()
-      })
-    },
-    handleReset() {
-      this.$refs.generateForm.reset()
-    },
-    handleGenerateJson() {
-      this.jsonVisible = true
-      this.jsonTemplate = this.widgetForm
-      this.$nextTick(() => {
-        const editor = ace.edit('jsoneditor')
-        editor.session.setMode('ace/mode/json')
-
-        if (!this.jsonClipboard) {
-          this.jsonClipboard = new Clipboard('.json-btn')
-          this.jsonClipboard.on('success', (e) => {
-            this.$message.success(this.$t('fm.message.copySuccess'))
-          })
-        }
-        this.jsonCopyValue = JSON.stringify(this.widgetForm)
-      })
-    },
-    handleGenerateCode() {
-      this.codeVisible = true
-      this.htmlTemplate = generateCode(JSON.stringify(this.widgetForm))
-      this.$nextTick(() => {
-        const editor = ace.edit('codeeditor')
-        editor.session.setMode('ace/mode/html')
-      })
-    },
-    handleUpload() {
-      this.uploadVisible = true
-      this.$nextTick(() => {
-        this.uploadEditor = ace.edit('uploadeditor')
-        this.uploadEditor.session.setMode('ace/mode/json')
-      })
-    },
-    handleUploadJson() {
-      try {
-        this.setJSON(JSON.parse(this.uploadEditor.getValue()))
-        this.uploadVisible = false
-      } catch (e) {
-        this.$message.error(e.message)
-        this.$refs.uploadJson.end()
-      }
-    },
-    handleClear() {
-      this.widgetForm = {
-        list: [],
-        config: {
-          labelWidth: 100,
-          labelPosition: 'right',
-          size: 'small',
-          customClass: ''
-        }
-      }
-
-      this.widgetFormSelect = {}
-    },
-    getJSON() {
-      return this.widgetForm
-    },
-    getHtml() {
-      return generateCode(JSON.stringify(this.widgetForm))
-    },
-    setJSON(json) {
-      this.widgetForm = json
-
-      if (json.list.length > 0) {
-        this.widgetFormSelect = json.list[0]
-      }
-    },
-    handleInput(val) {
-      this.blank = val
-    },
-    handleDataChange(field, value, data) {
-    }
-  }
-}
-</script>
-
-<style lang="scss">
-.widget-empty{
-  background-position: 50%;
-}
-
-aside {
-  background: #ffffff;
-  padding: 0;
-  margin-bottom: 0;
-
-  a {
-    color: #333333;
-  }
-}
-</style>
+<template>
+  <el-container class="fm2-container">
+    <el-main class="fm2-main">
+      <el-container>
+        <el-aside width="250px">
+          <div class="components-list">
+            <template v-if="basicFields.length">
+              <div class="widget-cate">{{ $t('fm.components.basic.title') }}</div>
+              <draggable
+                tag="ul"
+                :list="basicComponents"
+                v-bind="{group:{ name:'people', pull:'clone',put:false},sort:false, ghostClass: 'ghost'}"
+                :move="handleMove"
+                @end="handleMoveEnd"
+                @start="handleMoveStart"
+              >
+                <template v-for="(item, index) in basicComponents">
+                  <li v-if="basicFields.indexOf(item.type)>=0" :key="index" class="form-edit-widget-label" :class="{'no-put': item.type == 'divider'}">
+                    <a>
+                      <i class="icon iconfont" :class="item.icon" />
+                      <span>{{ item.name }}</span>
+                    </a>
+                  </li>
+                </template>
+
+              </draggable>
+            </template>
+
+            <template v-if="advanceFields.length">
+              <div class="widget-cate">{{ $t('fm.components.advance.title') }}</div>
+              <draggable
+                tag="ul"
+                :list="advanceComponents"
+                v-bind="{group:{ name:'people', pull:'clone',put:false},sort:false, ghostClass: 'ghost'}"
+                :move="handleMove"
+                @end="handleMoveEnd"
+                @start="handleMoveStart"
+              >
+                <template v-for="(item, index) in advanceComponents">
+                  <li v-if="advanceFields.indexOf(item.type) >= 0" :key="index" class="form-edit-widget-label" :class="{'no-put': item.type == 'table'}">
+                    <a>
+                      <i class="icon iconfont" :class="item.icon" />
+                      <span>{{ item.name }}</span>
+                    </a>
+                  </li>
+                </template>
+
+              </draggable>
+            </template>
+
+            <template v-if="layoutFields.length">
+              <div class="widget-cate">{{ $t('fm.components.layout.title') }}</div>
+              <draggable
+                tag="ul"
+                :list="layoutComponents"
+                v-bind="{group:{ name:'people', pull:'clone',put:false},sort:false, ghostClass: 'ghost'}"
+                :move="handleMove"
+                @end="handleMoveEnd"
+                @start="handleMoveStart"
+              >
+                <template v-for="(item, index) in layoutComponents">
+                  <li v-if="layoutFields.indexOf(item.type) >=0" :key="index" class="form-edit-widget-label no-put">
+                    <a>
+                      <i class="icon iconfont" :class="item.icon" />
+                      <span>{{ item.name }}</span>
+                    </a>
+                  </li>
+                </template>
+
+              </draggable>
+            </template>
+
+          </div>
+
+        </el-aside>
+        <el-container class="center-container" direction="vertical">
+          <el-header class="btn-bar" style="height: 45px;">
+            <slot name="action" />
+            <el-button v-if="upload" type="text" size="medium" icon="el-icon-upload2" @click="handleUpload">{{ $t('fm.actions.import') }}</el-button>
+            <el-button v-if="clearable" type="text" size="medium" icon="el-icon-delete" @click="handleClear">{{ $t('fm.actions.clear') }}</el-button>
+            <el-button v-if="preview" type="text" size="medium" icon="el-icon-view" @click="handlePreview">{{ $t('fm.actions.preview') }}</el-button>
+            <el-button v-if="generateJson" type="text" size="medium" icon="el-icon-tickets" @click="handleGenerateJson">{{ $t('fm.actions.json') }}</el-button>
+            <el-button v-if="generateCode" type="text" size="medium" icon="el-icon-document" @click="handleGenerateCode">{{ $t('fm.actions.code') }}</el-button>
+          </el-header>
+          <el-main :class="{'widget-empty': widgetForm.list.length == 0}">
+
+            <widget-form v-if="!resetJson" ref="widgetForm" :data="widgetForm" :select.sync="widgetFormSelect" />
+          </el-main>
+        </el-container>
+
+        <el-aside class="widget-config-container" style="width: 305px;">
+          <el-container>
+            <el-header height="45px">
+              <div class="config-tab" style="width: 100%;" :class="{active: configTab=='widget'}" @click="handleConfigSelect('widget')">{{ $t('fm.config.widget.title') }}</div>
+              <!-- <div class="config-tab" :class="{active: configTab=='form'}" @click="handleConfigSelect('form')">{{ $t('fm.config.form.title') }}</div> -->
+            </el-header>
+            <el-main class="config-content">
+              <widget-config v-if="widgetFormSelect!==null" v-show="configTab=='widget'" :form="widgetForm" :data="widgetFormSelect" />
+              <!-- <form-config v-show="configTab=='form'" :data="widgetForm.config" /> -->
+            </el-main>
+          </el-container>
+
+        </el-aside>
+
+        <cus-dialog
+          ref="widgetPreview"
+          :visible="previewVisible"
+          width="1000px"
+          form
+          @on-close="previewVisible = false"
+        >
+          <generate-form
+            v-if="previewVisible"
+            ref="generateForm"
+            insite="true"
+            :data="widgetForm"
+            :value="widgetModels"
+            :remote="remoteFuncs"
+            @on-change="handleDataChange"
+          >
+
+            <template slot-scope="scope">
+              Width <el-input v-model="scope.model.blank.width" style="width: 100px" />
+              Height <el-input v-model="scope.model.blank.height" style="width: 100px" />
+            </template>
+          </generate-form>
+
+          <template slot="action">
+            <el-button type="primary" @click="handleTest">{{ $t('fm.actions.getData') }}</el-button>
+            <el-button @click="handleReset">{{ $t('fm.actions.reset') }}</el-button>
+          </template>
+        </cus-dialog>
+
+        <cus-dialog
+          ref="uploadJson"
+          :visible="uploadVisible"
+          width="800px"
+          form
+          @on-close="uploadVisible = false"
+          @on-submit="handleUploadJson"
+        >
+          <el-alert type="info" :title="$t('fm.description.uploadJsonInfo')" />
+          <div id="uploadeditor" style="height: 400px;width: 100%;">{{ jsonEg }}</div>
+        </cus-dialog>
+
+        <cus-dialog
+          ref="jsonPreview"
+          :visible="jsonVisible"
+          width="800px"
+          form
+          @on-close="jsonVisible = false"
+        >
+
+          <div id="jsoneditor" style="height: 400px;width: 100%;">{{ jsonTemplate }}</div>
+
+          <template slot="action">
+            <el-button type="primary" class="json-btn" :data-clipboard-text="jsonCopyValue">{{ $t('fm.actions.copyData') }}</el-button>
+          </template>
+        </cus-dialog>
+
+        <cus-dialog
+          ref="codePreview"
+          :visible="codeVisible"
+          width="800px"
+          form
+          :action="false"
+          @on-close="codeVisible = false"
+        >
+          <div id="codeeditor" style="height: 500px; width: 100%;">{{ htmlTemplate }}</div>
+        </cus-dialog>
+      </el-container>
+    </el-main>
+    <!-- <el-footer height="30px" style="font-weight: 600;">Powered by <a target="_blank" href="http://www.fdevops.com">fdevops</a></el-footer> -->
+  </el-container>
+
+</template>
+
+<script>
+import Draggable from 'vuedraggable'
+import WidgetConfig from './WidgetConfig'
+// import FormConfig from './FormConfig'
+import WidgetForm from './WidgetForm'
+import CusDialog from './CusDialog'
+import GenerateForm from './GenerateForm'
+import Clipboard from 'clipboard'
+import { basicComponents, layoutComponents, advanceComponents } from './componentsConfig.js'
+import request from '../util/request.js'
+import generateCode from './generateCode.js'
+
+var ace = require('ace-builds/src-noconflict/ace')
+ace.config.set('basePath', '/lib/ace')
+ace.config.set('modePath', '/lib/ace')
+ace.config.set('themePath', '/lib/ace')
+window.define = window.define || ace.define
+window.require = window.require || ace.require
+
+export default {
+  name: 'FmMakingForm',
+  components: {
+    Draggable,
+    WidgetConfig,
+    // FormConfig,
+    WidgetForm,
+    CusDialog,
+    GenerateForm
+  },
+  props: {
+    preview: {
+      type: Boolean,
+      default: false
+    },
+    generateCode: {
+      type: Boolean,
+      default: false
+    },
+    generateJson: {
+      type: Boolean,
+      default: false
+    },
+    upload: {
+      type: Boolean,
+      default: false
+    },
+    clearable: {
+      type: Boolean,
+      default: false
+    },
+    basicFields: {
+      type: Array,
+      default: () => ['input', 'textarea', 'number', 'radio', 'checkbox', 'time', 'date', 'rate', 'color', 'select', 'switch', 'slider', 'text', 'organ', 'school']
+    },
+    advanceFields: {
+      type: Array,
+      default: () => ['blank', 'imgupload', 'editor', 'cascader']
+    },
+    layoutFields: {
+      type: Array,
+      default: () => ['grid', 'divider']
+    }
+  },
+  data() {
+    return {
+      basicComponents,
+      layoutComponents,
+      advanceComponents,
+      resetJson: false,
+      widgetForm: {
+        list: [],
+        config: {
+          labelWidth: 100,
+          labelPosition: 'right',
+          size: 'small'
+        }
+      },
+      configTab: 'widget',
+      widgetFormSelect: null,
+      previewVisible: false,
+      jsonVisible: false,
+      codeVisible: false,
+      uploadVisible: 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) {
+          request.get('http://tools-server.xiaoyaoji.cn/api/uptoken').then(res => {
+            resolve(res.uptoken)
+          })
+        },
+        upload_callback(response, file, fileList) {
+        }
+      },
+      widgetModels: {},
+      blank: '',
+      htmlTemplate: '',
+      jsonTemplate: '',
+      uploadEditor: null,
+      jsonCopyValue: '',
+      jsonClipboard: null,
+      jsonEg: `{
+  "list": [],
+  "config": {
+    "labelWidth": 100,
+    "labelPosition": "top",
+    "size": "small"
+  }
+}`
+    }
+  },
+  watch: {
+    widgetForm: {
+      deep: true,
+      handler: function(val) {
+      }
+    },
+    '$lang': function(val) {
+      this._loadComponents()
+    }
+  },
+  mounted() {
+    this._loadComponents()
+  },
+  methods: {
+    _loadComponents() {
+      this.basicComponents = this.basicComponents.map(item => {
+        return {
+          ...item,
+          name: this.$t(`fm.components.fields.${item.type}`)
+        }
+      })
+      this.advanceComponents = this.advanceComponents.map(item => {
+        return {
+          ...item,
+          name: this.$t(`fm.components.fields.${item.type}`)
+        }
+      })
+      this.layoutComponents = this.layoutComponents.map(item => {
+        return {
+          ...item,
+          name: this.$t(`fm.components.fields.${item.type}`)
+        }
+      })
+    },
+    handleConfigSelect(value) {
+      this.configTab = value
+    },
+    handleMoveEnd(evt) {
+    },
+    handleMoveStart({ oldIndex }) {
+    },
+    handleMove() {
+      return true
+    },
+    handlePreview() {
+      this.previewVisible = true
+    },
+    handleTest() {
+      this.$refs.generateForm.getData().then(data => {
+        this.$alert(data, '').catch(e => {})
+        this.$refs.widgetPreview.end()
+      }).catch(e => {
+        this.$refs.widgetPreview.end()
+      })
+    },
+    handleReset() {
+      this.$refs.generateForm.reset()
+    },
+    handleGenerateJson() {
+      this.jsonVisible = true
+      this.jsonTemplate = this.widgetForm
+      this.$nextTick(() => {
+        const editor = ace.edit('jsoneditor')
+        editor.session.setMode('ace/mode/json')
+
+        if (!this.jsonClipboard) {
+          this.jsonClipboard = new Clipboard('.json-btn')
+          this.jsonClipboard.on('success', (e) => {
+            this.$message.success(this.$t('fm.message.copySuccess'))
+          })
+        }
+        this.jsonCopyValue = JSON.stringify(this.widgetForm)
+      })
+    },
+    handleGenerateCode() {
+      this.codeVisible = true
+      this.htmlTemplate = generateCode(JSON.stringify(this.widgetForm))
+      this.$nextTick(() => {
+        const editor = ace.edit('codeeditor')
+        editor.session.setMode('ace/mode/html')
+      })
+    },
+    handleUpload() {
+      this.uploadVisible = true
+      this.$nextTick(() => {
+        this.uploadEditor = ace.edit('uploadeditor')
+        this.uploadEditor.session.setMode('ace/mode/json')
+      })
+    },
+    handleUploadJson() {
+      try {
+        this.setJSON(JSON.parse(this.uploadEditor.getValue()))
+        this.uploadVisible = false
+      } catch (e) {
+        this.$message.error(e.message)
+        this.$refs.uploadJson.end()
+      }
+    },
+    handleClear() {
+      this.widgetForm = {
+        list: [],
+        config: {
+          labelWidth: 100,
+          labelPosition: 'right',
+          size: 'small',
+          customClass: ''
+        }
+      }
+
+      this.widgetFormSelect = {}
+    },
+    getJSON() {
+      return this.widgetForm
+    },
+    getHtml() {
+      return generateCode(JSON.stringify(this.widgetForm))
+    },
+    setJSON(json) {
+      this.widgetForm = json
+
+      if (json.list.length > 0) {
+        this.widgetFormSelect = json.list[0]
+      }
+    },
+    handleInput(val) {
+      this.blank = val
+    },
+    handleDataChange(field, value, data) {
+    }
+  }
+}
+</script>
+
+<style lang="scss">
+.widget-empty{
+  background-position: 50%;
+}
+
+aside {
+  background: #ffffff;
+  padding: 0;
+  margin-bottom: 0;
+
+  a {
+    color: #333333;
+  }
+}
+</style>

+ 13 - 1
src/components/VueFormMaking/components/GenerateForm.vue

@@ -66,6 +66,7 @@
               style="width: 100%"
               :header-cell-style="{ padding: '5px 0' }"
               size="mini"
+              :class="!preview ? 'table-subform' : ''"
             >
               <el-table-column v-if="!preview" fixed width="50">
                 <template slot="header">
@@ -79,6 +80,7 @@
                   <i
                     style="font-size: 25px; color: red"
                     class="el-icon-remove"
+                    v-if="models[item.model].length > 1"
                     @click="delSubformCol(item, scope.$index)"
                   />
                 </template>
@@ -194,6 +196,13 @@ export default {
       let hiddenFormList = this.getSelectValueObject(tempData);
       this.formStatus = hiddenFormList;
       this.relationFormChange();
+
+      // 如果不是预览时,则默认给子表单添加一行数据
+      tempData.forEach(item => {
+        if (item.type === "subform") {
+          this.addSubformCol(item);
+        }
+      });
     } else {
       let tempData = this.templateData
       let hiddenFormList = this.getSelectValueObject(tempData);
@@ -432,5 +441,8 @@ export default {
 </script>
 
 <style lang="scss">
-// @import '../styles/cover.scss';
+.table-subform td .cell {
+  padding-top: 10px;
+  padding-bottom: 15px;
+}
 </style>

+ 1 - 1
src/components/VueFormMaking/components/GenerateFormItem.vue

@@ -446,7 +446,7 @@ export default {
   },
   created() {
     // 判断当前元素是否是分部表单()
-    console.log(this.widget, 'widget subform')
+    // console.log(this.widget, 'widget subform')
     if(this.widget.type == 'organ' && this.preview) {
       let tempStr = null
       this.organList.forEach(item => {

+ 292 - 290
src/components/VueFormMaking/components/WidgetForm.vue

@@ -1,290 +1,292 @@
-<template>
-  <div class="widget-form-container">
-    <div v-if="data.list.length == 0" class="form-empty">{{ $t('fm.description.containerEmpty') }}</div>
-    <el-form :size="data.config.size" label-suffix=":" :label-position="data.config.labelPosition" :label-width="data.config.labelWidth + 'px'">
-
-      <draggable
-        v-model="data.list"
-        class=""
-        v-bind="{group:'people', ghostClass: 'ghost',animation: 200, handle: '.drag-widget'}"
-        @end="handleMoveEnd"
-        @add="handleWidgetAdd"
-      >
-
-        <transition-group name="fade" tag="div" class="widget-form-list">
-          <template v-for="(element, index) in data.list">
-            <!-- 珊格 -->
-            <template v-if="element.type == 'grid'">
-              <el-row
-                v-if="element && element.key"
-                :key="element.key"
-                class="widget-col widget-view"
-                type="flex"
-                :class="{active: selectWidget.key == element.key}"
-                :gutter="element.options.gutter ? element.options.gutter : 0"
-                :justify="element.options.justify"
-                :align="element.options.align"
-                @click.native="handleSelectWidget(index)"
-              >
-                <el-col v-for="(col, colIndex) in element.columns" :key="colIndex" :span="col.span ? col.span : 0">
-
-                  <draggable
-                    v-model="col.list"
-                    :no-transition-on-drag="true"
-                    v-bind="{group:'people', ghostClass: 'ghost',animation: 200, handle: '.drag-widget'}"
-                    @end="handleMoveEnd"
-                    @add="handleWidgetColAdd($event, element, colIndex)"
-                  >
-                    <transition-group name="fade" tag="div" class="widget-col-list">
-                      <template v-for="(el, i) in col.list">
-                        <widget-form-item
-                          v-if="el.key"
-                          :key="el.key"
-                          :element="el"
-                          :select.sync="selectWidget"
-                          :index="i"
-                          :data="col"
-                          :data-config="data"
-                        />
-                      </template>
-
-                    </transition-group>
-
-                  </draggable>
-                </el-col>
-                <div v-if="selectWidget.key == element.key" class="widget-view-action widget-col-action">
-
-                  <i class="iconfont icon-trash" @click.stop="handleWidgetDelete(index)" />
-                </div>
-
-                <div v-if="selectWidget.key == element.key" class="widget-view-drag widget-col-drag">
-                  <i class="iconfont icon-drag drag-widget" />
-                </div>
-              </el-row>
-            </template>
-            <!-- 子表单 -->
-            <template v-else-if="element.type == 'subform'">
-              <el-row
-                v-if="element && element.key"
-                :key="element.key"
-              >
-                <el-form-item
-                  class="widget-col widget-view"
-                  :label-width="element.options.labelWidthStatus?data.config.labelWidth + 'px': '0px'"
-                  :class="{active: selectWidget.key === element.key, 'is_req': element.options.required}"
-                  :label="element.options.labelWidthStatus?element.name:''"
-                  @click.native="handleSelectWidget(index)"
-                >
-                  <div
-                    type="flex"
-                    :class="{active: selectWidget.key == element.key}"
-                    :gutter="element.options.gutter ? element.options.gutter : 0"
-                    :justify="element.options.justify"
-                    :align="element.options.align"
-                  >
-                    <el-col v-for="(col, colIndex) in element.columns" :key="colIndex" :span="col.span ? col.span : 0">
-                      <draggable
-                        v-model="col.list"
-                        :no-transition-on-drag="true"
-                        v-bind="{group:'people', ghostClass: 'ghost',animation: 200, handle: '.drag-widget'}"
-                        @end="handleMoveEnd"
-                        @add="handleWidgetColAdd($event, element, colIndex)"
-                      >
-                        <transition-group
-                          name="fade"
-                          tag="div"
-                          class="widget-col-list"
-                          style="min-height: 131px;overflow-x: auto; white-space: nowrap;"
-                        >
-                          <template v-for="(el, i) in col.list">
-                            <div
-                              v-if="el && el.key"
-                              :key="el.key"
-                              @click="handleSelectWidget(i)"
-                            >
-                              <widget-form-item
-                                :element="el"
-                                :select.sync="selectWidget"
-                                :index="i"
-                                :data="col"
-                                :data-config="data"
-                                :is-label="true"
-                                :is-table="true"
-                              />
-                            </div>
-                          </template>
-                        </transition-group>
-                      </draggable>
-                    </el-col>
-
-                    <div v-if="selectWidget.key == element.key" class="widget-view-action widget-col-action">
-                      <i class="iconfont icon-trash" @click.stop="handleWidgetDelete(index)" />
-                    </div>
-
-                    <div v-if="selectWidget.key == element.key" class="widget-view-drag widget-col-drag">
-                      <i class="iconfont icon-drag drag-widget" />
-                    </div>
-                  </div>
-                </el-form-item>
-              </el-row>
-            </template>
-            <template v-else>
-              <widget-form-item
-                v-if="element && element.key"
-                :key="element.key"
-                :element="element"
-                :select.sync="selectWidget"
-                :index="index"
-                :data-config="data"
-                :data="data"
-              />
-            </template>
-          </template>
-        </transition-group>
-      </draggable>
-    </el-form>
-  </div>
-</template>
-
-<script>
-import Draggable from 'vuedraggable'
-import WidgetFormItem from './WidgetFormItem'
-
-export default {
-  components: {
-    Draggable,
-    WidgetFormItem
-  },
-  /* eslint-disable */
-  props: ['data', 'select'],
-  data() {
-    return {
-      selectWidget: this.select
-    }
-  },
-  watch: {
-    select(val) {
-      this.selectWidget = val
-    },
-    selectWidget: {
-      handler(val) {
-        this.$emit('update:select', val)
-      },
-      deep: true
-    }
-  },
-  mounted() {
-    document.body.ondrop = function(event) {
-      const isFirefox = navigator.userAgent.toLowerCase().indexOf('firefox') > -1
-      if (isFirefox) {
-        event.preventDefault()
-        event.stopPropagation()
-      }
-    }
-  },
-  methods: {
-    handleMoveEnd({ newIndex, oldIndex }) {
-    },
-    handleSelectWidget(index) {
-      this.selectWidget = this.data.list[index]
-    },
-    handleWidgetAdd(evt) {
-      const newIndex = evt.newIndex
-      const to = evt.to
-
-      // 为拖拽到容器的元素添加唯一 key
-      const key = Date.parse(new Date()) + '_' + Math.ceil(Math.random() * 99999)
-      this.$set(this.data.list, newIndex, {
-        ...this.data.list[newIndex],
-        options: {
-          ...this.data.list[newIndex].options,
-          remoteFunc: 'func_' + key
-        },
-        key,
-        // 绑定键值
-        model: this.data.list[newIndex].type + '_' + key,
-        rules: []
-      })
-
-      if (this.data.list[newIndex].type === 'radio' || this.data.list[newIndex].type === 'checkbox' || this.data.list[newIndex].type === 'select') {
-        this.$set(this.data.list, newIndex, {
-          ...this.data.list[newIndex],
-          options: {
-            ...this.data.list[newIndex].options,
-            options: this.data.list[newIndex].options.options.map(item => ({
-              ...item
-            }))
-          }
-        })
-      }
-
-      if (this.data.list[newIndex].type === 'grid' || this.data.list[newIndex].type === 'subform') {
-        this.$set(this.data.list, newIndex, {
-          ...this.data.list[newIndex],
-          columns: this.data.list[newIndex].columns.map(item => ({ ...item }))
-        })
-      }
-
-      this.selectWidget = this.data.list[newIndex]
-    },
-    handleWidgetColAdd($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.list.splice(oldIndex, 0, row.columns[colIndex].list[newIndex])
-
-        row.columns[colIndex].list.splice(newIndex, 1)
-
-        return false
-      }
-
-      const key = Date.parse(new Date()) + '_' + Math.ceil(Math.random() * 99999)
-
-      this.$set(row.columns[colIndex].list, newIndex, {
-        ...row.columns[colIndex].list[newIndex],
-        options: {
-          ...row.columns[colIndex].list[newIndex].options,
-          remoteFunc: 'func_' + key
-        },
-        key,
-        // 绑定键值
-        model: row.columns[colIndex].list[newIndex].type + '_' + key,
-        rules: []
-      })
-
-      if (row.columns[colIndex].list[newIndex].type === 'radio' || row.columns[colIndex].list[newIndex].type === 'checkbox' || row.columns[colIndex].list[newIndex].type === 'select') {
-        this.$set(row.columns[colIndex].list, newIndex, {
-          ...row.columns[colIndex].list[newIndex],
-          options: {
-            ...row.columns[colIndex].list[newIndex].options,
-            options: row.columns[colIndex].list[newIndex].options.options.map(item => ({
-              ...item
-            }))
-          }
-        })
-      }
-
-      this.selectWidget = row.columns[colIndex].list[newIndex]
-    },
-    handleWidgetDelete(index) {
-      if (this.data.list.length - 1 === index) {
-        if (index === 0) {
-          this.selectWidget = {}
-        } else {
-          this.selectWidget = this.data.list[index - 1]
-        }
-      } else {
-        this.selectWidget = this.data.list[index + 1]
-      }
-
-      this.$nextTick(() => {
-        this.data.list.splice(index, 1)
-      })
-    }
-  }
-}
-</script>
+<template>
+  <div class="widget-form-container">
+    <div v-if="data.list.length == 0" class="form-empty">{{ $t('fm.description.containerEmpty') }}</div>
+    <el-form :size="data.config.size" label-suffix=":" :label-position="data.config.labelPosition" :label-width="data.config.labelWidth + 'px'">
+
+      <draggable
+        v-model="data.list"
+        class=""
+        v-bind="{group:'people', ghostClass: 'ghost',animation: 200, handle: '.drag-widget'}"
+        @end="handleMoveEnd"
+        @add="handleWidgetAdd"
+      >
+
+        <transition-group name="fade" tag="div" class="widget-form-list">
+          <template v-for="(element, index) in data.list">
+            <!-- 珊格 -->
+            <template v-if="element.type == 'grid'">
+              <el-row
+                v-if="element && element.key"
+                :key="element.key"
+                class="widget-col widget-view"
+                type="flex"
+                :class="{active: selectWidget.key == element.key}"
+                :gutter="element.options.gutter ? element.options.gutter : 0"
+                :justify="element.options.justify"
+                :align="element.options.align"
+                @click.native="handleSelectWidget(index)"
+              >
+                <el-col v-for="(col, colIndex) in element.columns" :key="colIndex" :span="col.span ? col.span : 0">
+
+                  <draggable
+                    v-model="col.list"
+                    :no-transition-on-drag="true"
+                    v-bind="{group:'people', ghostClass: 'ghost',animation: 200, handle: '.drag-widget'}"
+                    @end="handleMoveEnd"
+                    @add="handleWidgetColAdd($event, element, colIndex)"
+                  >
+                    <transition-group name="fade" tag="div" class="widget-col-list">
+                      <template v-for="(el, i) in col.list">
+                        <widget-form-item
+                          v-if="el.key"
+                          :key="el.key"
+                          :element="el"
+                          :select.sync="selectWidget"
+                          :index="i"
+                          :data="col"
+                          :data-config="data"
+                        />
+                      </template>
+
+                    </transition-group>
+
+                  </draggable>
+                </el-col>
+                <div v-if="selectWidget.key == element.key" class="widget-view-action widget-col-action">
+
+                  <i class="iconfont icon-trash" @click.stop="handleWidgetDelete(index)" />
+                </div>
+
+                <div v-if="selectWidget.key == element.key" class="widget-view-drag widget-col-drag">
+                  <i class="iconfont icon-drag drag-widget" />
+                </div>
+              </el-row>
+            </template>
+            <!-- 子表单 -->
+            <template v-else-if="element.type == 'subform'">
+              <el-row
+                v-if="element && element.key"
+                :key="element.key"
+              >
+                <el-form-item
+                  class="widget-col widget-view"
+                  :label-width="element.options.labelWidthStatus?data.config.labelWidth + 'px': '0px'"
+                  :class="{active: selectWidget.key === element.key, 'is_req': element.options.required}"
+                  :label="element.options.labelWidthStatus?element.name:''"
+                  @click.native="handleSelectWidget(index)"
+                >
+                  <div
+                    type="flex"
+                    :class="{active: selectWidget.key == element.key}"
+                    :gutter="element.options.gutter ? element.options.gutter : 0"
+                    :justify="element.options.justify"
+                    :align="element.options.align"
+                  >
+                    <el-col v-for="(col, colIndex) in element.columns" :key="colIndex" :span="col.span ? col.span : 0">
+                      <draggable
+                        v-model="col.list"
+                        :no-transition-on-drag="true"
+                        v-bind="{group:'people', ghostClass: 'ghost',animation: 200, handle: '.drag-widget'}"
+                        @end="handleMoveEnd"
+                        @add="handleWidgetColAdd($event, element, colIndex)"
+                      >
+                        <transition-group
+                          name="fade"
+                          tag="div"
+                          class="widget-col-list"
+                          style="min-height: 131px;overflow-x: auto; white-space: nowrap;"
+                        >
+                          <template v-for="(el, i) in col.list">
+                            <div
+                              v-if="el && el.key"
+                              :key="el.key"
+                              @click="handleSelectWidget(i)"
+                            >
+                              <widget-form-item
+                                :element="el"
+                                :select.sync="selectWidget"
+                                :index="i"
+                                :data="col"
+                                :data-config="data"
+                                :is-label="true"
+                                :is-table="true"
+                              />
+                            </div>
+                          </template>
+                        </transition-group>
+                      </draggable>
+                    </el-col>
+
+                    <div v-if="selectWidget.key == element.key" class="widget-view-action widget-col-action">
+                      <i class="iconfont icon-trash" @click.stop="handleWidgetDelete(index)" />
+                    </div>
+
+                    <div v-if="selectWidget.key == element.key" class="widget-view-drag widget-col-drag">
+                      <i class="iconfont icon-drag drag-widget" />
+                    </div>
+                  </div>
+                </el-form-item>
+              </el-row>
+            </template>
+            <template v-else>
+              <widget-form-item
+                v-if="element && element.key"
+                :key="element.key"
+                :element="element"
+                :select.sync="selectWidget"
+                :index="index"
+                :data-config="data"
+                :data="data"
+              />
+            </template>
+          </template>
+        </transition-group>
+      </draggable>
+    </el-form>
+  </div>
+</template>
+
+<script>
+import Draggable from 'vuedraggable'
+import WidgetFormItem from './WidgetFormItem'
+
+export default {
+  components: {
+    Draggable,
+    WidgetFormItem
+  },
+  /* eslint-disable */
+  props: ['data', 'select'],
+  data() {
+    return {
+      selectWidget: this.select
+    }
+  },
+  watch: {
+    select(val) {
+      this.selectWidget = val
+    },
+    selectWidget: {
+      handler(val) {
+        this.$emit('update:select', val)
+      },
+      deep: true
+    }
+  },
+  mounted() {
+    document.body.ondrop = function(event) {
+      const isFirefox = navigator.userAgent.toLowerCase().indexOf('firefox') > -1
+      if (isFirefox) {
+        event.preventDefault()
+        event.stopPropagation()
+      }
+    }
+
+    console.log(this.data.list)
+  },
+  methods: {
+    handleMoveEnd({ newIndex, oldIndex }) {
+    },
+    handleSelectWidget(index) {
+      this.selectWidget = this.data.list[index]
+    },
+    handleWidgetAdd(evt) {
+      const newIndex = evt.newIndex
+      const to = evt.to
+
+      // 为拖拽到容器的元素添加唯一 key
+      const key = Date.parse(new Date()) + '_' + Math.ceil(Math.random() * 99999)
+      this.$set(this.data.list, newIndex, {
+        ...this.data.list[newIndex],
+        options: {
+          ...this.data.list[newIndex].options,
+          remoteFunc: 'func_' + key
+        },
+        key,
+        // 绑定键值
+        model: this.data.list[newIndex].type + '_' + key,
+        rules: []
+      })
+
+      if (this.data.list[newIndex].type === 'radio' || this.data.list[newIndex].type === 'checkbox' || this.data.list[newIndex].type === 'select') {
+        this.$set(this.data.list, newIndex, {
+          ...this.data.list[newIndex],
+          options: {
+            ...this.data.list[newIndex].options,
+            options: this.data.list[newIndex].options.options.map(item => ({
+              ...item
+            }))
+          }
+        })
+      }
+
+      if (this.data.list[newIndex].type === 'grid' || this.data.list[newIndex].type === 'subform') {
+        this.$set(this.data.list, newIndex, {
+          ...this.data.list[newIndex],
+          columns: this.data.list[newIndex].columns.map(item => ({ ...item }))
+        })
+      }
+
+      this.selectWidget = this.data.list[newIndex]
+    },
+    handleWidgetColAdd($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.list.splice(oldIndex, 0, row.columns[colIndex].list[newIndex])
+
+        row.columns[colIndex].list.splice(newIndex, 1)
+
+        return false
+      }
+
+      const key = Date.parse(new Date()) + '_' + Math.ceil(Math.random() * 99999)
+
+      this.$set(row.columns[colIndex].list, newIndex, {
+        ...row.columns[colIndex].list[newIndex],
+        options: {
+          ...row.columns[colIndex].list[newIndex].options,
+          remoteFunc: 'func_' + key
+        },
+        key,
+        // 绑定键值
+        model: row.columns[colIndex].list[newIndex].type + '_' + key,
+        rules: []
+      })
+
+      if (row.columns[colIndex].list[newIndex].type === 'radio' || row.columns[colIndex].list[newIndex].type === 'checkbox' || row.columns[colIndex].list[newIndex].type === 'select') {
+        this.$set(row.columns[colIndex].list, newIndex, {
+          ...row.columns[colIndex].list[newIndex],
+          options: {
+            ...row.columns[colIndex].list[newIndex].options,
+            options: row.columns[colIndex].list[newIndex].options.options.map(item => ({
+              ...item
+            }))
+          }
+        })
+      }
+
+      this.selectWidget = row.columns[colIndex].list[newIndex]
+    },
+    handleWidgetDelete(index) {
+      if (this.data.list.length - 1 === index) {
+        if (index === 0) {
+          this.selectWidget = {}
+        } else {
+          this.selectWidget = this.data.list[index - 1]
+        }
+      } else {
+        this.selectWidget = this.data.list[index + 1]
+      }
+
+      this.$nextTick(() => {
+        this.data.list.splice(index, 1)
+      })
+    }
+  }
+}
+</script>