From 1d5aa0260234e327cae874e10a21e09f730f095b Mon Sep 17 00:00:00 2001
From: lixuliang <lixuliang_hd@126.com>
Date: 星期二, 10 九月 2024 11:10:33 +0800
Subject: [PATCH] 更新

---
 se-ui/src/utils/request.js                        |    4 
 se-ui/src/views/system/menu/index.vue             |   98 ++--
 se-ui/src/layout/components/Navbar.vue            |    4 
 se-ui/src/permission.js                           |   12 
 se-ui/src/router/index.js                         |   13 
 se-ui/src/views/system/permissions/authUser.vue   |  199 ++++++++++
 se-ui/src/views/register.vue                      |   18 
 se-ui/src/views/system/permissions/index.vue      |  598 +++++++++++++++++++++++++++++++
 se-ui/src/views/login.vue                         |    2 
 se-ui/.env.development                            |    4 
 se-ui/src/views/system/permissions/selectUser.vue |  136 +++++++
 se-ui/vue.config.js                               |    4 
 12 files changed, 1,015 insertions(+), 77 deletions(-)

diff --git a/se-ui/.env.development b/se-ui/.env.development
index 2fbdd7f..caf7958 100644
--- a/se-ui/.env.development
+++ b/se-ui/.env.development
@@ -3,7 +3,7 @@
 
 # 寮�鍙戠幆澧冮厤缃�
 ENV = 'development'
-
+port = 8080
 # 绠$悊绯荤粺/寮�鍙戠幆澧�
 VUE_APP_BASE_API = '/prod-api'
 
@@ -11,4 +11,4 @@
 VUE_CLI_BABEL_TRANSPILE_MODULES = true
 
 #椤圭洰瀛愯矾寰�
-VUE_APP_ITEM_PATH = '/sys'
\ No newline at end of file
+VUE_APP_ITEM_PATH = ''
\ No newline at end of file
diff --git a/se-ui/src/layout/components/Navbar.vue b/se-ui/src/layout/components/Navbar.vue
index 7673e93..c90562c 100644
--- a/se-ui/src/layout/components/Navbar.vue
+++ b/se-ui/src/layout/components/Navbar.vue
@@ -103,9 +103,9 @@
       })
         .then(() => {
           this.$store.dispatch("LogOut").then(() => {
-            if ((process.env.ENV = "development")) {
+            if ((process.env.ENV == "development")) {
               window.location.href = "http://localhost:8080/login";
-            } else if ((process.env.ENV = "production")) {
+            } else if ((process.env.ENV == "production")) {
               window.location.href = window.location.origin + "/sso/login";
             }
           });
diff --git a/se-ui/src/permission.js b/se-ui/src/permission.js
index b1eb0a7..78523d8 100644
--- a/se-ui/src/permission.js
+++ b/se-ui/src/permission.js
@@ -16,9 +16,9 @@
     to.meta.title && store.dispatch('settings/setTitle', to.meta.title)
     /* has token*/
     if (to.path === '/login') {
-      if (process.env.ENV = 'development') {
+      if (process.env.ENV == 'development') {
         window.location.href = 'http://localhost:8080/login'
-      } else if (process.env.ENV = 'production') {
+      } else if (process.env.ENV == 'production') {
         window.location.href = window.location.origin + '/sso/login'
       }
       // next({ path: '/' })
@@ -39,9 +39,9 @@
         }).catch(err => {
           store.dispatch('LogOut').then(() => {
             Message.error(err)
-            if (process.env.ENV = 'development') {
+            if (process.env.ENV == 'development') {
               window.location.href = 'http://localhost:8080/login'
-            } else if (process.env.ENV = 'production') {
+            } else if (process.env.ENV == 'production') {
               window.location.href = window.location.origin + '/sso/login'
             }
             // next({ path: '/' })
@@ -57,9 +57,9 @@
       // 鍦ㄥ厤鐧诲綍鐧藉悕鍗曪紝鐩存帴杩涘叆
       next()
     } else {
-      if (process.env.ENV = 'development') {
+      if (process.env.ENV == 'development') {
         window.location.href = 'http://localhost:8080/login'
-      } else if (process.env.ENV = 'production') {
+      } else if (process.env.ENV == 'production') {
         window.location.href = window.location.origin + '/sso/login'
       }
       NProgress.done()
diff --git a/se-ui/src/router/index.js b/se-ui/src/router/index.js
index 6b1ce51..e504bad 100644
--- a/se-ui/src/router/index.js
+++ b/se-ui/src/router/index.js
@@ -41,11 +41,11 @@
       }
     ]
   },
-  // {
-  //   path: '/login',
-  //   component: () => import('@/views/login'),
-  //   hidden: true
-  // },
+  {
+    path: '/login',
+    component: () => import('@/views/login'),
+    hidden: true
+  },
   {
     path: '/register',
     component: () => import('@/views/register'),
@@ -64,7 +64,8 @@
   {
     path: '',
     component: Layout,
-    redirect: 'system/user',
+    redirect: '/login',
+    // redirect: 'system/user',
     // children: [
     //   {
     //     path: 'index',
diff --git a/se-ui/src/utils/request.js b/se-ui/src/utils/request.js
index f92e8f6..2ebc750 100644
--- a/se-ui/src/utils/request.js
+++ b/se-ui/src/utils/request.js
@@ -88,9 +88,9 @@
       MessageBox.confirm('鐧诲綍鐘舵�佸凡杩囨湡锛屾偍鍙互缁х画鐣欏湪璇ラ〉闈紝鎴栬�呴噸鏂扮櫥褰�', '绯荤粺鎻愮ず', { confirmButtonText: '閲嶆柊鐧诲綍', cancelButtonText: '鍙栨秷', type: 'warning' }).then(() => {
         isRelogin.show = false;
         store.dispatch('LogOut').then(() => {
-          if ((process.env.ENV = "development")) {
+          if ((process.env.ENV == "development")) {
             window.location.href = "http://localhost:8080/login";
-          } else if ((process.env.ENV = "production")) {
+          } else if ((process.env.ENV == "production")) {
             window.location.href = window.location.origin + "/sso/login";
           }
         })
diff --git a/se-ui/src/views/login.vue b/se-ui/src/views/login.vue
index 23b0636..1053070 100644
--- a/se-ui/src/views/login.vue
+++ b/se-ui/src/views/login.vue
@@ -89,7 +89,7 @@
     }
   },
   created() {
-    this.getCode();
+    // this.getCode();
     this.getCookie();
   },
   methods: {
diff --git a/se-ui/src/views/register.vue b/se-ui/src/views/register.vue
index 43194ed..7e1276a 100644
--- a/se-ui/src/views/register.vue
+++ b/se-ui/src/views/register.vue
@@ -109,17 +109,17 @@
     };
   },
   created() {
-    this.getCode();
+    // this.getCode();
   },
   methods: {
     getCode() {
-      getCodeImg().then(res => {
-        this.captchaEnabled = res.captchaEnabled === undefined ? true : res.captchaEnabled;
-        if (this.captchaEnabled) {
-          this.codeUrl = "data:image/gif;base64," + res.img;
-          this.registerForm.uuid = res.uuid;
-        }
-      });
+      // getCodeImg().then(res => {
+      //   this.captchaEnabled = res.captchaEnabled === undefined ? true : res.captchaEnabled;
+      //   if (this.captchaEnabled) {
+      //     this.codeUrl = "data:image/gif;base64," + res.img;
+      //     this.registerForm.uuid = res.uuid;
+      //   }
+      // });
     },
     handleRegister() {
       this.$refs.registerForm.validate(valid => {
@@ -136,7 +136,7 @@
           }).catch(() => {
             this.loading = false;
             if (this.captchaEnabled) {
-              this.getCode();
+              // this.getCode();
             }
           })
         }
diff --git a/se-ui/src/views/system/menu/index.vue b/se-ui/src/views/system/menu/index.vue
index c703fa0..3a3dd78 100644
--- a/se-ui/src/views/system/menu/index.vue
+++ b/se-ui/src/views/system/menu/index.vue
@@ -37,13 +37,7 @@
         >鏂板</el-button>
       </el-col>
       <el-col :span="1.5">
-        <el-button
-          type="info"
-          plain
-          icon="el-icon-sort"
-          size="mini"
-          @click="toggleExpandAll"
-        >灞曞紑/鎶樺彔</el-button>
+        <el-button type="info" plain icon="el-icon-sort" size="mini" @click="toggleExpandAll">灞曞紑/鎶樺彔</el-button>
       </el-col>
       <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
     </el-row>
@@ -67,7 +61,7 @@
       <el-table-column prop="component" label="缁勪欢璺緞" :show-overflow-tooltip="true"></el-table-column>
       <el-table-column prop="status" label="鐘舵��" width="80">
         <template slot-scope="scope">
-          <dict-tag :options="dict.type.sys_normal_disable" :value="scope.row.status"/>
+          <dict-tag :options="dict.type.sys_normal_disable" :value="scope.row.status" />
         </template>
       </el-table-column>
       <el-table-column label="鍒涘缓鏃堕棿" align="center" prop="createTime">
@@ -117,13 +111,18 @@
               />
             </el-form-item>
           </el-col>
-          <el-col :span="24">
+          <el-col :span="12">
             <el-form-item label="鑿滃崟绫诲瀷" prop="menuType">
               <el-radio-group v-model="form.menuType">
                 <el-radio label="M">鐩綍</el-radio>
                 <el-radio label="C">鑿滃崟</el-radio>
                 <el-radio label="F">鎸夐挳</el-radio>
               </el-radio-group>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="鑿滃崟鏍囪瘑" prop="mark">
+              <el-input v-model="form.mark" placeholder="璇疯緭鍏ヨ彍鍗曟爣璇�" />
             </el-form-item>
           </el-col>
           <el-col :span="24" v-if="form.menuType != 'F'">
@@ -161,9 +160,8 @@
             <el-form-item prop="isFrame">
               <span slot="label">
                 <el-tooltip content="閫夋嫨鏄閾惧垯璺敱鍦板潃闇�瑕佷互`http(s)://`寮�澶�" placement="top">
-                <i class="el-icon-question"></i>
-                </el-tooltip>
-                鏄惁澶栭摼
+                  <i class="el-icon-question"></i>
+                </el-tooltip>鏄惁澶栭摼
               </span>
               <el-radio-group v-model="form.isFrame">
                 <el-radio label="0">鏄�</el-radio>
@@ -175,9 +173,8 @@
             <el-form-item prop="path">
               <span slot="label">
                 <el-tooltip content="璁块棶鐨勮矾鐢卞湴鍧�锛屽锛歚user`锛屽澶栫綉鍦板潃闇�鍐呴摼璁块棶鍒欎互`http(s)://`寮�澶�" placement="top">
-                <i class="el-icon-question"></i>
-                </el-tooltip>
-                璺敱鍦板潃
+                  <i class="el-icon-question"></i>
+                </el-tooltip>璺敱鍦板潃
               </span>
               <el-input v-model="form.path" placeholder="璇疯緭鍏ヨ矾鐢卞湴鍧�" />
             </el-form-item>
@@ -186,9 +183,8 @@
             <el-form-item prop="component">
               <span slot="label">
                 <el-tooltip content="璁块棶鐨勭粍浠惰矾寰勶紝濡傦細`system/user/index`锛岄粯璁ゅ湪`views`鐩綍涓�" placement="top">
-                <i class="el-icon-question"></i>
-                </el-tooltip>
-                缁勪欢璺緞
+                  <i class="el-icon-question"></i>
+                </el-tooltip>缁勪欢璺緞
               </span>
               <el-input v-model="form.component" placeholder="璇疯緭鍏ョ粍浠惰矾寰�" />
             </el-form-item>
@@ -197,10 +193,12 @@
             <el-form-item prop="perms">
               <el-input v-model="form.perms" placeholder="璇疯緭鍏ユ潈闄愭爣璇�" maxlength="100" />
               <span slot="label">
-                <el-tooltip content="鎺у埗鍣ㄤ腑瀹氫箟鐨勬潈闄愬瓧绗︼紝濡傦細@PreAuthorize(`@ss.hasPermi('system:user:list')`)" placement="top">
-                <i class="el-icon-question"></i>
-                </el-tooltip>
-                鏉冮檺瀛楃
+                <el-tooltip
+                  content="鎺у埗鍣ㄤ腑瀹氫箟鐨勬潈闄愬瓧绗︼紝濡傦細@PreAuthorize(`@ss.hasPermi('system:user:list')`)"
+                  placement="top"
+                >
+                  <i class="el-icon-question"></i>
+                </el-tooltip>鏉冮檺瀛楃
               </span>
             </el-form-item>
           </el-col>
@@ -208,10 +206,9 @@
             <el-form-item prop="query">
               <el-input v-model="form.query" placeholder="璇疯緭鍏ヨ矾鐢卞弬鏁�" maxlength="255" />
               <span slot="label">
-                <el-tooltip content='璁块棶璺敱鐨勯粯璁や紶閫掑弬鏁帮紝濡傦細`{"id": 1, "name": "ry"}`' placement="top">
-                <i class="el-icon-question"></i>
-                </el-tooltip>
-                璺敱鍙傛暟
+                <el-tooltip content="璁块棶璺敱鐨勯粯璁や紶閫掑弬鏁帮紝濡傦細`{id: 1, name: ry}`" placement="top">
+                  <i class="el-icon-question"></i>
+                </el-tooltip>璺敱鍙傛暟
               </span>
             </el-form-item>
           </el-col>
@@ -219,9 +216,8 @@
             <el-form-item prop="isCache">
               <span slot="label">
                 <el-tooltip content="閫夋嫨鏄垯浼氳`keep-alive`缂撳瓨锛岄渶瑕佸尮閰嶇粍浠剁殑`name`鍜屽湴鍧�淇濇寔涓�鑷�" placement="top">
-                <i class="el-icon-question"></i>
-                </el-tooltip>
-                鏄惁缂撳瓨
+                  <i class="el-icon-question"></i>
+                </el-tooltip>鏄惁缂撳瓨
               </span>
               <el-radio-group v-model="form.isCache">
                 <el-radio label="0">缂撳瓨</el-radio>
@@ -233,9 +229,8 @@
             <el-form-item prop="visible">
               <span slot="label">
                 <el-tooltip content="閫夋嫨闅愯棌鍒欒矾鐢卞皢涓嶄細鍑虹幇鍦ㄤ晶杈规爮锛屼絾浠嶇劧鍙互璁块棶" placement="top">
-                <i class="el-icon-question"></i>
-                </el-tooltip>
-                鏄剧ず鐘舵��
+                  <i class="el-icon-question"></i>
+                </el-tooltip>鏄剧ず鐘舵��
               </span>
               <el-radio-group v-model="form.visible">
                 <el-radio
@@ -250,9 +245,8 @@
             <el-form-item prop="status">
               <span slot="label">
                 <el-tooltip content="閫夋嫨鍋滅敤鍒欒矾鐢卞皢涓嶄細鍑虹幇鍦ㄤ晶杈规爮锛屼篃涓嶈兘琚闂�" placement="top">
-                <i class="el-icon-question"></i>
-                </el-tooltip>
-                鑿滃崟鐘舵��
+                  <i class="el-icon-question"></i>
+                </el-tooltip>鑿滃崟鐘舵��
               </span>
               <el-radio-group v-model="form.status">
                 <el-radio
@@ -274,14 +268,20 @@
 </template>
 
 <script>
-import { listMenu, getMenu, delMenu, addMenu, updateMenu } from "@/api/system/menu";
+import {
+  listMenu,
+  getMenu,
+  delMenu,
+  addMenu,
+  updateMenu
+} from "@/api/system/menu";
 import Treeselect from "@riophae/vue-treeselect";
 import "@riophae/vue-treeselect/dist/vue-treeselect.css";
 import IconSelect from "@/components/IconSelect";
 
 export default {
   name: "Menu",
-  dicts: ['sys_show_hide', 'sys_normal_disable'],
+  dicts: ["sys_show_hide", "sys_normal_disable"],
   components: { Treeselect, IconSelect },
   data() {
     return {
@@ -316,9 +316,7 @@
         orderNum: [
           { required: true, message: "鑿滃崟椤哄簭涓嶈兘涓虹┖", trigger: "blur" }
         ],
-        path: [
-          { required: true, message: "璺敱鍦板潃涓嶈兘涓虹┖", trigger: "blur" }
-        ]
+        path: [{ required: true, message: "璺敱鍦板潃涓嶈兘涓虹┖", trigger: "blur" }]
       }
     };
   },
@@ -353,7 +351,7 @@
     getTreeselect() {
       listMenu().then(response => {
         this.menuOptions = [];
-        const menu = { menuId: 0, menuName: '涓荤被鐩�', children: [] };
+        const menu = { menuId: 0, menuName: "涓荤被鐩�", children: [] };
         menu.children = this.handleTree(response.data, "menuId");
         this.menuOptions.push(menu);
       });
@@ -371,6 +369,7 @@
         menuName: undefined,
         icon: undefined,
         menuType: "M",
+        mark: "",
         orderNum: undefined,
         isFrame: "1",
         isCache: "0",
@@ -394,6 +393,7 @@
       this.getTreeselect();
       if (row != null && row.menuId) {
         this.form.parentId = row.menuId;
+        this.form.mark = row.mark;
       } else {
         this.form.parentId = 0;
       }
@@ -440,12 +440,16 @@
     },
     /** 鍒犻櫎鎸夐挳鎿嶄綔 */
     handleDelete(row) {
-      this.$modal.confirm('鏄惁纭鍒犻櫎鍚嶇О涓�"' + row.menuName + '"鐨勬暟鎹」锛�').then(function() {
-        return delMenu(row.menuId);
-      }).then(() => {
-        this.getList();
-        this.$modal.msgSuccess("鍒犻櫎鎴愬姛");
-      }).catch(() => {});
+      this.$modal
+        .confirm('鏄惁纭鍒犻櫎鍚嶇О涓�"' + row.menuName + '"鐨勬暟鎹」锛�')
+        .then(function() {
+          return delMenu(row.menuId);
+        })
+        .then(() => {
+          this.getList();
+          this.$modal.msgSuccess("鍒犻櫎鎴愬姛");
+        })
+        .catch(() => {});
     }
   }
 };
diff --git a/se-ui/src/views/system/permissions/authUser.vue b/se-ui/src/views/system/permissions/authUser.vue
new file mode 100644
index 0000000..147aa33
--- /dev/null
+++ b/se-ui/src/views/system/permissions/authUser.vue
@@ -0,0 +1,199 @@
+<template>
+  <div class="app-container">
+     <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch">
+      <el-form-item label="鐢ㄦ埛鍚嶇О" prop="userName">
+        <el-input
+          v-model="queryParams.userName"
+          placeholder="璇疯緭鍏ョ敤鎴峰悕绉�"
+          clearable
+          style="width: 240px"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="鎵嬫満鍙风爜" prop="phonenumber">
+        <el-input
+          v-model="queryParams.phonenumber"
+          placeholder="璇疯緭鍏ユ墜鏈哄彿鐮�"
+          clearable
+          style="width: 240px"
+          @keyup.enter.native="handleQuery"
+        />
+      </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-form-item>
+    </el-form>
+
+    <el-row :gutter="10" class="mb8">
+      <el-col :span="1.5">
+        <el-button
+          type="primary"
+          plain
+          icon="el-icon-plus"
+          size="mini"
+          @click="openSelectUser"
+          v-hasPermi="['system:role:add']"
+        >娣诲姞鐢ㄦ埛</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="danger"
+          plain
+          icon="el-icon-circle-close"
+          size="mini"
+          :disabled="multiple"
+          @click="cancelAuthUserAll"
+          v-hasPermi="['system:role:remove']"
+        >鎵归噺鍙栨秷鎺堟潈</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="warning"
+          plain
+          icon="el-icon-close"
+          size="mini"
+          @click="handleClose"
+        >鍏抽棴</el-button>
+      </el-col>
+      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
+
+    <el-table v-loading="loading" :data="userList" @selection-change="handleSelectionChange">
+      <el-table-column type="selection" width="55" align="center" />
+      <el-table-column label="鐢ㄦ埛鍚嶇О" prop="userName" :show-overflow-tooltip="true" />
+      <el-table-column label="鐢ㄦ埛鏄电О" prop="nickName" :show-overflow-tooltip="true" />
+      <el-table-column label="閭" prop="email" :show-overflow-tooltip="true" />
+      <el-table-column label="鎵嬫満" prop="phonenumber" :show-overflow-tooltip="true" />
+      <el-table-column label="鐘舵��" align="center" prop="status">
+        <template slot-scope="scope">
+          <dict-tag :options="dict.type.sys_normal_disable" :value="scope.row.status"/>
+        </template>
+      </el-table-column>
+      <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">
+        <template slot-scope="scope">
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-circle-close"
+            @click="cancelAuthUser(scope.row)"
+            v-hasPermi="['system:role:remove']"
+          >鍙栨秷鎺堟潈</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <pagination
+      v-show="total>0"
+      :total="total"
+      :page.sync="queryParams.pageNum"
+      :limit.sync="queryParams.pageSize"
+      @pagination="getList"
+    />
+    <select-user ref="select" :roleId="queryParams.roleId" @ok="handleQuery" />
+  </div>
+</template>
+
+<script>
+import { allocatedUserList, authUserCancel, authUserCancelAll } from "@/api/system/role";
+import selectUser from "./selectUser";
+
+export default {
+  name: "AuthUser",
+  dicts: ['sys_normal_disable'],
+  components: { selectUser },
+  data() {
+    return {
+      // 閬僵灞�
+      loading: true,
+      // 閫変腑鐢ㄦ埛缁�
+      userIds: [],
+      // 闈炲涓鐢�
+      multiple: true,
+      // 鏄剧ず鎼滅储鏉′欢
+      showSearch: true,
+      // 鎬绘潯鏁�
+      total: 0,
+      // 鐢ㄦ埛琛ㄦ牸鏁版嵁
+      userList: [],
+      // 鏌ヨ鍙傛暟
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        roleId: undefined,
+        userName: undefined,
+        phonenumber: undefined
+      }
+    };
+  },
+  created() {
+    const roleId = this.$route.params && this.$route.params.roleId;
+    if (roleId) {
+      this.queryParams.roleId = roleId;
+      this.getList();
+    }
+  },
+  methods: {
+    /** 鏌ヨ鎺堟潈鐢ㄦ埛鍒楄〃 */
+    getList() {
+      this.loading = true;
+      allocatedUserList(this.queryParams).then(response => {
+          this.userList = response.rows;
+          this.total = response.total;
+          this.loading = false;
+        }
+      );
+    },
+    // 杩斿洖鎸夐挳
+    handleClose() {
+      const obj = { path: "/system/role" };
+      this.$tab.closeOpenPage(obj);
+    },
+    /** 鎼滅储鎸夐挳鎿嶄綔 */
+    handleQuery() {
+      this.queryParams.pageNum = 1;
+      this.getList();
+    },
+    /** 閲嶇疆鎸夐挳鎿嶄綔 */
+    resetQuery() {
+      this.resetForm("queryForm");
+      this.handleQuery();
+    },
+    // 澶氶�夋閫変腑鏁版嵁
+    handleSelectionChange(selection) {
+      this.userIds = selection.map(item => item.userId)
+      this.multiple = !selection.length
+    },
+    /** 鎵撳紑鎺堟潈鐢ㄦ埛琛ㄥ脊绐� */
+    openSelectUser() {
+      this.$refs.select.show();
+    },
+    /** 鍙栨秷鎺堟潈鎸夐挳鎿嶄綔 */
+    cancelAuthUser(row) {
+      const roleId = this.queryParams.roleId;
+      this.$modal.confirm('纭瑕佸彇娑堣鐢ㄦ埛"' + row.userName + '"瑙掕壊鍚楋紵').then(function() {
+        return authUserCancel({ userId: row.userId, roleId: roleId });
+      }).then(() => {
+        this.getList();
+        this.$modal.msgSuccess("鍙栨秷鎺堟潈鎴愬姛");
+      }).catch(() => {});
+    },
+    /** 鎵归噺鍙栨秷鎺堟潈鎸夐挳鎿嶄綔 */
+    cancelAuthUserAll(row) {
+      const roleId = this.queryParams.roleId;
+      const userIds = this.userIds.join(",");
+      this.$modal.confirm('鏄惁鍙栨秷閫変腑鐢ㄦ埛鎺堟潈鏁版嵁椤癸紵').then(function() {
+        return authUserCancelAll({ roleId: roleId, userIds: userIds });
+      }).then(() => {
+        this.getList();
+        this.$modal.msgSuccess("鍙栨秷鎺堟潈鎴愬姛");
+      }).catch(() => {});
+    }
+  }
+};
+</script>
\ No newline at end of file
diff --git a/se-ui/src/views/system/permissions/index.vue b/se-ui/src/views/system/permissions/index.vue
new file mode 100644
index 0000000..fd1d1e6
--- /dev/null
+++ b/se-ui/src/views/system/permissions/index.vue
@@ -0,0 +1,598 @@
+<template>
+  <div class="app-container">
+    <el-row :gutter="20">
+      <el-col :span="5" :xs="24">
+        <el-card class="box-card">
+          <div slot="header" class="clearfix">
+            <span>瑙掕壊鍒楄〃</span>
+          </div>
+        </el-card>
+        <el-table
+          v-loading="loading"
+          width="100%"
+          border
+          :data="roleList"
+          @row-click="handleUpdate"
+          highlight-current-row
+          :show-header="true"
+          :header-cell-style="{'text-align':'center'}"
+        >
+          <el-table-column
+            label="瑙掕壊鍚嶇О"
+            prop="roleName"
+            align="center"
+            :show-overflow-tooltip="true"
+          />
+        </el-table>
+      </el-col>
+      <el-col :span="8" :xs="24">
+        <el-card class="box-card2">
+          <div slot="header" class="clearfix">
+            <span>鏉冮檺璁剧疆</span>
+          </div>
+          <el-form ref="form" :model="form" :rules="rules" label-width="100px">
+            <el-form-item label="瑙掕壊鍚嶇О" prop="roleName">
+              <el-input v-model="form.roleName" placeholder="璇疯緭鍏ヨ鑹插悕绉�" disabled />
+            </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-form-item>
+            <el-form-item size="large">
+              <el-tree
+                style="max-height:500px;overflow:auto;"
+                default-expand-all
+                class="tree-border"
+                :data="menuOptions"
+                show-checkbox
+                ref="menu"
+                node-key="id"
+                :check-strictly="!form.menuCheckStrictly"
+                empty-text="鍔犺浇涓紝璇风◢鍊�"
+                :props="defaultProps"
+              ></el-tree>
+            </el-form-item>
+            <el-form-item size="large">
+              <el-button type="primary" @click="submitForm">纭� 瀹�</el-button>
+              <el-button @click="cancel">鍙� 娑�</el-button>
+            </el-form-item>
+          </el-form>
+        </el-card>
+      </el-col>
+    </el-row>
+    <!-- <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
+      <el-form ref="form" :model="form" :rules="rules" label-width="100px">
+        <el-form-item label="瑙掕壊鍚嶇О" prop="roleName">
+          <el-input v-model="form.roleName" placeholder="璇疯緭鍏ヨ鑹插悕绉�" />
+        </el-form-item>
+        <el-form-item prop="roleKey">
+          <span slot="label">
+            <el-tooltip content="鎺у埗鍣ㄤ腑瀹氫箟鐨勬潈闄愬瓧绗︼紝濡傦細@PreAuthorize(`@ss.hasRole('admin')`)" placement="top">
+              <i class="el-icon-question"></i>
+            </el-tooltip>
+            鏉冮檺瀛楃
+          </span>
+          <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-form-item>
+        <el-form-item label="鐘舵��">
+          <el-radio-group v-model="form.status">
+            <el-radio
+              v-for="dict in dict.type.sys_normal_disable"
+              :key="dict.value"
+              :label="dict.value"
+            >{{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-tree
+            class="tree-border"
+            :data="menuOptions"
+            show-checkbox
+            ref="menu"
+            node-key="id"
+            :check-strictly="!form.menuCheckStrictly"
+            empty-text="鍔犺浇涓紝璇风◢鍊�"
+            :props="defaultProps"
+          ></el-tree>
+        </el-form-item>
+        <el-form-item label="澶囨敞">
+          <el-input v-model="form.remark" type="textarea" placeholder="璇疯緭鍏ュ唴瀹�"></el-input>
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="submitForm">纭� 瀹�</el-button>
+        <el-button @click="cancel">鍙� 娑�</el-button>
+      </div>
+    </el-dialog>-->
+
+    <!-- 鍒嗛厤瑙掕壊鏁版嵁鏉冮檺瀵硅瘽妗� -->
+    <!-- <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" />
+        </el-form-item>
+        <el-form-item label="鏉冮檺瀛楃">
+          <el-input v-model="form.roleKey" :disabled="true" />
+        </el-form-item>
+        <el-form-item label="鏉冮檺鑼冨洿">
+          <el-select v-model="form.dataScope" @change="dataScopeSelectChange">
+            <el-option
+              v-for="item in dataScopeOptions"
+              :key="item.value"
+              :label="item.label"
+              :value="item.value"
+            ></el-option>
+          </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-tree
+            class="tree-border"
+            :data="deptOptions"
+            show-checkbox
+            default-expand-all
+            ref="dept"
+            node-key="id"
+            :check-strictly="!form.deptCheckStrictly"
+            empty-text="鍔犺浇涓紝璇风◢鍊�"
+            :props="defaultProps"
+          ></el-tree>
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="submitDataScope">纭� 瀹�</el-button>
+        <el-button @click="cancelDataScope">鍙� 娑�</el-button>
+      </div>
+    </el-dialog>-->
+  </div>
+</template>
+<style scoped>
+.demo-drawer__footer {
+  width: 100%;
+  position: absolute;
+  bottom: 0;
+  left: 0;
+  border-top: 1px solid #e8e8e8;
+  padding: 10px 16px;
+  text-align: right;
+  background-color: bfa;
+}
+</style>
+<script>
+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"],
+  data() {
+    return {
+      // 閬僵灞�
+      loading: true,
+      // 閫変腑鏁扮粍
+      ids: [],
+      // 闈炲崟涓鐢�
+      single: true,
+      // 闈炲涓鐢�
+      multiple: true,
+      // 鏄剧ず鎼滅储鏉′欢
+      showSearch: true,
+      // 鎬绘潯鏁�
+      total: 0,
+      // 瑙掕壊琛ㄦ牸鏁版嵁
+      roleList: [],
+      // 寮瑰嚭灞傛爣棰�
+      title: "",
+      // 鏄惁鏄剧ず寮瑰嚭灞�
+      open: false,
+      // 鏄惁鏄剧ず寮瑰嚭灞傦紙鏁版嵁鏉冮檺锛�
+      openDataScope: false,
+      menuExpand: false,
+      menuNodeAll: false,
+      deptExpand: true,
+      deptNodeAll: false,
+      // 鏃ユ湡鑼冨洿
+      dateRange: [],
+      // 鏁版嵁鑼冨洿閫夐」
+      dataScopeOptions: [
+        {
+          value: "1",
+          label: "鍏ㄩ儴鏁版嵁鏉冮檺"
+        },
+        {
+          value: "2",
+          label: "鑷畾鏁版嵁鏉冮檺"
+        },
+        {
+          value: "3",
+          label: "鏈儴闂ㄦ暟鎹潈闄�"
+        },
+        {
+          value: "4",
+          label: "鏈儴闂ㄥ強浠ヤ笅鏁版嵁鏉冮檺"
+        },
+        {
+          value: "5",
+          label: "浠呮湰浜烘暟鎹潈闄�"
+        }
+      ],
+      // 鑿滃崟鍒楄〃
+      menuOptions: [],
+      // 閮ㄩ棬鍒楄〃
+      deptOptions: [],
+      // 鏌ヨ鍙傛暟
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        roleName: undefined,
+        roleKey: undefined,
+        status: undefined
+      },
+
+      // 琛ㄥ崟鍙傛暟
+      form: {},
+      defaultProps: {
+        children: "children",
+        label: "label"
+      },
+      // 琛ㄥ崟鏍¢獙
+      rules: {
+        roleName: [
+          { required: true, message: "瑙掕壊鍚嶇О涓嶈兘涓虹┖", trigger: "blur" }
+        ],
+        roleKey: [
+          { required: true, message: "鏉冮檺瀛楃涓嶈兘涓虹┖", trigger: "blur" }
+        ],
+        roleSort: [
+          { required: true, message: "瑙掕壊椤哄簭涓嶈兘涓虹┖", trigger: "blur" }
+        ]
+      },
+      refreshTable: true,
+      timer: null
+    };
+  },
+  created() {
+    this.getList();
+  },
+  methods: {
+    /** 鏌ヨ瑙掕壊鍒楄〃 */
+    getList() {
+      this.loading = true;
+      listRole(this.addDateRange(this.queryParams, this.dateRange)).then(
+        response => {
+          this.roleList = response.rows;
+          this.total = response.total;
+          this.loading = false;
+        }
+      );
+    },
+    /** 鏌ヨ鑿滃崟鏍戠粨鏋� */
+    getMenuTreeselect() {
+      menuTreeselect().then(response => {
+        this.menuOptions = response.data;
+      });
+    },
+    // 鎵�鏈夎彍鍗曡妭鐐规暟鎹�
+    getMenuAllCheckedKeys() {
+      // 鐩墠琚�変腑鐨勮彍鍗曡妭鐐�
+      let checkedKeys = this.$refs.menu.getCheckedKeys();
+      // 鍗婇�変腑鐨勮彍鍗曡妭鐐�
+      let halfCheckedKeys = this.$refs.menu.getHalfCheckedKeys();
+      checkedKeys.unshift.apply(checkedKeys, halfCheckedKeys);
+      return checkedKeys;
+    },
+    // 鎵�鏈夐儴闂ㄨ妭鐐规暟鎹�
+    getDeptAllCheckedKeys() {
+      // 鐩墠琚�変腑鐨勯儴闂ㄨ妭鐐�
+      let checkedKeys = this.$refs.dept.getCheckedKeys();
+      // 鍗婇�変腑鐨勯儴闂ㄨ妭鐐�
+      let halfCheckedKeys = this.$refs.dept.getHalfCheckedKeys();
+      checkedKeys.unshift.apply(checkedKeys, halfCheckedKeys);
+      return checkedKeys;
+    },
+    /** 鏍规嵁瑙掕壊ID鏌ヨ鑿滃崟鏍戠粨鏋� */
+    getRoleMenuTreeselect(roleId) {
+      return roleMenuTreeselect(roleId).then(response => {
+        this.menuOptions = response.menus;
+        return response;
+      });
+    },
+    /** 鏍规嵁瑙掕壊ID鏌ヨ閮ㄩ棬鏍戠粨鏋� */
+    getDeptTree(roleId) {
+      return deptTreeSelect(roleId).then(response => {
+        this.deptOptions = response.depts;
+        return response;
+      });
+    },
+    // 瑙掕壊鐘舵�佷慨鏀�
+    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";
+        });
+    },
+    // 鍙栨秷鎸夐挳
+    cancel() {
+      this.open = false;
+
+      this.reset();
+    },
+    // 鍙栨秷鎸夐挳锛堟暟鎹潈闄愶級
+    cancelDataScope() {
+      this.openDataScope = false;
+      this.reset();
+    },
+    // 琛ㄥ崟閲嶇疆
+    reset() {
+      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.resetForm("form");
+    },
+    /** 鎼滅储鎸夐挳鎿嶄綔 */
+    handleQuery() {
+      this.queryParams.pageNum = 1;
+      this.getList();
+    },
+    /** 閲嶇疆鎸夐挳鎿嶄綔 */
+    resetQuery() {
+      this.dateRange = [];
+      this.resetForm("queryForm");
+      this.handleQuery();
+    },
+    // 澶氶�夋閫変腑鏁版嵁
+    handleSelectionChange(selection) {
+      this.ids = selection.map(item => item.roleId);
+      this.single = selection.length != 1;
+      this.multiple = !selection.length;
+    },
+    // 鏇村鎿嶄綔瑙﹀彂
+    handleCommand(command, row) {
+      switch (command) {
+        case "handleDataScope":
+          this.handleDataScope(row);
+          break;
+        case "handleAuthUser":
+          this.handleAuthUser(row);
+          break;
+        default:
+          break;
+      }
+    },
+    // 鏍戞潈闄愶紙灞曞紑/鎶樺彔锛�
+    handleCheckedTreeExpand(value, type) {
+      console.log(value);
+      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;
+          // if (this.$refs.menu.store.nodesMap[treeList[i].id].childNodes) {
+          //   let children = this.$refs.menu.store.nodesMap[treeList[i].id]
+          //     .childNodes;
+          //   for (let i = 0; i < children.length; i++) {
+          //     children[i].expanded = value;
+          //   }
+          // }
+        }
+      } 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;
+        }
+      }
+    },
+    // 鏍戞潈闄愶紙鍏ㄩ��/鍏ㄤ笉閫夛級
+    handleCheckedTreeNodeAll(value, type) {
+      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;
+      }
+    },
+    /** 鏂板鎸夐挳鎿嶄綔 */
+    handleAdd() {
+      this.reset();
+      this.getMenuTreeselect();
+      this.open = true;
+
+      this.title = "娣诲姞瑙掕壊";
+    },
+    /** 淇敼鎸夐挳鎿嶄綔 */
+    handleUpdate(row) {
+      this.reset();
+      const roleId = row.roleId || this.ids;
+      const roleMenu = this.getRoleMenuTreeselect(roleId);
+      getRole(roleId).then(response => {
+        this.form = response.data;
+        this.open = true;
+
+        this.$nextTick(() => {
+          roleMenu.then(res => {
+            let checkedKeys = res.checkedKeys;
+            checkedKeys.forEach(v => {
+              this.$nextTick(() => {
+                this.$refs.menu.setChecked(v, true, false);
+              });
+            });
+          });
+        });
+        this.title = "淇敼瑙掕壊";
+      });
+    },
+    /** 閫夋嫨瑙掕壊鏉冮檺鑼冨洿瑙﹀彂 */
+    dataScopeSelectChange(value) {
+      if (value !== "2") {
+        this.$refs.dept.setCheckedKeys([]);
+      }
+    },
+    /** 鍒嗛厤鏁版嵁鏉冮檺鎿嶄綔 */
+    handleDataScope(row) {
+      this.reset();
+      const deptTreeSelect = this.getDeptTree(row.roleId);
+      getRole(row.roleId).then(response => {
+        this.form = response.data;
+        this.openDataScope = true;
+        this.$nextTick(() => {
+          deptTreeSelect.then(res => {
+            this.$refs.dept.setCheckedKeys(res.checkedKeys);
+          });
+        });
+        this.title = "鍒嗛厤鏁版嵁鏉冮檺";
+      });
+    },
+    /** 鍒嗛厤鐢ㄦ埛鎿嶄綔 */
+    handleAuthUser: function(row) {
+      const roleId = row.roleId;
+      this.$router.push("/system/role-auth/user/" + roleId);
+    },
+    /** 鎻愪氦鎸夐挳 */
+    submitForm: function() {
+      this.$refs["form"].validate(valid => {
+        if (valid) {
+          if (this.form.roleId != undefined) {
+            this.form.menuIds = this.getMenuAllCheckedKeys();
+            updateRole(this.form).then(response => {
+              this.$modal.msgSuccess("淇敼鎴愬姛");
+              this.open = false;
+
+              this.getList();
+            });
+          } else {
+            this.form.menuIds = this.getMenuAllCheckedKeys();
+            addRole(this.form).then(response => {
+              this.$modal.msgSuccess("鏂板鎴愬姛");
+              this.open = false;
+
+              this.getList();
+            });
+          }
+        }
+      });
+    },
+    /** 鎻愪氦鎸夐挳锛堟暟鎹潈闄愶級 */
+    submitDataScope: function() {
+      if (this.form.roleId != undefined) {
+        this.form.deptIds = this.getDeptAllCheckedKeys();
+        dataScope(this.form).then(response => {
+          this.$modal.msgSuccess("淇敼鎴愬姛");
+          this.openDataScope = false;
+          this.getList();
+        });
+      }
+    },
+    /** 鍒犻櫎鎸夐挳鎿嶄綔 */
+    handleDelete(row) {
+      const roleIds = row.roleId || this.ids;
+      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`
+      );
+    },
+    handleClose(done) {
+      if (this.loading) {
+        return;
+      }
+      this.$confirm("纭畾瑕佹彁浜よ〃鍗曞悧锛�")
+        .then(_ => {
+          this.loading = true;
+          this.timer = setTimeout(() => {
+            done();
+            // 鍔ㄧ敾鍏抽棴闇�瑕佷竴瀹氱殑鏃堕棿
+            setTimeout(() => {
+              this.loading = false;
+            }, 400);
+          }, 2000);
+        })
+        .catch(_ => {});
+    },
+    cancelForm() {
+      this.loading = false;
+      clearTimeout(this.timer);
+    }
+  }
+};
+</script>
\ No newline at end of file
diff --git a/se-ui/src/views/system/permissions/selectUser.vue b/se-ui/src/views/system/permissions/selectUser.vue
new file mode 100644
index 0000000..afd019c
--- /dev/null
+++ b/se-ui/src/views/system/permissions/selectUser.vue
@@ -0,0 +1,136 @@
+<template>
+  <!-- 鎺堟潈鐢ㄦ埛 -->
+  <el-dialog title="閫夋嫨鐢ㄦ埛" :visible.sync="visible" width="800px" top="5vh" append-to-body>
+    <el-form :model="queryParams" ref="queryForm" size="small" :inline="true">
+      <el-form-item label="鐢ㄦ埛鍚嶇О" prop="userName">
+        <el-input
+          v-model="queryParams.userName"
+          placeholder="璇疯緭鍏ョ敤鎴峰悕绉�"
+          clearable
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="鎵嬫満鍙风爜" prop="phonenumber">
+        <el-input
+          v-model="queryParams.phonenumber"
+          placeholder="璇疯緭鍏ユ墜鏈哄彿鐮�"
+          clearable
+          @keyup.enter.native="handleQuery"
+        />
+      </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-form-item>
+    </el-form>
+    <el-row>
+      <el-table @row-click="clickRow" ref="table" :data="userList" @selection-change="handleSelectionChange" height="260px">
+        <el-table-column type="selection" width="55"></el-table-column>
+        <el-table-column label="鐢ㄦ埛鍚嶇О" prop="userName" :show-overflow-tooltip="true" />
+        <el-table-column label="鐢ㄦ埛鏄电О" prop="nickName" :show-overflow-tooltip="true" />
+        <el-table-column label="閭" prop="email" :show-overflow-tooltip="true" />
+        <el-table-column label="鎵嬫満" prop="phonenumber" :show-overflow-tooltip="true" />
+        <el-table-column label="鐘舵��" align="center" prop="status">
+          <template slot-scope="scope">
+            <dict-tag :options="dict.type.sys_normal_disable" :value="scope.row.status"/>
+          </template>
+        </el-table-column>
+        <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>
+      <pagination
+        v-show="total>0"
+        :total="total"
+        :page.sync="queryParams.pageNum"
+        :limit.sync="queryParams.pageSize"
+        @pagination="getList"
+      />
+    </el-row>
+    <div slot="footer" class="dialog-footer">
+      <el-button type="primary" @click="handleSelectUser">纭� 瀹�</el-button>
+      <el-button @click="visible = false">鍙� 娑�</el-button>
+    </div>
+  </el-dialog>
+</template>
+
+<script>
+import { unallocatedUserList, authUserSelectAll } from "@/api/system/role";
+export default {
+  dicts: ['sys_normal_disable'],
+  props: {
+    // 瑙掕壊缂栧彿
+    roleId: {
+      type: [Number, String]
+    }
+  },
+  data() {
+    return {
+      // 閬僵灞�
+      visible: false,
+      // 閫変腑鏁扮粍鍊�
+      userIds: [],
+      // 鎬绘潯鏁�
+      total: 0,
+      // 鏈巿鏉冪敤鎴锋暟鎹�
+      userList: [],
+      // 鏌ヨ鍙傛暟
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        roleId: undefined,
+        userName: undefined,
+        phonenumber: undefined
+      }
+    };
+  },
+  methods: {
+    // 鏄剧ず寮规
+    show() {
+      this.queryParams.roleId = this.roleId;
+      this.getList();
+      this.visible = true;
+    },
+    clickRow(row) {
+      this.$refs.table.toggleRowSelection(row);
+    },
+    // 澶氶�夋閫変腑鏁版嵁
+    handleSelectionChange(selection) {
+      this.userIds = selection.map(item => item.userId);
+    },
+    // 鏌ヨ琛ㄦ暟鎹�
+    getList() {
+      unallocatedUserList(this.queryParams).then(res => {
+        this.userList = res.rows;
+        this.total = res.total;
+      });
+    },
+    /** 鎼滅储鎸夐挳鎿嶄綔 */
+    handleQuery() {
+      this.queryParams.pageNum = 1;
+      this.getList();
+    },
+    /** 閲嶇疆鎸夐挳鎿嶄綔 */
+    resetQuery() {
+      this.resetForm("queryForm");
+      this.handleQuery();
+    },
+    /** 閫夋嫨鎺堟潈鐢ㄦ埛鎿嶄綔 */
+    handleSelectUser() {
+      const roleId = this.queryParams.roleId;
+      const userIds = this.userIds.join(",");
+      if (userIds == "") {
+        this.$modal.msgError("璇烽�夋嫨瑕佸垎閰嶇殑鐢ㄦ埛");
+        return;
+      }
+      authUserSelectAll({ roleId: roleId, userIds: userIds }).then(res => {
+        this.$modal.msgSuccess(res.msg);
+        this.visible = false;
+        this.$emit("ok");
+      });
+    }
+  }
+};
+</script>
diff --git a/se-ui/vue.config.js b/se-ui/vue.config.js
index bd4f0b7..2cb82cf 100644
--- a/se-ui/vue.config.js
+++ b/se-ui/vue.config.js
@@ -34,8 +34,8 @@
     proxy: {
       // detail: https://cli.vuejs.org/config/#devserver-proxy
       [process.env.VUE_APP_BASE_API]: {
-        target: `http://localhost:8080`,
-        //target: `http://192.168.11.203:8090`,
+        // target: `http://localhost:8080`,
+        target: `http://192.168.11.203:8090`,
         changeOrigin: true,
         pathRewrite: {
           ['^' + process.env.VUE_APP_BASE_API]: process.env.VUE_APP_BASE_API

--
Gitblit v1.9.3