Z 1 gadu atpakaļ
vecāks
revīzija
47fc855484

+ 17 - 0
src/api/system/operationLog/api.js

@@ -0,0 +1,17 @@
+
+import request from '@/utils/request';
+
+/**
+ * 分页查询
+ * @param params 查询条件
+ */
+
+export async function operateLogPageAPI(params) {
+  const res = await request.get('/sys/operatelog/page', {
+    params
+  });
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}

+ 15 - 2
src/api/system/role/index.js

@@ -17,6 +17,19 @@ export async function pageRoles(params) {
   }
   return Promise.reject(new Error(res.data.message));
 }
+/**
+ * 查询所有角色
+ * @param params 查询条件
+ */
+export async function getRolesListAPI(params) {
+  const res = await request.post('/sys/role/list', {
+    params
+  });
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
 
 export async function putRoles(params) {
   const res = await request.put('/sys/role/update', params);
@@ -127,7 +140,7 @@ export async function updateRoleMenus(data) {
 
 /**
  * 点击新增获取角色列表
- * @param params 
+ * @param params
  */
 export async function getlistRole (id) {
   const res = await request.get('/sys/role/getByRoleName');
@@ -135,4 +148,4 @@ export async function getlistRole (id) {
     return res.data.data;
   }
   return Promise.reject(new Error(res.data.message));
-}
+}

+ 17 - 0
src/api/system/threeMembers/api.js

@@ -0,0 +1,17 @@
+
+import request from '@/utils/request';
+
+/**
+ * 分页查询
+ * @param params 查询条件
+ */
+
+export async function threeMembersPageAPI(params) {
+  const res = await request.get('/sys/role/pageSystem', {
+    params
+  });
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}

+ 28 - 3
src/enum/dict.js

@@ -83,8 +83,32 @@ export const reviewStatus = {
   2: '已审核',
   3: '审核不通过'
 };
+//涉密等级
+export const secretLevelList = [
+  {
+    value: 0,
+    label: '非密'
+  },
+  {
+    value: 1,
+    label: '内部'
+  },
+  {
+    value: 2,
+    label: '秘密'
+  },
+  {
+    value: 3,
+    label: '机密'
+  },
+  {
+    value: 4,
+    label: '绝密'
+  }
+];
 //编码粗规则
-export const roughRule = [{
+export const roughRule = [
+  {
     label: '数字',
     value: 1
   },
@@ -104,9 +128,10 @@ export const roughRule = [{
     label: '流水码',
     value: 5
   }
-]
+];
 //编码细规则
-export const fineRule = [{
+export const fineRule = [
+  {
     label: '0-9',
     value: '1',
     pid: '1',

+ 29 - 2
src/layout/index.vue

@@ -65,18 +65,33 @@
     <!-- 自定义菜单标题增加徽章、小红点 -->
     <template v-slot:title="{ title, item }">
       <span>{{ title }} </span>
+      <span
+        v-if="item.meta.secretLevel != 1"
+        :style="getSecretLevelStyle(item)"
+        >{{ getSecretLevel(item) }}</span
+      >
       <div v-if="item.meta && item.meta.badge" class="ele-menu-badge">
         <el-badge :value="item.meta.badge" :type="item.meta.badgeColor" />
       </div>
     </template>
     <template v-slot:top-title="{ title, item }">
       <span>{{ title }} </span>
+      <span
+        v-if="item.meta.secretLevel != 1"
+        :style="getSecretLevelStyle(item)"
+        >{{ getSecretLevel(item) }}</span
+      >
       <div v-if="item.meta && item.meta.badge" class="ele-menu-badge">
         <el-badge :value="item.meta.badge" :type="item.meta.badgeColor" />
       </div>
     </template>
     <template v-slot:nav-title="{ title, item }">
       <span>{{ title }} </span>
+      <span
+        v-if="item.meta.secretLevel != 1"
+        :style="getSecretLevelStyle(item)"
+        >{{ getSecretLevel(item) }}</span
+      >
       <div v-if="item.meta && item.meta.badge" class="ele-menu-badge">
         <el-badge :value="item.meta.badge" :type="item.meta.badgeColor" />
       </div>
@@ -112,13 +127,13 @@
     setHomeComponents,
     setPageTabs
   } from '@/utils/page-tab-util';
+  import { secretLevelList } from '@/enum/dict';
 
   export default {
     name: 'EleLayout',
     components: {
       RouterLayout,
-      HeaderTools,
-   
+      HeaderTools
     },
     data() {
       return {
@@ -150,6 +165,18 @@
       ...mapGetters(['theme'])
     },
     methods: {
+      getSecretLevelStyle(item) {
+        return {
+          color: item.meta.secretLevel > 1 ? 'red' : 'green',
+          fontWeight: 'bold',
+          fontSize: '15px'
+        };
+      },
+      getSecretLevel(item) {
+        let find =
+          secretLevelList.find((i) => item.meta.secretLevel == i.value) || {};
+        return '(' + find.label + ')';
+      },
       /* 侧栏折叠切换 */
       updateCollapse(value) {
         // console.log('value:', this.$store.state.user.menus);

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

@@ -24,6 +24,9 @@ const formatRouter = (list) => {
       } else {
         p.children = [];
       }
+      p.meta = {
+        secretLevel: p.secretLevel
+      };
       arr.push(p);
       // }
     }

+ 1 - 1
src/views/bpm/model/index.vue

@@ -200,7 +200,7 @@ export default {
         {
           columnKey: 'action',
           label: '操作',
-          width: 450,
+          width: 500,
           align: 'center',
           resizable: false,
           slot: 'action',

+ 13 - 1
src/views/system/menu/components/menu-edit.vue

@@ -45,6 +45,13 @@
           </el-form-item>
 
         </el-col>
+        <el-col :span="12">
+          <el-form-item label="密级:" prop="secretLevel">
+           <el-select v-model="form.secretLevel" style="width: 100%">
+             <el-option v-for="item in secretLevelList()" :key="item.value" :label="item.label" :value="item.value"></el-option>
+           </el-select>
+          </el-form-item>
+        </el-col>
         <el-col :span="12">
           <el-form-item label="排序号:" prop="sort">
             <el-input-number :min="0" v-model="form.sort" placeholder="请输入排序号" controls-position="right"
@@ -76,6 +83,7 @@
 <script>
 import { EleIconPicker } from 'ele-admin';
 import { saveOrUpdate } from '@/api/system/menu';
+import {secretLevelList} from "@/enum/dict";
 
 export default {
   components: { EleIconPicker },
@@ -100,7 +108,8 @@ export default {
       component: '',
       sort: null,
       rootId: null,
-      permissionCode: 1
+      permissionCode: 1,
+      secretLevel: 1,
     };
     return {
       defaultForm,
@@ -134,6 +143,9 @@ export default {
     // }
   },
   methods: {
+    secretLevelList() {
+      return secretLevelList
+    },
     /* 保存编辑 */
     save() {
       this.$refs.form.validate((valid) => {

+ 17 - 2
src/views/system/menu/index.vue

@@ -38,6 +38,10 @@
         <template v-slot:name="{ row }">
           <i :class="row.icon"></i> {{ row.name }}
         </template>
+        <!-- 标题列 -->
+        <template v-slot:secretLevel="{ row }">
+          {{  getSecretLevel(row.secretLevel) }}
+        </template>
         <!-- 类型列 -->
         <template v-slot:type="{ row }">
           <el-tag
@@ -105,6 +109,7 @@
 import MenuSearch from './components/menu-search.vue';
 import MenuEdit from './components/menu-edit.vue';
 import { listMenus, deleteMenu } from '@/api/system/menu';
+import {secretLevelList} from "../../../enum/dict";
 
 export default {
   name: 'SystemMenu',
@@ -142,7 +147,14 @@ export default {
           showOverflowTooltip: true,
           minWidth: 110
         },
-
+        {
+          prop: 'secretLevel',
+          label: '密级',
+          align: 'center',
+          showOverflowTooltip: true,
+          slot:'secretLevel',
+          minWidth: 110
+        },
         {
           prop: 'sort',
           label: '排序',
@@ -190,9 +202,12 @@ export default {
     };
   },
   methods: {
+    getSecretLevel(i) {
+      let find = secretLevelList.find(item=>item.value==i)||{}
+      return find.label
+    },
     /* 表格数据源 */
     datasource({ where }) {
-      console.log(listMenus({ ...where }))
       return listMenus({ ...where });
     },
     /* 数据转为树形结构 */

+ 64 - 0
src/views/system/operationLog/components/search.vue

@@ -0,0 +1,64 @@
+<!-- 搜索表单 -->
+<template>
+  <el-form
+    label-width="77px"
+    class="ele-form-search"
+    @keyup.enter.native="search"
+    @submit.native.prevent
+  >
+    <el-row :gutter="15">
+      <el-col v-bind="styleResponsive ? { lg: 6, md: 12 } : { span: 6 }">
+        <el-form-item label="用户名称:">
+          <el-input clearable v-model.trim="where.userName" placeholder="请输入" />
+        </el-form-item>
+      </el-col>
+      <el-col v-bind="styleResponsive ? { lg: 6, md: 12 } : { span: 6 }">
+        <div class="ele-form-actions">
+          <el-button
+            type="primary"
+            icon="el-icon-search"
+            class="ele-btn-icon"
+            @click="search"
+          >
+            查询
+          </el-button>
+          <el-button @click="reset">重置</el-button>
+        </div>
+      </el-col>
+    </el-row>
+  </el-form>
+</template>
+
+<script>
+  export default {
+    data() {
+      // 默认表单数据
+      const defaultWhere = {
+        userName: '',
+        groupName: ''
+      };
+      return {
+        // 表单数据
+        where: { ...defaultWhere }
+      };
+    },
+    computed: {
+      // 是否开启响应式布局
+      styleResponsive() {
+        return this.$store.state.theme.styleResponsive;
+      }
+    },
+    methods: {
+      /* 搜索 */
+      search() {
+        console.log(this.where);
+        this.$emit('search', this.where);
+      },
+      /*  重置 */
+      reset() {
+        this.where = { ...this.defaultWhere };
+        this.search();
+      }
+    }
+  };
+</script>

+ 118 - 0
src/views/system/operationLog/index.vue

@@ -0,0 +1,118 @@
+<template>
+  <div class="ele-body">
+    <el-card shadow="never">
+      <search @search="reload"></search>
+      <!-- 数据表格 -->
+      <ele-pro-table
+        ref="table"
+        :columns="columns"
+        :datasource="datasource"
+        height="calc(100vh - 300px)"
+        cache-key="systemRoleTable15"
+      >
+
+        <template v-slot:type="{ row }">
+          {{types[row.type]}}
+        </template>
+
+        <template v-slot:tableHeaderTitle="{ column }">
+          <span style="display: inline-block;text-align: center; width: 100%;">{{column.label}}</span>
+        </template>
+      </ele-pro-table>
+    </el-card>
+
+  </div>
+</template>
+
+<script>
+import search from "./components/search.vue";
+
+import {deepClone} from "@/utils";
+import {operateLogPageAPI} from "@/api/system/operationLog/api";
+
+export default {
+  name: 'index',
+components:{search},
+  data() {
+    return {
+      // 表格列配置
+      columns: [
+        {
+          columnKey: 'index',
+          label: '序号',
+          type: 'index',
+          width: 55,
+          align: 'center',
+          showOverflowTooltip: true,
+          fixed: 'left'
+        },
+        {
+          prop: 'userName',
+          label: '用户名称',
+          align: 'center',
+          showOverflowTooltip: true,
+          width: 120
+        },
+        {
+          prop: ' type',
+          label: '日志类型',
+          align: 'center',
+          slot: 'type',
+          showOverflowTooltip: true,
+          width: 120
+        },
+        {
+          prop: 'dateTime',
+          label: '操作时间',
+          minWidth: 100,
+          slot: 'dateTime',
+          align: 'center',
+          headerSlot: 'tableHeaderTitle',
+        },
+        {
+          prop: 'ip',
+          label: 'IP地址',
+          minWidth: 100,
+          align: 'center',
+        },
+        {
+          prop: 'tag',
+          label: '操作菜单',
+          minWidth: 100,
+          align: 'center',
+        },
+        {
+          prop: 'description',
+          label: '操作描述',
+          minWidth: 100,
+          align: 'center',
+        },
+        {
+          prop: 'api',
+          label: '访问接口',
+          minWidth: 100,
+          align: 'center',
+        }
+      ],
+      types:{
+        0:'常规日志',
+        1:'系统管理操作日志',
+        2:'系统安全操作日志',
+        3:'系统审计操作日志',
+      }
+    };
+  },
+  created() {
+  },
+  methods: {
+    /* 表格数据源 */
+    datasource({page, limit, where, order}) {
+      return operateLogPageAPI({pageNum: page, size: limit, ...where});
+    },
+    /* 刷新表格 */
+    reload(where) {
+      this.$refs.table.reload({page: 1, where});
+    },
+  }
+};
+</script>

+ 11 - 1
src/views/system/role/components/role-edit.vue

@@ -38,6 +38,11 @@
         >
         </el-switch>
       </el-form-item>
+      <el-form-item label="密级:" prop="secretLevel">
+        <el-select v-model="form.secretLevel" style="width: 100%">
+          <el-option v-for="item in secretLevelList()" :key="item.value" :label="item.label" :value="item.value"></el-option>
+        </el-select>
+      </el-form-item>
       <el-form-item label="权限范围" prop="dataScope">
         <DictSelection
           dictName="角色数据权限字典"
@@ -83,6 +88,7 @@
     listOrganizations,
 
   } from '@/api/system/organization';
+  import {secretLevelList} from "@/enum/dict";
   export default {
     props: {
       // 弹窗是否打开
@@ -99,7 +105,8 @@
         groupId: '',
         enable: 1,
         dataScope: '',
-        dataScopeDeptIds: ''
+        dataScopeDeptIds: '',
+        secretLevel: 1,
       };
       return {
         defaultForm,
@@ -132,6 +139,9 @@
       };
     },
     methods: {
+      secretLevelList() {
+        return secretLevelList
+      },
 
 
       query() {

+ 17 - 0
src/views/system/role/index.vue

@@ -8,6 +8,7 @@
         ref="table"
         :columns="columns"
         :datasource="datasource"
+        height="calc(100vh - 335px)"
         :selection.sync="selection"
         cache-key="systemRoleTable15"
       >
@@ -43,6 +44,9 @@
           >
           </el-switch>
         </template>
+        <template v-slot:secretLevel="{ row }">
+          {{  getSecretLevel(row.secretLevel) }}
+        </template>
         <!-- 操作列 -->
         <template v-slot:action="{ row }">
           <el-link
@@ -104,6 +108,7 @@ import {
   removeRoles,
   putRoles
 } from '@/api/system/role';
+import {secretLevelList} from "@/enum/dict";
 
 export default {
   name: 'SystemRole',
@@ -148,6 +153,14 @@ export default {
           showOverflowTooltip: true,
           minWidth: 110
         },
+        {
+          prop: 'secretLevel',
+          label: '密级',
+          align: 'center',
+          showOverflowTooltip: true,
+          slot:'secretLevel',
+          minWidth: 110
+        },
         {
           prop: 'enable',
           label: '启用状态',
@@ -213,6 +226,10 @@ export default {
     reload(where) {
       this.$refs.table.reload({page: 1, where});
     },
+    getSecretLevel(i) {
+      let find = secretLevelList.find(item=>item.value==i)||{}
+      return find.label
+    },
     /* 显示编辑 */
     openEdit(row) {
       if (row) {

+ 386 - 0
src/views/system/threeMembers/components/staffSelection.vue

@@ -0,0 +1,386 @@
+<template>
+  <div class="container">
+    <!-- 单据弹窗 -->
+    <el-dialog
+      title="用户"
+      :before-close="handleClose"
+      :visible.sync="dialogVisible"
+      :close-on-click-modal="false"
+      :append-to-body="true"
+      width="80%"
+    >
+      <el-row class="zw-page">
+        <el-col :span="6" class="zw-page-left">
+          <el-card>
+            <div class="zw-card-header" slot="header">
+              <span class="zw-header-title details-title">部门</span>
+            </div>
+            <div class="zw-page-left-tree">
+              <el-container class="zw-container">
+                <el-tree
+                  ref="tree"
+                  :data="treeList"
+                  highlight-current
+                  node-key="id"
+                  :props="{ label: 'name' }"
+                  :expand-on-click-node="false"
+                  :default-expand-all="true"
+                  @node-click="handleNodeClick"
+                >
+                </el-tree>
+              </el-container>
+            </div>
+          </el-card>
+        </el-col>
+        <el-col :span="9" class="zw-page-main">
+          <el-card>
+            <div class="zw-card-header" slot="header">
+              <span class="zw-header-title details-title">用户明细 </span>
+            </div>
+
+            <div class="zw-page-main-list">
+              <el-container class="zw-container">
+
+                <el-table
+                  :data="staffList"
+                  tooltip-effect="dark"
+                  style="width: 100%"
+                  max-height="450"
+                  :header-cell-style="{
+                    background: '#F0F3F3',
+                    border: 'none'
+                  }"
+                >
+                  <el-table-column prop="code" label="姓名">
+                    <template slot-scope="{ row }">
+                      <div>{{ row.name }}</div>
+                    </template>
+                  </el-table-column>
+                  <el-table-column label="工号">
+                    <template slot-scope="{ row }">
+                      <div>{{ row.jobNumber }}</div>
+                    </template>
+                  </el-table-column>
+                  <el-table-column label="用户账号">
+                    <template slot-scope="{ row }">
+                      <div>{{ row.loginName }}</div>
+                    </template>
+                  </el-table-column>
+                  <el-table-column width="180" label="操作" align="right">
+                    <template slot="header" slot-scope="scope">
+                      <div style="display: flex">
+
+                        <el-input v-model="userName" placeholder="输入姓名查询" clearable
+                                  @change="changeUserName"></el-input>
+                        <div
+                          v-if="staffList.length !== 0 && isMore"
+                          class="zw-page-list-more"
+                        >
+                          <el-button type="text" @click="getMore()">更多<i class="el-icon-caret-bottom"></i></el-button>
+                        </div>
+                      </div>
+                    </template>
+                    <template slot-scope="{ row }">
+                      <el-button
+                        size="mini"
+                        type="primary"
+                        @click="choiceAsset(row)"
+                        :disabled="row.disabled"
+                        icon="el-icon-arrow-right"
+                        circle
+                      >
+                      </el-button>
+                    </template>
+                  </el-table-column>
+                </el-table>
+
+              </el-container>
+            </div>
+          </el-card>
+        </el-col>
+        <el-col :span="9" class="zw-page-right">
+          <el-card>
+            <div class="zw-card-header" slot="header">
+              <span class="zw-header-title">已选用户</span>
+            </div>
+            <div class="zw-page-right-list">
+              <el-container class="zw-container">
+                <el-table
+                  :data="selectStafflist"
+                  tooltip-effect="dark"
+                  style="width: 100%"
+                  max-height="500"
+                  :header-cell-style="{
+                    background: '#F0F3F3',
+                    border: 'none'
+                  }"
+                >
+                  <el-table-column prop="code" label="姓名">
+                    <template slot-scope="{ row }">
+                      <div>{{ row.name }}</div>
+                    </template>
+                  </el-table-column>
+                  <el-table-column label="工号">
+                    <template slot-scope="{ row }">
+                      <div>{{ row.jobNumber }}</div>
+                    </template>
+                  </el-table-column>
+                  <el-table-column label="用户账号">
+                    <template slot-scope="{ row }">
+                      <div>{{ row.loginName }}</div>
+                    </template>
+                  </el-table-column>
+                  <el-table-column width="80" label="操作">
+                    <template slot-scope="scope">
+                      <el-button
+                        @click="deleteSelectStaff(scope.row, scope.$index)"
+                        size="mini"
+                        type="danger"
+                      >删除
+                      </el-button>
+                    </template>
+                  </el-table-column>
+                </el-table>
+              </el-container>
+            </div>
+          </el-card>
+        </el-col>
+      </el-row>
+      <div slot="footer" class="dialog-footer">
+        <el-button size="small" @click="handleClose">关 闭</el-button>
+        <el-button size="small" @click="submit" type="primary">确 认</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+<script>
+import {getUserPage, listOrganizations} from '@/api/system/organization';
+import {putRoles} from "@/api/system/role";
+
+export default {
+  data() {
+    return {
+      form: {
+        groupId: null
+      },
+      treeList: [],
+      staffList: [],
+      userName: '',
+      row: {},
+      currentData: {},
+      selectStafflist: [], //已选员工
+      defaultProps: {
+        children: 'children',
+        label: 'name',
+        value: 'id'
+      },
+      pageNum: 1, //设备当前页数
+      size: 10,
+      isMore: false,
+      dialogVisible: false
+    };
+  },
+  created() {
+  },
+  methods: {
+    open(row) {
+      this.dialogVisible = true;
+      this.row = row
+      this.selectStafflist = row.manager;
+      this.getInfo();
+    },
+    //初始数据
+    async getInfo() {
+      let list = await listOrganizations();
+      this.treeList = this.$util.toTreeData({
+        data: list,
+        idField: 'id',
+        parentIdField: 'parentId'
+      });
+      //this.treeList = res.data;
+    },
+    //选择分类
+    handleNodeClick(data) {
+      this.currentData = data
+      this.staffList = [];
+
+      this.form.groupId = data.id;
+      let params = {
+        pageNum: 1,
+        size: this.size,
+        groupId: this.form.groupId,
+        name: this.userName
+      };
+      this.getStaffList(params);
+    },
+    changeUserName() {
+      this.staffList = [];
+
+      this.form.groupId = this.currentData.id;
+      let params = {
+        pageNum: 1,
+        size: this.size,
+        groupId: this.form.groupId,
+        name: this.userName
+      };
+      this.getStaffList(params);
+    },
+    //获取员工列表
+    async getStaffList(params) {
+      let res = await getUserPage(params);
+      let list = res.list;
+      if (list.length < res.count) {
+        this.isMore = true;
+      } else {
+        this.isMore = false;
+      }
+      list.forEach((el) => {
+        let _index = this.selectStafflist.findIndex((n) => n.id == el.id);
+        if (_index !== -1) {
+          el.disabled = true;
+        } else {
+          el.disabled = false;
+        }
+      });
+      this.staffList = [...this.staffList, ...list];
+      // this.pageNum = res.pageNum;
+    },
+    //查询更多员工
+    async getMore() {
+      this.pageNum = this.pageNum + 1;
+      let params = {
+        pageNum: this.pageNum,
+        size: this.size,
+        groupId: this.form.groupId
+      };
+      await this.getStaffList(params);
+    },
+    //选择员工
+    choiceAsset(info) {
+      let data = JSON.parse(JSON.stringify(info));
+      this.selectStafflist.push(data);
+      info.disabled = true;
+    },
+    //删除已选员工
+    deleteSelectStaff(info, index) {
+      this.staffList.forEach((el) => {
+        if (el.id == info.id) {
+          el.disabled = false;
+        }
+      });
+      this.selectStafflist.splice(index, 1);
+    },
+    //保存
+    async submit() {
+      if (this.selectStafflist.length === 0) {
+        this.$message.warning('请选择');
+      } else {
+        this.row.accountIds = this.selectStafflist.map(item => item.accountId)
+        await putRoles(this.row)
+        this.$emit('reload');
+        this.handleClose();
+      }
+    },
+    handleClose() {
+      this.staffList = [];
+      this.selectStafflist = [];
+      this.dialogVisible = false;
+    }
+  }
+};
+</script>
+
+<style lang="scss" scoped>
+.container {
+  padding: 10px 0;
+}
+
+.zw-container {
+  height: 500px;
+  overflow-y: auto;
+}
+
+.zw-header-title {
+  display: inline-block;
+  margin-right: 10px;
+  font-weight: 600;
+}
+
+.details-title {
+  line-height: 32px;
+  height: 32px;
+}
+
+.zw-page-list-p {
+  font-size: 14px;
+  margin-bottom: 18px;
+  display: flex;
+  justify-content: space-between;
+  // align-items: center;
+  .zw-page-list-right {
+    display: flex;
+  }
+}
+
+.zw-page {
+  background: #fff;
+  //padding: 20px 0;
+  height: 600px;
+
+  .zw-page-left {
+    padding: 0 10px;
+  }
+
+  .zw-page-main {
+    padding: 0 10px;
+
+    .zw-page-main-list {
+      span {
+        margin-right: 10px;
+      }
+
+      .zw-page-span-num {
+        font-size: 12px;
+        color: #157a2c;
+      }
+
+      .zw-page-p-operation {
+        text-align: right;
+        // width: 200px;
+      }
+
+      .zw-page-operation-num {
+        width: 100px;
+        margin: 0 10px;
+      }
+    }
+
+    .zw-page-list-more {
+      text-align: center;
+    }
+  }
+
+  .zw-page-right {
+    .zw-card-header {
+      display: flex;
+      justify-content: space-between;
+      align-items: center;
+      height: 32px;
+    }
+
+    span {
+      margin-right: 10px;
+    }
+
+    .zw-page-span-num {
+      font-size: 12px;
+      color: #157a2c;
+    }
+  }
+}
+
+.notes {
+  font-size: 12px;
+  color: #909090;
+}
+</style>

+ 151 - 0
src/views/system/threeMembers/index.vue

@@ -0,0 +1,151 @@
+<template>
+  <div class="ele-body">
+    <el-card shadow="never">
+      <!-- 数据表格 -->
+      <ele-pro-table
+        ref="table"
+        :columns="columns"
+        :datasource="datasource"
+        height="calc(100vh - 255px)"
+        :need-page="false"
+        cache-key="systemRoleTable15"
+      >
+
+        <template v-slot:description="{ row }">
+          <div v-html="row.description"></div>
+        </template>
+        <template v-slot:userNames="{ row }">
+          <div>
+            <el-tag
+              v-for="item in row.manager"
+              :key="item.id"
+              size="mini"
+              type="primary"
+              :disable-transitions="true"
+            >
+              {{ item.name }}
+            </el-tag>
+          </div>
+
+        </template>
+        <!-- 操作列 -->
+        <template v-slot:action="{ row }">
+
+          <el-link
+            type="primary"
+            :underline="false"
+            icon="el-icon-finished"
+            @click="openUser(row)"
+          >
+           管理用户
+          </el-link>
+          <el-link
+            type="primary"
+            :underline="false"
+            icon="el-icon-finished"
+            @click="openAuth(row)"
+          >
+            管理菜单
+          </el-link>
+
+        </template>
+        <template v-slot:tableHeaderTitle="{ column }">
+          <span style="display: inline-block;text-align: center; width: 100%;">{{column.label}}</span>
+        </template>
+      </ele-pro-table>
+    </el-card>
+    <!-- 权限分配弹窗 -->
+    <role-auth :data="current" :visible.sync="showAuth"/>
+    <staffSelection
+      ref="staffSelection"
+      @reload="reload"
+    ></staffSelection>
+  </div>
+</template>
+
+<script>
+import {threeMembersPageAPI} from "@/api/system/threeMembers/api";
+import RoleAuth from "@/views/system/role/components/role-auth.vue";
+import staffSelection from "./components/staffSelection.vue";
+import {deepClone} from "@/utils";
+
+export default {
+  name: 'threeMembers',
+  components: {staffSelection, RoleAuth},
+  data() {
+    return {
+      current:{},
+      showAuth:false,
+      // 表格列配置
+      columns: [
+        {
+          columnKey: 'index',
+          label: '序号',
+          type: 'index',
+          width: 55,
+          align: 'center',
+          showOverflowTooltip: true,
+          fixed: 'left'
+        },
+        {
+          prop: 'name',
+          label: '角色',
+          align: 'center',
+          showOverflowTooltip: true,
+          width: 120
+        },
+        {
+          prop: 'userNames',
+          label: '用户账户',
+          minWidth: 100,
+          slot: 'userNames',
+          align: 'center',
+          headerSlot: 'tableHeaderTitle',
+        },
+        {
+          prop: 'description',
+          label: '说明',
+          minWidth: 250,
+          slot: 'description',
+          headerSlot: 'tableHeaderTitle',
+        },
+        {
+          columnKey: 'action',
+          label: '操作',
+          width: 300,
+          align: 'center',
+          resizable: false,
+          slot: 'action',
+          showOverflowTooltip: true
+        }
+      ],
+    };
+  },
+  created() {
+  },
+  methods: {
+    /* 表格数据源 */
+    datasource({page, limit, where, order}) {
+      return threeMembersPageAPI({pageNum: page, size: limit, ...where});
+    },
+    /* 刷新表格 */
+    reload(where) {
+      this.$refs.table.reload({page: 1, where});
+    },
+    /* 显示分配权限 */
+    openAuth(row) {
+      if (row) {
+        this.isUpdate = true;
+        this.current = Object.assign({}, row);
+      } else {
+        this.isUpdate = false;
+      }
+      this.showAuth = true;
+    },
+    openUser(row){
+      let params = deepClone(row)
+      this.$refs.staffSelection.open(params);
+    },
+  }
+};
+</script>

+ 1 - 0
src/views/system/user/components/role-select.vue

@@ -7,6 +7,7 @@
     class="ele-block"
     :placeholder="placeholder"
     @input="updateValue"
+    filterable
   >
     <el-option
       v-for="item in data"

+ 42 - 31
src/views/system/user/components/user-search.vue

@@ -9,13 +9,15 @@
     <el-row :gutter="15">
       <el-col v-bind="styleResponsive ? { lg: 6, md: 12 } : { span: 6 }">
         <el-form-item label="用户账号:">
-          <el-input clearable v-model.trim="where.loginName" placeholder="请输入" />
+          <el-input clearable v-model.trim="where.loginName" placeholder="请输入"/>
         </el-form-item>
       </el-col>
 
       <el-col v-bind="styleResponsive ? { lg: 6, md: 12 } : { span: 6 }">
         <el-form-item label="角色:">
-          <el-input clearable v-model.trim="where.roleName" placeholder="请输入" />
+          <el-select v-model="where.roleIds" filterable multiple clearable style="width: 100%">
+            <el-option v-for="item in roleList" :value="item.id" :label="item.name" :key="item.id"></el-option>
+          </el-select>
         </el-form-item>
       </el-col>
 
@@ -55,36 +57,45 @@
 </template>
 
 <script>
-  export default {
-    data() {
-      // 默认表单数据
-      const defaultWhere = {
-        loginName: '',
-        roleName: ''
-        // nickname: '',
-        // sex: undefined
-      };
-      return {
-        // 表单数据
-        where: { ...defaultWhere }
-      };
+import {getRolesListAPI} from "@/api/system/role";
+
+export default {
+  data() {
+    // 默认表单数据
+    const defaultWhere = {
+      loginName: '',
+      roleIds: []
+      // nickname: '',
+      // sex: undefined
+    };
+    return {
+      // 表单数据
+      where: {...defaultWhere},
+      roleList: []
+    };
+  },
+  computed: {
+    // 是否开启响应式布局
+    styleResponsive() {
+      return this.$store.state.theme.styleResponsive;
+    }
+  },
+  created() {
+    this.getRolesList()
+  },
+  methods: {
+    async getRolesList() {
+      this.roleList = await getRolesListAPI()
     },
-    computed: {
-      // 是否开启响应式布局
-      styleResponsive() {
-        return this.$store.state.theme.styleResponsive;
-      }
+    /* 搜索 */
+    search() {
+      this.$emit('search', this.where);
     },
-    methods: {
-      /* 搜索 */
-      search() {
-        this.$emit('search', this.where);
-      },
-      /*  重置 */
-      reset() {
-        this.where = { ...this.defaultWhere };
-        this.search();
-      }
+    /*  重置 */
+    reset() {
+      this.where = {...this.defaultWhere};
+      this.search();
     }
-  };
+  }
+};
 </script>

+ 2 - 0
src/views/system/user/index.vue

@@ -9,6 +9,7 @@
         :columns="columns"
         :datasource="datasource"
         :selection.sync="selection"
+        height="calc(100vh - 335px)"
         row-key="id"
         cache-key="systemUserTable"
       >
@@ -20,6 +21,7 @@
             icon="el-icon-plus"
             class="ele-btn-icon"
             @click="openEdit()"
+            v-if="$hasPermission('eom:contact:staff')"
           >
             新建
           </el-button>