瀏覽代碼

数据更新

dumingliang 1 天之前
父節點
當前提交
bf6a8cc402

+ 1 - 1
gw-admin/src/main/resources/application-druid.yml

@@ -1,7 +1,7 @@
 # 项目相关配置
 goldenwater:
   # 名称
-  name: GW
+  name: 太湖局水利工程项目管理系统
   # 版本
   version: 3.9.2
   # 版权年份

+ 2 - 2
gw-admin/src/main/resources/application-test.yml

@@ -1,7 +1,7 @@
 # 项目相关配置
 goldenwater:
   # 名称
-  name: GW
+  name: 太湖局水利工程项目管理系统
   # 版本
   version: 3.9.2
   # 版权年份
@@ -96,7 +96,7 @@ spring:
       # 端口,默认为6379
       port: 6379
       # 数据库索引
-      database: 15
+      database: 14
       # 密码
       password: ZjsthGw1125
       # 连接超时时间

+ 41 - 41
gw-ui/src/views/index.vue

@@ -1,46 +1,46 @@
 <template>
   <div class="app-container home">
-    <!-- 太浦闸 -->
-    <div class="section-header">
-      <svg-icon icon-class="monitor" class="section-icon" />
-      <span class="section-title">太浦闸</span>
-      <span class="section-line"></span>
-      <el-button link type="primary" icon="Plus" @click="openAdd('tpz')">添加模块</el-button>
-    </div>
-    <el-card class="home-card" shadow="never">
-      <el-row :gutter="12">
-        <el-col :xs="12" :sm="8" :md="6" :lg="4" :xl="3" v-for="(item, index) in tpzItems" :key="item.id">
-          <div class="card-item" @click="goToPage('/more/tpz?folderId=' + item.id)">
-            <span class="card-index">{{ index + 1 }}</span>
-            <span class="card-text" :title="item.name">{{ item.name }}</span>
-          </div>
-        </el-col>
-        <el-col :xs="12" :sm="8" :md="6" :lg="4" :xl="3" v-if="!loadingTpz && tpzItems.length === 0">
-          <div class="empty-text">暂无数据</div>
-        </el-col>
-      </el-row>
-    </el-card>
-
-    <!-- 望亭闸 -->
-    <div class="section-header">
-      <svg-icon icon-class="example" class="section-icon" />
-      <span class="section-title">望亭闸</span>
-      <span class="section-line"></span>
-      <el-button link type="primary" icon="Plus" @click="openAdd('wyh')">添加模块</el-button>
-    </div>
-    <el-card class="home-card" shadow="never">
-      <el-row :gutter="12">
-        <el-col :xs="12" :sm="8" :md="6" :lg="4" :xl="3" v-for="(item, index) in wyhItems" :key="item.id">
-          <div class="card-item" @click="goToPage('/more/wyh?folderId=' + item.id)">
-            <span class="card-index">{{ index + 1 }}</span>
-            <span class="card-text" :title="item.name">{{ item.name }}</span>
-          </div>
-        </el-col>
-        <el-col :xs="12" :sm="8" :md="6" :lg="4" :xl="3" v-if="!loadingWyh && wyhItems.length === 0">
-          <div class="empty-text">暂无数据</div>
-        </el-col>
-      </el-row>
-    </el-card>
+<!--    &lt;!&ndash; 太浦闸 &ndash;&gt;-->
+<!--    <div class="section-header">-->
+<!--      <svg-icon icon-class="monitor" class="section-icon" />-->
+<!--      <span class="section-title">太浦闸</span>-->
+<!--      <span class="section-line"></span>-->
+<!--      <el-button link type="primary" icon="Plus" @click="openAdd('tpz')">添加模块</el-button>-->
+<!--    </div>-->
+<!--    <el-card class="home-card" shadow="never">-->
+<!--      <el-row :gutter="12">-->
+<!--        <el-col :xs="12" :sm="8" :md="6" :lg="4" :xl="3" v-for="(item, index) in tpzItems" :key="item.id">-->
+<!--          <div class="card-item" @click="goToPage('/more/tpz?folderId=' + item.id)">-->
+<!--            <span class="card-index">{{ index + 1 }}</span>-->
+<!--            <span class="card-text" :title="item.name">{{ item.name }}</span>-->
+<!--          </div>-->
+<!--        </el-col>-->
+<!--        <el-col :xs="12" :sm="8" :md="6" :lg="4" :xl="3" v-if="!loadingTpz && tpzItems.length === 0">-->
+<!--          <div class="empty-text">暂无数据</div>-->
+<!--        </el-col>-->
+<!--      </el-row>-->
+<!--    </el-card>-->
+
+<!--    &lt;!&ndash; 望亭闸 &ndash;&gt;-->
+<!--    <div class="section-header">-->
+<!--      <svg-icon icon-class="example" class="section-icon" />-->
+<!--      <span class="section-title">望亭闸</span>-->
+<!--      <span class="section-line"></span>-->
+<!--      <el-button link type="primary" icon="Plus" @click="openAdd('wyh')">添加模块</el-button>-->
+<!--    </div>-->
+<!--    <el-card class="home-card" shadow="never">-->
+<!--      <el-row :gutter="12">-->
+<!--        <el-col :xs="12" :sm="8" :md="6" :lg="4" :xl="3" v-for="(item, index) in wyhItems" :key="item.id">-->
+<!--          <div class="card-item" @click="goToPage('/more/wyh?folderId=' + item.id)">-->
+<!--            <span class="card-index">{{ index + 1 }}</span>-->
+<!--            <span class="card-text" :title="item.name">{{ item.name }}</span>-->
+<!--          </div>-->
+<!--        </el-col>-->
+<!--        <el-col :xs="12" :sm="8" :md="6" :lg="4" :xl="3" v-if="!loadingWyh && wyhItems.length === 0">-->
+<!--          <div class="empty-text">暂无数据</div>-->
+<!--        </el-col>-->
+<!--      </el-row>-->
+<!--    </el-card>-->
 
     <!-- 直管工程 -->
     <div class="section-header">

+ 0 - 71
gw-ui/src/views/tool/build/CodeTypeDialog.vue

@@ -1,71 +0,0 @@
-<template>
-  <el-dialog v-model="open" width="500px" title="选择生成类型" @open="onOpen" @close="onClose">
-    <el-form ref="codeTypeForm" :model="formData" :rules="rules" label-width="100px">
-      <el-form-item label="生成类型" prop="type">
-        <el-radio-group v-model="formData.type">
-          <el-radio-button v-for="(item, index) in typeOptions" :key="index" :label="item.value">
-            {{ item.label }}
-          </el-radio-button>
-        </el-radio-group>
-      </el-form-item>
-      <el-form-item v-if="showFileName" label="文件名" prop="fileName">
-        <el-input v-model="formData.fileName" placeholder="请输入文件名" clearable />
-      </el-form-item>
-    </el-form>
-
-    <template #footer>
-      <el-button @click="onClose">取消</el-button>
-      <el-button type="primary" @click="handelConfirm">确定</el-button>
-    </template>
-  </el-dialog>
-</template>
-
-<script setup>
-const open = defineModel()
-const props = defineProps({
-  showFileName: Boolean
-})
-const emit = defineEmits(['confirm'])
-const formData = ref({
-  fileName: undefined,
-  type: 'file'
-})
-const codeTypeForm = ref()
-const rules = {
-  fileName: [{
-    required: true,
-    message: '请输入文件名',
-    trigger: 'blur'
-  }],
-  type: [{
-    required: true,
-    message: '生成类型不能为空',
-    trigger: 'change'
-  }]
-}
-const typeOptions = ref([
-  {
-    label: '页面',
-    value: 'file'
-  },
-  {
-    label: '弹窗',
-    value: 'dialog'
-  }
-])
-function onOpen() {
-  if (props.showFileName) {
-    formData.value.fileName = `${+new Date()}.vue`
-  }
-}
-function onClose() {
-  open.value = false
-}
-function handelConfirm() {
-  codeTypeForm.value.validate(valid => {
-    if (!valid) return
-    emit('confirm', { ...formData.value })
-    onClose()
-  })
-}
-</script>

+ 0 - 68
gw-ui/src/views/tool/build/DraggableItem.vue

@@ -1,68 +0,0 @@
-<template>
-  <el-col :span="element.span" :class="className" @click.stop="activeItem(element)">
-    <el-form-item :label="element.label" :label-width="element.labelWidth ? element.labelWidth + 'px' : null"
-      :required="element.required" v-if="element.layout === 'colFormItem'">
-      <render :key="element.tag" :conf="element" v-model="element.defaultValue" />
-    </el-form-item>
-    <el-row :gutter="element.gutter" :class="element.class" @click.stop="activeItem(element)" v-else>
-      <span class="component-name"> {{ element.componentName }} </span>
-      <draggable group="componentsGroup" :animation="340" :list="element.children" class="drag-wrapper" item-key="label"
-        ref="draggableItemRef" :component-data="getComponentData()">
-        <template #item="scoped">
-          <draggable-item :key="scoped.element.renderKey" :drawing-list="element.children" :element="scoped.element"
-            :index="index" :active-id="activeId" :form-conf="formConf" @activeItem="activeItem(scoped.element)"
-            @copyItem="copyItem(scoped.element, element.children)"
-            @deleteItem="deleteItem(scoped.index, element.children)" />
-        </template>
-      </draggable>
-    </el-row>
-    <span class="drawing-item-copy" title="复制" @click.stop="copyItem(element)">
-      <el-icon><CopyDocument /></el-icon>
-    </span>
-    <span class="drawing-item-delete" title="删除" @click.stop="deleteItem(index)">
-      <el-icon><Delete /></el-icon>
-    </span>
-  </el-col>
-</template>
-<script setup name="DraggableItem">
-import draggable from "vuedraggable/dist/vuedraggable.common"
-import render from '@/utils/generator/render'
-
-const props = defineProps({
-  element: Object,
-  index: Number,
-  drawingList: Array,
-  activeId: {
-    type: [String, Number]
-  },
-  formConf: Object
-})
-const className = ref('')
-const draggableItemRef = ref(null)
-const emits = defineEmits(['activeItem', 'copyItem', 'deleteItem'])
-
-function activeItem(item) {
-  emits('activeItem', item)
-}
-function copyItem(item, parent) {
-  emits('copyItem', item, parent ?? props.drawingList)
-}
-function deleteItem(item, parent) {
-  emits('deleteItem', item, parent ?? props.drawingList)
-}
-
-function getComponentData() {
-  return {
-    gutter: props.element.gutter,
-    justify: props.element.justify,
-    align: props.element.align
-  }
-}
-
-watch(() => props.activeId, (val) => {
-  className.value = (props.element.layout === 'rowFormItem' ? 'drawing-row-item' : 'drawing-item') + (val === props.element.formId ? ' active-from-item' : '')
-  if (props.formConf.unFocusedComponentBorder) {
-    className.value += ' unfocus-bordered'
-  }
-}, { immediate: true })
-</script>

+ 0 - 115
gw-ui/src/views/tool/build/IconsDialog.vue

@@ -1,115 +0,0 @@
-<template>
-  <div class="icon-dialog">
-    <el-dialog v-model="value" width="980px" :close-on-click-modal="false" :modal-append-to-body="false" @open="onOpen"
-      @close="onClose">
-      <template #header="{ close, titleId, titleClass }">
-        选择图标
-        <el-input v-model="key" size="small" :style="{ width: '260px' }" placeholder="请输入图标名称" prefix-icon="Search"
-          clearable />
-      </template>
-      <ul class="icon-ul">
-        <li v-for="icon in iconList" :key="icon" :class="active === icon ? 'active-item' : ''" @click="onSelect(icon)">
-          <div>
-            <el-icon :size="30">
-              <component :is="icon" />
-            </el-icon>
-            <div>{{ icon }}</div>
-          </div>
-        </li>
-      </ul>
-    </el-dialog>
-  </div>
-</template>
-<script setup>
-import * as ElementPlusIconsVue from '@element-plus/icons-vue'
-import { watch } from 'vue'
-
-const iconList = ref([])
-const originList = []
-const key = ref('')
-const active = ref('')
-const emit = defineEmits(['select'])
-const value = defineModel()
-for (const [key] of Object.entries(ElementPlusIconsVue)) {
-  iconList.value.push(key)
-  originList.push(key)
-}
-
-function onOpen() { }
-function onClose() { }
-function onSelect(icon) {
-  active.value = icon
-  emit('select', icon)
-  value.value = false
-}
-
-watch(key, (val) => {
-  if (val) {
-    iconList.value = originList.filter(name => name.indexOf(val) > -1)
-  } else {
-    iconList.value = originList
-  }
-})
-</script>
-<style lang="scss" scoped>
-.icon-ul {
-  margin: 0;
-  padding: 0;
-  font-size: 0;
-
-  li {
-    list-style-type: none;
-    text-align: center;
-    font-size: 14px;
-    display: inline-flex;
-    width: 16.66%;
-    box-sizing: border-box;
-    height: 108px;
-    padding: 6px 6px 6px 6px;
-    cursor: pointer;
-    overflow: hidden;
-    align-items: center;
-    justify-content: center;
-
-    &:hover {
-      background: #f2f2f2;
-    }
-
-    &.active-item {
-      background: #e1f3fb;
-      color: #7a6df0
-    }
-
-    i {
-      font-size: 30px;
-      line-height: 50px;
-      margin-bottom: 10px;
-    }
-  }
-}
-
-.icon-dialog {
-  :deep() {
-    .el-dialog {
-      border-radius: 8px;
-      margin-bottom: 0;
-      margin-top: 4vh !important;
-      display: flex;
-      flex-direction: column;
-      max-height: 92vh;
-      overflow: hidden;
-      box-sizing: border-box;
-
-      .el-dialog__header {
-        padding-top: 14px;
-      }
-
-      .el-dialog__body {
-        margin: 0 20px 20px 20px;
-        padding: 0;
-        overflow: auto;
-      }
-    }
-  }
-}
-</style>

+ 0 - 906
gw-ui/src/views/tool/build/RightPanel.vue

@@ -1,906 +0,0 @@
-<template>
-  <div class="right-board">
-    <el-tabs v-model="currentTab" stretch class="center-tabs">
-      <el-tab-pane label="组件属性" name="field" />
-      <el-tab-pane label="表单属性" name="form" />
-    </el-tabs>
-    <div class="field-box">
-      <a class="document-link" target="_blank" :href="documentLink" title="查看组件文档">
-        <el-icon>
-          <Link />
-        </el-icon>
-      </a>
-      <el-scrollbar class="right-scrollbar">
-        <!-- 组件属性 -->
-        <el-form v-show="currentTab === 'field' && showField" size="default" label-width="90px" label-position="top"
-          style="">
-          <el-form-item v-if="activeData.changeTag" label="组件类型">
-            <el-select v-model="activeData.tagIcon" placeholder="请选择组件类型" :style="{ width: '100%' }" @change="tagChange">
-              <el-option-group v-for="group in tagList" :key="group.label" :label="group.label">
-                <el-option v-for="item in group.options" :key="item.label" :label="item.label" :value="item.tagIcon">
-                  <svg-icon class="node-icon" :icon-class="item.tagIcon" style="margin-right: 10px;" />
-                  <span> {{ item.label }}</span>
-                </el-option>
-              </el-option-group>
-            </el-select>
-          </el-form-item>
-          <el-form-item v-if="activeData.vModel !== undefined" label="字段名">
-            <el-input v-model="activeData.vModel" placeholder="请输入字段名(v-model)" />
-          </el-form-item>
-          <el-form-item v-if="activeData.componentName !== undefined" label="组件名">
-            {{ activeData.componentName }}
-          </el-form-item>
-          <el-form-item v-if="activeData.label !== undefined" label="标题">
-            <el-input v-model="activeData.label" placeholder="请输入标题" />
-          </el-form-item>
-          <el-form-item v-if="activeData.placeholder !== undefined" label="占位提示">
-            <el-input v-model="activeData.placeholder" placeholder="请输入占位提示" />
-          </el-form-item>
-          <el-form-item v-if="activeData['start-placeholder'] !== undefined" label="开始占位">
-            <el-input v-model="activeData['start-placeholder']" placeholder="请输入占位提示" />
-          </el-form-item>
-          <el-form-item v-if="activeData['end-placeholder'] !== undefined" label="结束占位">
-            <el-input v-model="activeData['end-placeholder']" placeholder="请输入占位提示" />
-          </el-form-item>
-          <el-form-item v-if="activeData.span !== undefined" label="表单栅格">
-            <el-slider v-model="activeData.span" :max="24" :min="1" :marks="{ 12: '' }" @change="spanChange" />
-          </el-form-item>
-          <el-form-item v-if="activeData.layout === 'rowFormItem'" label="栅格间隔">
-            <el-input-number v-model="activeData.gutter" :min="0" placeholder="栅格间隔" />
-          </el-form-item>
-
-          <el-form-item v-if="activeData.justify !== undefined" label="水平排列">
-            <el-select v-model="activeData.justify" placeholder="请选择水平排列" :style="{ width: '100%' }">
-              <el-option v-for="(item, index) in justifyOptions" :key="index" :label="item.label" :value="item.value" />
-            </el-select>
-          </el-form-item>
-          <el-form-item v-if="activeData.align !== undefined" label="垂直排列">
-            <el-radio-group v-model="activeData.align">
-              <el-radio-button label="top" />
-              <el-radio-button label="middle" />
-              <el-radio-button label="bottom" />
-            </el-radio-group>
-          </el-form-item>
-          <el-form-item v-if="activeData.labelWidth !== undefined" label="标签宽度">
-            <el-input v-model.number="activeData.labelWidth" type="number" placeholder="请输入标签宽度" />
-          </el-form-item>
-          <el-form-item v-if="activeData.style && activeData.style.width !== undefined" label="组件宽度">
-            <el-input v-model="activeData.style.width" placeholder="请输入组件宽度" clearable />
-          </el-form-item>
-          <el-form-item v-if="activeData.vModel !== undefined" label="默认值">
-            <el-input :value="setDefaultValue(activeData.defaultValue)" placeholder="请输入默认值"
-              @input="onDefaultValueInput" />
-          </el-form-item>
-          <el-form-item v-if="activeData.tag === 'el-checkbox-group'" label="至少应选">
-            <el-input-number :value="activeData.min" :min="0" placeholder="至少应选"
-              @input="$set(activeData, 'min', $event ? $event : undefined)" />
-          </el-form-item>
-          <el-form-item v-if="activeData.tag === 'el-checkbox-group'" label="最多可选">
-            <el-input-number :value="activeData.max" :min="0" placeholder="最多可选"
-              @input="$set(activeData, 'max', $event ? $event : undefined)" />
-          </el-form-item>
-          <el-form-item v-if="activeData.prepend !== undefined" label="前缀">
-            <el-input v-model="activeData.prepend" placeholder="请输入前缀" />
-          </el-form-item>
-          <el-form-item v-if="activeData.append !== undefined" label="后缀">
-            <el-input v-model="activeData.append" placeholder="请输入后缀" />
-          </el-form-item>
-          <el-form-item v-if="activeData['prefix-icon'] !== undefined" label="前图标">
-            <el-input v-model="activeData['prefix-icon']" placeholder="请输入前图标名称">
-              <template #append>
-                <el-button icon="Pointer" @click="openIconsDialog('prefix-icon')">
-                  选择
-                </el-button>
-              </template>
-            </el-input>
-          </el-form-item>
-          <el-form-item v-if="activeData['suffix-icon'] !== undefined" label="后图标">
-            <el-input v-model="activeData['suffix-icon']" placeholder="请输入后图标名称">
-              <template #append>
-                <el-button icon="Pointer" @click="openIconsDialog('suffix-icon')">
-                  选择
-                </el-button>
-              </template>
-            </el-input>
-          </el-form-item>
-          <el-form-item v-if="activeData.tag === 'el-cascader'" label="选项分隔符">
-            <el-input v-model="activeData.separator" placeholder="请输入选项分隔符" />
-          </el-form-item>
-          <el-form-item v-if="activeData.autosize !== undefined" label="最小行数">
-            <el-input-number v-model="activeData.autosize.minRows" :min="1" placeholder="最小行数" />
-          </el-form-item>
-          <el-form-item v-if="activeData.autosize !== undefined" label="最大行数">
-            <el-input-number v-model="activeData.autosize.maxRows" :min="1" placeholder="最大行数" />
-          </el-form-item>
-          <el-form-item v-if="activeData.min !== undefined" label="最小值">
-            <el-input-number v-model="activeData.min" placeholder="最小值" />
-          </el-form-item>
-          <el-form-item v-if="activeData.max !== undefined" label="最大值">
-            <el-input-number v-model="activeData.max" placeholder="最大值" />
-          </el-form-item>
-          <el-form-item v-if="activeData.step !== undefined" label="步长">
-            <el-input-number v-model="activeData.step" placeholder="步数" />
-          </el-form-item>
-          <el-form-item v-if="activeData.tag === 'el-input-number'" label="精度">
-            <el-input-number v-model="activeData.precision" :min="0" placeholder="精度" />
-          </el-form-item>
-          <el-form-item v-if="activeData.tag === 'el-input-number'" label="按钮位置">
-            <el-radio-group v-model="activeData['controls-position']">
-              <el-radio-button label="">
-                默认
-              </el-radio-button>
-              <el-radio-button label="right">
-                右侧
-              </el-radio-button>
-            </el-radio-group>
-          </el-form-item>
-          <el-form-item v-if="activeData.maxlength !== undefined" label="最多输入">
-            <el-input v-model="activeData.maxlength" placeholder="请输入字符长度">
-              <template slot="append">
-                个字符
-              </template>
-            </el-input>
-          </el-form-item>
-          <el-form-item v-if="activeData['active-text'] !== undefined" label="开启提示">
-            <el-input v-model="activeData['active-text']" placeholder="请输入开启提示" />
-          </el-form-item>
-          <el-form-item v-if="activeData['inactive-text'] !== undefined" label="关闭提示">
-            <el-input v-model="activeData['inactive-text']" placeholder="请输入关闭提示" />
-          </el-form-item>
-          <el-form-item v-if="activeData['active-value'] !== undefined" label="开启值">
-            <el-input :value="setDefaultValue(activeData['active-value'])" placeholder="请输入开启值"
-              @input="onSwitchValueInput($event, 'active-value')" />
-          </el-form-item>
-          <el-form-item v-if="activeData['inactive-value'] !== undefined" label="关闭值">
-            <el-input :value="setDefaultValue(activeData['inactive-value'])" placeholder="请输入关闭值"
-              @input="onSwitchValueInput($event, 'inactive-value')" />
-          </el-form-item>
-          <el-form-item v-if="activeData.type !== undefined && 'el-date-picker' === activeData.tag" label="时间类型">
-            <el-select v-model="activeData.type" placeholder="请选择时间类型" :style="{ width: '100%' }"
-              @change="dateTypeChange">
-              <el-option v-for="(item, index) in dateOptions" :key="index" :label="item.label" :value="item.value" />
-            </el-select>
-          </el-form-item>
-          <el-form-item v-if="activeData.name !== undefined" label="文件字段名">
-            <el-input v-model="activeData.name" placeholder="请输入上传文件字段名" />
-          </el-form-item>
-          <el-form-item v-if="activeData.accept !== undefined" label="文件类型">
-            <el-select v-model="activeData.accept" placeholder="请选择文件类型" :style="{ width: '100%' }" clearable>
-              <el-option label="图片" value="image/*" />
-              <el-option label="视频" value="video/*" />
-              <el-option label="音频" value="audio/*" />
-              <el-option label="excel" value=".xls,.xlsx" />
-              <el-option label="word" value=".doc,.docx" />
-              <el-option label="pdf" value=".pdf" />
-              <el-option label="txt" value=".txt" />
-            </el-select>
-          </el-form-item>
-          <el-form-item v-if="activeData.fileSize !== undefined" label="文件大小">
-            <el-input v-model.number="activeData.fileSize" placeholder="请输入文件大小">
-              <el-select slot="append" v-model="activeData.sizeUnit" :style="{ width: '66px' }">
-                <el-option label="KB" value="KB" />
-                <el-option label="MB" value="MB" />
-                <el-option label="GB" value="GB" />
-              </el-select>
-            </el-input>
-          </el-form-item>
-          <el-form-item v-if="activeData.action !== undefined" label="上传地址">
-            <el-input v-model="activeData.action" placeholder="请输入上传地址" clearable />
-          </el-form-item>
-          <el-form-item v-if="activeData['list-type'] !== undefined" label="列表类型">
-            <el-radio-group v-model="activeData['list-type']" size="small">
-              <el-radio-button label="text">
-                text
-              </el-radio-button>
-              <el-radio-button label="picture">
-                picture
-              </el-radio-button>
-              <el-radio-button label="picture-card">
-                picture-card
-              </el-radio-button>
-            </el-radio-group>
-          </el-form-item>
-          <el-form-item v-if="activeData.buttonText !== undefined" v-show="'picture-card' !== activeData['list-type']"
-            label="按钮文字">
-            <el-input v-model="activeData.buttonText" placeholder="请输入按钮文字" />
-          </el-form-item>
-          <el-form-item v-if="activeData['range-separator'] !== undefined" label="分隔符">
-            <el-input v-model="activeData['range-separator']" placeholder="请输入分隔符" />
-          </el-form-item>
-          <el-form-item v-if="activeData['picker-options'] !== undefined" label="时间段">
-            <el-input v-model="activeData['picker-options'].selectableRange" placeholder="请输入时间段" />
-          </el-form-item>
-          <el-form-item v-if="activeData.format !== undefined" label="时间格式">
-            <el-input :value="activeData.format" placeholder="请输入时间格式" @input="setTimeValue($event)" />
-          </el-form-item>
-          <template v-if="['el-checkbox-group', 'el-radio-group', 'el-select'].indexOf(activeData.tag) > -1">
-            <el-divider>选项</el-divider>
-            <draggable :list="activeData.options" :animation="340" group="selectItem" handle=".option-drag"
-              item-key="label">
-              <template #item="{ element, index }">
-                <div :key="index" class="select-item">
-                  <div class="select-line-icon option-drag">
-                    <i class="el-icon-s-operation" />
-                  </div>
-                  <el-input v-model="element.label" placeholder="选项名" size="small" />
-                  <el-input placeholder="选项值" size="small" :value="element.value"
-                    @input="setOptionValue(element, $event)" />
-                  <div class="close-btn select-line-icon" @click="activeData.options.splice(index, 1)">
-                    <el-icon>
-                      <Remove />
-                    </el-icon>
-                  </div>
-                </div>
-              </template>
-            </draggable>
-            <div>
-              <el-button icon="CirclePlus" style="margin-left: 8px; margin-top: 10px;" text bg type="primary"
-                @click="addSelectItem">
-                添加选项
-              </el-button>
-            </div>
-            <el-divider />
-          </template>
-
-          <template v-if="['el-cascader'].indexOf(activeData.tag) > -1">
-            <el-divider>选项</el-divider>
-            <el-form-item label="数据类型">
-              <el-radio-group v-model="activeData.dataType" size="small">
-                <el-radio-button label="dynamic">
-                  动态数据
-                </el-radio-button>
-                <el-radio-button label="static">
-                  静态数据
-                </el-radio-button>
-              </el-radio-group>
-            </el-form-item>
-
-            <template v-if="activeData.dataType === 'dynamic'">
-              <el-form-item label="标签键名">
-                <el-input v-model="activeData.labelKey" placeholder="请输入标签键名" />
-              </el-form-item>
-              <el-form-item label="值键名">
-                <el-input v-model="activeData.valueKey" placeholder="请输入值键名" />
-              </el-form-item>
-              <el-form-item label="子级键名">
-                <el-input v-model="activeData.childrenKey" placeholder="请输入子级键名" />
-              </el-form-item>
-            </template>
-
-            <el-tree v-if="activeData.dataType === 'static'" draggable :data="activeData.options" node-key="id"
-              :expand-on-click-node="false" :render-content="renderContent" />
-            <div v-if="activeData.dataType === 'static'">
-              <el-button icon="CirclePlus" style="margin-left: 0; margin-top: 10px;" type="primary" text bg
-                @click="addTreeItem">
-                添加父级
-              </el-button>
-            </div>
-            <el-divider />
-          </template>
-
-          <el-form-item v-if="activeData.optionType !== undefined" label="选项样式">
-            <el-radio-group v-model="activeData.optionType">
-              <el-radio-button label="default">
-                默认
-              </el-radio-button>
-              <el-radio-button label="button">
-                按钮
-              </el-radio-button>
-            </el-radio-group>
-          </el-form-item>
-          <el-form-item v-if="activeData['active-color'] !== undefined" label="开启颜色">
-            <el-color-picker v-model="activeData['active-color']" />
-          </el-form-item>
-          <el-form-item v-if="activeData['inactive-color'] !== undefined" label="关闭颜色">
-            <el-color-picker v-model="activeData['inactive-color']" />
-          </el-form-item>
-
-          <el-form-item v-if="activeData['allow-half'] !== undefined" label="允许半选">
-            <el-switch v-model="activeData['allow-half']" />
-          </el-form-item>
-          <el-form-item v-if="activeData['show-text'] !== undefined" label="辅助文字">
-            <el-switch v-model="activeData['show-text']" @change="rateTextChange" />
-          </el-form-item>
-          <el-form-item v-if="activeData['show-score'] !== undefined" label="显示分数">
-            <el-switch v-model="activeData['show-score']" @change="rateScoreChange" />
-          </el-form-item>
-          <el-form-item v-if="activeData['show-stops'] !== undefined" label="显示间断点">
-            <el-switch v-model="activeData['show-stops']" />
-          </el-form-item>
-          <el-form-item v-if="activeData.range !== undefined" label="范围选择">
-            <el-switch v-model="activeData.range" @change="rangeChange" />
-          </el-form-item>
-          <el-form-item v-if="activeData.border !== undefined && activeData.optionType === 'default'" label="是否带边框">
-            <el-switch v-model="activeData.border" />
-          </el-form-item>
-          <el-form-item v-if="activeData.tag === 'el-color-picker'" label="颜色格式">
-            <el-select v-model="activeData['color-format']" placeholder="请选择颜色格式" :style="{ width: '100%' }"
-              @change="colorFormatChange">
-              <el-option v-for="(item, index) in colorFormatOptions" :key="index" :label="item.label"
-                :value="item.value" />
-            </el-select>
-          </el-form-item>
-          <el-form-item v-if="activeData.size !== undefined &&
-            (activeData.optionType === 'button' ||
-              activeData.border ||
-              activeData.tag === 'el-color-picker')" label="选项尺寸">
-            <el-radio-group v-model="activeData.size">
-              <el-radio-button label="large">
-                较大
-              </el-radio-button>
-              <el-radio-button label="default">
-                默认
-              </el-radio-button>
-              <el-radio-button label="small">
-                较小
-              </el-radio-button>
-            </el-radio-group>
-          </el-form-item>
-          <el-form-item v-if="activeData['show-word-limit'] !== undefined" label="输入统计">
-            <el-switch v-model="activeData['show-word-limit']" />
-          </el-form-item>
-          <el-form-item v-if="activeData.tag === 'el-input-number'" label="严格步数">
-            <el-switch v-model="activeData['step-strictly']" />
-          </el-form-item>
-          <el-form-item v-if="activeData.tag === 'el-cascader'" label="是否多选">
-            <el-switch v-model="activeData.props.props.multiple" />
-          </el-form-item>
-          <el-form-item v-if="activeData.tag === 'el-cascader'" label="展示全路径">
-            <el-switch v-model="activeData['show-all-levels']" />
-          </el-form-item>
-          <el-form-item v-if="activeData.tag === 'el-cascader'" label="可否筛选">
-            <el-switch v-model="activeData.filterable" />
-          </el-form-item>
-          <el-form-item v-if="activeData.clearable !== undefined" label="能否清空">
-            <el-switch v-model="activeData.clearable" />
-          </el-form-item>
-          <el-form-item v-if="activeData.showTip !== undefined" label="显示提示">
-            <el-switch v-model="activeData.showTip" />
-          </el-form-item>
-          <el-form-item v-if="activeData.multiple !== undefined" label="多选文件">
-            <el-switch v-model="activeData.multiple" />
-          </el-form-item>
-          <el-form-item v-if="activeData['auto-upload'] !== undefined" label="自动上传">
-            <el-switch v-model="activeData['auto-upload']" />
-          </el-form-item>
-          <el-form-item v-if="activeData.readonly !== undefined" label="是否只读">
-            <el-switch v-model="activeData.readonly" />
-          </el-form-item>
-          <el-form-item v-if="activeData.disabled !== undefined" label="是否禁用">
-            <el-switch v-model="activeData.disabled" />
-          </el-form-item>
-          <el-form-item v-if="activeData.tag === 'el-select'" label="是否可搜索">
-            <el-switch v-model="activeData.filterable" />
-          </el-form-item>
-          <el-form-item v-if="activeData.tag === 'el-select'" label="是否多选">
-            <el-switch v-model="activeData.multiple" @change="multipleChange" />
-          </el-form-item>
-          <el-form-item v-if="activeData.required !== undefined" label="是否必填">
-            <el-switch v-model="activeData.required" />
-          </el-form-item>
-
-          <template v-if="activeData.layoutTree">
-            <el-divider>布局结构树</el-divider>
-            <el-tree :data="[activeData]" :props="layoutTreeProps" node-key="renderKey" default-expand-all draggable>
-              <template #default="{ node, data }">
-                <span class="node-label">
-                  <svg-icon class="node-icon" :icon-class="data.tagIcon" style="margin-right: 5px;" />
-                  {{ node.label }}
-                </span>
-              </template>
-            </el-tree>
-          </template>
-
-          <template v-if="activeData.layout === 'colFormItem'">
-            <el-divider>正则校验</el-divider>
-            <div v-for="(item, index) in activeData.regList" :key="index" class="reg-item">
-              <span class="close-btn" @click="activeData.regList.splice(index, 1)">
-                <el-icon>
-                  <Close />
-                </el-icon>
-              </span>
-              <el-form-item label="表达式">
-                <el-input v-model="item.pattern" placeholder="请输入正则" />
-              </el-form-item>
-              <el-form-item label="错误提示" style="margin-bottom:0">
-                <el-input v-model="item.message" placeholder="请输入错误提示" />
-              </el-form-item>
-            </div>
-            <div>
-              <el-button icon="CirclePlus" style="margin-left: 0; margin-top: 10px;" type="primary" text bg
-                @click="addReg">
-                添加规则
-              </el-button>
-            </div>
-          </template>
-        </el-form>
-        <!-- 表单属性 -->
-        <el-form v-show="currentTab === 'form'" label-width="90px" label-position="top">
-          <el-form-item label="表单名">
-            <el-input v-model="formConf.formRef" placeholder="请输入表单名(ref)" />
-          </el-form-item>
-          <el-form-item label="表单模型">
-            <el-input v-model="formConf.formModel" placeholder="请输入数据模型" />
-          </el-form-item>
-          <el-form-item label="校验模型">
-            <el-input v-model="formConf.formRules" placeholder="请输入校验模型" />
-          </el-form-item>
-          <el-form-item label="表单尺寸">
-            <el-radio-group v-model="formConf.size">
-              <el-radio-button label="large" value="较大" />
-              <el-radio-button label="default" value="默认" />
-              <el-radio-button label="small" value="较小" />
-            </el-radio-group>
-          </el-form-item>
-          <el-form-item label="标签对齐">
-            <el-radio-group v-model="formConf.labelPosition">
-              <el-radio-button label="left" value="左对齐" />
-              <el-radio-button label="right" value="右对齐" />
-              <el-radio-button label="top" value="顶部对齐" />
-            </el-radio-group>
-          </el-form-item>
-          <el-form-item label="标签宽度">
-            <el-input-number v-model="formConf.labelWidth" placeholder="标签宽度" />
-          </el-form-item>
-          <el-form-item label="栅格间隔">
-            <el-input-number v-model="formConf.gutter" :min="0" placeholder="栅格间隔" />
-          </el-form-item>
-          <el-form-item label="禁用表单">
-            <el-switch v-model="formConf.disabled" />
-          </el-form-item>
-          <el-form-item label="表单按钮">
-            <el-switch v-model="formConf.formBtns" />
-          </el-form-item>
-          <el-form-item label="显示未选中组件边框">
-            <el-switch v-model="formConf.unFocusedComponentBorder" />
-          </el-form-item>
-        </el-form>
-      </el-scrollbar>
-    </div>
-    <icons-dialog v-model="iconsVisible" :current="activeData[currentIconModel]" @select="setIcon" />
-    <treeNode-dialog v-model="dialogVisible" @commit="addNode" />
-
-  </div>
-</template>
-
-<script setup>
-import draggable from "vuedraggable/dist/vuedraggable.common"
-import { isNumberStr } from '@/utils/index'
-import IconsDialog from './IconsDialog'
-import TreeNodeDialog from './TreeNodeDialog'
-import { inputComponents, selectComponents } from '@/utils/generator/config'
-
-const { proxy } = getCurrentInstance()
-const dateTimeFormat = {
-  date: 'YYYY-MM-DD',
-  week: 'YYYY 第 ww 周',
-  month: 'YYYY-MM',
-  year: 'YYYY',
-  datetime: 'YYYY-MM-DD HH:mm:ss',
-  daterange: 'YYYY-MM-DD',
-  monthrange: 'YYYY-MM',
-  datetimerange: 'YYYY-MM-DD HH:mm:ss'
-}
-const props = defineProps({
-  showField: Boolean,
-  activeData: Object,
-  formConf: Object
-})
-
-const data = reactive({
-  currentTab: 'field',
-  currentNode: null,
-  dialogVisible: false,
-  iconsVisible: false,
-  currentIconModel: null,
-  dateTypeOptions: [
-    {
-      label: '日(date)',
-      value: 'date'
-    },
-    {
-      label: '周(week)',
-      value: 'week'
-    },
-    {
-      label: '月(month)',
-      value: 'month'
-    },
-    {
-      label: '年(year)',
-      value: 'year'
-    },
-    {
-      label: '日期时间(datetime)',
-      value: 'datetime'
-    }
-  ],
-  dateRangeTypeOptions: [
-    {
-      label: '日期范围(daterange)',
-      value: 'daterange'
-    },
-    {
-      label: '月范围(monthrange)',
-      value: 'monthrange'
-    },
-    {
-      label: '日期时间范围(datetimerange)',
-      value: 'datetimerange'
-    }
-  ],
-  colorFormatOptions: [
-    {
-      label: 'hex',
-      value: 'hex'
-    },
-    {
-      label: 'rgb',
-      value: 'rgb'
-    },
-    {
-      label: 'rgba',
-      value: 'rgba'
-    },
-    {
-      label: 'hsv',
-      value: 'hsv'
-    },
-    {
-      label: 'hsl',
-      value: 'hsl'
-    }
-  ],
-  justifyOptions: [
-    {
-      label: 'start',
-      value: 'start'
-    },
-    {
-      label: 'end',
-      value: 'end'
-    },
-    {
-      label: 'center',
-      value: 'center'
-    },
-    {
-      label: 'space-around',
-      value: 'space-around'
-    },
-    {
-      label: 'space-between',
-      value: 'space-between'
-    }
-  ],
-  layoutTreeProps: {
-    label(data, node) {
-      return data.componentName || `${data.label}: ${data.vModel}`
-    }
-  }
-})
-
-const { currentTab, currentNode, dialogVisible, iconsVisible, currentIconModel, dateTypeOptions, dateRangeTypeOptions, colorFormatOptions, justifyOptions, layoutTreeProps } = toRefs(data)
-
-const documentLink = computed(() => props.activeData.document || 'https://element-plus.org/zh-CN/guide/installation')
-
-const dateOptions = computed(() => {
-  if (props.activeData.type !== undefined && props.activeData.tag === 'el-date-picker') {
-    if (props.activeData['start-placeholder'] === undefined) {
-      return dateTypeOptions.value
-    }
-    return dateRangeTypeOptions.value
-  }
-  return []
-})
-
-const tagList = ref([
-  {
-    label: '输入型组件',
-    options: inputComponents
-  },
-  {
-    label: '选择型组件',
-    options: selectComponents
-  }
-])
-
-const emit = defineEmits(['tag-change'])
-
-function addReg() {
-  props.activeData.regList.push({
-    pattern: '',
-    message: ''
-  })
-}
-function addSelectItem() {
-  props.activeData.options.push({
-    label: '',
-    value: ''
-  })
-}
-
-function addTreeItem() {
-  ++proxy.idGlobal
-  dialogVisible.value = true
-  currentNode.value = props.activeData.options
-}
-
-function renderContent(h, { node, data, store }) {
-  return h('div', {
-    class: "custom-tree-node"
-  }, [
-    h('span', node.label),
-    h('span', {
-      class: "node-operation"
-    }, [
-      h(resolveComponent('el-link'), {
-        type: "primary",
-        icon: "Plus",
-        underline: false,
-        onClick: () => {
-          append(data)
-
-        }
-      }),
-      h(resolveComponent('el-link'), {
-        type: "danger",
-        icon: "Delete",
-        underline: false,
-        style: "margin-left: 5px;",
-        onClick: () => {
-          remove(node, data)
-        }
-      })
-    ])
-  ])
-}
-function append(data) {
-  if (!data.children) {
-    data.children = []
-  }
-  dialogVisible.value = true
-  currentNode.value = data.children
-}
-function remove(node, data) {
-  const { parent } = node
-  const children = parent.data.children || parent.data
-  const index = children.findIndex(d => d.id === data.id)
-  children.splice(index, 1)
-}
-function addNode(data) {
-  currentNode.value.push(data)
-}
-
-function setOptionValue(item, val) {
-  item.value = isNumberStr(val) ? +val : val
-}
-function setDefaultValue(val) {
-  if (Array.isArray(val)) {
-    return val.join(',')
-  }
-  if (['string', 'number'].indexOf(val) > -1) {
-    return val
-  }
-  if (typeof val === 'boolean') {
-    return `${val}`
-  }
-  return val
-}
-
-function onDefaultValueInput(str) {
-  if (Array.isArray(props.activeData.defaultValue)) {
-    // 数组
-    props.activeData.defaultValue = str.split(',').map(val => (isNumberStr(val) ? +val : val))
-  } else if (['true', 'false'].indexOf(str) > -1) {
-    // 布尔
-    props.activeData.defaultValue = JSON.parse(str)
-  } else {
-    // 字符串和数字
-    props.activeData.defaultValue = isNumberStr(str) ? +str : str
-  }
-}
-
-function onSwitchValueInput(val, name) {
-  if (['true', 'false'].indexOf(val) > -1) {
-    props.activeData[name] = JSON.parse(val)
-  } else {
-    props.activeData[name] = isNumberStr(val) ? +val : val
-  }
-}
-
-function setTimeValue(val, type) {
-  const valueFormat = type === 'week' ? dateTimeFormat.date : val
-  props.activeData.defaultValue = null
-  props.activeData['value-format'] = valueFormat
-  props.activeData.format = val
-}
-
-function spanChange(val) {
-  props.formConf.span = val
-}
-
-function multipleChange(val) {
-  props.activeData.defaultValue = val ? [] : ''
-}
-
-function dateTypeChange(val) {
-  setTimeValue(dateTimeFormat[val], val)
-}
-
-function rangeChange(val) {
-  props.activeData.defaultValue = val ? [props.activeData.min, props.activeData.max] : props.activeData.min
-}
-
-function rateTextChange(val) {
-  if (val) props.activeData['show-score'] = false
-}
-
-function rateScoreChange(val) {
-  if (val) props.activeData['show-text'] = false
-}
-
-function colorFormatChange(val) {
-  props.activeData.defaultValue = null
-  props.activeData['show-alpha'] = val.indexOf('a') > -1
-  props.activeData.renderKey = +new Date() // 更新renderKey,重新渲染该组件
-}
-
-function openIconsDialog(model) {
-  iconsVisible.value = true
-  currentIconModel.value = model
-}
-
-function setIcon(val) {
-  props.activeData[currentIconModel.value] = val
-}
-
-function tagChange(tagIcon) {
-  let target = inputComponents.find(item => item.tagIcon === tagIcon)
-  if (!target) target = selectComponents.find(item => item.tagIcon === tagIcon)
-  emit('tag-change', target)
-}
-</script>
-
-<style lang="scss" scoped>
-.right-board {
-  width: 350px;
-  position: absolute;
-  right: 0;
-  top: 0;
-  padding-top: 3px;
-
-  &:deep() {
-    .el-tabs__header {
-      margin: 0;
-    }
-
-    .el-input-group__append .el-button {
-      display: inline-flex;
-    }
-  }
-
-  .field-box {
-    position: relative;
-    height: calc(100vh - 50px - 40px - 42px);
-    box-sizing: border-box;
-    overflow: hidden;
-  }
-
-  .el-scrollbar {
-    height: 100%;
-
-    &:deep() {
-      .el-scrollbar__view {
-        padding: 30px 20px;
-      }
-
-    }
-  }
-}
-
-.reg-item {
-  padding: 12px 6px;
-  background: var(--el-border-color-extra-light);
-  position: relative;
-  border-radius: 4px;
-
-  .close-btn {
-    position: absolute;
-    right: -6px;
-    top: -6px;
-    display: flex;
-    align-items: center;
-    justify-content: center;
-    width: 16px;
-    height: 16px;
-    line-height: 16px;
-    background: rgba(0, 0, 0, .2);
-    border-radius: 50%;
-    color: #fff;
-    z-index: 1;
-    cursor: pointer;
-    font-size: 12px;
-  }
-}
-
-.select-item {
-  display: flex;
-  border: 1px dashed #fff;
-  box-sizing: border-box;
-
-  & .close-btn {
-    cursor: pointer;
-    color: #f56c6c;
-  }
-
-  & .el-input+.el-input {
-    margin-left: 4px;
-  }
-}
-
-.select-item+.select-item {
-  margin-top: 4px;
-}
-
-.select-item.sortable-chosen {
-  border: 1px dashed #409eff;
-}
-
-.select-line-icon {
-  line-height: 32px;
-  font-size: 22px;
-  padding: 0 4px;
-  color: #777;
-}
-
-.option-drag {
-  cursor: move;
-}
-
-.time-range {
-  .el-date-editor {
-    width: 227px;
-  }
-
-  :deep() {
-    .el-icon-time {
-      display: none;
-    }
-  }
-}
-
-.document-link {
-  position: absolute;
-  display: flex;
-  width: 26px;
-  height: 26px;
-  top: 0;
-  left: 0;
-  cursor: pointer;
-  background: #409eff;
-  z-index: 1;
-  border-radius: 0 0 6px 0;
-  justify-content: center;
-  align-items: center;
-  color: #fff;
-  font-size: 18px;
-}
-
-.node-label {
-  font-size: 14px;
-}
-
-.node-icon {
-  color: #bebfc3;
-}
-
-.custom-tree-node {
-  flex: 1;
-  display: flex;
-  align-items: center;
-  justify-content: space-between;
-  font-size: 14px;
-  padding-right: 8px;
-}
-</style>

+ 0 - 93
gw-ui/src/views/tool/build/TreeNodeDialog.vue

@@ -1,93 +0,0 @@
-<template>
-  <div>
-    <el-dialog title="添加选项" v-model="open" width="800px" :close-on-click-modal="false" :modal-append-to-body="false"
-      @open="onOpen" @close="onClose">
-      <el-form ref="treeNodeForm" :model="formData" :rules="rules" label-width="100px">
-        <el-col :span="24">
-          <el-form-item label="选项名" prop="label">
-            <el-input v-model="formData.label" placeholder="请输入选项名" clearable />
-          </el-form-item>
-        </el-col>
-        <el-col :span="24">
-          <el-form-item label="选项值" prop="value">
-            <el-input v-model="formData.value" placeholder="请输入选项值" clearable>
-              <template #append>
-                <el-select v-model="dataType" :style="{ width: '100px' }">
-                  <el-option v-for="(item, index) in dataTypeOptions" :key="index" :label="item.label" :value="item.value"
-                    :disabled="item.disabled" />
-                </el-select>
-              </template>
-
-            </el-input>
-          </el-form-item>
-        </el-col>
-      </el-form>
-      <template #footer>
-        <div class="dialog-footer">
-          <el-button type="primary" @click="handelConfirm">确 定</el-button>
-          <el-button @click="onClose">取 消</el-button>
-        </div>
-      </template>
-    </el-dialog>
-  </div>
-</template>
-<script setup>
-const open = defineModel()
-const emit = defineEmits(['confirm'])
-const formData = ref({
-  label: undefined,
-  value: undefined
-})
-const rules = {
-  label: [
-    {
-      required: true,
-      message: '请输入选项名',
-      trigger: 'blur'
-    }
-  ],
-  value: [
-    {
-      required: true,
-      message: '请输入选项值',
-      trigger: 'blur'
-    }
-  ]
-}
-const dataType = ref('string')
-const dataTypeOptions = ref([
-  {
-    label: '字符串',
-    value: 'string'
-  },
-  {
-    label: '数字',
-    value: 'number'
-  }
-])
-const id = ref(100)
-const treeNodeForm = ref()
-
-function onOpen() {
-  formData.value = {
-    label: undefined,
-    value: undefined
-  }
-}
-
-function onClose() {
-  open.value = false
-}
-
-function handelConfirm() {
-  treeNodeForm.value.validate(valid => {
-    if (!valid) return
-    if (dataType.value === 'number') {
-      formData.value.value = parseFloat(formData.value.value)
-    }
-    formData.value.id = id.value++
-    emit('commit', formData.value)
-    onClose()
-  })
-}
-</script>

+ 0 - 660
gw-ui/src/views/tool/build/index.vue

@@ -1,660 +0,0 @@
-<template>
-  <div class="container">
-    <div class="left-board">
-      <div class="logo-wrapper">
-        <div class="logo">
-          <img :src="logo" alt="logo"> Form Generator
-        </div>
-      </div>
-      <el-scrollbar class="left-scrollbar">
-        <div class="components-list">
-          <div class="components-title">
-            <svg-icon icon-class="component" />输入型组件
-          </div>
-          <draggable class="components-draggable" :list="inputComponents"
-            :group="{ name: 'componentsGroup', pull: 'clone', put: false }" :clone="cloneComponent"
-            draggable=".components-item" :sort="false" @end="onEnd" item-key="label">
-            <template #item="{ element, index }">
-              <div :key="index" class="components-item" @click="addComponent(element)">
-                <div class="components-body">
-                  <svg-icon :icon-class="element.tagIcon" />
-                  {{ element.label }}
-                </div>
-              </div>
-            </template>
-          </draggable>
-          <div class="components-title">
-            <svg-icon icon-class="component" />选择型组件
-          </div>
-          <draggable class="components-draggable" :list="selectComponents"
-            :group="{ name: 'componentsGroup', pull: 'clone', put: false }" :clone="cloneComponent"
-            draggable=".components-item" :sort="false" @end="onEnd" item-key="label">
-            <template #item="{ element, index }">
-              <div :key="index" class="components-item" @click="addComponent(element)">
-                <div class="components-body">
-                  <svg-icon :icon-class="element.tagIcon" />
-                  {{ element.label }}
-                </div>
-              </div>
-            </template>
-          </draggable>
-          <div class="components-title">
-            <svg-icon icon-class="component" /> 布局型组件
-          </div>
-          <draggable class="components-draggable" :list="layoutComponents"
-            :group="{ name: 'componentsGroup', pull: 'clone', put: false }" :clone="cloneComponent"
-            draggable=".components-item" :sort="false" @end="onEnd" item-key="label">
-            <template #item="{ element, index }">
-              <div :key="index" class="components-item" @click="addComponent(element)">
-                <div class="components-body">
-                  <svg-icon :icon-class="element.tagIcon" />
-                  {{ element.label }}
-                </div>
-              </div>
-            </template>
-          </draggable>
-        </div>
-      </el-scrollbar>
-    </div>
-    <div class="center-board">
-      <div class="action-bar">
-        <el-button icon="Download" type="primary" text @click="download">
-          导出vue文件
-        </el-button>
-        <el-button class="copy-btn-main" icon="DocumentCopy" type="primary" text @click="copy">
-          复制代码
-        </el-button>
-        <el-button class="delete-btn" icon="Delete" text @click="empty" type="danger">
-          清空
-        </el-button>
-      </div>
-      <el-scrollbar class="center-scrollbar">
-        <el-row class="center-board-row" :gutter="formConf.gutter">
-          <el-form :size="formConf.size" :label-position="formConf.labelPosition" :disabled="formConf.disabled"
-            :label-width="formConf.labelWidth + 'px'">
-            <draggable class="drawing-board" :list="drawingList" :animation="340" group="componentsGroup"
-              item-key="label">
-              <template #item="{ element, index }">
-                <draggable-item :key="element.renderKey" :drawing-list="drawingList" :element="element" :index="index"
-                  :active-id="activeId" :form-conf="formConf" @activeItem="activeFormItem" @copyItem="drawingItemCopy"
-                  @deleteItem="drawingItemDelete" />
-              </template>
-            </draggable>
-            <div v-show="!drawingList.length" class="empty-info">
-              从左侧拖入或点选组件进行表单设计
-            </div>
-          </el-form>
-        </el-row>
-      </el-scrollbar>
-    </div>
-    <right-panel :active-data="activeData" :form-conf="formConf" :show-field="!!drawingList.length"
-      @tag-change="tagChange" />
-
-    <code-type-dialog v-model="dialogVisible" title="选择生成类型" :showFileName="showFileName" @confirm="generate" />
-    <input id="copyNode" type="hidden">
-  </div>
-</template>
-
-<script setup>
-import draggable from "vuedraggable/dist/vuedraggable.common"
-import ClipboardJS from 'clipboard'
-import beautifier from 'js-beautify'
-import logo from '@/assets/logo/logo.png'
-import { inputComponents, selectComponents, layoutComponents, formConf as formConfData } from '@/utils/generator/config'
-import { beautifierConf } from '@/utils/index'
-import { drawingDefaultValue, initDrawingDefaultValue, cleanDrawingDefaultValue } from '@/utils/generator/drawingDefault'
-import { makeUpHtml, vueTemplate, vueScript, cssStyle } from '@/utils/generator/html'
-import { makeUpJs } from '@/utils/generator/js'
-import { makeUpCss } from '@/utils/generator/css'
-import Download from '@/plugins/download'
-import { ElNotification } from 'element-plus'
-import DraggableItem from './DraggableItem'
-import RightPanel from './RightPanel'
-import CodeTypeDialog from './CodeTypeDialog'
-import { onMounted, watch } from 'vue'
-
-initDrawingDefaultValue()
-
-const drawingList = ref(drawingDefaultValue)
-const { proxy } = getCurrentInstance()
-const dialogVisible = ref(false)
-const showFileName = ref(false)
-const operationType = ref('')
-const idGlobal = ref(100)
-const activeData = ref(drawingDefaultValue[0])
-const activeId = ref(drawingDefaultValue[0].formId)
-const generateConf = ref(null)
-const formData = ref({})
-const formConf = ref(formConfData)
-let oldActiveId
-let tempActiveData
-
-function activeFormItem(element) {
-  activeData.value = element
-  activeId.value = element.formId
-}
-function copy() {
-  dialogVisible.value = true
-  showFileName.value = false
-  operationType.value = 'copy'
-}
-function download() {
-  dialogVisible.value = true
-  showFileName.value = true
-  operationType.value = 'download'
-}
-function empty() {
-  proxy.$modal.confirm('确定要清空所有组件吗?', '提示', { type: 'warning' }).then(() => {
-      idGlobal.value = 100
-      drawingList.value = []
-      cleanDrawingDefaultValue()
-    }
-  )
-}
-
-function onEnd(obj, a) {
-  if (obj.from !== obj.to) {
-    activeData.value = tempActiveData
-    activeId.value = idGlobal.value
-  }
-}
-
-function addComponent(item) {
-  const clone = cloneComponent(item)
-  drawingList.value.push(clone)
-  activeFormItem(clone)
-}
-
-function cloneComponent(origin) {
-  const clone = JSON.parse(JSON.stringify(origin))
-  clone.formId = ++idGlobal.value
-  clone.span = formConf.value.span
-  clone.renderKey = +new Date() // 改变renderKey后可以实现强制更新组件
-  if (!clone.layout) clone.layout = 'colFormItem'
-  if (clone.layout === 'colFormItem') {
-    clone.vModel = `field${idGlobal.value}`
-    clone.placeholder !== undefined && (clone.placeholder += clone.label)
-    tempActiveData = clone
-  } else if (clone.layout === 'rowFormItem') {
-    delete clone.label
-    clone.componentName = `row${idGlobal.value}`
-    clone.gutter = formConf.value.gutter
-    tempActiveData = clone
-  }
-  return tempActiveData
-}
-
-function drawingItemCopy(item, parent) {
-  let clone = JSON.parse(JSON.stringify(item))
-  clone = createIdAndKey(clone)
-  parent.push(clone)
-  activeFormItem(clone)
-}
-
-
-function createIdAndKey(item) {
-  item.formId = ++idGlobal.value
-  item.renderKey = +new Date()
-  if (item.layout === 'colFormItem') {
-    item.vModel = `field${idGlobal.value}`
-  } else if (item.layout === 'rowFormItem') {
-    item.componentName = `row${idGlobal.value}`
-  }
-  if (Array.isArray(item.children)) {
-    item.children = item.children.map(childItem => createIdAndKey(childItem))
-  }
-  return item
-}
-
-function drawingItemDelete(index, parent) {
-  parent.splice(index, 1)
-  nextTick(() => {
-    const len = drawingList.value.length
-    if (len) {
-      activeFormItem(drawingList.value[len - 1])
-    }
-  })
-}
-
-function tagChange(newTag) {
-  newTag = cloneComponent(newTag)
-  newTag.vModel = activeData.value.vModel
-  newTag.formId = activeId.value
-  newTag.span = activeData.value.span
-  delete activeData.value.tag
-  delete activeData.value.tagIcon
-  delete activeData.value.document
-  Object.keys(newTag).forEach(key => {
-    if (activeData.value[key] !== undefined
-      && typeof activeData.value[key] === typeof newTag[key]) {
-      newTag[key] = activeData.value[key]
-    }
-  })
-  activeData.value = newTag
-  updateDrawingList(newTag, drawingList.value)
-}
-
-
-function updateDrawingList(newTag, list) {
-  const index = list.findIndex(item => item.formId === activeId.value)
-  if (index > -1) {
-    list.splice(index, 1, newTag)
-  } else {
-    list.forEach(item => {
-      if (Array.isArray(item.children)) updateDrawingList(newTag, item.children)
-    })
-  }
-}
-function generate(data) {
-  generateConf.value = data
-  nextTick(() => {
-    switch (operationType.value) {
-      case 'copy':
-        execCopy(data)
-        break
-      case 'download':
-        execDownload(data)
-        break
-      default:
-        break
-    }
-  })
-}
-
-function execDownload(data) {
-  const codeStr = generateCode()
-  const blob = new Blob([codeStr], { type: 'text/plain;charset=utf-8' })
-  Download.saveAs(blob, data.fileName)
-}
-
-function execCopy(data) {
-  document.getElementById('copyNode').click()
-}
-function AssembleFormData() {
-  formData.value = { fields: JSON.parse(JSON.stringify(drawingList.value)), ...formConf.value }
-}
-function generateCode() {
-  const { type } = generateConf.value
-  AssembleFormData()
-  const script = vueScript(makeUpJs(formData.value, type))
-  const html = vueTemplate(makeUpHtml(formData.value, type))
-  const css = cssStyle(makeUpCss(formData.value))
-  return beautifier.html(html + script + css, beautifierConf.html)
-}
-watch(() => activeData.value.label, (val, oldVal) => {
-  if (
-    activeData.value.placeholder === undefined
-    || !activeData.value.tag
-    || oldActiveId !== activeId.value
-  ) {
-    return
-  }
-  activeData.value.placeholder = activeData.value.placeholder.replace(oldVal, '') + val
-})
-watch(activeId, (val) => {
-  oldActiveId = val
-}, { immediate: true })
-
-let clipboard = null
-onMounted(() => {
-  clipboard = new ClipboardJS('#copyNode', {
-    text: trigger => {
-      const codeStr = generateCode()
-      ElNotification({ title: '成功', message: '代码已复制到剪切板,可粘贴。', type: 'success' })
-      return codeStr
-    }
-  })
-  clipboard.on('error', e => {
-    proxy.$modal.msgError('代码复制失败')
-  })
-})
-onUnmounted(() => {
-  clipboard.destroy()
-})
-</script>
-
-<style lang='scss'>
-$lighterBlue: #409EFF;
-
-.container {
-  position: relative;
-  width: 100%;
-  background-color: var(--el-bg-color-overlay);
-  height: calc(100vh - 50px - 40px);
-  overflow: hidden;
-
-  .left-board {
-    width: 260px;
-    position: absolute;
-    left: 0;
-    top: 0;
-    height: calc(100vh - 50px - 40px);
-
-    .logo-wrapper {
-      position: relative;
-      height: 42px;
-      border-bottom: 1px solid var(--el-border-color-extra-light);
-      box-sizing: border-box;
-
-      .logo {
-        position: absolute;
-        left: 12px;
-        top: 6px;
-        line-height: 30px;
-        color: #00afff;
-        font-weight: 600;
-        font-size: 17px;
-        white-space: nowrap;
-
-        >img {
-          width: 30px;
-          height: 30px;
-          vertical-align: top;
-        }
-
-        .github {
-          display: inline-block;
-          vertical-align: sub;
-          margin-left: 15px;
-
-          >img {
-            height: 22px;
-          }
-        }
-      }
-    }
-
-    .left-scrollbar {
-      .el-scrollbar__wrap {
-        box-sizing: border-box;
-        overflow-x: hidden !important;
-        margin-bottom: 0 !important;
-
-        .components-list {
-          padding: 8px;
-          box-sizing: border-box;
-          height: 100%;
-
-          .components-title {
-            font-size: 14px;
-            // color: #222;
-            margin: 6px 2px;
-
-            .svg-icon {
-              // color: #666;
-              font-size: 18px;
-              margin-right: 5px;
-            }
-          }
-
-          .components-draggable {
-            padding-bottom: 20px;
-
-            .components-item {
-              display: inline-block;
-              width: 48%;
-              margin: 1%;
-              transition: transform 0ms !important;
-
-              .components-body {
-                padding: 8px 10px;
-                background: var(--el-border-color-extra-light);
-                font-size: 12px;
-                cursor: move;
-                border: 1px dashed var(--el-border-color-extra-light);
-                border-radius: 3px;
-
-                .svg-icon {
-                  // color: #777;
-                  font-size: 15px;
-                  margin-right: 5px;
-                }
-
-                &:hover {
-                  border: 1px dashed #787be8;
-                  color: #787be8;
-
-                  .svg-icon {
-                    color: #787be8;
-                  }
-                }
-              }
-            }
-          }
-
-
-        }
-      }
-    }
-  }
-
-  .center-board {
-    height: calc(100vh - 50px - 40px);
-    width: auto;
-    margin: 0 350px 0 260px;
-    box-sizing: border-box;
-
-    .action-bar {
-      position: relative;
-      height: 42px;
-      padding: 0 15px;
-      box-sizing: border-box;
-      ;
-      border: 1px solid var(--el-border-color-extra-light);
-      border-top: none;
-      border-left: none;
-      display: flex;
-      align-items: center;
-      justify-content: flex-end;
-
-      u .delete-btn {
-        color: #F56C6C;
-      }
-    }
-
-    .center-scrollbar {
-      height: calc(100vh - 50px - 40px - 42px);
-      overflow: hidden;
-      border-left: 1px solid var(--el-border-color-extra-light);
-      border-right: 1px solid var(--el-border-color-extra-light);
-      box-sizing: border-box;
-
-      .el-scrollbar__view {
-        overflow-x: hidden;
-      }
-
-      .center-board-row {
-        padding: 12px 12px 15px 12px;
-        box-sizing: border-box;
-
-        &>.el-form {
-          // 69 = 12+15+42
-          height: calc(100vh - 50px - 40px - 69px);
-          flex: 1;
-
-          .drawing-board {
-            height: 100%;
-            position: relative;
-
-            .components-body {
-              padding: 0;
-              margin: 0;
-              font-size: 0;
-            }
-
-            .sortable-ghost {
-              position: relative;
-              display: block;
-              overflow: hidden;
-
-              &::before {
-                content: " ";
-                position: absolute;
-                left: 0;
-                right: 0;
-                top: 0;
-                height: 3px;
-                background: rgb(89, 89, 223);
-                z-index: 2;
-              }
-            }
-
-            .components-item.sortable-ghost {
-              width: 100%;
-              height: 60px;
-              background: var(--el-border-color-extra-light);
-            }
-
-            .active-from-item {
-              &>.el-form-item {
-                background: var(--el-border-color-extra-light);
-                border-radius: 6px;
-              }
-
-              &>.drawing-item-copy,
-              &>.drawing-item-delete {
-                display: initial;
-              }
-
-              &>.component-name {
-                color: $lighterBlue;
-              }
-
-              .el-input__wrapper {
-                box-shadow: 0 0 0 1px var(--el-input-hover-border-color) inset;
-              }
-            }
-
-            .el-form-item {
-              margin-bottom: 15px;
-            }
-          }
-
-          .drawing-item {
-            position: relative;
-            cursor: move;
-
-            &.unfocus-bordered:not(.activeFromItem)>div:first-child {
-              border: 1px dashed #ccc;
-            }
-
-            .el-form-item {
-              padding: 12px 10px;
-            }
-          }
-
-          .drawing-row-item {
-            position: relative;
-            cursor: move;
-            box-sizing: border-box;
-            border: 1px dashed #ccc;
-            border-radius: 3px;
-            padding: 0 2px;
-            margin-bottom: 15px;
-
-            .drawing-row-item {
-              margin-bottom: 2px;
-            }
-
-            .el-col {
-              margin-top: 22px;
-            }
-
-            .el-form-item {
-              margin-bottom: 0;
-            }
-
-            .drag-wrapper {
-              min-height: 80px;
-              flex: 1;
-              display: flex;
-              flex-wrap: wrap;
-            }
-
-            &.active-from-item {
-              border: 1px dashed $lighterBlue;
-            }
-
-            .component-name {
-              position: absolute;
-              top: 0;
-              left: 0;
-              font-size: 12px;
-              color: #bbb;
-              display: inline-block;
-              padding: 0 6px;
-            }
-          }
-
-          .drawing-item,
-          .drawing-row-item {
-            &:hover {
-              &>.el-form-item {
-                background: var(--el-border-color-extra-light);
-                border-radius: 6px;
-              }
-
-              &>.drawing-item-copy,
-              &>.drawing-item-delete {
-                display: initial;
-              }
-            }
-
-            &>.drawing-item-copy,
-            &>.drawing-item-delete {
-              display: none;
-              position: absolute;
-              top: -10px;
-              width: 22px;
-              height: 22px;
-              line-height: 22px;
-              text-align: center;
-              border-radius: 50%;
-              font-size: 12px;
-              border: 1px solid;
-              cursor: pointer;
-              z-index: 1;
-            }
-
-            &>.drawing-item-copy {
-              right: 56px;
-              border-color: $lighterBlue;
-              color: $lighterBlue;
-              background: #fff;
-
-              &:hover {
-                background: $lighterBlue;
-                color: #fff;
-              }
-            }
-
-            &>.drawing-item-delete {
-              right: 24px;
-              border-color: #F56C6C;
-              color: #F56C6C;
-              background: #fff;
-
-              &:hover {
-                background: #F56C6C;
-                color: #fff;
-              }
-            }
-          }
-
-          .empty-info {
-            position: absolute;
-            top: 46%;
-            left: 0;
-            right: 0;
-            text-align: center;
-            font-size: 18px;
-            color: #ccb1ea;
-            letter-spacing: 4px;
-          }
-
-        }
-      }
-    }
-  }
-}
-</style>