hfxc226 2 years ago
parent
commit
3f47172cad

+ 1 - 0
package.json

@@ -22,6 +22,7 @@
     "enquire.js": "^2.1.6",
     "jquery": "^3.2.1",
     "jssha": "^2.3.1",
+    "k-form-design": "^3.7.91",
     "lodash.get": "^4.4.2",
     "lodash.pick": "^4.4.0",
     "md5": "^2.2.1",

+ 129 - 0
src/api/design/designForm.js

@@ -0,0 +1,129 @@
+import { axios } from '@/utils/request'
+import { stringify } from 'qs'
+
+/**
+ * page func
+ * parameter: { }
+ * @param parameter
+ * @returns {*}
+ */
+export function getDesignFormPage (parameter) {
+    return axios({
+        url: '/design/design-forms/page?' + stringify(parameter),
+        method: 'get',
+        headers: {
+            'Content-Type': 'application/json;charset=UTF-8'
+        }
+    })
+}
+
+/**
+ * add func
+ * parameter: { }
+ * @param parameter
+ * @returns {*}
+ */
+export function addDesignForm (parameter) {
+    return axios({
+        url: '/design/design-forms',
+        method: 'POST',
+        headers: {
+            'Accept': 'application/json',
+            'Content-Type': 'application/json;charset=UTF-8'
+        },
+        data: parameter
+    })
+}
+
+/**
+ * update func
+ * parameter: { }
+ * @param parameter
+ * @returns {*}
+ */
+export function updateDesignForm (parameter) {
+    return axios({
+        url: '/design/design-forms/' + parameter.id,
+        method: 'PUT',
+        data: parameter
+    })
+}
+
+                                    
+/**
+ * fetch single func
+ * parameter: { }
+ * @param parameter
+ * @returns {*}
+ */
+export function fetchDesignForm (parameter) {
+    return axios({
+        url: '/design/design-forms/' + parameter.id,
+        method: 'get',
+        headers: {
+            'Content-Type': 'application/json;charset=UTF-8'
+        }
+    })
+}
+
+/**
+ * query list func
+ * parameter: { }
+ * @param parameter
+ * @returns {*}
+ */
+export function queryDesignForm (parameter) {
+    return axios({
+        url: '/design/design-forms?' + stringify(parameter),
+        method: 'get',
+        headers: {
+            'Content-Type': 'application/json;charset=UTF-8'
+        }
+    })
+}
+
+/**
+ * delete batch func
+ * parameter: { }
+ * @param parameter
+ * @returns {*}
+ */
+export function deleteDesignForms (parameter) {
+    return axios({
+        url: '/design/design-forms',
+        method: 'DELETE',
+        data: parameter
+    })
+}
+
+/**
+ * delete single func
+ * parameter: { }
+ * @param parameter
+ * @returns {*}
+ */
+export function deleteDesignForm (parameter) {
+    return axios({
+        url: '/design/design-forms/' + parameter.id,
+        method: 'DELETE',
+        data: parameter
+    })
+}
+
+
+/**
+ * export file
+ * parameter: { }
+ * @param parameter :
+ * @returns {*}
+ */
+export function exportDesignForm (parameter) {
+    return axios({
+        url: '/design/design-forms/export?' + stringify(parameter),
+        method: 'get',
+        headers: {
+            'Content-Type': 'application/json;charset=UTF-8'
+        },
+        responseType: 'blob'
+    })
+}

+ 3 - 0
src/main.js

@@ -20,7 +20,10 @@ import BaseTool from './utils/install'
 import echarts from 'echarts'
 import VueI18n from 'vue-i18n'
 import Print from 'vue-print-nb'
+import KFormDesign from 'k-form-design'
+import 'k-form-design/lib/k-form-design.css'
 
+Vue.use(KFormDesign)
 Vue.use(Print) // 注册
 
 Vue.prototype.$echarts = echarts

+ 10 - 19
src/router/generator-platform-routers.js

@@ -216,11 +216,14 @@ const constantRouterComponents = {
   'PurchaseOrder': () => import('@/views/purchase/purchase-order/PurchaseOrder'),
   'PurchaseApply': () => import('@/views/purchase/purchase-apply/PurchaseApply'),
   'PurchaseDispatchOrderPage': () => import('@/views/purchase/purchase-dispatch-order/PurchaseDispatchOrderPage'),
-
+  // 审批
   'Model': () => import('@/views/activiti/model/Model'),
   'Flow': () => import('@/views/activiti/flow/Flow'),
-  'MyTask': () => import('@/views/activiti/task/MyTask'),
+  'MyTask': () => import('@/views/activiti/task/MyTask'),// 我的待办
+  'MyTaskFinish': () => import('@/views/activiti/task/MyTaskFinish'), // 我的已办
+  'MyStart': () => import('@/views/activiti/task/MyStart'), // 我的申请
   'ActivitiUserModel': () => import('@/views/activiti/user-model/ActivitiUserModel'),
+  'DesignForm': () => import('@/views/design/designForm/DesignForm'),
   // 调拨申请
   'SbAllocateApply': () => import('@/views/sb/allocate-apply/ProjectSbAllocateApply'),
   'GroupToProjectSbAllocateApply': () => import('@/views/sb/allocate-apply/GroupToProjectSbAllocateApply'),
@@ -361,26 +364,14 @@ export const constantRouterMap = [
     ]
   },
   {
-    path: '/screen',
-    component: BlankLayout,
-    redirect: '/screen/leader',
-    children: [
-      {
-        path: 'leader',
-        name: 'LeaderScreen',
-        component: () => import('@/views/big-screen/LeaderScreen')
-      }
-    ]
-  },
-  {
-    path: '/chartReport',
+    path: '/kdesign',
     component: BlankLayout,
-    redirect: '/chart/report',
+    redirect: '/kdesign/design',
     children: [
       {
-        path: 'ChartReport',
-        name: 'ChartReport',
-        component: () => import('@/views/dashboard/template/ChartReport')
+        path: 'design',
+        name: 'design',
+        component: () => import('@/views/kdesign/Design')
       }
     ]
   },

+ 202 - 0
src/views/activiti/task/MyStart.vue

@@ -0,0 +1,202 @@
+<template>
+  <a-card :bordered="false">
+    <div v-if="visible">
+      <div class="table-page-search-wrapper">
+        <a-form layout="inline">
+          <a-row :gutter="48">
+            <a-col :md="8" :sm="24">
+              <a-form-item label="关键字">
+                <a-input v-model.trim="queryParam.keyword" placeholder="请输入名称/类型名称"/>
+              </a-form-item>
+            </a-col>
+            <a-col :md="8 || 24" :sm="24">
+              <span class="table-page-search-submitButtons">
+                <a-button type="primary" @click="$refs.table.refresh(true)">查询</a-button>
+                <a-button style="margin-left: 8px" @click="resetSearchForm">重置</a-button>
+              </span>
+            </a-col>
+          </a-row>
+        </a-form>
+      </div>
+
+      <s-table
+        ref="table"
+        size="small"
+        rowKey="id"
+        :columns="columns"
+        :data="loadData"
+        showPagination="auto"
+      >
+        <span slot="action" slot-scope="record">
+          <template>
+            <a @click="handleAudit(record)">审批</a>
+            <a-divider type="vertical" />
+            <a @click="handleChange(record)">转签</a>
+          </template>
+        </span>
+      </s-table>
+    </div>
+    <audit ref="auditModal" @ok="handleOk"/>
+    <suplier-audit-form ref="supplierAuditModal" @ok="handleOk"/>
+    <detail-audit-scrap ref="detailAuditScrapModal" @ok="handleOk"/>
+    <assign-form ref="assignForm" @ok="handleOk"/>
+  </a-card>
+</template>
+
+<script>
+import { STable, Ellipsis } from '@/components'
+import Audit from '../audit/Audit'
+import AssignForm from './modules/AssignForm'
+import SuplierAuditForm from '@/views/purchase/supplier/modules/AuditForm'
+import DetailAuditScrap from '@/views/sb/scrap/modules/DetailAuditScrap'
+import { getTaskPage } from '@/api/activiti/activiti'
+
+export default {
+  name: 'TaskList',
+  components: {
+    STable,
+    Ellipsis,
+    SuplierAuditForm,
+    Audit,
+    DetailAuditScrap,
+    AssignForm
+  },
+  data () {
+    return {
+      mdl: {},
+      // 查询参数
+      queryParam: {
+      },
+      // 表头
+      columns: [
+        {
+          title: '序号',
+          dataIndex: 'index',
+          customRender: (text, record, index) => {
+            return `${(this.$refs.table.localPagination.current - 1) * this.$refs.table.localPagination.pageSize + index + 1}`
+          }
+        },
+        {
+          title: '类型',
+          dataIndex: 'targetCode',
+          customRender: (text, record, index) => {
+            if (text === 'supplier') {
+              return '供应商审批'
+            } else if (text === 'sb_info_scrap' || text === '设备报废审批') {
+              return '设备报废审批'
+            }
+          }
+        },
+        {
+          title: '任务名称',
+          dataIndex: 'targetName'
+        },
+        {
+          title: '申请人',
+          dataIndex: 'userName'
+        },
+        {
+          title: '创建时间',
+          dataIndex: 'applyTime'
+        },
+        {
+          title: '操作',
+          key: 'action',
+          width: '220px',
+          align: 'center',
+          scopedSlots: { customRender: 'action' }
+        }
+      ],
+      // 加载数据方法 必须为 Promise 对象
+      loadData: parameter => {
+        return getTaskPage(Object.assign(parameter, this.queryParam))
+          .then(res => {
+            return res.data
+          })
+      },
+      selectedRowKeys: [],
+      selectedRows: [],
+      menus: [],
+      visible: true,
+
+      options: {
+        alert: { show: true, clear: () => { this.selectedRowKeys = [] } },
+        rowSelection: {
+          selectedRowKeys: this.selectedRowKeys,
+          onChange: this.onSelectChange
+        }
+      },
+      optionAlertShow: false
+    }
+  },
+  created () {
+    this.tableOption()
+  },
+  methods: {
+    tableOption () {
+      if (!this.optionAlertShow) {
+        this.options = {
+          alert: { show: true, clear: () => { this.selectedRowKeys = [] } },
+          rowSelection: {
+            selectedRowKeys: this.selectedRowKeys,
+            onChange: this.onSelectChange,
+            getCheckboxProps: record => ({
+              props: {
+                disabled: false,
+                name: record.id
+              }
+            })
+          }
+        }
+        this.optionAlertShow = true
+      } else {
+        this.options = {
+          alert: false,
+          rowSelection: null
+        }
+        this.optionAlertShow = false
+      }
+    },
+    handleAudit (record) {
+      this.visible = false
+      if (record.targetCode === 'purchase_plan') {
+        this.$refs.purchasePlanAuditModal.base(record)
+      } else if (record.targetCode === 'purchase_apply') {
+        this.$refs.purchaseApplyAuditModal.base(record)
+      } else if (record.targetCode === 'purchase_demand_plan') {
+        this.$refs.purchaseDemandPlanAuditModal.base(record)
+      } else if (record.targetCode === 'purchase_demand_plan_add') {
+        this.$refs.purchaseDemandPlanAuditAddModal.base(record)
+      } else if (record.targetCode === 'purchase_bid') {
+        this.$refs.purchaseBidAuditAddModal.base(record)
+      } else if (record.targetCode === 'supplier') {
+        this.$refs.supplierAuditModal.base(record)
+      } else if (record.targetCode === 'sb_info_scrap' || record.targetCode === '设备报废审批') {
+        this.$refs.detailAuditScrapModal.base(record)
+      } else if (record.targetCode === 'sb_info_scrap_second') {
+        this.$refs.detailAuditScrapSecondModal.base(record)
+      }
+      // this.$refs.auditModal.base(record)
+    },
+    handleChange (record) {
+      this.$refs.assignForm.base(record)
+    },
+    handleOk () {
+      this.visible = true
+      this.$refs.table.refresh()
+    },
+    onSelectChange (selectedRowKeys, selectedRows) {
+      this.selectedRowKeys = selectedRowKeys
+      this.selectedRows = selectedRows
+    },
+    resetSearchForm () {
+      this.queryParam = {
+      }
+      this.$refs.table.refresh(true)
+    }
+  }
+}
+</script>
+<style lang="less" scoped>
+
+</style>

+ 202 - 0
src/views/activiti/task/MyTaskFinish.vue

@@ -0,0 +1,202 @@
+<template>
+  <a-card :bordered="false">
+    <div v-if="visible">
+      <div class="table-page-search-wrapper">
+        <a-form layout="inline">
+          <a-row :gutter="48">
+            <a-col :md="8" :sm="24">
+              <a-form-item label="关键字">
+                <a-input v-model.trim="queryParam.keyword" placeholder="请输入名称/类型名称"/>
+              </a-form-item>
+            </a-col>
+            <a-col :md="8 || 24" :sm="24">
+              <span class="table-page-search-submitButtons">
+                <a-button type="primary" @click="$refs.table.refresh(true)">查询</a-button>
+                <a-button style="margin-left: 8px" @click="resetSearchForm">重置</a-button>
+              </span>
+            </a-col>
+          </a-row>
+        </a-form>
+      </div>
+
+      <s-table
+        ref="table"
+        size="small"
+        rowKey="id"
+        :columns="columns"
+        :data="loadData"
+        showPagination="auto"
+      >
+        <span slot="action" slot-scope="record">
+          <template>
+            <a @click="handleAudit(record)">审批</a>
+            <a-divider type="vertical" />
+            <a @click="handleChange(record)">转签</a>
+          </template>
+        </span>
+      </s-table>
+    </div>
+    <audit ref="auditModal" @ok="handleOk"/>
+    <suplier-audit-form ref="supplierAuditModal" @ok="handleOk"/>
+    <detail-audit-scrap ref="detailAuditScrapModal" @ok="handleOk"/>
+    <assign-form ref="assignForm" @ok="handleOk"/>
+  </a-card>
+</template>
+
+<script>
+import { STable, Ellipsis } from '@/components'
+import Audit from '../audit/Audit'
+import AssignForm from './modules/AssignForm'
+import SuplierAuditForm from '@/views/purchase/supplier/modules/AuditForm'
+import DetailAuditScrap from '@/views/sb/scrap/modules/DetailAuditScrap'
+import { getTaskPage } from '@/api/activiti/activiti'
+
+export default {
+  name: 'TaskList',
+  components: {
+    STable,
+    Ellipsis,
+    SuplierAuditForm,
+    Audit,
+    DetailAuditScrap,
+    AssignForm
+  },
+  data () {
+    return {
+      mdl: {},
+      // 查询参数
+      queryParam: {
+      },
+      // 表头
+      columns: [
+        {
+          title: '序号',
+          dataIndex: 'index',
+          customRender: (text, record, index) => {
+            return `${(this.$refs.table.localPagination.current - 1) * this.$refs.table.localPagination.pageSize + index + 1}`
+          }
+        },
+        {
+          title: '类型',
+          dataIndex: 'targetCode',
+          customRender: (text, record, index) => {
+            if (text === 'supplier') {
+              return '供应商审批'
+            } else if (text === 'sb_info_scrap' || text === '设备报废审批') {
+              return '设备报废审批'
+            }
+          }
+        },
+        {
+          title: '任务名称',
+          dataIndex: 'targetName'
+        },
+        {
+          title: '申请人',
+          dataIndex: 'userName'
+        },
+        {
+          title: '创建时间',
+          dataIndex: 'applyTime'
+        },
+        {
+          title: '操作',
+          key: 'action',
+          width: '220px',
+          align: 'center',
+          scopedSlots: { customRender: 'action' }
+        }
+      ],
+      // 加载数据方法 必须为 Promise 对象
+      loadData: parameter => {
+        return getTaskPage(Object.assign(parameter, this.queryParam))
+          .then(res => {
+            return res.data
+          })
+      },
+      selectedRowKeys: [],
+      selectedRows: [],
+      menus: [],
+      visible: true,
+
+      options: {
+        alert: { show: true, clear: () => { this.selectedRowKeys = [] } },
+        rowSelection: {
+          selectedRowKeys: this.selectedRowKeys,
+          onChange: this.onSelectChange
+        }
+      },
+      optionAlertShow: false
+    }
+  },
+  created () {
+    this.tableOption()
+  },
+  methods: {
+    tableOption () {
+      if (!this.optionAlertShow) {
+        this.options = {
+          alert: { show: true, clear: () => { this.selectedRowKeys = [] } },
+          rowSelection: {
+            selectedRowKeys: this.selectedRowKeys,
+            onChange: this.onSelectChange,
+            getCheckboxProps: record => ({
+              props: {
+                disabled: false,
+                name: record.id
+              }
+            })
+          }
+        }
+        this.optionAlertShow = true
+      } else {
+        this.options = {
+          alert: false,
+          rowSelection: null
+        }
+        this.optionAlertShow = false
+      }
+    },
+    handleAudit (record) {
+      this.visible = false
+      if (record.targetCode === 'purchase_plan') {
+        this.$refs.purchasePlanAuditModal.base(record)
+      } else if (record.targetCode === 'purchase_apply') {
+        this.$refs.purchaseApplyAuditModal.base(record)
+      } else if (record.targetCode === 'purchase_demand_plan') {
+        this.$refs.purchaseDemandPlanAuditModal.base(record)
+      } else if (record.targetCode === 'purchase_demand_plan_add') {
+        this.$refs.purchaseDemandPlanAuditAddModal.base(record)
+      } else if (record.targetCode === 'purchase_bid') {
+        this.$refs.purchaseBidAuditAddModal.base(record)
+      } else if (record.targetCode === 'supplier') {
+        this.$refs.supplierAuditModal.base(record)
+      } else if (record.targetCode === 'sb_info_scrap' || record.targetCode === '设备报废审批') {
+        this.$refs.detailAuditScrapModal.base(record)
+      } else if (record.targetCode === 'sb_info_scrap_second') {
+        this.$refs.detailAuditScrapSecondModal.base(record)
+      }
+      // this.$refs.auditModal.base(record)
+    },
+    handleChange (record) {
+      this.$refs.assignForm.base(record)
+    },
+    handleOk () {
+      this.visible = true
+      this.$refs.table.refresh()
+    },
+    onSelectChange (selectedRowKeys, selectedRows) {
+      this.selectedRowKeys = selectedRowKeys
+      this.selectedRows = selectedRows
+    },
+    resetSearchForm () {
+      this.queryParam = {
+      }
+      this.$refs.table.refresh(true)
+    }
+  }
+}
+</script>
+<style lang="less" scoped>
+
+</style>

+ 265 - 0
src/views/design/designForm/DesignForm.vue

@@ -0,0 +1,265 @@
+<template>
+  <a-card :bordered="false">
+    <div v-show="visible">
+      <div class="table-page-search-wrapper" @keyup.enter="handleEnter">
+        <a-form layout="inline">
+          <a-row :gutter="48" v-show="advanced">
+            <a-col :md="6" :sm="24">
+              <a-form-item label="关键字">
+                <a-input v-model="queryParam.keyword" placeholder="请输入名称/类型名称"/>
+              </a-form-item>
+            </a-col>
+          </a-row>
+          <a-row :gutter="48">
+            <a-col :md="24 || 24" :sm="24" style="text-align: right">
+              <span class="table-page-search-submitButtons">
+                <a-button type="primary" @click="$refs.table.refresh(true)">查询</a-button>
+                <a-button style="margin-left: 8px" @click="resetSearchForm">重置</a-button>
+                <a @click="()=>{ this.advanced = !this.advanced}" style="margin-left: 8px">
+                  {{ advanced ? '收起' : '展开' }}
+                  <a-icon :type="advanced ? 'up' : 'down'"/>
+                </a>
+              </span>
+            </a-col>
+          </a-row>
+        </a-form>
+      </div>
+
+      <div class="table-operator" style="margin-bottom: 8px;">
+        <a-row>
+          <a-col :md="16">
+            <a-button v-if="$auth('design-design-forms-add')" type="primary" icon="plus" @click="handleAdd()">新增</a-button>
+            <a-button style="margin-left: 8px" v-if="$auth('design-design-forms-export')" type="primary" icon="download" @click="doExport">导出</a-button>
+            <a-dropdown v-action:edit v-if="selectedRowKeys.length > 0 && $auth('design-design-forms-del')">
+              <a-menu slot="overlay">
+                <a-popconfirm title="是否要删除所选数据?" @confirm="batchDelete()">
+                  <a-menu-item key="1"><a-icon type="delete" /><a>删除</a></a-menu-item>
+                </a-popconfirm>
+              </a-menu>
+              <a-button style="margin-left: 8px">
+                批量操作 <a-icon type="down" />
+              </a-button>
+            </a-dropdown>
+          </a-col>
+        </a-row>
+      </div>
+
+      <s-table
+        ref="table"
+        size="default"
+        rowKey="id"
+        :columns="columns"
+        :data="loadData"
+        :alert="options.alert"
+        :rowSelection="options.rowSelection"
+        showPagination="auto"
+      >
+        <span slot="action" slot-scope="record">
+          <template>
+            <a @click="handleView(record)">查看</a>
+            <operation-button
+              v-if="$auth('design-design-forms-edit')"
+              @click="handleEdit(record)"
+            >修改</operation-button>
+            <operation-button
+              v-if="$auth('design-design-forms-del')"
+              :type="2"
+              title="是否要删除该条数据?"
+              @confirm="batchDelete(record.id)">删除</operation-button>
+          </template>
+        </span>
+      </s-table>
+    </div>
+    <base-form ref="baseModal" @ok="handleOk"/>
+    <detail ref="detailModal" @ok="handleOk"/>
+  </a-card>
+</template>
+
+<script>
+import { STable, Ellipsis } from '@/components'
+import BaseForm from './modules/BaseForm'
+import Detail from './modules/Detail'
+import { getDesignFormPage, deleteDesignForms, fetchDesignForm, exportDesignForm } from '@/api/design/designForm'
+
+export default {
+  name: 'DesignFormList',
+  components: {
+    STable,
+    Ellipsis,
+    BaseForm,
+    Detail
+  },
+  data () {
+    return {
+      advanced: false,
+      visible: true,
+      // 查询参数
+      queryParam: {
+      },
+      // 表头
+      columns: [
+        {
+          title: '序号',
+          dataIndex: 'index',
+          customRender: (text, record, index) => {
+            return `${(this.$refs.table.localPagination.current - 1) * this.$refs.table.localPagination.pageSize + index + 1}`
+          }
+        },
+        {
+          title: '表单代号',
+          dataIndex: 'code'
+        },
+        {
+          title: '表单名称',
+          dataIndex: 'name'
+        },
+        {
+          title: '表单类型。0:简单表单;1:复杂表单;',
+          dataIndex: 'type'
+        },
+        {
+          title: '表单主题。不配置默认为表单名称',
+          dataIndex: 'theme'
+        },
+        {
+          title: '表单设计数据。',
+          dataIndex: 'designData'
+        },
+        {
+          title: '表单js代码。仅当复杂表单才有',
+          dataIndex: 'jsCode'
+        },
+        {
+          title: '创建时间',
+          dataIndex: 'createTime'
+        },
+        {
+          title: '操作',
+          key: 'action',
+          width: '200px',
+          align: 'center',
+          scopedSlots: { customRender: 'action' }
+        }
+      ],
+      // 下拉框map
+      // 加载数据方法 必须为 Promise 对象
+      loadData: parameter => {
+        parameter = {
+          ...parameter,
+          ...this.queryParam,
+          dataScope: {
+            sortBy: 'desc',
+            sortName: 'update_time'
+          }
+        }
+        return getDesignFormPage(Object.assign(parameter, this.queryParam))
+          .then(res => {
+            return res.data
+          })
+      },
+      selectedRowKeys: [],
+      selectedRows: [],
+
+      options: {
+        alert: { show: true, clear: () => { this.selectedRowKeys = [] } },
+        rowSelection: {
+          selectedRowKeys: this.selectedRowKeys,
+          onChange: this.onSelectChange
+        }
+      },
+      optionAlertShow: false
+    }
+  },
+  created () {
+    // 下拉框map
+    this.tableOption()
+  },
+  methods: {
+    tableOption () {
+      if (!this.optionAlertShow) {
+        this.options = {
+          alert: { show: true, clear: () => { this.selectedRowKeys = [] } },
+          rowSelection: {
+            selectedRowKeys: this.selectedRowKeys,
+            onChange: this.onSelectChange,
+            getCheckboxProps: record => ({
+              props: {
+                disabled: false,
+                name: record.id
+              }
+            })
+          }
+        }
+        this.optionAlertShow = true
+      } else {
+        this.options = {
+          alert: false,
+          rowSelection: null
+        }
+        this.optionAlertShow = false
+      }
+    },
+    batchDelete (id) {
+      let ids = []
+      if (this.BaseTool.String.isBlank(id)) {
+        const length = this.selectedRows.length
+        if (length === 0) {
+          this.$message.info('请选择要删除的记录')
+          return
+        }
+        ids = this.selectedRows.map(item => item.id)
+      } else {
+        ids = [id]
+      }
+      deleteDesignForms(ids).then(res => {
+        this.$message.info('删除成功')
+        this.handleOk()
+        this.$refs.table.clearSelected()
+      })
+    },
+    handleAdd () {
+      this.visible = false
+      const modal = this.$refs.baseModal
+      modal.base()
+    },
+    handleEdit (record) {
+      this.visible = false
+      fetchDesignForm({ id: record.id }).then(res => {
+        const modal = this.$refs.baseModal
+        modal.base(res.data)
+      })
+    },
+    handleView (record) {
+      this.visible = false
+      fetchDesignForm({ id: record.id }).then(res => {
+        const modal = this.$refs.detailModal
+        modal.base(res.data)
+      })
+    },
+    handleOk (values) {
+      this.visible = true
+      this.$refs.table.refresh()
+    },
+    onSelectChange (selectedRowKeys, selectedRows) {
+      this.selectedRowKeys = selectedRowKeys
+      this.selectedRows = selectedRows
+    },
+    resetSearchForm () {
+      this.queryParam = {
+      }
+      this.$refs.table.refresh(true)
+    },
+    doExport () {
+      const parameter = {
+        ...this.queryParam
+      }
+      exportDesignForm(parameter).then(file => {
+        this.BaseTool.Util.downLoadExportExcel(file)
+      })
+    },
+    handleEnter () {
+      this.$refs.table.refresh(true)
+    }
+  }
+}
+</script>

+ 179 - 0
src/views/design/designForm/modules/BaseForm.vue

@@ -0,0 +1,179 @@
+<template>
+  <a-card :bordered="false" v-show="visible" class="card" :title="modalTitle">
+    <a-row :gutter="48" slot="extra">
+      <a-col :md="48" :sm="48">
+        <span class="table-page-search-submitButtons" style="float: right">
+          <a-button :loading="confirmLoading" type="primary" @click="save()">保存</a-button>
+          <a-button style="margin-left: 8px" type="default" @click="handleCancel()">返回</a-button>
+        </span>
+      </a-col>
+    </a-row>
+    <a-form :form="form">
+
+      <a-form-item v-show="false">
+        <a-input v-decorator="['id']" type="hidden"/>
+      </a-form-item>
+
+      <row-list :col="2">
+        <row-item>
+
+          <a-form-item
+            label="表单代号"
+            :labelCol="BaseTool.Constant.labelCol"
+            :wrapperCol="BaseTool.Constant.wrapperCol"
+          >
+            <a-input
+              v-decorator="['code', {rules: [{required: true, message: '表单代号不能为空'}]}]"/>
+          </a-form-item>
+        </row-item>
+        <row-item>
+
+          <a-form-item
+            label="表单名称"
+            :labelCol="BaseTool.Constant.labelCol"
+            :wrapperCol="BaseTool.Constant.wrapperCol"
+          >
+            <a-input
+              v-decorator="['name', {rules: [{required: true, message: '表单名称不能为空'}]}]"/>
+          </a-form-item>
+        </row-item>
+        <row-item>
+
+          <a-form-item
+            label="表单类型。0:简单表单;1:复杂表单;"
+            :labelCol="BaseTool.Constant.labelCol"
+            :wrapperCol="BaseTool.Constant.wrapperCol"
+          >
+          </a-form-item>
+        </row-item>
+        <row-item>
+
+          <a-form-item
+            label="表单主题。不配置默认为表单名称"
+            :labelCol="BaseTool.Constant.labelCol"
+            :wrapperCol="BaseTool.Constant.wrapperCol"
+          >
+            <a-input
+              v-decorator="['theme', {rules: [{required: true, message: '表单主题。不配置默认为表单名称不能为空'}]}]"/>
+          </a-form-item>
+        </row-item>
+        <row-item>
+
+          <a-form-item
+            label="表单设计数据。"
+            :labelCol="BaseTool.Constant.labelCol"
+            :wrapperCol="BaseTool.Constant.wrapperCol"
+          >
+          </a-form-item>
+        </row-item>
+        <row-item>
+
+          <a-form-item
+            label="表单js代码。仅当复杂表单才有"
+            :labelCol="BaseTool.Constant.labelCol"
+            :wrapperCol="BaseTool.Constant.wrapperCol"
+          >
+          </a-form-item>
+        </row-item>
+        <row-item>
+
+          <a-form-item
+            label="创建时间"
+            :labelCol="BaseTool.Constant.labelCol"
+            :wrapperCol="BaseTool.Constant.wrapperCol"
+          >
+            <a-date-picker
+              showTime
+              style="width: 100%"
+              :format="BaseTool.Date.PICKER_NORM_DATE_PATTERN"
+              v-decorator="['createTime', {rules: [{required: true, message: '创建时间不能为空'}]}]"/>
+          </a-form-item>
+        </row-item>
+      </row-list>
+    </a-form>
+  </a-card>
+</template>
+
+<script>
+import pick from 'lodash.pick'
+import { addDesignForm, updateDesignForm } from '@/api/design/designForm'
+export default {
+  name: 'BaseDesignForm',
+  data () {
+    return {
+      confirmLoading: false,
+      modalTitle: null,
+      form: this.$form.createForm(this),
+      visible: false
+      // 下拉框map
+    }
+  },
+  props: {},
+  created () {
+    // 下拉框map
+  },
+  methods: {
+    base (record) {
+      this.visible = true
+      // 如果是空标识添加
+      if (this.BaseTool.Object.isBlank(record)) {
+        this.modalTitle = '添加'
+        return
+      }
+      this.modalTitle = '编辑'
+      const { form: { setFieldsValue } } = this
+      // 日期处理
+      record.createTime = this.BaseTool.Moment(record.createTime, this.BaseTool.Date.PICKER_NORM_DATE_PATTERN)
+      this.$nextTick(() => {
+        setFieldsValue(Object.assign(pick(record, [
+          'id',
+          'code',
+          'name',
+          'type',
+          'theme',
+          'designData',
+          'jsCode',
+          'createTime'
+        ])))
+      })
+    },
+    save () {
+      const { form: { validateFieldsAndScroll } } = this
+      this.confirmLoading = true
+      validateFieldsAndScroll((errors, values) => {
+        if (errors) {
+          this.confirmLoading = false
+          return
+        }
+        // 日期处理
+        values.createTime = this.BaseTool.Date.formatter(values.createTime, this.BaseTool.Date.PICKER_NORM_DATE_PATTERN)
+        if (this.BaseTool.String.isBlank(values.id)) {
+          addDesignForm(values)
+            .then(() => {
+              this.handleCancel(values)
+            }).catch(() => {
+              this.confirmLoading = false
+            })
+        } else {
+          updateDesignForm(values)
+            .then(() => {
+              this.handleCancel(values)
+            }).catch(() => {
+              this.confirmLoading = false
+            })
+        }
+      })
+    },
+    handleCancel (values) {
+      this.visible = false
+      this.confirmLoading = false
+      this.form.resetFields()
+      if (this.BaseTool.Object.isNotBlank(values)) {
+        this.$emit('ok', values)
+      } else {
+        this.$emit('ok')
+      }
+    }
+  }
+}
+</script>

+ 289 - 0
src/views/design/designForm/modules/DesignFormSelectModal.vue

@@ -0,0 +1,289 @@
+<template>
+  <a-modal
+    :title="modalTitle"
+    :width="1000"
+    :visible="visible"
+    :confirmLoading="confirmLoading"
+    class="ant-modal2"
+    @cancel="handleCancel"
+  >
+    <a-card :bordered="false">
+      <div class="table-page-search-wrapper">
+        <a-form layout="inline">
+          <a-row :gutter="48">
+            <a-col :md="6" :sm="24">
+              <a-form-item label="关键字">
+                <a-input v-model="queryParam.keyword" placeholder="请输入名称/类型名称"/>
+              </a-form-item>
+            </a-col>
+            <a-col :md="6 || 24" :sm="24">
+              <span class="table-page-search-submitButtons">
+                <a-button type="primary" @click="$refs.table.refresh(true)">查询</a-button>
+                <a-button style="margin-left: 8px" @click="resetSearchForm">重置</a-button>
+                <a @click="()=>{ this.advanced = !this.advanced}" style="margin-left: 8px">
+                  {{ advanced ? '收起' : '展开' }}
+                  <a-icon :type="advanced ? 'up' : 'down'"/>
+                </a>
+              </span>
+            </a-col>
+          </a-row>
+        </a-form>
+      </div>
+
+      <div class="table-operator">
+      </div>
+
+      <s-table
+        ref="table"
+        size="default"
+        rowKey="id"
+        :columns="columns"
+        :data="loadData"
+        :alert="options.alert"
+        :customRow="options.customRow"
+        :rowSelection="options.rowSelection"
+        showPagination="auto"
+      >
+        <span slot="action" slot-scope="record1">
+          <template>
+            <a @click="handleView(record1)">查看</a>
+          </template>
+        </span>
+      </s-table>
+      <detail ref="detailModal"/>
+    </a-card>
+    <template slot="footer">
+      <a-button :loading="confirmLoading" type="primary" @click="handleCancel()">取消</a-button>
+      <a-button :loading="confirmLoading" type="primary" @click="handleSelect()">确定</a-button>
+    </template>
+  </a-modal>
+</template>
+
+<script>
+import { STable, Ellipsis } from '@/components'
+import Detail from './Detail'
+import { getDesignFormPage, fetchDesignForm } from '@/api/design/designForm'
+
+export default {
+  name: 'DesignFormSelectModal',
+  components: {
+    STable,
+    Ellipsis,
+    Detail
+  },
+  props: {
+    type: {
+      type: String,
+      default: 'radio'
+    },
+    selectedRowKey: {
+      type: Array,
+      default: () => {
+        return []
+      }
+    },
+    selectedRow: {
+      type: Array,
+      default: () => {
+        return []
+      }
+    }
+  },
+  data () {
+    return {
+      advanced: false,
+      confirmLoading: false,
+      mdl: {},
+      modalTitle: null,
+      visible: false,
+      record: null,
+      // 查询参数
+      queryParam: {
+      },
+      extraQueryParam: {
+      },
+      // 表头
+      columns: [
+        {
+          title: '序号',
+          dataIndex: 'index',
+          customRender: (text, record, index) => {
+            return `${(this.$refs.table.localPagination.current - 1) * this.$refs.table.localPagination.pageSize + index + 1}`
+          }
+        },
+        {
+          title: '表单代号',
+          dataIndex: 'code'
+        },
+        {
+          title: '表单名称',
+          dataIndex: 'name'
+        },
+        {
+          title: '表单类型。0:简单表单;1:复杂表单;',
+          dataIndex: 'type'
+        },
+        {
+          title: '表单主题。不配置默认为表单名称',
+          dataIndex: 'theme'
+        },
+        {
+          title: '表单设计数据。',
+          dataIndex: 'designData'
+        },
+        {
+          title: '表单js代码。仅当复杂表单才有',
+          dataIndex: 'jsCode'
+        },
+        {
+          title: '创建时间',
+          dataIndex: 'createTime'
+        },
+        {
+          title: '操作',
+          key: 'action',
+          width: '200px',
+          align: 'center',
+          scopedSlots: { customRender: 'action' }
+        }
+      ],
+      // 下拉框map
+      // 加载数据方法 必须为 Promise 对象
+      loadData: parameter => {
+        parameter = {
+          ...parameter,
+          ...this.queryParam,
+          ...this.extraQueryParam,
+          dataScope: {
+            sortBy: 'desc',
+            sortName: 'update_time'
+          }
+        }
+        return getDesignFormPage(Object.assign(parameter, this.queryParam))
+          .then(res => {
+            return res.data
+          })
+      },
+      selectedRowKeys: [],
+      selectedRows: [],
+
+      options: {
+        alert: { show: true, clear: () => { this.selectedRowKeys = [] } },
+        rowSelection: {
+          selectedRowKeys: this.selectedRowKeys,
+          onChange: this.onSelectChange
+        }
+      },
+      optionAlertShow: false,
+      isCreated: false
+    }
+  },
+  created () {
+    // 下拉框map
+  },
+  methods: {
+    tableOption () {
+      if (!this.optionAlertShow) {
+        this.options = {
+          alert: { show: true, clear: () => { this.selectedRowKeys = [] } },
+          rowSelection: {
+            selectedRowKeys: this.selectedRowKeys,
+            onChange: this.onSelectChange,
+            type: this.type,
+            getCheckboxProps: record => ({
+              props: {
+                disabled: false,
+                name: record.id
+              }
+            })
+          },
+          customRow: (record) => {
+            return {
+              on: { // 事件
+                click: (event) => { // 点击行
+                  // 选择对象
+                  this.mySelect([record.id], [record])
+                },
+                dblclick: (event) => {
+                  this.mySelect([record.id], [record])
+                  this.handleSelect()
+                }
+              }
+            }
+          }
+        }
+        this.optionAlertShow = true
+      } else {
+        this.options = {
+          alert: false,
+          rowSelection: null
+        }
+        this.optionAlertShow = false
+      }
+    },
+    handleView (record) {
+      fetchDesignForm({ id: record.id }).then(res => {
+        const modal = this.$refs.detailModal
+        modal.base(res.data)
+      })
+    },
+    handleOk () {
+      this.$refs.table.refresh()
+    },
+    onSelectChange (selectedRowKeys, selectedRows) {
+      this.selectedRowKeys = selectedRowKeys
+      this.selectedRows = selectedRows
+    },
+    resetSearchForm () {
+      this.queryParam = {
+      }
+      this.$refs.table.refresh(true)
+    },
+    base (record, queryParam = {}) {
+      this.visible = true
+      this.modalTitle = '选择信息'
+      this.extraQueryParam = queryParam
+      this.record = record
+      if (this.isCreated) {
+        this.$refs.table.clearSelected()
+        this.options.rowSelection.type = this.type
+        this.handleOk()
+      } else {
+        this.tableOption()
+        this.isCreated = true
+      }
+    },
+    handleCancel () {
+      this.visible = false
+      this.confirmLoading = false
+    },
+    handleSelect () {
+      if (this.selectedRowKeys.length === 0) {
+        this.$message.warn('请至少选择一项信息')
+      } else {
+        this.confirmLoading = true
+        this.$emit('selected', this.record, this.selectedRowKeys, this.selectedRows)
+        this.confirmLoading = false
+        this.visible = false
+      }
+    },
+    mySelect (selectedRowKeys, selectedRows) {
+      if (this.type === 'radio') {
+        this.$refs.table.updateSelect(selectedRowKeys, selectedRows)
+        this.$refs.table.rowSelection.onChange(selectedRowKeys, selectedRows)
+      } else {
+        let mySelectedRowKeys
+        let mySelectedRows = this.selectedRows.filter(item => item.id !== selectedRowKeys[0])
+        if (this.selectedRowKeys.includes(selectedRowKeys[0])) {
+          mySelectedRowKeys = this.selectedRowKeys.filter(item => item !== selectedRowKeys[0])
+        } else {
+          mySelectedRowKeys = [...selectedRowKeys, ...this.selectedRowKeys]
+          mySelectedRows = [...mySelectedRows, ...selectedRows]
+        }
+        this.$refs.table.updateSelect(mySelectedRowKeys, mySelectedRows)
+        this.$refs.table.rowSelection.onChange(mySelectedRowKeys, mySelectedRows)
+      }
+    }
+  }
+}
+</script>

+ 68 - 0
src/views/design/designForm/modules/Detail.vue

@@ -0,0 +1,68 @@
+<template>
+  <a-card :bordered="false" v-show="visible" class="card" :title="modalTitle">
+    <a-row :gutter="48" slot="extra">
+      <a-col :md="48" :sm="48">
+        <span class="table-page-search-submitButtons" style="float: right">
+          <a-button style="margin-left: 8px" type="default" @click="handleCancel()">返回</a-button>
+        </span>
+      </a-col>
+    </a-row>
+    <detail-list title="" :col="2">
+      <detail-list-item term="表单代号">{{ model.code }}</detail-list-item>
+      <detail-list-item term="表单名称">{{ model.name }}</detail-list-item>
+      <detail-list-item term="表单类型。0:简单表单;1:复杂表单;">{{ model.type }}</detail-list-item>
+      <detail-list-item term="表单主题。不配置默认为表单名称">{{ model.theme }}</detail-list-item>
+      <detail-list-item term="表单设计数据。">{{ model.designData }}</detail-list-item>
+      <detail-list-item term="表单js代码。仅当复杂表单才有">{{ model.jsCode }}</detail-list-item>
+      <detail-list-item term="创建时间">{{ model.createTime }}</detail-list-item>
+      <detail-list-item term="更新时间">{{ model.updateTime }}</detail-list-item>
+    </detail-list>
+  </a-card>
+</template>
+
+<script>
+import DetailList from '@/components/tools/DetailList'
+const DetailListItem = DetailList.Item
+
+export default {
+  name: 'DesignFormDetail',
+  components: {
+    DetailList,
+    DetailListItem
+  },
+  data () {
+    return {
+      confirmLoading: false,
+      mdl: {},
+      modalTitle: null,
+      visible: false,
+      // 下拉框map
+      model: {
+        'code': null,
+        'name': null,
+        'type': null,
+        'theme': null,
+        'designData': null,
+        'jsCode': null,
+        'createTime': null,
+        'updateTime': null
+      }
+    }
+  },
+  created () {
+    // 下拉框map
+
+  },
+  methods: {
+    base (record) {
+      this.visible = true
+      this.modalTitle = '详情'
+      this.model = record
+    },
+    handleCancel () {
+      this.visible = false
+      this.confirmLoading = false
+    }
+  }
+}
+</script>

+ 14 - 0
src/views/kdesign/Design.vue

@@ -0,0 +1,14 @@
+<template>
+  <div>
+    <k-form-design />
+  </div>
+</template>
+
+<script>
+
+export default {
+  name: 'Design',
+  data () {
+  }
+}
+</script>

+ 88 - 3
yarn.lock

@@ -2057,7 +2057,7 @@ ansi-styles@^4.0.0, ansi-styles@^4.1.0:
   dependencies:
     color-convert "^2.0.1"
 
-ant-design-vue@^1.4.5:
+ant-design-vue@^1.4.5, ant-design-vue@^1.7.2:
   version "1.7.8"
   resolved "https://registry.yarnpkg.com/ant-design-vue/-/ant-design-vue-1.7.8.tgz#1abbf86b68a4f5b1000bea0487b8031dc0001661"
   integrity sha512-F1hmiS9vwbyfuFvlamdW5l9bHKqRlj9wHaGDIE41NZMWXyWy8qL0UFa/+I0Wl8gQWZCqODW5pN6Yfoyn85At3A==
@@ -2517,6 +2517,13 @@ babel-plugin-import@^1.11.0:
     "@babel/helper-module-imports" "^7.0.0"
     "@babel/runtime" "^7.0.0"
 
+babel-plugin-import@^1.13.0:
+  version "1.13.5"
+  resolved "https://registry.yarnpkg.com/babel-plugin-import/-/babel-plugin-import-1.13.5.tgz#42eed1c5afd9a35ee1b1f8fe922b07c44077d753"
+  integrity sha512-IkqnoV+ov1hdJVofly9pXRJmeDm9EtROfrc5i6eII0Hix2xMs5FEm8FG3ExMvazbnZBbgHIt6qdO8And6lCloQ==
+  dependencies:
+    "@babel/helper-module-imports" "^7.0.0"
+
 babel-plugin-istanbul@^4.1.6:
   version "4.1.6"
   resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-4.1.6.tgz#36c59b2192efce81c5b378321b74175add1c9a45"
@@ -2604,6 +2611,15 @@ babel-polyfill@6.23.0:
     core-js "^2.4.0"
     regenerator-runtime "^0.10.0"
 
+babel-polyfill@^6.26.0:
+  version "6.26.0"
+  resolved "https://registry.yarnpkg.com/babel-polyfill/-/babel-polyfill-6.26.0.tgz#379937abc67d7895970adc621f284cd966cf2153"
+  integrity sha512-F2rZGQnAdaHWQ8YAoeRbukc7HS9QgdgeyJ0rQDd485v9opwuPvjpPFcOOT/WmkKTdgy9ESgSPXDcTNpzrGr6iQ==
+  dependencies:
+    babel-runtime "^6.26.0"
+    core-js "^2.5.0"
+    regenerator-runtime "^0.10.5"
+
 babel-preset-jest@^23.2.0:
   version "23.2.0"
   resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-23.2.0.tgz#8ec7a03a138f001a1a8fb1e8113652bf1a55da46"
@@ -3356,6 +3372,15 @@ clipboard@^2.0.0:
     select "^1.1.2"
     tiny-emitter "^2.0.0"
 
+clipboard@^2.0.6:
+  version "2.0.11"
+  resolved "https://registry.yarnpkg.com/clipboard/-/clipboard-2.0.11.tgz#62180360b97dd668b6b3a84ec226975762a70be5"
+  integrity sha512-C+0bbOqkezLIsmWSvlsXS0Q0bmkugu7jcfMIACB+RDEntIzQIkdr148we28AfSloQLRdZlYL/QYyrq05j/3Faw==
+  dependencies:
+    good-listener "^1.2.2"
+    select "^1.1.2"
+    tiny-emitter "^2.0.0"
+
 clipboardy@^2.0.0:
   version "2.3.0"
   resolved "https://registry.yarnpkg.com/clipboardy/-/clipboardy-2.3.0.tgz#3c2903650c68e46a91b388985bc2774287dba290"
@@ -3430,6 +3455,11 @@ code-point-at@^1.0.0:
   resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77"
   integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=
 
+codemirror@^5.22.0:
+  version "5.65.4"
+  resolved "https://registry.yarnpkg.com/codemirror/-/codemirror-5.65.4.tgz#384c257f27d1d06f44311722c98ad802cce3984e"
+  integrity sha512-tytrSm5Rh52b6j36cbDXN+FHwHCl9aroY4BrDZB2NFFL3Wjfq9nuYVLFFhaOYOczKAg3JXTr8BuT8LcE5QY4Iw==
+
 collection-visit@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0"
@@ -6158,6 +6188,11 @@ highlight.js@^10.7.1:
   resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-10.7.3.tgz#697272e3991356e40c3cac566a74eef681756531"
   integrity sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==
 
+highlight.js@^9.12.0:
+  version "9.18.5"
+  resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-9.18.5.tgz#d18a359867f378c138d6819edfc2a8acd5f29825"
+  integrity sha512-a5bFyofd/BHCX52/8i8uJkjr9DYwXIPnM/plwI6W7ezItLGqzt7X2G2nXuYSfsIJdkwwj/g9DG1LkcGJI/dDoA==
+
 hmac-drbg@^1.0.1:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1"
@@ -7702,6 +7737,24 @@ jssha@^2.3.1:
   resolved "https://registry.yarnpkg.com/jssha/-/jssha-2.4.2.tgz#d950b095634928bd6b2bda1d42da9a3a762d65e9"
   integrity sha512-/jsi/9C0S70zfkT/4UlKQa5E1xKurDnXcQizcww9JSR/Fv+uIbWM2btG+bFcL3iNoK9jIGS0ls9HWLr1iw0kFg==
 
+k-form-design@^3.7.91:
+  version "3.7.91"
+  resolved "https://registry.yarnpkg.com/k-form-design/-/k-form-design-3.7.91.tgz#9c0300124743ba37df5a917a047b3aec27516ec0"
+  integrity sha512-kEuIkJlK3YMojskaGQgFcyCTzkiF4qoj9AQ0Z+LhBqNzPUJIkePe4sMgoNE/DjtIGTzjxgpIccjztIFIayMIxw==
+  dependencies:
+    ant-design-vue "^1.7.2"
+    babel-plugin-import "^1.13.0"
+    babel-polyfill "^6.26.0"
+    clipboard "^2.0.6"
+    core-js "^2.6.5"
+    moment "^2.24.0"
+    vcolorpicker "^1.1.0"
+    vue "^2.6.10"
+    vue-codemirror-lite "^1.0.4"
+    vue-quill-editor "^3.0.6"
+    vue-router "^3.0.3"
+    vuedraggable "^2.23.2"
+
 killable@^1.0.1:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/killable/-/killable-1.0.1.tgz#4c8ce441187a061c7474fb87ca08e2a638194892"
@@ -10519,7 +10572,7 @@ regenerate@^1.4.2:
   resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.2.tgz#b9346d8827e8f5a32f7ba29637d398b69014848a"
   integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==
 
-regenerator-runtime@^0.10.0:
+regenerator-runtime@^0.10.0, regenerator-runtime@^0.10.5:
   version "0.10.5"
   resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz#336c3efc1220adcedda2c9fab67b5a7955a33658"
   integrity sha1-M2w+/BIgrc7dosn6tntaeVWjNlg=
@@ -11283,6 +11336,11 @@ sort-keys@^1.0.0:
   dependencies:
     is-plain-obj "^1.0.0"
 
+sortablejs@1.10.2:
+  version "1.10.2"
+  resolved "https://registry.yarnpkg.com/sortablejs/-/sortablejs-1.10.2.tgz#6e40364d913f98b85a14f6678f92b5c1221f5290"
+  integrity sha512-YkPGufevysvfwn5rfdlGyrGjt7/CRHwvRPogD/lC+TnvcN29jDpCifKP+rBqf+LRldfXSTh+0CGLcSg0VIxq3A==
+
 source-list-map@^2.0.0:
   version "2.0.1"
   resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34"
@@ -12401,6 +12459,14 @@ vary@~1.1.2:
   resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"
   integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=
 
+vcolorpicker@^1.1.0:
+  version "1.1.0"
+  resolved "https://registry.yarnpkg.com/vcolorpicker/-/vcolorpicker-1.1.0.tgz#527e2463ab330faab8b9637a30f915aebbef75f6"
+  integrity sha512-FbI7rq0EliwaPU8Qh/QVv9MFdZnG3dHjZEvODIcpPS774TTvilg6tq6cWDRbtCITBNDdpgVWnNlJ0aKnecgrJg==
+  dependencies:
+    highlight.js "^9.12.0"
+    vue "^2.5.17"
+
 vendors@^1.0.0:
   version "1.0.4"
   resolved "https://registry.yarnpkg.com/vendors/-/vendors-1.0.4.tgz#e2b800a53e7a29b93506c3cf41100d16c4c4ad8e"
@@ -12464,6 +12530,13 @@ vue-clipboard2@^0.2.1:
   dependencies:
     clipboard "^2.0.0"
 
+vue-codemirror-lite@^1.0.4:
+  version "1.0.4"
+  resolved "https://registry.yarnpkg.com/vue-codemirror-lite/-/vue-codemirror-lite-1.0.4.tgz#48a5cd7d17c0914503c8cd9d9b56b438e49c3410"
+  integrity sha1-SKXNfRfAkUUDyM2dm1a0OOScNBA=
+  dependencies:
+    codemirror "^5.22.0"
+
 vue-cookie@^1.1.4:
   version "1.1.4"
   resolved "https://registry.yarnpkg.com/vue-cookie/-/vue-cookie-1.1.4.tgz#b8b46d112bda9f93a2f47017c2ed5282d2064fda"
@@ -12565,6 +12638,11 @@ vue-ref@^2.0.0:
   resolved "https://registry.yarnpkg.com/vue-ref/-/vue-ref-2.0.0.tgz#483084d732abed11da796778a8266a3af0ea1a9c"
   integrity sha512-uKNKpFOVeWNqS2mrBZqnpLyXJo5Q+vnkex6JvpENvhXHFNBW/SJTP8vJywLuVT3DpxwXcF9N0dyIiZ4/NpTexQ==
 
+vue-router@^3.0.3:
+  version "3.5.4"
+  resolved "https://registry.yarnpkg.com/vue-router/-/vue-router-3.5.4.tgz#c453c0b36bc75554de066fefc3f2a9c3212aca70"
+  integrity sha512-x+/DLAJZv2mcQ7glH2oV9ze8uPwcI+H+GgTgTmb5I55bCgY3+vXWIsqbYUzbBSZnwFHEJku4eoaH/x98veyymQ==
+
 vue-router@^3.1.2:
   version "3.5.3"
   resolved "https://registry.yarnpkg.com/vue-router/-/vue-router-3.5.3.tgz#041048053e336829d05dafacf6a8fb669a2e7999"
@@ -12611,11 +12689,18 @@ vue-template-es2015-compiler@^1.6.0, vue-template-es2015-compiler@^1.9.0:
   resolved "https://registry.yarnpkg.com/vue-template-es2015-compiler/-/vue-template-es2015-compiler-1.9.1.tgz#1ee3bc9a16ecbf5118be334bb15f9c46f82f5825"
   integrity sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw==
 
-vue@^2.5.3, vue@^2.6.10, vue@^2.6.11:
+vue@^2.5.17, vue@^2.5.3, vue@^2.6.10, vue@^2.6.11:
   version "2.6.14"
   resolved "https://registry.yarnpkg.com/vue/-/vue-2.6.14.tgz#e51aa5250250d569a3fbad3a8a5a687d6036e235"
   integrity sha512-x2284lgYvjOMj3Za7kqzRcUSxBboHqtgRE2zlos1qWaOye5yUmHn42LB1250NJBLRwEcdrB0JRwyPTEPhfQjiQ==
 
+vuedraggable@^2.23.2:
+  version "2.24.3"
+  resolved "https://registry.yarnpkg.com/vuedraggable/-/vuedraggable-2.24.3.tgz#43c93849b746a24ce503e123d5b259c701ba0d19"
+  integrity sha512-6/HDXi92GzB+Hcs9fC6PAAozK1RLt1ewPTLjK0anTYguXLAeySDmcnqE8IC0xa7shvSzRjQXq3/+dsZ7ETGF3g==
+  dependencies:
+    sortablejs "1.10.2"
+
 vuex@^3.1.1:
   version "3.6.2"
   resolved "https://registry.yarnpkg.com/vuex/-/vuex-3.6.2.tgz#236bc086a870c3ae79946f107f16de59d5895e71"