Browse Source

Merge remote-tracking branch 'origin/master'

001295 2 years ago
parent
commit
45bbf0f67a

+ 2 - 2
.env.development

@@ -1,10 +1,10 @@
 # 页面标题
-VUE_APP_TITLE = 德荣管理系统
+VUE_APP_TITLE = 德荣供应链管理平台
 
 # 开发环境配置
 ENV = 'development'
 
-# 德荣管理系统/开发环境
+# 德荣供应链管理平台/开发环境
 VUE_APP_BASE_API = '/drp-admin'
 #应用访问路径 例如使用前缀 /drp/
 VUE_APP_CONTEXT_PATH = '/drp'

+ 2 - 2
.env.production

@@ -1,10 +1,10 @@
 # 页面标题
-VUE_APP_TITLE = 德荣管理系统
+VUE_APP_TITLE = 德荣供应链管理平台
 
 # 生产环境配置
 ENV = 'production'
 
-# 德荣管理系统/生产环境
+# 德荣供应链管理平台/生产环境
 VUE_APP_BASE_API = '/drp-admin'
 #应用访问路径 例如使用前缀 /drp/
 VUE_APP_CONTEXT_PATH = '/drp'

+ 2 - 2
.env.staging

@@ -1,12 +1,12 @@
 # 页面标题
-VUE_APP_TITLE = 德荣管理系统
+VUE_APP_TITLE = 德荣供应链管理平台
 
 NODE_ENV = production
 
 # 测试环境配置
 ENV = 'staging'
 
-# 德荣管理系统/测试环境
+# 德荣供应链管理平台/测试环境
 VUE_APP_BASE_API = '/drp-admin'
 #应用访问路径 例如使用前缀 /drp/
 VUE_APP_CONTEXT_PATH = '/drp'

+ 2 - 1
package.json

@@ -1,11 +1,12 @@
 {
   "name": "ruoyi",
   "version": "3.8.5",
-  "description": "德荣管理系统",
+  "description": "德荣供应链管理平台",
   "author": "德荣",
   "license": "MIT",
   "scripts": {
     "dev": "vue-cli-service serve",
+    "dev:highNode": "SET NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service serve",
     "build:prod": "vue-cli-service build",
     "build:stage": "vue-cli-service build --mode staging",
     "preview": "node build/index.js --preview",

+ 1 - 1
public/index.html

@@ -7,7 +7,7 @@
     <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
     <link rel="icon" href="<%= BASE_URL %>favicon.ico">
     <!-- <title><%= webpackConfig.name %></title> -->
-    <title>德荣管理系统</title>
+    <title>德荣供应链管理平台</title>
     <!--[if lt IE 11]><script>window.location.href='/html/ie.html';</script><![endif]-->
 	  <style>
     html,

+ 41 - 0
src/api/classify/basic.js

@@ -0,0 +1,41 @@
+import request from '@/utils/request'
+
+// 获取物料分类树形结构数据
+export function getTree() {
+  return request({
+    url: `/system/classify/list`,
+    method: 'post',
+  })
+}
+// 获取物料基本分类详细信息
+export function getDetail(id) {
+  return request({
+    url: `/system/classify/details`,
+    method: 'get',
+    params: {id}
+  })
+}
+// 新增物料基本信息
+export function add(data) {
+  return request({
+    url: `/system/classify/add`,
+    method: 'post',
+    data: data
+  })
+}
+// 删除物料基本分类
+export function delClassify(data) {
+  return request({
+    url:`/system/classify/delete`,
+    method: 'post',
+    data: data
+  })
+}
+// 修改物料基本分类
+export function edit(data) {
+  return request({
+    url:`/system/classify/edit`,
+    method: 'post',
+    data: data
+  })
+}

+ 90 - 3
src/api/material/basic.js

@@ -1,7 +1,7 @@
 import request from '@/utils/request'
 
 // 获取物料列表信息以及表头字段
-export function materialList(data) {
+const materialList = (data) => {
 
   return request({
     url: `/system/material/list`,
@@ -10,8 +10,17 @@ export function materialList(data) {
   })
 }
 
+// 表头数据 | 表单控件
+const tagList = (data) => {
+  return request({
+    url: `/system/tag/list`,
+    method: 'post',
+    data: data
+  })
+}
+
 // 获取物料基本信息详细信息
-export function materialDetails(id, templateCode) {
+const materialDetails = (id, templateCode) => {
   return request({
     url: `/system/material/details/${id}`,
     method: 'get',
@@ -20,10 +29,88 @@ export function materialDetails(id, templateCode) {
 }
 
 // 获取医药行业信息详细信息+表单属性
-export function medcineDetails(id, templateCode) {
+const medcineDetails = (id, templateCode) => {
   return request({
     url: `/system/medcine/details/${id}`,
     method: 'get',
     params: { templateCode }
   })
+}
+
+// 查询成本信息列表
+const costList = (data) => {
+  return request({
+    url: `/system/cost/list`,
+    method: 'post',
+    data: data
+  })
+}
+
+// 查询财务信息列表
+const financeList = (data) => {
+  return request({
+    url: `/system/finance/list`,
+    method: 'post',
+    data: data
+  })
+}
+
+// 获取物料辅助属性详细信息
+const propertyDetails = (id, templateCode) => {
+  return request({
+    url: `/system/property/details/${id}`,
+    method: 'get',
+    params: { templateCode }
+  })
+}
+
+// 查询物料辅助属性列表
+const propertyList = (data) => {
+  return request({
+    url: `/system/property/list`,
+    method: 'post',
+    data: data
+  })
+}
+
+
+//获取辅助计量单位基本信息
+const unitDetails = (materialId, templateCode, id) => {
+  return request({
+    url: `/system/unit/details/${materialId}`,
+    method: 'get',
+    params: { templateCode, id }
+  })
+}
+
+//获取辅计量管理列表信息
+const unitList = (data) => {
+  return request({
+    url: `/system/unit/list`,
+    method: 'post',
+    data: data
+  })
+}
+
+// 查询计划信息列表
+const planList = (data) => {
+  return request({
+    url: `/system/plan/list`,
+    method: 'post',
+    data: data
+  })
+}
+
+export default {
+  materialList,
+  tagList,
+  materialDetails,
+  medcineDetails,
+  costList,
+  financeList,
+  propertyDetails,
+  propertyList,
+  unitDetails,
+  unitList,
+  planList,
 }

+ 11 - 0
src/api/material/label.js

@@ -0,0 +1,11 @@
+import request from "@/utils/request";
+import { parseStrEmpty } from "@/utils/ruoyi";
+
+// 查询用户列表
+export function listTree(query) {
+  return request({
+    url: "/system/user/list",
+    method: "get",
+    params: query,
+  });
+}

+ 39 - 0
src/api/system/table-template.js

@@ -0,0 +1,39 @@
+import request from "@/utils/request";
+
+import { parseStrEmpty } from "@/utils/ruoyi";
+
+// fetch table template list
+export function list(data, page) {
+  return request({
+    url: "/system/template/list",
+    method: "post",
+    data: data,
+    params: page,
+  });
+}
+
+// fetch table template item
+export function item(id) {
+  return request({
+    url: "/system/template/detail/" + parseStrEmpty(id),
+    method: "get",
+  });
+}
+
+// fetch table template item
+export function role(id) {
+  return request({
+    url: "/system/template/template_role/detail/" + parseStrEmpty(id),
+    method: "get",
+  });
+}
+
+// fetch table template list
+export function auth(data, page) {
+  return request({
+    url: "/system/template/role/add",
+    method: "post",
+    data: data,
+    params: page,
+  });
+}

BIN
src/assets/images/homePage.png


+ 1 - 1
src/layout/components/Sidebar/Logo.vue

@@ -35,7 +35,7 @@ export default {
   },
   data() {
     return {
-      title: '德荣管理系统',
+      title: '德荣供应链管理平台',
       logo: logoImg
     }
   }

+ 5 - 0
src/store/modules/user.js

@@ -4,6 +4,7 @@ import { getToken, setToken, removeToken } from '@/utils/auth'
 const user = {
   state: {
     token: getToken(),
+    id: '',
     name: '',
     avatar: '',
     roles: [],
@@ -14,6 +15,9 @@ const user = {
     SET_TOKEN: (state, token) => {
       state.token = token
     },
+    SET_ID: (state, id) => {
+      state.id = id
+    },
     SET_NAME: (state, name) => {
       state.name = name
     },
@@ -59,6 +63,7 @@ const user = {
             commit('SET_ROLES', ['ROLE_DEFAULT'])
           }
           commit('SET_NAME', user.userName)
+          commit('SET_ID', user.userId)
           commit('SET_AVATAR', avatar)
           resolve(res)
         }).catch(error => {

+ 15 - 1
src/views/index.vue

@@ -1,3 +1,17 @@
+<template>
+  <div class="app-container home">
+  </div>
+</template>
+
+<style scoped lang="scss">
+.home{
+  width: 100%;
+  height: calc(100vh - 90px);
+  background-image: url('../assets/images/homePage.png');
+  background-repeat: no-repeat;
+  background-size: 100% 100%;
+}
+</style>
 <!-- <template>
   <div class="app-container home">
     <el-row :gutter="20">
@@ -41,7 +55,7 @@
       <el-col :sm="24" :lg="12" style="padding-left: 20px">
         <h2>德荣后台管理框架</h2>
         <p>
-          一直想做一款后台管理系统,看了很多优秀的开源项目但是发现没有合适自己的。于是利用空闲休息时间开始自己写一套后台系统。如此有了德荣管理系统,她可以用于所有的Web应用程序,如网站管理后台,网站会员中心,CMS,CRM,OA等等,当然,您也可以对她进行深度定制,以做出更强系统。所有前端后台代码封装过后十分精简易上手,出错概率低。同时支持移动客户端访问。系统会陆续更新一些实用功能。
+          一直想做一款后台管理系统,看了很多优秀的开源项目但是发现没有合适自己的。于是利用空闲休息时间开始自己写一套后台系统。如此有了德荣供应链管理平台,她可以用于所有的Web应用程序,如网站管理后台,网站会员中心,CMS,CRM,OA等等,当然,您也可以对她进行深度定制,以做出更强系统。所有前端后台代码封装过后十分精简易上手,出错概率低。同时支持移动客户端访问。系统会陆续更新一些实用功能。
         </p>
         <p>
           <b>当前版本:</b> <span>v{{ version }}</span>

+ 1 - 1
src/views/login.vue

@@ -1,7 +1,7 @@
 <template>
   <div class="login">
     <el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form">
-      <h3 class="title">德荣后台管理系统</h3>
+      <h3 class="title">德荣供应链管理平台</h3>
       <el-form-item prop="username">
         <el-input
           v-model="loginForm.username"

+ 32 - 0
src/views/material/api/basic.js

@@ -0,0 +1,32 @@
+/* 物料基础信息接口方法 */
+import { materialDetails, medcineDetails } from '@/api/material/basic';
+
+// 获取物料基本信息详细信息
+const getMaterialDetails = (id, templateCode) => {
+
+  console.log(id, templateCode);
+  materialDetails(
+    id,
+    templateCode,
+  ).then((res) => {
+
+    return res;
+  })
+
+}
+// 获取医药行业信息详细信息+表单属性
+const getMedcineDetails = (id, templateCode) => {
+
+  medcineDetails(id, templateCode).then((res) => {
+
+    return res;
+  })
+}
+
+export default {
+  getMaterialDetails,
+  getMedcineDetails
+}
+
+
+

+ 366 - 51
src/views/material/basicFile/details.vue

@@ -4,117 +4,170 @@
 
     <el-row type="flex" justify="space-between">
       <el-col :span="6">
-        <el-button size="small" @click="handleBack">返回</el-button>
+        <el-button size="small" @click="handleBack" :disabled="headerParam.isEdit">返回</el-button>
       </el-col>
       <el-col :span="6" style="text-align: right;">
         <!-- 附件管理 -->
         <el-button-group>
-          <el-button size="small" icon="el-icon-paperclip"></el-button>
+          <el-button size="small" icon="el-icon-paperclip" @click="handleFile"></el-button>
         </el-button-group>
 
         <!-- 切换 -->
         <el-button-group>
-          <el-button size="small" icon="el-icon-d-arrow-left"></el-button>
-          <el-button size="small" icon="el-icon-arrow-left"></el-button>
-          <el-button size="small" icon="el-icon-arrow-right"></el-button>
-          <el-button size="small" icon="el-icon-d-arrow-right"></el-button>
+          <el-button size="small" icon="el-icon-d-arrow-left" :disabled="headerParam.isEdit"
+            @click="handleChangePage('first')"></el-button>
+          <el-button size="small" icon="el-icon-arrow-left" :disabled="headerParam.isEdit"
+            @click="handleChangePage('pre')"></el-button>
+          <el-button size="small" icon="el-icon-arrow-right" :disabled="headerParam.isEdit"
+            @click="handleChangePage('next')"></el-button>
+          <el-button size="small" icon="el-icon-d-arrow-right" :disabled="headerParam.isEdit"
+            @click="handleChangePage('end')"></el-button>
         </el-button-group>
       </el-col>
     </el-row>
 
     <div class="md-content">
-      <el-form :inline="true" label-position="right" :model="fromData.value" class="demo-form-inline">
+      <el-form :inline="true" label-position="right" :model="basicData.value">
       <!-- <el-form-item label="所属组织">
-          <el-input v-model="fromData.orgName" placeholder="所属组织"></el-input>
-                                                                                                </el-form-item> -->
+          <el-input v-model="basicData.value.orgName":readonly="!headerParam.isEdit" placeholder="所属组织"></el-input>
+                                                          </el-form-item> -->
         <el-form-item label="物料编码">
-          <el-input v-model="fromData.value.code" placeholder="物料编码"></el-input>
+          <el-input v-model="basicData.value.code" size="small" :readonly="!headerParam.isEdit"
+            placeholder="物料编码"></el-input>
         </el-form-item>
         <el-form-item label="物料名称">
-          <el-input v-model="fromData.value.name" placeholder="物料名称"></el-input>
+          <el-input v-model="basicData.value.name" size="small" :readonly="!headerParam.isEdit"
+            placeholder="物料名称"></el-input>
         </el-form-item>
         <el-form-item label="英文名称">
-          <el-input v-model="fromData.value.enName" placeholder="英文名称"></el-input>
+          <el-input v-model="basicData.value.enName" size="small" :readonly="!headerParam.isEdit"
+            placeholder="英文名称"></el-input>
         </el-form-item>
       <!-- <el-form-item label="版本号">
-          <el-input v-model="fromData.value.version" placeholder="版本号"></el-input>
-                                                                                                </el-form-item> -->
+          <el-input v-model="basicData.value.version" :readonly="!headerParam.isEdit" placeholder="版本号"></el-input>
+                                                           </el-form-item> -->
 
       </el-form>
 
-      <dr-tabs :tabList="detailsTabs">
+      <dr-tabs :tabList="detailsTabs" :handleTabClick="handleMainTabClick">
         <template #tabContent>
 
           <div class="md-basic">
 
             <!-- 主信息 -->
             <div class="md-main">
-              <el-form :inline="true" label-position="right" :hide-required-asterisk="true" :model="fromData.value"
-                class="demo-form-inline">
+
+              <!-- 基本信息展示表单 -->
+              <el-form v-if="activeMainTab == 'material'" :inline="true" label-position="right"
+                :hide-required-asterisk="true" :model="basicData.value">
 
                 <el-row :gutter="10">
-                  <el-col :span="8" v-for="f in fromData.form" style="text-align: right;">
-                    <el-form-item v-if="f.show" :label="f.name" :rules="[
-                      { required: f.required, message: '请输入', trigger: 'blur' },
-                    ]">
-                      <el-input v-model="fromData.value[f.prop]" :placeholder="f.name"></el-input>
+                  <el-col :span="8" v-for="f in basicData.form" style="text-align: right;">
+                    <el-form-item v-if="f.show" :label="f.name">
+                      <el-input size="small" v-model="basicData.value[f.prop]" :readonly="!headerParam.isEdit"
+                        :placeholder="f.name"></el-input>
                     </el-form-item>
                   </el-col>
                 </el-row>
 
-
               </el-form>
 
+              <!-- 其他展示为列表 -->
+              <el-table v-else :data="mainMsg.value" @cell-dblclick="handledbClick" class="material-table">
+                <!-- <el-table-column type="selection" width="55" /> -->
+                <el-table-column type="index" label="序号" width="55" align="center" />
+                <el-table-column v-for="m in  mainMsg.form" v-if="m.show" :label="m.name" align="center" :prop="m.prop"
+                  show-overflow-tooltip />
+              </el-table>
+
             </div>
 
             <!-- 副信息 -->
             <div class="md-vice">
 
-              <dr-tabs :tabList="basicMessage">
+              <dr-tabs v-if="activeMainTab == 'material'" :tabList="basicMessage" :handleTabClick="handleViceTabClick">
 
                 <template #tabContent>
 
-                  <el-form :inline="true" label-position="right" :hide-required-asterisk="true" :model="medcineData.value"
-                    class="demo-form-inline">
+                  <el-form v-if="activeViceTab == 'material_medcine'" :inline="true" label-position="right"
+                    :hide-required-asterisk="true" :model="medcineData.value" class="md-vice-content">
 
                     <el-row :gutter="10">
                       <el-col :span="8" v-for="m in medcineData.form" style="text-align: right;">
                         <el-form-item v-if="m.show" :label="m.name" :rules="[
                           { required: m.required, message: '请输入', trigger: 'blur' },
                         ]">
-                          <el-input v-model="medcineData.value[f.prop]" :placeholder="m.name"></el-input>
+                          <el-input v-model="medcineData.value[m.prop]" :readonly="!headerParam.isEdit"
+                            :placeholder="m.name"></el-input>
                         </el-form-item>
                       </el-col>
                     </el-row>
 
 
                   </el-form>
+
+                  <!-- 其他展示为列表 -->
+                  <el-table v-else :data="viceMsg.value" class="material-table">
+                    <el-table-column type="index" label="序号" width="55" align="center" />
+                    <el-table-column v-for="v in  viceMsg.form" v-if="v.show" :label="v.name" align="center"
+                      :prop="v.prop" show-overflow-tooltip />
+                  </el-table>
                 </template>
               </dr-tabs>
+
+              <!-- 其他展示为列表 -->
+            <!-- <el-table v-else :data="viceMsg.value" class="material-table">
+                 <el-table-column type="selection" width="55" /> 
+                <el-table-column type="index" label="序号" width="55" align="center" />
+                <el-table-column v-for="v in  viceMsg.form" v-if="v.show" :label="v.name" align="center" :prop="v.prop"
+                  show-overflow-tooltip />
+               </el-table> -->
             </div>
 
+            <div class="md-auditInfo" v-if="activeMainTab == 'material'">
+              <el-divider content-position="left">审计信息</el-divider>
+              <el-form :inline="true" label-position="right" :model="basicData.value">
+                <el-form-item label="创建人">
+                  <el-input v-model="basicData.value.createBy" size="small" readonly placeholder="创建人"></el-input>
+                </el-form-item>
+                <el-form-item label="创建时间">
+                  <el-input v-model="basicData.value.createTime" size="small" readonly placeholder="创建时间"></el-input>
+                </el-form-item>
+                <el-form-item label="最后修改人">
+                  <el-input v-model="basicData.value.updateBy" size="small" readonly placeholder="最后修改人"></el-input>
+                </el-form-item>
+                <el-form-item label="最后修改时间">
+                  <el-input v-model="basicData.value.updateTime" size="small" readonly placeholder="最后修改时间"></el-input>
+                </el-form-item>
 
+              </el-form>
+
+            </div>
           </div>
         </template>
       </dr-tabs>
 
     </div>
+
   </el-card>
 </template>
 
 <script>
 import drTabs from '../components/dr-tabs.vue';
 import detailsTabs from '../config/detailsTabs';
-import { materialDetails, medcineDetails } from '@/api/material/basic';
+import materialApi from '@/api/material/basic';
 
 export default {
   name: 'material-details',
-  props: ['id'],
+  props: ['headerParams'],
   data() {
     return {
-
+      // 详情固定标签页
       detailsTabs,
-
+      // 标签页当前激活状态
+      activeMainTab: 'material',
+      activeViceTab: 'material_medcine',
+      headerParam: this.$props.headerParams,
       // 基本信息下的页签
       basicMessage: [
         {
@@ -133,9 +186,8 @@ export default {
           isShow: true,
         },
       ],
-
-      // 主信息
-      fromData: {
+      // 基本信息
+      basicData: {
         value: {},
         form: []
       },
@@ -143,7 +195,17 @@ export default {
       medcineData: {
         value: {},
         form: []
-      }
+      },
+      // 主标签信息
+      mainMsg: {
+        form: [],
+        value: []
+      },
+      // 副信息
+      viceMsg: {
+        form: [],
+        value: []
+      },
 
     }
   },
@@ -162,28 +224,167 @@ export default {
       this.$emit("actionBar", JSON.stringify(bar))
 
     },
+    // 附件按钮
+    handleFile() {
+      console.log('附件按钮');
+    },
+    // 改变分页情况 
+    handleChangePage(type) {
+      switch (type) {
+        case 'first':
+          console.log('第一页');
+          break;
+        case 'pre':
+          console.log('上一页');
+          break;
+        case 'next':
+          console.log('下一页');
+          break;
+        case 'end':
+          console.log('最后页');
+          break;
+      }
+    },
+    // 切换主信息标签
+    handleMainTabClick(e) {
+
+      this.activeMainTab = detailsTabs[e.index].code;
+
+      switch (this.activeMainTab) {
+
+        // 基本信息
+        case 'material':
+          this.getTagList('material', (form) => {
+            this.basicData.form = form;
+            this.getMaterialDetails(this.headerParam.materialId, 'material');
+          })
+          break;
+        // 财物信息
+        case 'material_finance':
+          this.getTagList('material_finance', (form) => {
+            this.mainMsg.form = form;
+            this.getFinanceList('');
+          });
+          break;
+        // 利润中心信息
+        case 'profit_center':
+          this.getTagList('profit_center', (form) => {
+
+            this.mainMsg.form = form;
+          });
+          break;
+        // 采购信息
+        case 'material_purchase':
+          this.getTagList('material_purchase', (form) => {
+
+            this.mainMsg.form = form;
+          });
+          break;
+        // 库存信息
+        case 'material_inventory':
+          this.getTagList('material_inventory', (form) => {
+
+            this.mainMsg.form = form;
+          });
+          break;
+        // 计划信息
+        case 'material_plan':
+          this.getTagList('material_plan', (form) => {
+            this.mainMsg.form = form;
+            this.getPlanList('');
+          });
+          break;
+        // 成本信息
+        case 'material_cost':
+          this.getTagList('material_cost', (form) => {
+
+            this.mainMsg.form = form;
+            this.getCostList('');
+          });
+          break;
+
+
+        default:
+
+          break;
+      }
+
+    },
+    // 切换副表信息
+    handleViceTabClick(e) {
+      console.log(this.basicMessage[e.index], '切换标签');
+      this.activeViceTab = this.basicMessage[e.index].code;
+
+      switch (this.activeViceTab) {
+
+        // 医药行业
+        case 'material_medcine':
+          this.getTagList('material_medcine', (form) => {
+            this.medcineData.form = form;
+            this.getMedcineDetails(this.headerParam.materialId, 'material_medcine');
+          })
+          break;
+        // 辅计量管理
+        case 'material_unit':
+          this.getTagList('material_unit', (form) => {
+            console.log(form, 'form');
+            this.viceMsg.form = form;
+          });
+          break;
+        // 辅助属性
+        case 'material_property':
+          this.getTagList('material_property', (form) => {
+
+            this.viceMsg.form = form;
+          });
+          break;
+
+        default:
+          break;
+      }
+    },
+    handledbClick() { },
     // 获取物料基本信息详细信息
     getMaterialDetails(id, templateCode) {
-
-      console.log(id, templateCode);
-      materialDetails(
+      materialApi.materialDetails(
         id,
         templateCode,
-      ).then((res) => {
-
+      ).then(res => {
         console.log(res, '物料基本信息');
         let { code, data } = res;
         if (code == 200) {
-          this.fromData.value = data.data;
-          this.fromData.form = data.form;
+          this.basicData.value = data.data;
+          // this.basicData.form = data.form;
+
         }
       })
     },
+    // 查询财务信息列表
+    getFinanceList(materialId) {
+      materialApi.financeList({ materialId }).then(res => {
+        console.log(res, '查询财务信息列表');
+      })
+    },
+    // 查询计划信息列表
+    getPlanList(materialId) {
+      materialApi.planList({ materialId }).then(res => {
+        console.log(res, '查询计划信息列表');
+      })
+    },
+    // 查询成本信息列表
+    getCostList(materialId) {
+      materialApi.costList({ materialId }).then((res) => {
+        console.log(res, '成本信息列表+表头');
+      })
+    },
+
+
+    /* 二级标签页 */
     // 获取医药行业信息详细信息+表单属性
     getMedcineDetails(id, templateCode) {
 
       console.log(id, templateCode);
-      medcineDetails(
+      materialApi.medcineDetails(
         id,
         templateCode,
       ).then((res) => {
@@ -191,15 +392,60 @@ export default {
         console.log(res, '医药行业');
         let { code, data } = res;
         if (code == 200) {
-          this.medcineData.value = data.data;
-          this.medcineData.form = data.form;
+          this.medcineData.value = data.data || {};
+          // this.medcineData.form = data.form;
+        }
+      })
+    },
+    // 获取物料辅助属性详细信息+表单列段属性
+    getPropertyDetails() {
+      materialApi.propertyDetails().then(res => {
+        console.log(res, '物料辅助属性详细信息');
+      })
+    },
+    // 查询物料辅助属性列表+表头字段
+    getPropertyList() {
+      materialApi.propertyList().then(res => {
+        console.log(res, '料辅助属性列表');
+      })
+    },
+    //获取辅助计量单位基本信息+表单列段属性 
+    getUnitDetails() {
+      materialApi.unitDetails().then(res => {
+        console.log(res, '辅助计量单位基本信息');
+      })
+    },
+    //获取辅计量管理列表信息+表头字段
+    getUnitList() {
+      materialApi.unitList().then(res => {
+        console.log(res, '辅计量管理列表信息');
+      })
+    },
+
+    // 获取物料列表表头
+    getTagList(templateCode, cb) {
+      materialApi.tagList({ templateCode }).then(res => {
+        console.log(res, `获取${templateCode}表头`);
+        if (res.code == 200) {
+          // return resheaderParams.data;
+          cb(res.data);
         }
       })
     },
+
+
   },
   created() {
-    this.getMaterialDetails(this.$props.id, 'material');
-    this.getMedcineDetails(this.$props.id, 'material_medcine');
+    // 基本信息
+    this.getTagList('material', (form) => {
+      this.basicData.form = form;
+      this.getMaterialDetails(this.headerParam.materialId, 'material');
+    })
+    // 医疗行业
+    this.getTagList('material_medcine', (form) => {
+      this.medcineData.form = form;
+      this.getMedcineDetails(this.headerParam.materialId, 'material_medcine');
+    })
   },
 
 }
@@ -210,6 +456,10 @@ export default {
   height: calc(100vh - 158px);
   box-sizing: border-box;
 
+  .el-card__body {
+    padding: 12px;
+  }
+
   .md-content {
     margin-top: 12px;
 
@@ -217,19 +467,84 @@ export default {
       overflow: auto;
 
       .md-main {
-        max-height: 290px;
+        height: calc(100vh - 625px);
+        // max-height: 290px;
         margin-bottom: 10px;
         overflow-y: auto;
         overflow-x: hidden;
       }
+
+      .md-vice-content {
+        height: 140px;
+        overflow-y: auto;
+        overflow-x: hidden;
+      }
+    }
+
+    .md-auditInfo {
+
+      .el-divider--horizontal {
+        margin: 20px 0px 15px;
+      }
     }
+
   }
+
 }
 </style>
 
-<style>
->>>.el-form-item__label {
-  font-size: 12px;
+<style scoped>
+.md-content>>>.el-form-item {
+  margin-bottom: 10px;
+}
+
+.md-content>>>.el-tabs--border-card>.el-tabs__content {
+  padding-bottom: 8px;
+}
+
+.md-content .md-auditInfo>>>.el-form-item {
+  margin-bottom: 0px;
+}
+
+.md-main>>>.el-form-item,
+.md-vice>>>.el-form-item {
+  width: 100%;
+  box-sizing: border-box;
+}
+
+.md-main>>>.el-form-item__label,
+.md-vice>>>.el-form-item__label {
+  width: 40%;
+}
+
+.md-main>>>.el-form-item__content,
+.md-md-vice>>>.el-form-item__content {
+  width: 60%;
+}
+
+.md-content>>>.el-form-item__label {
   font-weight: normal;
+  /* text-align: left;
+  width: 28%; */
+  white-space: nowrap;
+  /* IE6 需要定义宽度 */
+  overflow: hidden;
+
+  -o-text-overflow: ellipsis;
+  /* Opera */
+  text-overflow: ellipsis;
+  /* IE, Safari (WebKit) */
+  /* -moz-binding: url('ellipsis.xml#ellipsis'); */
+  /* Firefox */
+}
+
+.md-main>>>.material-table {
+  height: 100%;
+}
+
+.md-vice>>>.material-table {
+  height: 140px;
+  overflow-y: auto;
+  overflow-x: auto;
 }
 </style>

+ 173 - 94
src/views/material/basicFile/index.vue

@@ -3,83 +3,94 @@
   <div class="material-basic">
 
     <!-- 操作栏 -->
-    <el-row :gutter="10" class="mb10">
+    <el-row :gutter="10" class="mb10" v-if="!headerParams.isEdit">
+      <!-- 新增、修改、删除、复制 -->
       <el-col :span="1.5">
         <el-button-group>
-          <el-button size="small">新增</el-button>
-          <el-button size="small">修改</el-button>
-          <el-button size="small">删除</el-button>
-          <el-button size="small">复制</el-button>
-          <el-dropdown split-button size="small" @click="handleClick">
-            批改
-            <el-dropdown-menu slot="dropdown">
-              <el-dropdown-item>批改</el-dropdown-item>
-              <el-dropdown-item>向导批改</el-dropdown-item>
-              <el-dropdown-item>按规则批改</el-dropdown-item>
-            </el-dropdown-menu>
-          </el-dropdown>
-
+          <el-button size="small" @click="handleInster">新增</el-button>
+          <el-button size="small" @click="handleEdit">修改</el-button>
+          <el-button size="small" @click="handleDel">删除</el-button>
+          <el-button size="small" @click="handleCopy">复制</el-button>
         </el-button-group>
       </el-col>
 
+      <!-- 查询、刷新、过滤 -->
       <el-col :span="1.5">
         <el-button-group>
 
-          <el-dropdown size="small" v-if="isComponent == 'materiaList'">
+          <el-dropdown size="small" v-if="isComponent == 'materiaList'" @command="handleFilter">
             <el-button size="small">
               过滤<i class="el-icon-arrow-down el-icon--right"></i>
             </el-button>
             <el-dropdown-menu slot="dropdown">
-              <el-dropdown-item>显示停用</el-dropdown-item>
-              <el-dropdown-item>显示已分配</el-dropdown-item>
+              <el-dropdown-item :command="filterCondition('stop')">显示停用</el-dropdown-item>
+              <el-dropdown-item :command="filterCondition('allot')">显示已分配</el-dropdown-item>
             </el-dropdown-menu>
           </el-dropdown>
 
-          <el-button size="small">查询</el-button>
-          <el-button size="small">刷新</el-button>
+          <el-button size="small" @click="handleQuery">查询</el-button>
+          <el-button size="small" @click="handleRefresh">刷新</el-button>
 
         </el-button-group>
       </el-col>
 
+      <!-- 启用 -->
       <el-col :span="1.5">
         <el-button-group>
-
-          <el-dropdown split-button size="small" @click="handleClick">
+          <el-dropdown split-button size="small" @click="handleIsInvoke(true)" @command="handleIsInvoke">
             启用
             <el-dropdown-menu slot="dropdown">
-              <el-dropdown-item>启用</el-dropdown-item>
-              <el-dropdown-item>停用</el-dropdown-item>
+              <el-dropdown-item :command="isInvoke(true)">启用</el-dropdown-item>
+              <el-dropdown-item :command="isInvoke(false)">停用</el-dropdown-item>
             </el-dropdown-menu>
           </el-dropdown>
-
-          <!-- 辅助功能 -->
-          <el-button size="small">创建新版本</el-button>
         </el-button-group>
       </el-col>
 
+      <!-- 申请单查询 -->
       <el-col :span="1.5">
         <el-button-group>
-          <el-button size="small">申请单查询</el-button>
+          <el-button size="small" @click="handleQueryForm">申请单查询</el-button>
         </el-button-group>
       </el-col>
 
+      <!-- 导入导出 -->
       <el-col :span="1.5">
         <el-button-group>
+          <el-button size="small" @click="handleImport">批量导入</el-button>
+          <el-button size="small" @click="handleExport">批量导出</el-button>
+        </el-button-group>
+      </el-col>
 
-          <el-dropdown split-button size="small" @click="handleClick">
-            打印
-            <el-dropdown-menu slot="dropdown">
-              <el-dropdown-item>打印</el-dropdown-item>
-              <el-dropdown-item>预览</el-dropdown-item>
-              <el-dropdown-item>输出</el-dropdown-item>
-            </el-dropdown-menu>
-          </el-dropdown>
+    </el-row>
+
+    <el-row :gutter="10" class="mb10" v-else>
+      <el-col :span="1.5">
+        <el-button-group>
+          <el-button size="small" @click="handleSave">保存</el-button>
+          <el-button size="small" @click="handleSaveAdd" disabled>保存新增</el-button>
+          <el-button size="small" @click="handleUpdateImport">更新导入</el-button>
+        </el-button-group>
+      </el-col>
 
+      <el-col :span="1.5">
+        <el-button-group>
+          <el-button size="small" @click="handleCancel">取消</el-button>
         </el-button-group>
       </el-col>
     </el-row>
 
-    <component :is="isComponent" @actionBar="handleActionBar" :id="materialId"></component>
+    <el-dialog title="操作提示" :visible.sync="optionDialog.show" width="30%" center top="50vh">
+      <span>是否确认{{ optionDialog.op }}?</span>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="handleOptionShow('option', false)">取 消</el-button>
+        <el-button type="primary" @click="handleComfirmOption('cancal')">确 定</el-button>
+      </span>
+    </el-dialog>
+
+    <component :is="isComponent" @actionBar="handleActionBar" :headerParams="headerParams"
+      @headerOption="handleHeaderOption">
+    </component>
 
   </div>
 </template>
@@ -103,14 +114,6 @@ export default {
       multiple: true,
       // 显示搜索条件
       showSearch: true,
-      // 物料基本信息数据
-      taskList: [
-        {
-          id: 1,
-          code: '001',
-          name: '名称'
-        }
-      ],
       // 总条数
       total: 0,
       // 查询参数
@@ -120,78 +123,154 @@ export default {
         code: null,
         name: null
       },
-      materialId: ''
+      // 头部数据
+      headerParams: {
+        // 物料id
+        materialId: '',
+        // 是否编辑
+        isEdit: false,
+      },
+
+
+      // 列表选中数据
+      checkedList: [],
+      // 操作弹窗
+      optionDialog: {
+        show: false,
+        op: ''
+      }
     }
   },
   created() {
     // this.getList();
   },
   methods: {
-
-    // 触发动态组件
-    handleActionBar(params) {
-      let bar = JSON.parse(params);
-      console.log(bar);
-      this.isComponent = bar.address;
-      this.materialId = bar.id;
+    // 新增
+    handleInster() {
+      this.$message({
+        message: '物料只能通过申请审批增加,不能在节点直接录入!',
+        type: 'warning'
+      });
     },
-
-    handleClick() {
-
-    },
-
-
-    /** 查询【请填写功能名称】列表 */
-    getList() {
-
+    // 修改
+    handleEdit() {
+      if (this.isComponent == 'materiaList' && this.checkedList.length == 1) {
+        this.headerParams.isEdit = true;
+        let bar = JSON.stringify({
+          address: 'materiaDetails',
+          id: this.checkedList[0].id
+        })
+        this.handleActionBar(bar);
+      } else if (this.isComponent == 'materiaList' && this.checkedList.length > 1) {
+        this.$message({
+          message: '修改只能选择单个数据!',
+          type: 'warning'
+        });
+      } else if (this.isComponent == 'materiaDetails') {
+        this.headerParams.isEdit = true;
+        console.log('详情修改');
+      } else {
+        this.$message({
+          message: '请选择需要修改的信息!',
+          type: 'warning'
+        });
+      }
     },
-    // 取消按钮
-    cancel() {
-      this.reset();
+    // 删除
+    handleDel() {
+      console.log('删除');
     },
-    // 表单重置
-    reset() {
-
-      this.resetForm("form");
+    // 复制
+    handleCopy() {
+      console.log('复制');
     },
-    /** 搜索按钮操作 */
+    //查询 
     handleQuery() {
 
-      this.getList();
     },
-    /** 重置按钮操作 */
-    resetQuery() {
-      this.resetForm("queryForm");
-      this.handleQuery();
+    // 刷新
+    handleRefresh() {
+      console.log('刷新');
     },
-    // 多选框选中数据
-    handleSelectionChange(selection) {
-
+    // 过滤
+    handleFilter(e) {
+      console.log(e, '过滤');
     },
-    /** 新增按钮操作 */
-    handleAdd() {
-      this.reset();
-
+    filterCondition(type) {
+      return {
+        type
+      }
     },
-    /** 修改按钮操作 */
-    handleUpdate(row) {
-      this.reset();
-
+    // 启用
+    handleIsInvoke(e) {
+      console.log('启用', e);
     },
-    /** 提交按钮 */
-    submitForm() {
-
+    isInvoke(val) {
+      return val;
     },
-    /** 删除按钮操作 */
-    handleDelete(row) {
-
+    // 申请单查询
+    handleQueryForm() {
+      console.log('申请单查询');
+    },
+    // 批量导入
+    handleImport() {
+      console.log('批量导入');
     },
-    /** 导出按钮操作 */
+    // 批量导出
     handleExport() {
+      console.log('批量导出');
+    },
 
-    }
-  }
+    // 取消保存
+    handleCancel() {
+      console.log('取消保存');
+      this.optionDialog.op = '取消';
+      this.handleOptionShow('option', true);
+    },
+    // 保存修改
+    handleSave() {
+      console.log('保存修改');
+    },
+    // 保存修改并新增
+    handleSaveAdd() {
+      console.log('保存修改并新增');
+    },
+    // 更新导入
+    handleUpdateImport() {
+      console.log('更新导入');
+    },
+    // 头部数据处理
+    handleHeaderOption(params) {
+      let query = JSON.parse(params);
+      console.log(query, 'query');
+      this.checkedList = query.checkedList || [];
+    },
+    // 触发动态组件
+    handleActionBar(params) {
+      let bar = JSON.parse(params);
+      console.log(bar);
+      this.isComponent = bar.address;
+      this.headerParams.materialId = bar.id;
+    },
+    // 操作弹窗显隐
+    handleOptionShow(type, val) {
+      switch (type) {
+        case 'option':
+          this.optionDialog.show = val;
+          break;
+      }
+    },
+    // 操作弹窗确认按钮
+    handleComfirmOption(op) {
+      switch (op) {
+        case 'cancal':
+          this.handleOptionShow('option', false);
+          this.headerParams.isEdit = false;
+          break;
+      }
+    },
 
+  }
 
 };
 </script>

+ 43 - 22
src/views/material/basicFile/list.vue

@@ -2,31 +2,35 @@
 
 <template>
   <el-card class="material-list">
-    <el-table :data="taskList" @cell-dblclick="handledbClick" class="material-table"
+    <el-table v-loading="loading" :data="taskList" @cell-dblclick="handledbClick"
       @selection-change="handleSelectionChange">
       <el-table-column type="selection" width="55" />
       <el-table-column type="index" label="序号" width="55" align="center" />
-    <el-table-column v-for="h in  tableHeader" v-if="h.show" :label="h.name" align="center" :prop="h.prop" />
+      <el-table-column v-for="h in  tableHeader" v-if="h.show" :label="h.name" align="center" :prop="h.prop"
+        show-overflow-tooltip />
     </el-table>
 
     <!-- v-show="total > 0" -->
     <pagination :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize"
-      @pagination="getList" />
+      @pagination="getMaterialList" />
   </el-card>
 </template>
 
 <script>
-import { materialList } from '@/api/material/basic';
+import materialApi from '@/api/material/basic';
 
 export default {
   name: 'material-list',
- 
+
   data() {
     return {
       // 物料基本信息数据
       taskList: [],
       // 总条数
       total: 1,
+
+      loading: false,
+
       // 查询参数
       queryParams: {
         pageNum: 1,
@@ -35,7 +39,9 @@ export default {
         name: null
       },
       // 表头
-      tableHeader: []
+      tableHeader: [],
+      // 多选数组
+      checkedList: [],
     }
   },
   methods: {
@@ -43,35 +49,50 @@ export default {
     handledbClick(e) {
       let bar = {
         address: 'materiaDetails',
-        id: e.id
+        id: e.id,
+        list: this.checkedList
       }
       this.$emit("actionBar", JSON.stringify(bar))
     },
-    handleSelectionChange() {
-
+    // 选中数据改变
+    handleSelectionChange(list) {
+      this.checkedList = list;
+      this.$emit('headerOption', JSON.stringify({ checkedList: [...list] }))
     },
-    getList() {
-
-    },
-    // 获取物料列表信息以及表头字段
-    getMaterialList() {
-
-      materialList({
-        templateCode: 'material'
-      }).then((res) => {
+    // 获取物料列表信息
+    getMaterialList(templateCode) {
+      this.loading = true;
+      materialApi.materialList({ templateCode }).then((res) => {
+        this.loading = false;
         console.log(res, '获取物料列表信息以及表头字段');
         let { code, data } = res;
         if (code == 200) {
           this.taskList = data.tableBody.rows;
           this.total = data.tableBody.total;
-          this.tableHeader = data.tableHeader;
+
+        }
+      })
+    },
+    // 获取物料列表表头
+    getTagList(templateCode) {
+      materialApi.tagList({ templateCode }).then(res => {
+        console.log(res, '获取物料列表表头');
+        if (res.code == 200) {
+          this.tableHeader = res.data;
         }
       })
     },
   },
   created() {
-    
-    this.getMaterialList();
+
+    this.getMaterialList('material');
+    this.getTagList('material');
   }
 }
-</script>
+</script>
+
+<style>
+.material-list>>>.el-table__body-wrapper {
+  height: 100%;
+}
+</style>

+ 1 - 0
src/views/material/basicFile/style/index.scss

@@ -10,6 +10,7 @@
 
   .el-card{
     overflow: auto;
+    box-sizing: border-box;
   }
 
   

+ 316 - 0
src/views/material/classify/index.vue

@@ -0,0 +1,316 @@
+<template>
+  <div class="classify">
+    <el-row :gutter="10" class="mb10">
+      <el-col :span="1.5">
+        <el-button type="primary" size="small" plain @click="addClassify">新增</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button type="primary" size="small" plain @click="editClassify">修改</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button type="primary" size="small" plain @click="deleteClassify">删除</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button type="primary" size="small" plain>启用</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button type="primary" size="small" plain>停用</el-button>
+      </el-col>
+    </el-row>
+
+    <el-card>
+      <el-row :gutter="10" class="content">
+        <el-col :span="6">
+          <el-input
+            placeholder="输入关键字进行过滤"
+            size="small"
+            v-model="filterText">
+          </el-input>
+
+          <el-tree
+            class="filter-tree"
+            :data="data"
+            :props="defaultProps"
+            node-key="id"
+            @node-click="clickTree"
+            highlight-current
+            :default-expanded-keys="[1]"
+            :default-checked-keys="[2]"
+            :filter-node-method="filterNode"
+            ref="tree">
+          </el-tree>
+        </el-col>
+
+        <el-col :span="18">
+          <span class="title">基本信息</span>
+          <el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="140px" class="demo-ruleForm">
+            <el-row :gutter="20">
+              <el-col :span="12">
+                <el-form-item label="物料基本分类编码" prop="code">
+                  <el-input :disabled="disable" v-model="ruleForm.code"></el-input>
+                  <span>编码规则x-xxx-xxx-xxx</span>
+                </el-form-item>
+              </el-col>
+              <el-col :span="12">
+                <el-form-item label="物料基本分类名称" prop="materialType">
+                  <el-input :disabled="disable" v-model="ruleForm.materialType"></el-input>
+                </el-form-item>
+              </el-col>
+            </el-row>
+            <el-row :gutter="20">
+              <el-col :span="12">
+                <el-form-item label="启用状态" prop="isEnable">
+                  <el-select
+                    v-model="ruleForm.isEnable"
+                    placeholder="启用状态"
+                    clearable
+                    :disabled="disable"
+                    style="width: 230px"
+                  >
+                    <el-option
+                      v-for="dict in dict.type.material_enable"
+                      :key="dict.value"
+                      :label="dict.label"
+                      :value="dict.value"
+                    />
+                  </el-select>
+                </el-form-item>
+              </el-col>
+            </el-row>
+            <span class="title">辅助属性</span>
+            <el-row :gutter="20">
+              <el-col :span="12">
+                <el-form-item label="辅助属性结构" prop="marasstframe">
+                  <el-select
+                    v-model="ruleForm.marasstframe"
+                    placeholder="属性结构"
+                    clearable
+                    :disabled="disable"
+                    style="width: 230px"
+                  >
+                    <el-option
+                      v-for="dict in dict.type.sys_assist_condtion"
+                      :key="dict.value"
+                      :label="dict.label"
+                      :value="dict.value"
+                    />
+                  </el-select>
+                </el-form-item>
+              </el-col>
+            </el-row>
+            <el-row :gutter="20">
+              <el-col :span="24">
+                <el-form-item label="" prop="name">
+                  <el-checkbox-group :disabled="disable" v-model="checkList">
+                  <el-checkbox label="库存状态"></el-checkbox>
+                  <!-- <el-checkbox label="项目"></el-checkbox>
+                  <el-checkbox label="供应商"></el-checkbox>
+                  <el-checkbox label="生产厂商"></el-checkbox>
+                  <el-checkbox label="客户"></el-checkbox>
+                  <el-checkbox label="特征码"></el-checkbox> -->
+                  <el-checkbox label="产品批号"></el-checkbox>
+                </el-checkbox-group>
+                </el-form-item>
+              </el-col>
+            </el-row>
+
+            <el-row :gutter="20">
+              <el-col :span="24">
+                <el-form-item v-if="!disable">
+                  <el-button type="primary" @click="submitForm('ruleForm')">保存</el-button>
+                  <el-button @click="resetForm('ruleForm')">取消</el-button>
+                </el-form-item>
+              </el-col>
+            </el-row>
+            </el-form>
+        </el-col>
+      </el-row>
+    </el-card>
+  </div>
+</template>
+
+<script>
+import { getTree, getDetail, add, delClassify, edit} from '@/api/classify/basic';
+export default {
+  name:'classify',
+  dicts: ['material_enable', 'sys_assist_condtion'],
+  data() {
+    return {
+      filterText: '',
+      data: [],
+      defaultProps: {
+          children: 'childrens',
+          label: 'materialType'
+      },
+      ruleForm: {
+        code: '',
+        materialType: '',
+        isEnable: '0',
+        delFlag: '',
+        marasstframe: '',
+      },
+      rules: {
+        code:[{ required: true, message: '请输入物料基本分类编码', trigger: 'blur' }],
+        materialType:[{ required: true, message: '请输入物料基本分类名称', trigger: 'blur' }],
+      },
+      checkList: [],
+      disable: true,
+      biao: {parentId: 0},
+      // 删除节点id
+      delId: '',
+      // 判断是新增还是修改
+      isAdd: true
+    }
+  },
+  created() {
+    this.getTreeData()
+    // 
+  },
+  mounted() {
+  },
+  methods: {
+    // 获取树形结构
+    getTreeData(data) {
+      getTree(data).then(res => {
+        let {code, rows} = res
+        if(code === 200) {
+          this.data = rows
+        }
+      })
+    },
+    // 获取物料基本分类详情
+    getDetailData(id) {
+      getDetail(id).then(res => {
+        let {code, data} = res
+        if (code === 200) {
+          console.log('data', data)
+          this.ruleForm = data
+        }
+      })
+    },
+    filterNode(value, data) {
+        if (!value) return true;
+        return data.label.indexOf(value) !== -1;
+    },
+    clickTree(data){
+      console.log('data', data)
+      // 如果点击新增时选择了树形节点,则不回显数据,且需要清空ruleForm内的数据
+      if (this.disable) {
+        this.getDetailData(data.id)
+      } else {
+        this.$refs['ruleForm'].resetFields();
+      }
+      // 标记是否为树形结构最外层
+      this.biao.parentId = data.id
+      // 将节点id用作删除id
+      this.delId = data.id
+    },
+    submitForm(formName) {
+        this.$refs[formName].validate((valid) => {
+          if (valid) {
+            if(this.isAdd) { //判断是走新增还是修改
+              console.log('add!');
+              console.log(this.biao.parentId)
+              console.log(this.ruleForm)
+              let params = {...this.ruleForm, ...this.biao}
+              console.log('params',params)
+              add(params).then(res => {
+                if(res.code === 200) {
+                  this.$message({
+                    message: res.msg,
+                    type: 'success'
+                  });
+                  this.getTreeData()
+                  // this.$refs['ruleForm'].resetFields();
+                  this.disable = true
+                }
+              })
+            } else { //修改
+              console.log('edit')
+              let ids = {id: this.biao.parentId}
+              console.log('ids', ids)
+              let params = {...this.ruleForm, ...ids}
+              console.log('params', params)
+              edit(params).then(res => {
+                if(res.code === 200) {
+                  this.$message({
+                    message: res.msg,
+                    type: 'success'
+                  });
+                  this.disable = true
+                }
+              })
+            }
+          } else {
+            console.log('error submit!!');
+            return false;
+          }
+        });
+      },
+    resetForm(formName) {
+      console.log(formName)
+      if(this.isAdd) {
+        this.$refs[formName].resetFields();
+        this.disable = true
+      } else {
+        this.disable = true
+      }
+    },
+    // 点击新增按钮
+    addClassify() {
+      // console.log('值呢:', this.ruleForm)
+      // 如果点击了树形节点后再点击新增,则清空数据再填写
+      if(this.biao.parentId !== 0) {
+        this.$refs['ruleForm'].resetFields();
+      }
+      this.disable = false
+      this.isAdd = true
+    },
+    // 删除按钮
+    deleteClassify() {
+      
+      if(this.biao.parentId == 0) {
+        this.$message({
+          message: '请选择删除节点',
+          type: 'warning'
+        });
+      } else {
+        console.log('删除', this.delId)
+        delClassify({id: this.delId}).then(res => {
+          if (res.code === 200) {
+            this.$message({
+              message: '删除成功',
+              type: 'success'
+            });
+            this.getTreeData()
+          }
+        })
+      }
+    },
+    // 修改按钮
+    editClassify() {
+      if(this.biao.parentId == 0) {
+        this.$message({
+          message: '请选择修改节点',
+          type: 'warning'
+        });
+      } else {
+        console.log('修改')
+        this.disable = false
+        this.isAdd = false
+      }
+    }
+  },
+}
+</script>
+
+<style scoped lang="scss">
+.classify {
+  height: calc(100vh - 84px);
+  padding: 12px;
+  box-sizing: border-box;
+}
+.title {
+  font-weight: bold;
+}
+</style>

+ 8 - 2
src/views/material/components/dr-tabs.vue

@@ -1,6 +1,6 @@
 <!-- 标签页 -->
 <template>
-  <el-tabs type="border-card">
+  <el-tabs type="border-card" @tab-click="handleTabchange">
     <el-tab-pane v-for="t in tabList" :label="t.label" v-if="t.isShow">
       <slot name="tabContent"></slot>
     </el-tab-pane>
@@ -10,13 +10,19 @@
 <script>
 export default {
   name: 'dr-tabs',
-  props: ['tabList'],
+  props: ['tabList', 'handleTabClick'],
   data() {
     return {
       // tabList,
       // detailsTabs,
     }
   },
+  methods: {
+    // 标签页切换
+    handleTabchange(e) {
+      this.handleTabClick(e);
+    },
+  },
   created() {
     // console.log(this.tabList, 'tabList');
   }

+ 15 - 15
src/views/material/config/detailsTabs.js

@@ -20,11 +20,11 @@ const detailsTabs = [
     code: 'material_purchase',
     isShow: true,
   },
-  {
-    label: '销售信息',
-    code: '',
-    isShow: true,
-  },
+  // {
+  //   label: '销售信息',
+  //   code: '',
+  //   isShow: false,
+  // },
   {
     label: '库存信息',
     code: 'material_inventory',
@@ -35,21 +35,21 @@ const detailsTabs = [
     code: 'material_plan',
     isShow: true,
   },
-  {
-    label: '生产信息',
-    code: '',
-    isShow: true,
-  },
+  // {
+  //   label: '生产信息',
+  //   code: '',
+  //   isShow: false,
+  // },
   {
     label: '成本信息',
     code: 'material_cost',
     isShow: true,
   },
-  {
-    label: '利润中心成本',
-    code: '',
-    isShow: true,
-  },
+  // {
+  //   label: '利润中心成本',
+  //   code: '',
+  //   isShow: false,
+  // },
 
 ]
 

+ 50 - 0
src/views/material/label/index.vue

@@ -0,0 +1,50 @@
+<script>
+import LabelTree from "./lable-tree.vue";
+import LabelTable from "./lable-table.vue";
+export default {
+  name: "MaterialLabel",
+  components: {
+    LabelTree,
+    LabelTable,
+  },
+  data() {
+    return {};
+  },
+  methods: {
+    onNodeClick({ label }) {
+      console.log("213", this);
+      this.$message(label);
+    },
+  },
+};
+</script>
+
+<template>
+  <el-container class="container material-label">
+    <el-aside width="275px">
+      <label-tree></label-tree>
+    </el-aside>
+    <label-table></label-table>
+  </el-container>
+</template>
+
+<style scoped>
+.container {
+  --size: 12px;
+  --margin: var(--size);
+  --padding: var(--size);
+}
+.container {
+  width: calc(100% - calc(var(--size) * 2));
+  height: calc(100vh - calc(var(--size) * 2));
+  margin: var(--margin);
+  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.12), 0 0 6px rgba(0, 0, 0, 0.04);
+}
+.container .el-aside {
+  margin: 0;
+  padding: var(--padding);
+  background-color: rgba(255, 255, 255, 1);
+  border-right: 1px solid #dcdfe6;
+  overflow: hidden;
+}
+</style>

+ 170 - 0
src/views/material/label/lable-table.vue

@@ -0,0 +1,170 @@
+<script>
+export default {
+  name: "MaterialLabelTable",
+  data() {
+    return {
+      from: { input: "", select: "" },
+      options: [
+        {
+          value: "选项1",
+          label: "黄金糕",
+        },
+        {
+          value: "选项2",
+          label: "双皮奶",
+        },
+        {
+          value: "选项3",
+          label: "蚵仔煎",
+        },
+        {
+          value: "选项4",
+          label: "龙须面",
+        },
+        {
+          value: "选项5",
+          label: "北京烤鸭",
+        },
+      ],
+      tableData: [
+        {
+          date: "2016-05-022016-05-022016-05-022016-05-02",
+          name: "王小虎",
+          address: "上海市普陀区金沙江路 1518 弄",
+        },
+        {
+          date: "2016-05-04",
+          name: "王小虎",
+          address: "上海市普陀区金沙江路 1517 弄",
+        },
+        {
+          date: "2016-05-01",
+          name: "王小虎",
+          address: "上海市普陀区金沙江路 1519 弄",
+        },
+        {
+          date: "2016-05-03",
+          name: "王小虎",
+          address: "上海市普陀区金沙江路 1516 弄",
+        },
+      ],
+    };
+  },
+  methods: {
+    duanduan(value) {
+      this.$message(value + "duanduan");
+    },
+  },
+};
+</script>
+
+<template>
+  <el-container class="material-label-table">
+    <el-header>
+      <div class="table-header-top">
+        <span>查询条件</span>
+        <div>
+          <el-select v-model="from.select" size="small" placeholder="请选择">
+            <el-option
+              v-for="item in options"
+              :key="item.value"
+              :label="item.label"
+              :value="item.value"
+            >
+            </el-option>
+          </el-select>
+          <el-input
+            v-model="from.input"
+            size="small"
+            placeholder="请输入内容"
+            :readonly="isSearching"
+            @change="onSearch"
+          >
+            <template #suffix>
+              <i
+                v-show="isSearching"
+                class="el-input__icon el-icon-loading"
+              ></i>
+              <i
+                v-show="!isSearching"
+                class="el-input__icon el-icon-search"
+              ></i>
+            </template>
+          </el-input>
+          <el-button size="small">搜索</el-button>
+          <el-button size="small">重置</el-button>
+        </div>
+      </div>
+      <div class="table-header-bottom">
+        <el-button size="small">新增</el-button>
+        <el-button size="small">导入</el-button>
+        <el-button size="small">导出</el-button>
+      </div>
+    </el-header>
+    <el-main>
+      <el-table :data="tableData">
+        <el-table-column
+          type="selection"
+          width="55"
+          fixed="left"
+          align="center"
+          show-overflow-tooltip
+        >
+        </el-table-column>
+        <el-table-column prop="date" label="日期" show-overflow-tooltip>
+        </el-table-column>
+        <el-table-column prop="name" label="姓名" show-overflow-tooltip>
+        </el-table-column>
+        <el-table-column prop="address" label="地址" show-overflow-tooltip>
+        </el-table-column>
+      </el-table>
+    </el-main>
+    <el-footer>
+      <el-pagination
+        @size-change="handleSizeChange"
+        @current-change="handleCurrentChange"
+        :current-page="currentPage4"
+        :page-sizes="[100, 200, 300, 400]"
+        :page-size="100"
+        layout="total, prev, pager, next, sizes, jumper"
+        :total="400"
+      >
+      </el-pagination>
+    </el-footer>
+  </el-container>
+</template>
+
+<style scoped>
+.material-label-table .el-header {
+  height: fit-content !important;
+  padding-top: var(--padding);
+  padding-bottom: var(--padding);
+  border-bottom: 1px solid #dcdfe6;
+}
+.material-label-table .table-header-top {
+  margin-bottom: var(--margin);
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+}
+.material-label-table .table-header-top .el-select {
+  width: 150px;
+  margin-right: var(--margin);
+}
+.material-label-table .table-header-top .el-input {
+  width: 250px;
+  margin-right: var(--margin);
+}
+.material-label-table .el-main {
+  padding: 0;
+}
+.material-label-table .el-main .el-table {
+  width: 100%;
+  height: 100%;
+}
+.material-label-table .el-footer {
+  display: flex;
+  justify-content: end;
+  align-items: center;
+}
+</style>

+ 125 - 0
src/views/material/label/lable-tree.vue

@@ -0,0 +1,125 @@
+<script>
+export default {
+  name: "MaterialLabelTree",
+  data() {
+    return {
+      loading: false,
+      form: {
+        radio: 3,
+        input: "",
+      },
+      data: [],
+      defaultProps: {
+        children: "children",
+        label: "label",
+      },
+    };
+  },
+  methods: {
+    fetchMaterialTree() {
+      this.loading = true;
+      setTimeout(() => {
+        this.data = [
+          {
+            label: "一级 1",
+            children: [
+              {
+                label: "二级 1-1",
+                children: [
+                  {
+                    label: "三级 1-1-1",
+                  },
+                ],
+              },
+            ],
+          },
+          {
+            label: "一级 2",
+            children: [
+              {
+                label: "二级 2-1",
+                children: [
+                  {
+                    label: "三级 2-1-1",
+                  },
+                ],
+              },
+              {
+                label: "二级 2-2",
+                children: [
+                  {
+                    label: "三级 2-2-1",
+                  },
+                ],
+              },
+            ],
+          },
+        ];
+        this.$message.success("success");
+        this.loading = false;
+      }, 1000);
+    },
+    onSearch() {
+      this.loading = true;
+      setTimeout(() => {
+        console.log(this.form);
+        this.loading = false;
+      }, 3000);
+    },
+    onNodeClick({ label }) {
+      console.log("213", this);
+      this.$parent.$parent.$children[1].duanduan(label);
+      // this.$message(label);
+    },
+  },
+  created() {
+    this.fetchMaterialTree();
+  },
+};
+</script>
+
+<template>
+  <div class="material-label-tree" v-loading="loading">
+    <el-form ref="form" :model="form" label-width="0">
+      <el-radio-group v-model="form.radio" @change="onSearch">
+        <el-radio :label="3">物料分类</el-radio>
+        <el-radio :label="6">物料特征</el-radio>
+      </el-radio-group>
+      <el-input
+        v-model="form.input"
+        size="small"
+        placeholder="请输入内容"
+        @change="onSearch"
+      >
+        <template #suffix>
+          <i class="el-input__icon el-icon-search"></i>
+        </template>
+      </el-input>
+    </el-form>
+    <el-scrollbar>
+      <el-tree
+        :data="data"
+        :props="defaultProps"
+        @node-click="onNodeClick"
+      ></el-tree>
+    </el-scrollbar>
+  </div>
+</template>
+
+<style scoped>
+.material-label-tree {
+  height: 100%;
+  display: flex;
+  flex-direction: column;
+}
+.material-label-tree .el-input {
+  margin: var(--margin) 0;
+}
+
+.material-label-tree .el-scrollbar {
+  flex: 1;
+}
+.material-label-tree .el-tree {
+  user-select: none;
+}
+</style>

+ 13 - 2
src/views/material/requisition/details.vue

@@ -34,13 +34,24 @@
 
 <script>
 import drTabs from '../components/dr-tabs.vue';
-import detailsTabs from '../config/detailsTabs';
+// import detailsTabs from '../config/detailsTabs';
 export default {
   name: 'material-details',
   data() {
     return {
 
-      detailsTabs,
+      detailsTabs: [
+        {
+          label: '基本信息',
+          code: 'material',
+          isShow: true,
+        },
+        {
+          label: '医药行业',
+          code: 'material_medcine',
+          isShow: true,
+        },
+      ]
     }
   },
   components: {

+ 63 - 45
src/views/material/requisition/index.vue

@@ -5,37 +5,37 @@
     <el-row :gutter="10" class="mb10">
       <el-col :span="1.5">
         <el-button-group>
-          <el-button size="small">新增</el-button>
-          <el-button size="small">修改</el-button>
-          <el-button size="small">删除</el-button>
-          <el-button size="small">复制</el-button>
+          <el-button size="small" @click="handleInster">新增</el-button>
+          <el-button size="small" @click="handleEdit">修改</el-button>
+          <el-button size="small" @click="handleDel">删除</el-button>
+          <el-button size="small" @click="handleCopy">复制</el-button>
         </el-button-group>
       </el-col>
 
       <el-col :span="1.5">
         <el-button-group>
-          <el-button size="small">查询</el-button>
-          <el-button size="small">刷新</el-button>
+          <el-button size="small" @click="handleQuery">查询</el-button>
+          <el-button size="small" @click="handleRefresh">刷新</el-button>
         </el-button-group>
       </el-col>
 
       <el-col :span="1.5">
         <el-button-group>
 
-          <el-dropdown split-button size="small" @click="handleClick">
+          <el-dropdown split-button size="small" @click="handleSubmit(true)" @command="handleSubmit">
             提交
             <el-dropdown-menu slot="dropdown">
-              <el-dropdown-item>提交</el-dropdown-item>
-              <el-dropdown-item>收回</el-dropdown-item>
+              <el-dropdown-item :command="isSubmit(true)">提交</el-dropdown-item>
+              <el-dropdown-item :command="isSubmit(false)">收回</el-dropdown-item>
             </el-dropdown-menu>
           </el-dropdown>
 
-          <el-dropdown split-button size="small" @click="handleClick">
+          <el-dropdown split-button size="small" @click="handleApproval('approval')" @command="handleApproval">
             审批
             <el-dropdown-menu slot="dropdown">
-              <el-dropdown-item>审批</el-dropdown-item>
-              <el-dropdown-item>取消审批</el-dropdown-item>
-              <el-dropdown-item>查看审批意见</el-dropdown-item>
+              <el-dropdown-item :command="approvalState('approval')">审批</el-dropdown-item>
+              <el-dropdown-item :command="approvalState('cancel')">取消审批</el-dropdown-item>
+              <el-dropdown-item :command="approvalState('view')">查看审批意见</el-dropdown-item>
             </el-dropdown-menu>
           </el-dropdown>
         </el-button-group>
@@ -43,23 +43,14 @@
 
       <el-col :span="1.5">
         <el-button-group>
-
-          <el-dropdown split-button size="small" @click="handleClick">
-            打印
-            <el-dropdown-menu slot="dropdown">
-              <el-dropdown-item>打印</el-dropdown-item>
-              <el-dropdown-item>预览</el-dropdown-item>
-              <el-dropdown-item>输出</el-dropdown-item>
-            </el-dropdown-menu>
-          </el-dropdown>
           <el-button size="small" v-if="isComponent == 'requestDetails'">附件管理</el-button>
-          <el-button size="small">维护物料</el-button>
+          <!-- <el-button size="small">维护物料</el-button> -->
 
         </el-button-group>
       </el-col>
     </el-row>
 
-    <component :is="isComponent" @actionBar="handleActionBar"></component>
+    <component :is="isComponent" @actionBar="handleActionBar" :headerParams="headerParams"></component>
   </div>
 </template>
 
@@ -68,6 +59,8 @@ import './style/index.scss';
 
 import requestList from './list.vue';
 import requestDetails from './details.vue';
+
+import Store from '@/store/index'
 export default {
   name: "material-requisition",
   components: {
@@ -77,22 +70,13 @@ export default {
   data() {
     return {
       isComponent: 'requestList',
-      // 遮罩层
-      loading: true,
-      // 选中数组
-      ids: [],
-      // 非单个禁用
-      single: true,
-      // 非多个禁用
-      multiple: true,
-      // 显示搜索条件
-      showSearch: true,
+      // 头部参数
+      headerParams: {
+        // 是否编辑
+        isEdit: false,
+      },
       // 总条数
-      total: 0,
-      // 【请填写功能名称】表格数据
-      taskList: [],
-      // 弹出层标题
-      title: "",
+      total: 1,
       // 是否显示弹出层
       open: false,
       // 查询参数
@@ -102,18 +86,52 @@ export default {
         code: null,
         name: null
       },
-      // 表单参数
-      form: {},
-      // 表单校验
-      rules: {
-      }
     };
   },
   created() {
     this.getList();
+    console.log(Store.state.user, 'Store');
   },
   methods: {
-
+    // 新增
+    handleInster() {
+      console.log('新增');
+      this.isComponent = 'requestDetails';
+    },
+    // 修改
+    handleEdit() {
+      console.log('修改');
+    },
+    // 删除
+    handleDel() {
+      console.log('删除');
+    },
+    // 复制
+    handleCopy() {
+      console.log('复制');
+    },
+    // 查询
+    handleQuery() {
+      console.log('查询');
+    },
+    // 刷新
+    handleRefresh() {
+      console.log('刷新');
+    },
+    // 提交
+    handleSubmit(val) {
+      console.log(val, '提交');
+    },
+    isSubmit(type) {
+      return type
+    },
+    // 审批
+    handleApproval(val) {
+      console.log(val, '审批');
+    },
+    approvalState(type) {
+      return type
+    },
     // 触发动态组件
     handleActionBar(params) {
       console.log(`需要更换至${params}~~~`);

+ 1 - 3
src/views/material/requisition/list.vue

@@ -2,9 +2,7 @@
 <template>
   <el-card class="request-list">
     <!-- v-loading="loading" @selection-change="handleSelectionChange" -->
-    <el-table :data="taskList" @cell-dblclick="handledbClick" class="request-table"
-      @selection-change="handleSelectionChange">
-      <el-table-column type="selection" width="55" />
+    <el-table :data="taskList" @cell-dblclick="handledbClick" class="request-table">
       <el-table-column type="index" label="序号" width="55" align="center" />
       <el-table-column label="主键" align="center" prop="id" />
       <el-table-column label="编码" align="center" prop="code" />

+ 170 - 0
src/views/material/specialAttr/index.vue

@@ -0,0 +1,170 @@
+<template>
+  <div class="specialAttr">
+    <el-row :gutter="10" class="mb10">
+      <el-col :span="1.5">
+
+        <el-select size="small" v-model="textValue" placeholder="请选择">
+        <el-option
+          v-for="item in text"
+          :key="item.value"
+          :label="item.label"
+          :value="item.value">
+        </el-option>
+      </el-select>
+
+      <el-select size="small" v-model="ruleValue" placeholder="请选择">
+        <el-option
+          v-for="item in rule"
+          :key="item.value"
+          :label="item.label"
+          :value="item.value">
+        </el-option>
+      </el-select>
+
+      <el-input
+        v-model="input"
+        size="small"
+        placeholder="请输入"
+        clearable
+        style="width: 240px"
+      />
+
+      </el-col>
+
+      <el-col :span="1.5">
+        <el-button type="primary" size="small" plain>查询</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button type="primary" size="small" plain>高级查询</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button type="primary" size="small" plain>重置</el-button>
+      </el-col>
+
+    </el-row>
+
+    <el-card>
+      <el-row :gutter="10" class="content">
+        <el-col :span="6">
+          <el-input
+            placeholder="输入关键字进行过滤"
+            size="small"
+            v-model="filterText">
+          </el-input>
+
+          <el-tree
+            class="filter-tree"
+            :data="data"
+            :props="defaultProps"
+            default-expand-all
+            :filter-node-method="filterNode"
+            ref="tree">
+          </el-tree>
+        </el-col>
+        
+        <el-col :span="18">
+
+          <el-row>
+            <el-button type="primary" size="small" plain>新增</el-button>
+            <el-button type="primary" size="small" plain>删除</el-button>
+          </el-row>
+
+          <el-row>
+            <el-table 
+              :data="taskList" 
+              class="request-table"
+              @selection-change="handleSelectionChange"
+            >
+              <el-table-column type="selection" width="55" />
+              <el-table-column type="index" label="序号" width="55" align="center" />
+              <el-table-column label="属性名称" align="center" prop="name" />
+              <el-table-column label="属性编码" align="center" prop="code" />
+              <el-table-column label="字段类型" align="center" prop="type" />
+              <el-table-column label="字段ID值" align="center" prop="id" />
+              <el-table-column label="排序" align="center" prop="id" />
+              <el-table-column label="字段说明" align="center" prop="remark" />
+            </el-table>
+          </el-row>
+
+        </el-col>
+      </el-row>
+    </el-card>
+
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'specialAttr',
+  watch: {
+    filterText(val) {
+      this.$refs.tree.filter(val);
+    }
+  },
+  data () {
+    return{
+      textValue: 1,
+      text: [{label: '文本字段', value: 1}, {label: '字典字段', value: 2}],
+      ruleValue: 1,
+      rule:[{label: '包含', value: 1}, {label: '不包含', value: 2}, {label: '等于', value: 3}, {label: '不等于', value: 4}],
+      input: '',
+      filterText: '',
+      data: [{
+          id: 1,
+          label: '一级 1',
+          children: [{
+            id: 4,
+            label: '二级 1-1',
+            children: [{
+              id: 9,
+              label: '三级 1-1-1'
+            }, {
+              id: 10,
+              label: '三级 1-1-2'
+            }]
+          }]
+        }, {
+          id: 2,
+          label: '一级 2',
+          children: [{
+            id: 5,
+            label: '二级 2-1'
+          }, {
+            id: 6,
+            label: '二级 2-2'
+          }]
+        }, {
+          id: 3,
+          label: '一级 3',
+          children: [{
+            id: 7,
+            label: '二级 3-1'
+          }, {
+            id: 8,
+            label: '二级 3-2'
+          }]
+      }],
+      defaultProps: {
+          children: 'children',
+          label: 'label'
+      },
+      taskList:[]
+    }
+  },
+  methods: {
+    filterNode(value, data) {
+        if (!value) return true;
+        return data.label.indexOf(value) !== -1;
+    },
+    handleSelectionChange() { }
+  },
+}
+</script>
+
+<style scoped lang="scss">
+.specialAttr {
+  height: calc(100vh - 84px);
+  padding: 12px;
+  box-sizing: border-box;
+}
+</style>

+ 1 - 1
src/views/register.vue

@@ -1,7 +1,7 @@
 <template>
   <div class="register">
     <el-form ref="registerForm" :model="registerForm" :rules="registerRules" class="register-form">
-      <h3 class="title">德荣后台管理系统</h3>
+      <h3 class="title">德荣供应链管理平台</h3>
       <el-form-item prop="username">
         <el-input v-model="registerForm.username" type="text" auto-complete="off" placeholder="账号">
           <svg-icon slot="prefix" icon-class="user" class="el-input__icon input-icon" />

+ 245 - 119
src/views/system/role/index.vue

@@ -1,6 +1,12 @@
 <template>
   <div class="app-container">
-    <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch">
+    <el-form
+      :model="queryParams"
+      ref="queryForm"
+      size="small"
+      :inline="true"
+      v-show="showSearch"
+    >
       <el-form-item label="角色名称" prop="roleName">
         <el-input
           v-model="queryParams.roleName"
@@ -46,8 +52,16 @@
         ></el-date-picker>
       </el-form-item>
       <el-form-item>
-        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
-        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
+        <el-button
+          type="primary"
+          icon="el-icon-search"
+          size="mini"
+          @click="handleQuery"
+          >搜索</el-button
+        >
+        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery"
+          >重置</el-button
+        >
       </el-form-item>
     </el-form>
 
@@ -60,7 +74,8 @@
           size="mini"
           @click="handleAdd"
           v-hasPermi="['system:role:add']"
-        >新增</el-button>
+          >新增</el-button
+        >
       </el-col>
       <el-col :span="1.5">
         <el-button
@@ -71,7 +86,8 @@
           :disabled="single"
           @click="handleUpdate"
           v-hasPermi="['system:role:edit']"
-        >修改</el-button>
+          >修改</el-button
+        >
       </el-col>
       <el-col :span="1.5">
         <el-button
@@ -82,7 +98,8 @@
           :disabled="multiple"
           @click="handleDelete"
           v-hasPermi="['system:role:remove']"
-        >删除</el-button>
+          >删除</el-button
+        >
       </el-col>
       <el-col :span="1.5">
         <el-button
@@ -92,16 +109,34 @@
           size="mini"
           @click="handleExport"
           v-hasPermi="['system:role:export']"
-        >导出</el-button>
+          >导出</el-button
+        >
       </el-col>
-      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
+      <right-toolbar
+        :showSearch.sync="showSearch"
+        @queryTable="getList"
+      ></right-toolbar>
     </el-row>
 
-    <el-table v-loading="loading" :data="roleList" @selection-change="handleSelectionChange">
+    <el-table
+      v-loading="loading"
+      :data="roleList"
+      @selection-change="handleSelectionChange"
+    >
       <el-table-column type="selection" width="55" align="center" />
       <el-table-column label="角色编号" prop="roleId" width="120" />
-      <el-table-column label="角色名称" prop="roleName" :show-overflow-tooltip="true" width="150" />
-      <el-table-column label="权限字符" prop="roleKey" :show-overflow-tooltip="true" width="150" />
+      <el-table-column
+        label="角色名称"
+        prop="roleName"
+        :show-overflow-tooltip="true"
+        width="150"
+      />
+      <el-table-column
+        label="权限字符"
+        prop="roleKey"
+        :show-overflow-tooltip="true"
+        width="150"
+      />
       <el-table-column label="显示顺序" prop="roleSort" width="100" />
       <el-table-column label="状态" align="center" width="100">
         <template slot-scope="scope">
@@ -113,12 +148,21 @@
           ></el-switch>
         </template>
       </el-table-column>
-      <el-table-column label="创建时间" align="center" prop="createTime" width="180">
+      <el-table-column
+        label="创建时间"
+        align="center"
+        prop="createTime"
+        width="180"
+      >
         <template slot-scope="scope">
           <span>{{ parseTime(scope.row.createTime) }}</span>
         </template>
       </el-table-column>
-      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+      <el-table-column
+        label="操作"
+        align="center"
+        class-name="small-padding fixed-width"
+      >
         <template slot-scope="scope" v-if="scope.row.roleId !== 1">
           <el-button
             size="mini"
@@ -126,21 +170,37 @@
             icon="el-icon-edit"
             @click="handleUpdate(scope.row)"
             v-hasPermi="['system:role:edit']"
-          >修改</el-button>
+            >修改</el-button
+          >
           <el-button
             size="mini"
             type="text"
             icon="el-icon-delete"
             @click="handleDelete(scope.row)"
             v-hasPermi="['system:role:remove']"
-          >删除</el-button>
-          <el-dropdown size="mini" @command="(command) => handleCommand(command, scope.row)" v-hasPermi="['system:role:edit']">
-            <el-button size="mini" type="text" icon="el-icon-d-arrow-right">更多</el-button>
+            >删除</el-button
+          >
+          <el-dropdown
+            size="mini"
+            @command="(command) => handleCommand(command, scope.row)"
+            v-hasPermi="['system:role:edit']"
+          >
+            <el-button size="mini" type="text" icon="el-icon-d-arrow-right"
+              >更多</el-button
+            >
             <el-dropdown-menu slot="dropdown">
-              <el-dropdown-item command="handleDataScope" icon="el-icon-circle-check"
-                v-hasPermi="['system:role:edit']">数据权限</el-dropdown-item>
-              <el-dropdown-item command="handleAuthUser" icon="el-icon-user"
-                v-hasPermi="['system:role:edit']">分配用户</el-dropdown-item>
+              <el-dropdown-item
+                command="handleDataScope"
+                icon="el-icon-circle-check"
+                v-hasPermi="['system:role:edit']"
+                >数据权限</el-dropdown-item
+              >
+              <el-dropdown-item
+                command="handleAuthUser"
+                icon="el-icon-user"
+                v-hasPermi="['system:role:edit']"
+                >分配用户</el-dropdown-item
+              >
             </el-dropdown-menu>
           </el-dropdown>
         </template>
@@ -148,7 +208,7 @@
     </el-table>
 
     <pagination
-      v-show="total>0"
+      v-show="total > 0"
       :total="total"
       :page.sync="queryParams.pageNum"
       :limit.sync="queryParams.pageSize"
@@ -163,7 +223,10 @@
         </el-form-item>
         <el-form-item prop="roleKey">
           <span slot="label">
-            <el-tooltip content="控制器中定义的权限字符,如:@PreAuthorize(`@ss.hasRole('admin')`)" placement="top">
+            <el-tooltip
+              content="控制器中定义的权限字符,如:@PreAuthorize(`@ss.hasRole('admin')`)"
+              placement="top"
+            >
               <i class="el-icon-question"></i>
             </el-tooltip>
             权限字符
@@ -171,7 +234,11 @@
           <el-input v-model="form.roleKey" placeholder="请输入权限字符" />
         </el-form-item>
         <el-form-item label="角色顺序" prop="roleSort">
-          <el-input-number v-model="form.roleSort" controls-position="right" :min="0" />
+          <el-input-number
+            v-model="form.roleSort"
+            controls-position="right"
+            :min="0"
+          />
         </el-form-item>
         <el-form-item label="状态">
           <el-radio-group v-model="form.status">
@@ -179,13 +246,26 @@
               v-for="dict in dict.type.sys_normal_disable"
               :key="dict.value"
               :label="dict.value"
-            >{{dict.label}}</el-radio>
+              >{{ dict.label }}</el-radio
+            >
           </el-radio-group>
         </el-form-item>
         <el-form-item label="菜单权限">
-          <el-checkbox v-model="menuExpand" @change="handleCheckedTreeExpand($event, 'menu')">展开/折叠</el-checkbox>
-          <el-checkbox v-model="menuNodeAll" @change="handleCheckedTreeNodeAll($event, 'menu')">全选/全不选</el-checkbox>
-          <el-checkbox v-model="form.menuCheckStrictly" @change="handleCheckedTreeConnect($event, 'menu')">父子联动</el-checkbox>
+          <el-checkbox
+            v-model="menuExpand"
+            @change="handleCheckedTreeExpand($event, 'menu')"
+            >展开/折叠</el-checkbox
+          >
+          <el-checkbox
+            v-model="menuNodeAll"
+            @change="handleCheckedTreeNodeAll($event, 'menu')"
+            >全选/全不选</el-checkbox
+          >
+          <el-checkbox
+            v-model="form.menuCheckStrictly"
+            @change="handleCheckedTreeConnect($event, 'menu')"
+            >父子联动</el-checkbox
+          >
           <el-tree
             class="tree-border"
             :data="menuOptions"
@@ -198,7 +278,11 @@
           ></el-tree>
         </el-form-item>
         <el-form-item label="备注">
-          <el-input v-model="form.remark" type="textarea" placeholder="请输入内容"></el-input>
+          <el-input
+            v-model="form.remark"
+            type="textarea"
+            placeholder="请输入内容"
+          ></el-input>
         </el-form-item>
       </el-form>
       <div slot="footer" class="dialog-footer">
@@ -208,7 +292,12 @@
     </el-dialog>
 
     <!-- 分配角色数据权限对话框 -->
-    <el-dialog :title="title" :visible.sync="openDataScope" width="500px" append-to-body>
+    <el-dialog
+      :title="title"
+      :visible.sync="openDataScope"
+      width="500px"
+      append-to-body
+    >
       <el-form :model="form" label-width="80px">
         <el-form-item label="角色名称">
           <el-input v-model="form.roleName" :disabled="true" />
@@ -227,9 +316,21 @@
           </el-select>
         </el-form-item>
         <el-form-item label="数据权限" v-show="form.dataScope == 2">
-          <el-checkbox v-model="deptExpand" @change="handleCheckedTreeExpand($event, 'dept')">展开/折叠</el-checkbox>
-          <el-checkbox v-model="deptNodeAll" @change="handleCheckedTreeNodeAll($event, 'dept')">全选/全不选</el-checkbox>
-          <el-checkbox v-model="form.deptCheckStrictly" @change="handleCheckedTreeConnect($event, 'dept')">父子联动</el-checkbox>
+          <el-checkbox
+            v-model="deptExpand"
+            @change="handleCheckedTreeExpand($event, 'dept')"
+            >展开/折叠</el-checkbox
+          >
+          <el-checkbox
+            v-model="deptNodeAll"
+            @change="handleCheckedTreeNodeAll($event, 'dept')"
+            >全选/全不选</el-checkbox
+          >
+          <el-checkbox
+            v-model="form.deptCheckStrictly"
+            @change="handleCheckedTreeConnect($event, 'dept')"
+            >父子联动</el-checkbox
+          >
           <el-tree
             class="tree-border"
             :data="deptOptions"
@@ -252,12 +353,24 @@
 </template>
 
 <script>
-import { listRole, getRole, delRole, addRole, updateRole, dataScope, changeRoleStatus, deptTreeSelect } from "@/api/system/role";
-import { treeselect as menuTreeselect, roleMenuTreeselect } from "@/api/system/menu";
+import {
+  listRole,
+  getRole,
+  delRole,
+  addRole,
+  updateRole,
+  dataScope,
+  changeRoleStatus,
+  deptTreeSelect,
+} from "@/api/system/role";
+import {
+  treeselect as menuTreeselect,
+  roleMenuTreeselect,
+} from "@/api/system/menu";
 
 export default {
   name: "Role",
-  dicts: ['sys_normal_disable'],
+  dicts: ["sys_normal_disable"],
   data() {
     return {
       // 遮罩层
@@ -290,24 +403,24 @@ export default {
       dataScopeOptions: [
         {
           value: "1",
-          label: "全部数据权限"
+          label: "全部数据权限",
         },
         {
           value: "2",
-          label: "自定数据权限"
+          label: "自定数据权限",
         },
         {
           value: "3",
-          label: "本部门数据权限"
+          label: "本部门数据权限",
         },
         {
           value: "4",
-          label: "本部门及以下数据权限"
+          label: "本部门及以下数据权限",
         },
         {
           value: "5",
-          label: "仅本人数据权限"
-        }
+          label: "仅本人数据权限",
+        },
       ],
       // 菜单列表
       menuOptions: [],
@@ -319,26 +432,26 @@ export default {
         pageSize: 10,
         roleName: undefined,
         roleKey: undefined,
-        status: undefined
+        status: undefined,
       },
       // 表单参数
       form: {},
       defaultProps: {
         children: "children",
-        label: "label"
+        label: "label",
       },
       // 表单校验
       rules: {
         roleName: [
-          { required: true, message: "角色名称不能为空", trigger: "blur" }
+          { required: true, message: "角色名称不能为空", trigger: "blur" },
         ],
         roleKey: [
-          { required: true, message: "权限字符不能为空", trigger: "blur" }
+          { required: true, message: "权限字符不能为空", trigger: "blur" },
         ],
         roleSort: [
-          { required: true, message: "角色顺序不能为空", trigger: "blur" }
-        ]
-      }
+          { required: true, message: "角色顺序不能为空", trigger: "blur" },
+        ],
+      },
     };
   },
   created() {
@@ -348,7 +461,8 @@ export default {
     /** 查询角色列表 */
     getList() {
       this.loading = true;
-      listRole(this.addDateRange(this.queryParams, this.dateRange)).then(response => {
+      listRole(this.addDateRange(this.queryParams, this.dateRange)).then(
+        (response) => {
           this.roleList = response.rows;
           this.total = response.total;
           this.loading = false;
@@ -357,7 +471,7 @@ export default {
     },
     /** 查询菜单树结构 */
     getMenuTreeselect() {
-      menuTreeselect().then(response => {
+      menuTreeselect().then((response) => {
         this.menuOptions = response.data;
       });
     },
@@ -381,14 +495,14 @@ export default {
     },
     /** 根据角色ID查询菜单树结构 */
     getRoleMenuTreeselect(roleId) {
-      return roleMenuTreeselect(roleId).then(response => {
+      return roleMenuTreeselect(roleId).then((response) => {
         this.menuOptions = response.menus;
         return response;
       });
     },
     /** 根据角色ID查询部门树结构 */
     getDeptTree(roleId) {
-      return deptTreeSelect(roleId).then(response => {
+      return deptTreeSelect(roleId).then((response) => {
         this.deptOptions = response.depts;
         return response;
       });
@@ -396,13 +510,17 @@ export default {
     // 角色状态修改
     handleStatusChange(row) {
       let text = row.status === "0" ? "启用" : "停用";
-      this.$modal.confirm('确认要"' + text + '""' + row.roleName + '"角色吗?').then(function() {
-        return changeRoleStatus(row.roleId, row.status);
-      }).then(() => {
-        this.$modal.msgSuccess(text + "成功");
-      }).catch(function() {
-        row.status = row.status === "0" ? "1" : "0";
-      });
+      this.$modal
+        .confirm('确认要"' + text + '""' + row.roleName + '"角色吗?')
+        .then(function () {
+          return changeRoleStatus(row.roleId, row.status);
+        })
+        .then(() => {
+          this.$modal.msgSuccess(text + "成功");
+        })
+        .catch(function () {
+          row.status = row.status === "0" ? "1" : "0";
+        });
     },
     // 取消按钮
     cancel() {
@@ -419,22 +537,22 @@ export default {
       if (this.$refs.menu != undefined) {
         this.$refs.menu.setCheckedKeys([]);
       }
-      this.menuExpand = false,
-      this.menuNodeAll = false,
-      this.deptExpand = true,
-      this.deptNodeAll = false,
-      this.form = {
-        roleId: undefined,
-        roleName: undefined,
-        roleKey: undefined,
-        roleSort: 0,
-        status: "0",
-        menuIds: [],
-        deptIds: [],
-        menuCheckStrictly: true,
-        deptCheckStrictly: true,
-        remark: undefined
-      };
+      (this.menuExpand = false),
+        (this.menuNodeAll = false),
+        (this.deptExpand = true),
+        (this.deptNodeAll = false),
+        (this.form = {
+          roleId: undefined,
+          roleName: undefined,
+          roleKey: undefined,
+          roleSort: 0,
+          status: "0",
+          menuIds: [],
+          deptIds: [],
+          menuCheckStrictly: true,
+          deptCheckStrictly: true,
+          remark: undefined,
+        });
       this.resetForm("form");
     },
     /** 搜索按钮操作 */
@@ -450,9 +568,9 @@ export default {
     },
     // 多选框选中数据
     handleSelectionChange(selection) {
-      this.ids = selection.map(item => item.roleId)
-      this.single = selection.length!=1
-      this.multiple = !selection.length
+      this.ids = selection.map((item) => item.roleId);
+      this.single = selection.length != 1;
+      this.multiple = !selection.length;
     },
     // 更多操作触发
     handleCommand(command, row) {
@@ -469,12 +587,12 @@ export default {
     },
     // 树权限(展开/折叠)
     handleCheckedTreeExpand(value, type) {
-      if (type == 'menu') {
+      if (type == "menu") {
         let treeList = this.menuOptions;
         for (let i = 0; i < treeList.length; i++) {
           this.$refs.menu.store.nodesMap[treeList[i].id].expanded = value;
         }
-      } else if (type == 'dept') {
+      } else if (type == "dept") {
         let treeList = this.deptOptions;
         for (let i = 0; i < treeList.length; i++) {
           this.$refs.dept.store.nodesMap[treeList[i].id].expanded = value;
@@ -483,18 +601,18 @@ export default {
     },
     // 树权限(全选/全不选)
     handleCheckedTreeNodeAll(value, type) {
-      if (type == 'menu') {
-        this.$refs.menu.setCheckedNodes(value ? this.menuOptions: []);
-      } else if (type == 'dept') {
-        this.$refs.dept.setCheckedNodes(value ? this.deptOptions: []);
+      if (type == "menu") {
+        this.$refs.menu.setCheckedNodes(value ? this.menuOptions : []);
+      } else if (type == "dept") {
+        this.$refs.dept.setCheckedNodes(value ? this.deptOptions : []);
       }
     },
     // 树权限(父子联动)
     handleCheckedTreeConnect(value, type) {
-      if (type == 'menu') {
-        this.form.menuCheckStrictly = value ? true: false;
-      } else if (type == 'dept') {
-        this.form.deptCheckStrictly = value ? true: false;
+      if (type == "menu") {
+        this.form.menuCheckStrictly = value ? true : false;
+      } else if (type == "dept") {
+        this.form.deptCheckStrictly = value ? true : false;
       }
     },
     /** 新增按钮操作 */
@@ -507,19 +625,19 @@ export default {
     /** 修改按钮操作 */
     handleUpdate(row) {
       this.reset();
-      const roleId = row.roleId || this.ids
+      const roleId = row.roleId || this.ids;
       const roleMenu = this.getRoleMenuTreeselect(roleId);
-      getRole(roleId).then(response => {
+      getRole(roleId).then((response) => {
         this.form = response.data;
         this.open = true;
         this.$nextTick(() => {
-          roleMenu.then(res => {
-            let checkedKeys = res.checkedKeys
+          roleMenu.then((res) => {
+            let checkedKeys = res.checkedKeys;
             checkedKeys.forEach((v) => {
-                this.$nextTick(()=>{
-                    this.$refs.menu.setChecked(v, true ,false);
-                })
-            })
+              this.$nextTick(() => {
+                this.$refs.menu.setChecked(v, true, false);
+              });
+            });
           });
         });
         this.title = "修改角色";
@@ -527,7 +645,7 @@ export default {
     },
     /** 选择角色权限范围触发 */
     dataScopeSelectChange(value) {
-      if(value !== '2') {
+      if (value !== "2") {
         this.$refs.dept.setCheckedKeys([]);
       }
     },
@@ -535,11 +653,11 @@ export default {
     handleDataScope(row) {
       this.reset();
       const deptTreeSelect = this.getDeptTree(row.roleId);
-      getRole(row.roleId).then(response => {
+      getRole(row.roleId).then((response) => {
         this.form = response.data;
         this.openDataScope = true;
         this.$nextTick(() => {
-          deptTreeSelect.then(res => {
+          deptTreeSelect.then((res) => {
             this.$refs.dept.setCheckedKeys(res.checkedKeys);
           });
         });
@@ -547,24 +665,24 @@ export default {
       });
     },
     /** 分配用户操作 */
-    handleAuthUser: function(row) {
+    handleAuthUser: function (row) {
       const roleId = row.roleId;
       this.$router.push("/system/role-auth/user/" + roleId);
     },
     /** 提交按钮 */
-    submitForm: function() {
-      this.$refs["form"].validate(valid => {
+    submitForm: function () {
+      this.$refs["form"].validate((valid) => {
         if (valid) {
           if (this.form.roleId != undefined) {
             this.form.menuIds = this.getMenuAllCheckedKeys();
-            updateRole(this.form).then(response => {
+            updateRole(this.form).then((response) => {
               this.$modal.msgSuccess("修改成功");
               this.open = false;
               this.getList();
             });
           } else {
             this.form.menuIds = this.getMenuAllCheckedKeys();
-            addRole(this.form).then(response => {
+            addRole(this.form).then((response) => {
               this.$modal.msgSuccess("新增成功");
               this.open = false;
               this.getList();
@@ -574,10 +692,10 @@ export default {
       });
     },
     /** 提交按钮(数据权限) */
-    submitDataScope: function() {
+    submitDataScope: function () {
       if (this.form.roleId != undefined) {
         this.form.deptIds = this.getDeptAllCheckedKeys();
-        dataScope(this.form).then(response => {
+        dataScope(this.form).then((response) => {
           this.$modal.msgSuccess("修改成功");
           this.openDataScope = false;
           this.getList();
@@ -587,19 +705,27 @@ export default {
     /** 删除按钮操作 */
     handleDelete(row) {
       const roleIds = row.roleId || this.ids;
-      this.$modal.confirm('是否确认删除角色编号为"' + roleIds + '"的数据项?').then(function() {
-        return delRole(roleIds);
-      }).then(() => {
-        this.getList();
-        this.$modal.msgSuccess("删除成功");
-      }).catch(() => {});
+      this.$modal
+        .confirm('是否确认删除角色编号为"' + roleIds + '"的数据项?')
+        .then(function () {
+          return delRole(roleIds);
+        })
+        .then(() => {
+          this.getList();
+          this.$modal.msgSuccess("删除成功");
+        })
+        .catch(() => {});
     },
     /** 导出按钮操作 */
     handleExport() {
-      this.download('system/role/export', {
-        ...this.queryParams
-      }, `role_${new Date().getTime()}.xlsx`)
-    }
-  }
+      this.download(
+        "system/role/export",
+        {
+          ...this.queryParams,
+        },
+        `role_${new Date().getTime()}.xlsx`
+      );
+    },
+  },
 };
-</script>
+</script>

+ 526 - 0
src/views/system/table-template/index.vue

@@ -0,0 +1,526 @@
+<script>
+// import LabelTree from "./lable-tree.vue";
+// import TemplateTable from "./template-table.vue";
+import { list, item, role, auth } from "@/api/system/table-template";
+import { listRole } from "@/api/system/role";
+export default {
+  name: "TableTemplate",
+  components: {
+    // LabelTree,
+    // TemplateTable,
+  },
+  data() {
+    return {
+      loading: false,
+      // 详情弹窗标题
+      itemDialogTitle: "",
+      // 详情弹窗显隐
+      itemDialogVisible: false,
+      // 授权弹窗显隐
+      authDialogVisible: false,
+      // 授权查询参数
+      authQueryParams: { id: "", pageNum: 1, pageSize: 10 },
+      // 角色列表
+      roleList: [],
+      // 角色总数
+      roleTotal: 0,
+      // 已授权角色列表,
+      authRoleList: [],
+
+      form1: { input: "", select: "" },
+      form2: { input: "", select: "" },
+      page: { pageNum: 1, pageSize: 25 },
+      total: 0,
+      options: [],
+      tableData: [],
+      selectionTableData: [],
+      columns: [
+        {
+          type: "text",
+          prop: "templateCode",
+          label: "模板编码",
+          showOverflowTooltip: true,
+        },
+        {
+          type: "text",
+          prop: "templateName",
+          label: "模板名称",
+          showOverflowTooltip: true,
+        },
+        {
+          type: "text",
+          prop: "desc",
+          label: "描述",
+          showOverflowTooltip: true,
+        },
+        {
+          type: "text",
+          prop: "remark",
+          label: "备注",
+          showOverflowTooltip: true,
+        },
+        {
+          type: "select",
+          prop: "status",
+          label: "启用状态",
+          showOverflowTooltip: true,
+        },
+        {
+          type: "text",
+          prop: "createBy",
+          label: "创建者",
+          showOverflowTooltip: true,
+        },
+        {
+          type: "text",
+          prop: "createTime",
+          label: "创建时间",
+          showOverflowTooltip: true,
+        },
+        {
+          type: "text",
+          prop: "updateBy",
+          label: "更新者",
+          showOverflowTooltip: true,
+        },
+        {
+          type: "text",
+          prop: "updateTime",
+          label: "更新时间",
+          showOverflowTooltip: true,
+        },
+      ],
+    };
+  },
+  methods: {
+    // 搜索模板列表
+    fetchList() {
+      list(this.from, this.page).then((res) => {
+        let { total, rows } = res;
+        this.tableData = rows;
+        this.total = total;
+      });
+    },
+    // 查询模板列表
+    onSearch() {
+      this.pageNum = 1;
+      this.fetchList();
+    },
+    //
+    onSizeChnage() {
+      this.pageNum = 1;
+      this.fetchList();
+    },
+    //
+    onCurrentChange() {
+      this.fetchList();
+    },
+    // 选择待复制模板
+    onSelectionChange(value) {
+      this.selectionTableData = value;
+    },
+    // 打开授权弹窗
+    onAuthTemplate(props) {
+      let { id } = props;
+      this.authDialogVisible = true;
+      this.authQueryParams.id = id;
+      listRole(this.authQueryParams).then((res) => {
+        let { rows, total } = res;
+        this.roleList = rows.map((item) => ({
+          key: item.roleId,
+          label: item.roleName,
+        }));
+        this.roleTotal = total;
+      });
+      role(id).then((res) => {
+        let { data } = res;
+        this.authRoleList = data.map((item) => item.roleId);
+      });
+    },
+    // 打开编辑弹窗
+    onEditTemplate(props) {
+      this.itemDialogTitle = "编辑";
+      this.itemDialogVisible = true;
+      let { id } = props;
+      item(id).then((res) => {
+        let { data } = res;
+        this.form2 = data;
+        this.form2.sysTemplateItemList = data.sysTemplateItemList.map(
+          (item) => ({
+            ...item,
+            isEdit: item.isEdit === "1" ? true : false,
+            isShow: item.isShow === "1" ? true : false,
+            isRequired: item.isRequired === "1" ? true : false,
+          })
+        );
+      });
+    },
+    // 提交授权
+    onSubmitAuth() {
+      let templateId = this.authQueryParams.id;
+      let roleIdList = this.authRoleList;
+      auth({ templateId, roleIdList }).then((res) => {
+        let { code } = res;
+        if (code == 200) {
+          this.authDialogVisible = false;
+          this.$message.success("授权成功");
+        }
+      });
+    },
+    // 复制编辑模板
+    onCopyTemplate(props) {
+      this.itemDialogTitle = "复制";
+      this.itemDialogVisible = true;
+      let { id } = props;
+      item(id).then((res) => {
+        let { data } = res;
+        this.form2 = data;
+        this.form2.sysTemplateItemList = data.sysTemplateItemList.map(
+          (item) => ({
+            ...item,
+            isEdit: item.isEdit === "1" ? true : false,
+            isShow: item.isShow === "1" ? true : false,
+            isRequired: item.isRequired === "1" ? true : false,
+          })
+        );
+      });
+    },
+
+    // 删除模板row
+    onRemoveTemplateRow(props) {
+      let { code } = props;
+      this.form2.sysTemplateItemList = this.form2.sysTemplateItemList.filter(
+        (item) => item.code !== code
+      );
+    },
+    // 移动模板row
+    onMoveTemplateRow(direction, index1) {
+      let index2 = 0;
+      let swapArr = (arr, index1, index2) => {
+        arr[index1] = arr.splice(index2, 1, arr[index1])[0];
+        return arr;
+      };
+      index2 = direction === "top" ? index1 - 1 : index1 + 1;
+      this.form2.sysTemplateItemList = swapArr(
+        this.form2.sysTemplateItemList,
+        index1,
+        index2
+      );
+    },
+  },
+
+  created() {
+    this.fetchList();
+  },
+};
+</script>
+
+<template>
+  <el-container class="container table-template">
+    <el-container class="table-template-table">
+      <el-header>
+        <div class="table-header-top">
+          <span>查询条件</span>
+          <div>
+            <el-select v-model="form1.select" size="small" placeholder="请选择">
+              <el-option
+                v-for="item in options"
+                :key="item.value"
+                :label="item.label"
+                :value="item.value"
+              >
+              </el-option>
+            </el-select>
+            <el-input
+              v-model="form1.input"
+              size="small"
+              placeholder="请输入内容"
+              :readonly="loading"
+              @change="onSearch"
+            >
+              <template #suffix>
+                <i v-show="loading" class="el-input__icon el-icon-loading"></i>
+                <i v-show="!loading" class="el-input__icon el-icon-search"></i>
+              </template>
+            </el-input>
+            <el-button size="small">搜索</el-button>
+            <el-button size="small">重置</el-button>
+          </div>
+        </div>
+        <div class="table-header-bottom">
+          <el-button size="small">新增</el-button>
+          <el-button
+            size="small"
+            :disabled="selectionTableData.length !== 1"
+            @click="onCopyTemplate(selectionTableData[0])"
+            >复制</el-button
+          >
+          <el-button size="small">导入</el-button>
+          <el-button size="small">导出</el-button>
+        </div>
+      </el-header>
+      <el-main>
+        <el-table :data="tableData" @selection-change="onSelectionChange">
+          <el-table-column
+            type="selection"
+            width="55"
+            fixed="left"
+            align="center"
+            show-overflow-tooltip
+          >
+          </el-table-column>
+          <el-table-column
+            v-for="column in columns"
+            :key="column.prop"
+            :prop="column.prop"
+            :label="column.label"
+            :show-overflow-tooltip="column.showOverflowTooltip"
+          >
+          </el-table-column>
+          <el-table-column fixed="right" label="操作" width="225">
+            <template slot-scope="scope">
+              <el-button
+                @click.native.prevent="onAuthTemplate(scope.row)"
+                size="small"
+              >
+                授权
+              </el-button>
+              <el-button
+                @click.native.prevent="onEditTemplate(scope.row)"
+                size="small"
+              >
+                修改
+              </el-button>
+              <el-button
+                @click.native.prevent="deleteRow(scope.$index, tableData)"
+                size="small"
+              >
+                删除
+              </el-button>
+            </template>
+          </el-table-column>
+        </el-table>
+      </el-main>
+      <el-footer>
+        <el-pagination
+          @size-change="onSizeChnage"
+          @current-change="onCurrentChange"
+          :current-page="page.pageNum"
+          :page-sizes="[25, 50, 100]"
+          :page-size="page.pageSize"
+          layout="total, prev, pager, next, sizes, jumper"
+          :total="total"
+        >
+        </el-pagination>
+      </el-footer>
+    </el-container>
+    <el-dialog
+      width="75%"
+      destroy-on-close
+      :title="itemDialogTitle"
+      :visible.sync="itemDialogVisible"
+    >
+      <el-row :gutter="20">
+        <el-form size="mini" :model="form2" label-position="top">
+          <el-col v-for="column in columns" :key="column.prop" :span="6">
+            <el-form-item :label="column.label">
+              <el-input
+                v-if="column.type === 'text'"
+                v-model="form2[column.prop]"
+              ></el-input>
+              <el-select
+                v-if="column.type === 'select'"
+                v-model="form2[column.prop]"
+              >
+                <el-option label="区域一" value="shanghai"></el-option>
+                <el-option label="区域二" value="beijing"></el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="24">
+            <el-form-item label="模板配置">
+              <el-table :data="form2.sysTemplateItemList">
+                <el-table-column type="index" width="50"> </el-table-column>
+                <el-table-column prop="code" label="字段编码" width="200">
+                  <template slot-scope="scope">
+                    <el-input v-model="scope.row.code"></el-input>
+                  </template>
+                </el-table-column>
+                <el-table-column prop="name" label="字段名称" width="200">
+                  <template slot-scope="scope">
+                    <el-input v-model="scope.row.name"></el-input>
+                  </template>
+                </el-table-column>
+                <el-table-column prop="isEdit" label="是否编辑">
+                  <template slot-scope="scope">
+                    <el-switch v-model="scope.row.isEdit"> </el-switch>
+                  </template>
+                </el-table-column>
+                <el-table-column prop="isShow" label="是否显示">
+                  <template slot-scope="scope">
+                    <el-switch v-model="scope.row.isShow"> </el-switch>
+                  </template>
+                </el-table-column>
+                <el-table-column prop="isRequired" label="是否必填">
+                  <template slot-scope="scope">
+                    <el-switch v-model="scope.row.isRequired"> </el-switch>
+                  </template>
+                </el-table-column>
+                <el-table-column
+                  prop="conditionType"
+                  label="字段类型"
+                  width="200"
+                >
+                  <template slot-scope="scope">
+                    <el-input v-model="scope.row.conditionType"></el-input>
+                  </template>
+                </el-table-column>
+                <el-table-column prop="dictId" label="字典ID" width="200">
+                  <template slot-scope="scope">
+                    <el-input v-model="scope.row.dictId"></el-input>
+                  </template>
+                </el-table-column>
+                <el-table-column
+                  prop="textAttribute"
+                  label="文本类型"
+                  width="200"
+                >
+                  <template slot-scope="scope">
+                    <el-input v-model="scope.row.textAttribute"></el-input>
+                  </template>
+                </el-table-column>
+                <el-table-column prop="checkRule" label="校验规则" width="200">
+                  <template slot-scope="scope">
+                    <el-input v-model="scope.row.checkRule"></el-input>
+                  </template>
+                </el-table-column>
+                <el-table-column fixed="right" label="操作" width="150">
+                  <template slot-scope="scope">
+                    <el-button
+                      :disabled="scope.$index === 0"
+                      @click.native.prevent="
+                        onMoveTemplateRow('top', scope.$index)
+                      "
+                      icon="el-icon-top"
+                      circle
+                    >
+                    </el-button>
+                    <el-button
+                      :disabled="
+                        scope.$index === form2.sysTemplateItemList.length - 1
+                      "
+                      @click.native.prevent="
+                        onMoveTemplateRow('bottom', scope.$index)
+                      "
+                      icon="el-icon-bottom"
+                      circle
+                    >
+                    </el-button>
+                    <el-button
+                      @click.native.prevent="onRemoveTemplateRow(scope.row)"
+                      icon="el-icon-remove"
+                      circle
+                    >
+                    </el-button>
+                  </template>
+                </el-table-column>
+              </el-table>
+            </el-form-item>
+          </el-col>
+          <!-- <el-col :span="12">
+            <el-form-item label="活动区域">
+              <el-select v-model="form2.region" placeholder="请选择活动区域">
+                <el-option label="区域一" value="shanghai"></el-option>
+                <el-option label="区域二" value="beijing"></el-option>
+              </el-select>
+            </el-form-item>
+          </el-col> -->
+        </el-form>
+      </el-row>
+      <div slot="footer">
+        <el-button @click="itemDialogVisible = false">取 消</el-button>
+        <el-button type="primary" @click="itemDialogVisible = false"
+          >确 定</el-button
+        >
+      </div>
+    </el-dialog>
+    <el-dialog
+      width="fit-content"
+      destroy-on-close
+      title="君权孙授"
+      :visible.sync="authDialogVisible"
+    >
+      <el-transfer
+        v-model="authRoleList"
+        :data="roleList"
+        :titles="['未授权', '已授权']"
+      >
+        <template #left-footer>
+          <el-pagination :total="roleTotal" layout="prev, pager, next">
+          </el-pagination>
+        </template>
+      </el-transfer>
+      <div slot="footer">
+        <el-button @click="authDialogVisible = false">取 消</el-button>
+        <el-button type="primary" @click="onSubmitAuth">确 定 </el-button>
+      </div>
+    </el-dialog>
+  </el-container>
+</template>
+
+<style scoped>
+.container {
+  --size: 12px;
+  --margin: var(--size);
+  --padding: var(--size);
+}
+.container {
+  width: calc(100% - calc(var(--size) * 2));
+  /* height: calc(100vh - calc(var(--size) * 2)); */
+  margin: var(--padding);
+  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.12), 0 0 6px rgba(0, 0, 0, 0.04);
+}
+.container .el-aside {
+  margin: 0;
+  padding: var(--padding);
+  background-color: rgba(255, 255, 255, 1);
+  border-right: 1px solid #dcdfe6;
+  overflow: hidden;
+}
+.table-template-table .el-header {
+  height: fit-content !important;
+  padding-top: var(--padding);
+  padding-bottom: var(--padding);
+  border-bottom: 1px solid #dcdfe6;
+}
+.table-template-table .table-header-top {
+  margin-bottom: var(--margin);
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+}
+.table-template-table .table-header-top .el-select {
+  width: 150px;
+  margin-right: var(--margin);
+}
+.table-template-table .table-header-top .el-input {
+  width: 250px;
+  margin-right: var(--margin);
+}
+.table-template-table .el-main {
+  padding: 0;
+}
+.table-template-table .el-main .el-table {
+  width: 100%;
+  height: 100%;
+}
+.table-template-table .el-footer {
+  display: flex;
+  justify-content: end;
+  align-items: center;
+}
+.el-transfer .el-transfer-panel__footer {
+  display: flex;
+  align-items: center;
+}
+</style>

+ 171 - 0
src/views/system/table-template/template-table.vue

@@ -0,0 +1,171 @@
+<script>
+import { list, item } from "@/api/system/table-template";
+export default {
+  name: "TableTemplateTable",
+  data() {
+    return {
+      from: { input: "", select: "" },
+      options: [
+        {
+          value: "选项1",
+          label: "黄金糕",
+        },
+        {
+          value: "选项2",
+          label: "双皮奶",
+        },
+        {
+          value: "选项3",
+          label: "蚵仔煎",
+        },
+        {
+          value: "选项4",
+          label: "龙须面",
+        },
+        {
+          value: "选项5",
+          label: "北京烤鸭",
+        },
+      ],
+      tableData: [
+        {
+          date: "2016-05-022016-05-022016-05-022016-05-02",
+          name: "王小虎",
+          address: "上海市普陀区金沙江路 1518 弄",
+        },
+        {
+          date: "2016-05-04",
+          name: "王小虎",
+          address: "上海市普陀区金沙江路 1517 弄",
+        },
+        {
+          date: "2016-05-01",
+          name: "王小虎",
+          address: "上海市普陀区金沙江路 1519 弄",
+        },
+        {
+          date: "2016-05-03",
+          name: "王小虎",
+          address: "上海市普陀区金沙江路 1516 弄",
+        },
+      ],
+    };
+  },
+  methods: {
+    duanduan(value) {
+      this.$message(value + "duanduan");
+    },
+  },
+};
+</script>
+
+<template>
+  <el-container class="table-template-table">
+    <el-header>
+      <div class="table-header-top">
+        <span>查询条件</span>
+        <div>
+          <el-select v-model="from.select" size="small" placeholder="请选择">
+            <el-option
+              v-for="item in options"
+              :key="item.value"
+              :label="item.label"
+              :value="item.value"
+            >
+            </el-option>
+          </el-select>
+          <el-input
+            v-model="from.input"
+            size="small"
+            placeholder="请输入内容"
+            :readonly="isSearching"
+            @change="onSearch"
+          >
+            <template #suffix>
+              <i
+                v-show="isSearching"
+                class="el-input__icon el-icon-loading"
+              ></i>
+              <i
+                v-show="!isSearching"
+                class="el-input__icon el-icon-search"
+              ></i>
+            </template>
+          </el-input>
+          <el-button size="small">搜索</el-button>
+          <el-button size="small">重置</el-button>
+        </div>
+      </div>
+      <div class="table-header-bottom">
+        <el-button size="small">新增</el-button>
+        <el-button size="small">导入</el-button>
+        <el-button size="small">导出</el-button>
+      </div>
+    </el-header>
+    <el-main>
+      <el-table :data="tableData">
+        <el-table-column
+          type="selection"
+          width="55"
+          fixed="left"
+          align="center"
+          show-overflow-tooltip
+        >
+        </el-table-column>
+        <el-table-column prop="date" label="日期" show-overflow-tooltip>
+        </el-table-column>
+        <el-table-column prop="name" label="姓名" show-overflow-tooltip>
+        </el-table-column>
+        <el-table-column prop="address" label="地址" show-overflow-tooltip>
+        </el-table-column>
+      </el-table>
+    </el-main>
+    <el-footer>
+      <el-pagination
+        @size-change="handleSizeChange"
+        @current-change="handleCurrentChange"
+        :current-page="currentPage4"
+        :page-sizes="[100, 200, 300, 400]"
+        :page-size="100"
+        layout="total, prev, pager, next, sizes, jumper"
+        :total="400"
+      >
+      </el-pagination>
+    </el-footer>
+  </el-container>
+</template>
+
+<style scoped>
+.table-template-table .el-header {
+  height: fit-content !important;
+  padding-top: var(--padding);
+  padding-bottom: var(--padding);
+  border-bottom: 1px solid #dcdfe6;
+}
+.table-template-table .table-header-top {
+  margin-bottom: var(--margin);
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+}
+.table-template-table .table-header-top .el-select {
+  width: 150px;
+  margin-right: var(--margin);
+}
+.table-template-table .table-header-top .el-input {
+  width: 250px;
+  margin-right: var(--margin);
+}
+.table-template-table .el-main {
+  padding: 0;
+}
+.table-template-table .el-main .el-table {
+  width: 100%;
+  height: 100%;
+}
+.table-template-table .el-footer {
+  display: flex;
+  justify-content: end;
+  align-items: center;
+}
+</style>

+ 1 - 1
vue.config.js

@@ -37,7 +37,7 @@ module.exports = {
       // detail: https://cli.vuejs.org/config/#devserver-proxy
       [process.env.VUE_APP_BASE_API]: {
         // target: `http://172.16.100.107:8080/ruoyi-admin`, //生产
-        target: `http://172.16.100.107:8000/drp-admin`, //测试
+        target: `http://172.16.63.202:8000/drp-admin`, //测试
         changeOrigin: true,
         pathRewrite: {
           ['^' + process.env.VUE_APP_BASE_API]: ''