Browse Source

feat:走秀视频

chenjiaxin 1 week ago
parent
commit
6ef90bbcec

+ 58 - 54
src/api/auth/org.js

@@ -43,71 +43,75 @@ export function deleteOrg(data) {
   })
 }
 
-// 组织搜索
-export function orgSearch(query) {
-  return requestSys({
-    url: '/sysOrg/search',
-    method: 'get',
-    params: query
-  })
-}
 
 
 
-// 获取组织列表
-export function sysOrgList(query) {
-  return requestSys({
-    url: '/sysOrg/list',
-    method: 'get',
-    params: query
-  })
-}
 
+// // 组织搜索
+// export function orgSearch(query) {
+//   return requestSys({
+//     url: '/sysOrg/search',
+//     method: 'get',
+//     params: query
+//   })
+// }
 
 
-// 通过id查询组织信息
-export function getOrgById(id) {
-  return requestSys({
-    url: '/sysOrg/info/' + id,
-    method: 'get'
-  })
-}
 
+// // 获取组织列表
+// export function sysOrgList(query) {
+//   return requestSys({
+//     url: '/sysOrg/list',
+//     method: 'get',
+//     params: query
+//   })
+// }
 
-// 获取资源数和组织资源关系
-export function getOrgResTree(id) {
-  return requestSys({
-    url: '/sysOrgResRel/list',
-    method: 'get',
-    params: {
-      orgId: id
-    }
-  })
-}
 
 
-// 获取组织列表(键值对,ID:名称)
-export function fetchOrgKeyValueList() {
-  return requestSys({
-    url: '/sysOrg/keyValueList',
-    method: 'get'
-  })
-}
+// // 通过id查询组织信息
+// export function getOrgById(id) {
+//   return requestSys({
+//     url: '/sysOrg/info/' + id,
+//     method: 'get'
+//   })
+// }
 
 
-export function getOrgDistributionChannel(id) {
-  return requestSys({
-    url: '/pimOrgDistributionChannel/list',
-    method: 'get',
-    params: { orgId: id }
-  })
-}
+// // 获取资源数和组织资源关系
+// export function getOrgResTree(id) {
+//   return requestSys({
+//     url: '/sysOrgResRel/list',
+//     method: 'get',
+//     params: {
+//       orgId: id
+//     }
+//   })
+// }
 
-export function saveOrgDistributionChannel(data) {
-  return requestSys({
-    url: '/pimOrgDistributionChannel/save',
-    method: 'post',
-    data
-  })
-}
+
+// // 获取组织列表(键值对,ID:名称)
+// export function fetchOrgKeyValueList() {
+//   return requestSys({
+//     url: '/sysOrg/keyValueList',
+//     method: 'get'
+//   })
+// }
+
+
+// export function getOrgDistributionChannel(id) {
+//   return requestSys({
+//     url: '/pimOrgDistributionChannel/list',
+//     method: 'get',
+//     params: { orgId: id }
+//   })
+// }
+
+// export function saveOrgDistributionChannel(data) {
+//   return requestSys({
+//     url: '/pimOrgDistributionChannel/save',
+//     method: 'post',
+//     data
+//   })
+// }
 

+ 46 - 0
src/api/auth/position.js

@@ -0,0 +1,46 @@
+import requestSys from '@/utils/requestSys'
+
+
+// 获取组织树
+export function dynamicTree(query) {
+  return requestSys({
+    url: '/org/tree',
+    method: 'get',
+    params: query
+  })
+}
+// 获取职位列表
+export function fetchList(query) {
+  return requestSys({
+    url: '/position/page',
+    method: 'get',
+    params: query
+  })
+}
+
+// 创建职位
+export function createPosition(data) {
+  return requestSys({
+    url: '/position/add',
+    method: 'post',
+    data
+  })
+}
+// 更新职位信息
+export function updatePosition(data) {
+  return requestSys({
+    url: '/position/edit',
+    method: 'post',
+    data
+  })
+}
+// 删除职位
+export function deletePosition(data) {
+  return requestSys({
+    url: '/position/delete',
+    method: 'post',
+    data
+  })
+}
+
+

+ 21 - 86
src/api/auth/user.js

@@ -1,112 +1,47 @@
-import requestAuth from '@/utils/requestAuth'
+import requestSys from '@/utils/requestSys'
+
 
 // 获取用户列表
 export function fetchList(query) {
-  return requestAuth({
-    url: '/sysOrgUser/list',
+  return requestSys({
+    url: '/user/page',
+    method: 'get',
+    params: query
+  })
+}
+// 获取职位数据
+export function fetchPositionList(query) {
+  return requestSys({
+    url: '/user/positionSelector',
     method: 'get',
     params: query
   })
 }
-
 // 创建用户
 export function createUser(data) {
-  return requestAuth({
-    url: '/sysOrgUser/save',
+  return requestSys({
+    url: '/user/add',
     method: 'post',
     data
   })
 }
-
-// 更新用户
+// 更新职位信息
 export function updateUser(data) {
-  return requestAuth({
-    url: '/sysOrgUser/update',
+  return requestSys({
+    url: '/user/edit',
     method: 'post',
     data
   })
 }
-
-// 获取用户详情
-export function getUserById(id) {
-  return requestAuth({
-    url: '/sysOrgUser/info/' + id,
-    method: 'get'
-  })
-}
-
-// 删除用户信息
+// 删除职位
 export function deleteUser(data) {
-  return requestAuth({
-    url: '/sysOrgUser/delete',
-    method: 'delete',
-    data
-  })
-}
-
-// 禁用用户
-export function closeUser(id) {
-  return requestAuth({
-    url: '/sysOrgUser/update',
-    method: 'post',
-    data: {
-      userId: id,
-      status: 0
-    }
-  })
-}
-
-// 启用用户
-export function openUser(id) {
-  return requestAuth({
-    url: '/sysOrgUser/update',
-    method: 'post',
-    data: {
-      userId: id,
-      status: 1
-    }
-  })
-}
-
-// 获取角色树以及用户和角色的关联关系
-export function getUserRoleTree(userId) {
-  return requestAuth({
-    url: '/sysOrgUserRole/list',
-    method: 'get',
-    params: { userId: userId }
-  })
-}
-
-// 更新用户角色关联关系
-export function updateUserRole(data) {
-  return requestAuth({
-    url: '/sysOrgUserRole/save',
+  return requestSys({
+    url: '/user/delete',
     method: 'post',
     data
   })
 }
 
-// 保存用户操作记录
-export function saveUserOpRecored(data) {
-  return requestAuth({
-    url: '/userOpRecord/save',
-    method: 'post',
-    data
-  })
-}
 
-// 获取推荐用户菜单
-export function getUseMenu() {
-  return requestAuth({
-    url: '/userMenu/userlist',
-    method: 'get'
-  })
-}
 
-export function channgePass(data) {
-  return requestAuth({
-    url: '/changePassword',
-    method: 'post',
-    data
-  })
-}
+

+ 2 - 2
src/components/Pagination/index.vue

@@ -75,13 +75,13 @@ export default {
   },
   methods: {
     handleSizeChange(val) {
-      this.$emit('pagination', { page: this.currentPage, limit: val });
+      this.$emit('pagination', { currentPage: this.currentPage, pageSize: val });
       if (this.autoScroll) {
         scrollTo(0, 800)
       }
     },
     handleCurrentChange(val) {
-      this.$emit('pagination', { page: val, limit: this.pageSize });
+      this.$emit('pagination', { currentPage: val, pageSize: this.pageSize });
       if (this.autoScroll) {
         scrollTo(0, 800)
       }

+ 11 - 0
src/constants/index.js

@@ -9,6 +9,17 @@ export const orgCategory = [
   { value: 'DEPT', label: '部门' },
   { value: 'COMPANY', label: '公司' },
 ];
+// 组织分类
+export const positionCategory = [
+  { value: 'HIGH', label: '高层' },
+  { value: 'MIDDLE', label: '中层' },
+  { value: 'LOW', label: '基层' },
+];
+// 用户状态
+export const userStatus = [
+  { value: 'ENABLE', label: '启用' },
+  { value: 'DISABLED', label: '禁用' },
+];
 export default {
   auditStatus
 }

+ 14 - 6
src/layout/MenuSingleLayer.vue

@@ -1,13 +1,11 @@
 <template>
   <el-container>
-    <el-aside :width="sidebar.opened ? '230px' : '64px'">
+    <el-aside class="aside" :width="sidebar.opened ? '230px' : '64px'">
       <sidebarA class="sidebar-container" />
     </el-aside>
     <el-container>
-      <el-header
-        class="header"
-        :style="{ width: `calc(100% - ${sidebar.opened ? '230px' : '64px'})` }"
-      >
+      <div v-if="device === 'mobile' && sidebar.opened" class="drawer-bg" @click="handleClickOutside" />
+      <el-header class="header" :style="{ width: `calc(100% - ${sidebar.opened ? '230px' : '64px'})` }">
         <!-- 头部 导航 -->
         <navbar :nameshow="nameshow" />
       </el-header>
@@ -77,9 +75,12 @@ export default {
 
   methods: {
     handleClickOutside() {
-      this.$store.dispatch("app/closeSideBar", {
+      if(this.sidebar.opened){
+        this.$store.dispatch("app/closeSideBar", {
         withoutAnimation: false
       });
+      }
+
     },
     byChildByParent(currRouter) {
       this.currRouter = currRouter;
@@ -99,6 +100,7 @@ export default {
 <style lang="scss" scoped>
 @import "../styles/mixin.scss";
 @import "../styles/variablesSingleLayer.scss";
+
 ::v-deep .el-main {
   padding: 0;
 }
@@ -116,6 +118,11 @@ export default {
   }
 }
 
+.aside {
+  z-index: 1002;
+  background: #fff;
+}
+
 .el-main {
   margin-top: 50px;
 }
@@ -125,6 +132,7 @@ export default {
   position: relative;
   height: 100%;
   width: 100%;
+
   &.mobile.openSidebar {
     position: fixed;
     top: 0;

+ 70 - 10
src/layout/components/Navbar.vue

@@ -7,7 +7,11 @@
           :class="[sidebar.opened ? 'el-icon-s-fold' : 'el-icon-s-unfold']"
         ></i>
       </div>
-      <breadcrumb id="breadcrumb-container" class="breadcrumb-container" />
+      <breadcrumb
+        id="breadcrumb-container"
+        class="breadcrumb-container"
+        v-show="!isMobile || !sidebar.opened"
+      />
     </div>
 
     <div class="right-menu">
@@ -18,7 +22,7 @@
       >
         <div class="avatar-wrapper">
           <img class="user-avatar" :src="avatar" alt="avatar" />
-          <span style="color: #fff; font-size: medium">{{ name }}</span>
+          <span style="font-size: medium">{{ name }}</span>
           <i class="el-icon-caret-bottom" />
         </div>
         <el-dropdown-menu slot="dropdown">
@@ -54,13 +58,19 @@ export default {
     Screenfull
   },
   computed: {
-    ...mapGetters(["sidebar", "avatar", "name", "device"])
+    ...mapGetters(["sidebar", "avatar", "name", "device"]),
+    isMobile() {
+      return this.device === "mobile";
+    }
   },
   data() {
     return {
-      helpswitch: true
+      helpswitch: true,
     };
   },
+  created() {
+    console.log(this.name,'name')
+  },
   methods: {
     clickopen() {
       this.$emit("helpcenterEvent", this.helpswitch);
@@ -111,35 +121,78 @@ export default {
   -webkit-box-shadow: 0 2px 20px 0 rgba(15, 12, 70, 0.1);
   box-shadow: 0 2px 20px 0 rgba(15, 12, 70, 0.1);
   color: #000;
+
   .left-menu {
     display: flex;
     flex-direction: row;
     align-items: center;
     margin-left: 10px;
-    .hamburger-container {
-      i {
-        font-size: 20px;
-        cursor: pointer;
+    flex: 1;
+    overflow: hidden;
+
+    @media screen and (max-width: 768px) {
+      .breadcrumb-container {
+        transition: opacity 0.3s;
       }
     }
   }
+
   .breadcrumb-container {
     float: left;
     margin-left: 10px;
   }
+
   .errLog-container {
     display: inline-block;
     vertical-align: top;
   }
+
   .right-menu {
-    position: fixed;
+    background: #fff;
+    position: absolute; // 改为 absolute 定位,避免在小屏幕上的定位问题
     right: 20px;
-    line-height: 50px;
+    line-height: 54px;
     display: flex;
     flex-direction: row;
+    align-items: center; // 添加垂直居中对齐
+
+    @media screen and (max-width: 768px) {
+      // 添加移动端适配
+      right: 0;
+      padding-right: 10px;
+
+      .right-menu-item {
+        padding: 0 5px; // 减小内边距
+      }
+      .screenfull-container {
+        display: none !important; // 在移动端隐藏用户名
+      }
+      .avatar-container {
+        margin-left: 0px !important;
+        margin-right: 0px !important;
+
+        .avatar-wrapper {
+          .user-avatar {
+            width: 30px; // 减小头像尺寸
+            height: 30px;
+          }
+
+          .el-icon-caret-bottom {
+            right: -10px !important;
+            top: 14px !important;
+          }
+
+          span {
+            display: none; // 在移动端隐藏用户名
+          }
+        }
+      }
+    }
+
     &:focus {
       outline: none;
     }
+
     .right-menu-item {
       display: inline-block;
       padding: 0 8px;
@@ -147,25 +200,31 @@ export default {
       font-size: 18px;
       color: #000;
       vertical-align: text-bottom;
+
       span {
         color: #000 !important;
       }
+
       &.hover-effect {
         cursor: pointer;
         transition: background 0.3s;
+
         &:hover {
           background: rgba(0, 0, 0, 0.025);
         }
       }
     }
+
     .avatar-container {
       margin-right: 35px;
       margin-left: 10px;
+
       .avatar-wrapper {
         position: relative;
         height: 100%;
         display: flex;
         align-items: center;
+
         .user-avatar {
           cursor: pointer;
           width: 36px;
@@ -175,6 +234,7 @@ export default {
           border: 1px solid #ddd;
           object-fit: cover;
         }
+
         .el-icon-caret-bottom {
           cursor: pointer;
           position: absolute;

+ 4 - 0
src/permission.js

@@ -36,9 +36,13 @@ router.beforeEach(async (to, from, next) => {
             { routerPath: "/auth/user" },
             { routerPath: "/auth/role" },
             { routerPath: "/auth/orgGroup" },
+            { routerPath: "/auth/position" },
             { routerPath: "/auth/changePassword" },
             { routerPath: "/auth/org" },
             { routerPath: "/auth/res" },
+            { routerPath: "/ai" },
+            { routerPath: "/ai/cutVideo" },
+            { routerPath: "/ai/faceSwapVideo" },
             { routerPath: "/video" },
             { routerPath: "/video/oralVideo" }]
           const accessRoutes = await store.dispatch('permission/generateRoutes', data);

+ 2 - 1
src/router/index.js

@@ -35,9 +35,10 @@ export const constantRoutes = [
 ];
 import userAuthRouter from "./modules/userAuth";
 import videoRouter from "./modules/video";
-
+import aiToolsRouter from "./modules/aiTools";
 
 export const asyncRoutes = [
+  aiToolsRouter,
   videoRouter,
   // userAuthRouter,
 ];

+ 26 - 0
src/router/modules/aiTools.js

@@ -0,0 +1,26 @@
+/** When your routing table is too long, you can split it into small modules **/
+
+import Layout from "@/layout";
+
+const aiToolsRouter = {
+  path: "/ai",
+  component: Layout,
+  redirect: "/ai/cutVideo",
+  name: "AI工具",
+  meta: { title: "AI工具", icon: "el-icon-s-cooperation" },
+  children: [
+    {
+      path: "cutVideo",
+      component: () => import("@/views/ai-tools/cut-video"),
+      name: "走秀视频剪辑",
+      meta: { title: "走秀视频剪辑" }
+    },
+    // {
+    //     path: "faceSwapVideo",
+    //     component: () => import("@/views/ai-tools/video-face-swap"),
+    //     name: "视频换脸",
+    //     meta: { title: "视频换脸" }
+    //   }
+  ]
+};
+export default aiToolsRouter;

+ 7 - 1
src/router/modules/userAuth.js

@@ -11,7 +11,7 @@ const userAuthRouter = {
   children: [
     {
       path: "user",
-      component: () => import("@/views/auth/user/userIndex"),
+      component: () => import("@/views/auth/user/index"),
       name: "userIndex",
       meta: { title: "用户列表", icon: "" }
     },
@@ -33,6 +33,12 @@ const userAuthRouter = {
       name: "orgIndex",
       meta: { title: "组织管理" }
     },
+    {
+      path: "position",
+      component: () => import("@/views/auth/position/index"),
+      name: "positionIndex",
+      meta: { title: "职位管理" }
+    },
     {
       path: "role",
       component: () => import("@/views/auth/role/roleIndex"),

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

@@ -68,9 +68,6 @@ const actions = {
       }).then(
         response => {
           const { data } = response;
-          // const token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJsb2dpblR5cGUiOiJCIiwibG9naW5JZCI6MTU0MzgzNzg2Mzc4ODg3OTg3MSwicm5TdHIiOiJzeXo2NENGdTdQN3Jsa1RYbEx0TzZxSFNwV2U5eUwyRyIsInVzZXJJZCI6MTU0MzgzNzg2Mzc4ODg3OTg3MSwidXNlck5hbWUiOiLotoXmmJ_ovrAiLCJkZXB0SWQiOjE1NDM4NDI5MzQyNzAzOTQzNjh9.e3kZ1Nt534N6reeFompPdOVSFQzgz8JtSu7WZbDRna0"
-          // commit('SET_TOKEN', token);
-          // setToken(token);
           commit('SET_TOKEN', data.accessToken);
           setToken(data.accessToken);
           resolve();
@@ -100,7 +97,7 @@ const actions = {
           reject('getInfo: roles must be a non-null array !')
         }
         //名称
-        commit('SET_NAME', data.nickname);
+        commit('SET_NAME', data.name);
         //按钮权限
         const btns = data.buttonCodeList;
         sessionStorage.setItem('userBtns', btns);
@@ -108,8 +105,8 @@ const actions = {
         const avatar = data.avatar || 'https://testdgxcx-oss.gloria.com.cn/goelia-ai/avata.png';
         commit('SET_AVATAR', avatar);
         //用户名
-        if (response.name) {
-          commit('SET_LOGINNAME', response.name);
+        if (response.account) {
+          commit('SET_LOGINNAME', response.account);
         }
         //组织名称
         commit('SET_ORGNAME', orgName);

+ 59 - 0
src/views/ai-tools/cut-video.vue

@@ -0,0 +1,59 @@
+<template>
+  <div class="cut-video-container">
+    <iframe
+      ref="iframeRef"
+      :src="iframeUrl"
+      frameborder="0"
+      width="100%"
+      height="100%"
+      allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
+      allowfullscreen
+    ></iframe>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'CutVideo',
+  data() {
+    return {
+      iframeUrl: 'http://60.165.238.181:8189/'
+    }
+  },
+  mounted() {
+    // 添加消息事件监听器,用于处理iframe的跨域通信
+    window.addEventListener('message', this.handleMessage)
+  },
+  beforeDestroy() {
+    // 组件销毁前移除事件监听器
+    window.removeEventListener('message', this.handleMessage)
+  },
+  methods: {
+    handleMessage(event) {
+      // 验证消息来源
+      if (event.origin !== 'http://60.165.238.181:8189') {
+        return
+      }
+      // 处理来自iframe的消息
+      console.log('Received message from iframe:', event.data)
+      // 根据需要处理接收到的消息
+      // this.processMessage(event.data)
+    },
+    // 向iframe发送消息的方法
+    sendMessageToIframe(message) {
+      const iframe = this.$refs.iframeRef
+      if (iframe) {
+        iframe.contentWindow.postMessage(message, 'http://60.165.238.181:8189')
+      }
+    }
+  }
+}
+</script>
+
+<style scoped>
+.cut-video-container {
+  width: 100%;
+  height: 100vh;
+  overflow: hidden;
+}
+</style>

+ 59 - 0
src/views/ai-tools/video-face-swap.vue

@@ -0,0 +1,59 @@
+<template>
+  <div class="cut-video-container">
+    <iframe
+      ref="iframeRef"
+      :src="iframeUrl"
+      frameborder="0"
+      width="100%"
+      height="100%"
+      allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
+      allowfullscreen
+    ></iframe>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'CutVideo',
+  data() {
+    return {
+      iframeUrl: 'http://118.145.148.169:7777/'
+    }
+  },
+  mounted() {
+    // 添加消息事件监听器,用于处理iframe的跨域通信
+    window.addEventListener('message', this.handleMessage)
+  },
+  beforeDestroy() {
+    // 组件销毁前移除事件监听器
+    window.removeEventListener('message', this.handleMessage)
+  },
+  methods: {
+    handleMessage(event) {
+      // 验证消息来源
+      if (event.origin !== 'http://118.145.148.169:7777') {
+        return
+      }
+      // 处理来自iframe的消息
+      console.log('Received message from iframe:', event.data)
+      // 根据需要处理接收到的消息
+      // this.processMessage(event.data)
+    },
+    // 向iframe发送消息的方法
+    sendMessageToIframe(message) {
+      const iframe = this.$refs.iframeRef
+      if (iframe) {
+        iframe.contentWindow.postMessage(message, 'http://118.145.148.169:7777')
+      }
+    }
+  }
+}
+</script>
+
+<style scoped>
+.cut-video-container {
+  width: 100%;
+  height: 100vh;
+  overflow: hidden;
+}
+</style>

+ 6 - 5
src/views/auth/org/components/org/addOrEditOrgDialog.vue

@@ -102,9 +102,10 @@ export default {
   methods: {
     async initData() {
       //对整个表单进行重置,将所有字段值重置为初始值并移除校验结果
-      // this.$nextTick(() => {
-      //   this.$refs["dataForm"].resetFields();
-      // });
+      this.$nextTick(() => {
+        this.$refs["dataForm"].resetFields();
+      });
+
       await fetchGropList().then(response => {
         const data = response.data;
         this.orgGroupList = [
@@ -112,7 +113,8 @@ export default {
         ];
       });
       if (this.addOrEditData.status === "update") {
-        this.org = this.addOrEditData.orgData;
+        const data = { ...this.addOrEditData.orgData };
+        this.org = data;
       }
     },
     createData() {
@@ -141,7 +143,6 @@ export default {
       //提交更新
       this.$refs["dataForm"].validate(valid => {
         if (valid) {
-          this.org.addr = this.addr;
           updateOrg(this.org)
             .then(() => {
               this.$notify({

+ 7 - 8
src/views/auth/org/orgIndex.vue

@@ -18,8 +18,6 @@
           @click="handleFilter"
           >搜索</el-button
         >
-      </div>
-      <div class="filter-container-rt">
         <el-button
           v-waves
           type="primary"
@@ -147,8 +145,8 @@ export default {
       total: null,
       listLoading: true,
       listQuery: {
-        page: 1,
-        limit: 20,
+        currentPage: 1,
+        pageSize: 20,
         searchKey: null
       },
 
@@ -176,8 +174,9 @@ export default {
       this.listLoading = true;
       fetchList(this.listQuery)
         .then(response => {
-          this.list = response.data.rows;
-          this.total = response.data.total;
+          const { rows, total } = response.data;
+          this.list = rows;
+          this.total = total;
         })
         .finally(() => {
           this.listLoading = false;
@@ -189,7 +188,7 @@ export default {
     },
     handleFilter() {
       //查询
-      this.listQuery.page = 1;
+      this.listQuery.currentPage = 1;
       this.getList();
     },
     handleCreate() {
@@ -208,7 +207,7 @@ export default {
 
     handleDelete(row) {
       //删除
-      this.$confirm("删除此组织与下级组织吗??", "提示", {
+      this.$confirm("确定删除此组织与下级组织?", "提示", {
         confirmButtonText: "确定",
         cancelButtonText: "取消",
         type: "warning"

+ 180 - 0
src/views/auth/position/components/addPositionEditDialog.vue

@@ -0,0 +1,180 @@
+<template>
+  <el-dialog
+    :title="textMap[addPositionData.status]"
+    :visible.sync="addPositionData.visible"
+    @opened="initData"
+    width="600px"
+    top="10%"
+  >
+    <el-form
+      ref="dataForm"
+      :rules="rules"
+      :model="formData"
+      label-position="left"
+      label-width="90px"
+      style="width: 400px; margin-left:30px;"
+    >
+      <el-form-item label="所属组织" prop="orgId">
+        <el-cascader
+          v-model="formData.orgId"
+          :options="orgGroupList"
+          :props="defaultProps"
+          :show-all-levels="false"
+          clearable
+        />
+      </el-form-item>
+
+      <el-form-item label="职位名称" prop="name">
+        <el-input v-model="formData.name" clearable />
+      </el-form-item>
+
+      <el-form-item label="职位分类" prop="category">
+        <el-select v-model="formData.category" class="filter-item" clearable>
+          <el-option
+            v-for="orgGroup in positionCategory"
+            :key="orgGroup.value"
+            :label="orgGroup.label"
+            :value="orgGroup.value"
+          />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="排序" prop="sortCode">
+        <el-input v-model="formData.sortCode" clearable />
+      </el-form-item>
+    </el-form>
+    <div slot="footer" class="dialog-footer">
+      <el-button @click="handleClose">取消</el-button>
+      <el-button
+        type="primary"
+        :loading="btnloading"
+        @click="addPositionData.status === 'create' ? createData() : updateData()"
+        >确认</el-button
+      >
+    </div>
+  </el-dialog>
+</template>
+
+<script>
+import waves from "@/directive/waves"; // 水波纹指令
+import { positionCategory } from "@/constants/index";
+/* 组织 */
+import { dynamicTree, createPosition, updatePosition } from "@/api/auth/position";
+
+export default {
+  name: "addOrEditOrgDialog", //添加 或 编辑组织信息
+  directives: {
+    waves
+  },
+  props: ["addPositionData"],
+  data() {
+    return {
+      positionCategory,
+      btnloading: false,
+      defaultProps: {
+        label: "name",
+        value: "id",
+        checkStrictly: true,
+        emitPath: false
+      },
+      formData: {
+        orgId: null,
+        name: null,
+        category: null,
+        sortCode: null
+      },
+      textMap: {
+        create: "新建职位",
+        update: "编辑职位"
+      },
+      orgGroupList: [],
+      rules: {
+        name: [{ required: true, message: "请填写职位名称", trigger: "blur" }],
+        orgId: [
+          { required: true, message: "请选择所属组织", trigger: "change" }
+        ],
+        category: [
+          { required: true, message: "请选择职位分类", trigger: "change" }
+        ],
+        sortCode: [{ required: true, message: "请输入排序", trigger: "blur" }]
+      }
+    };
+  },
+  methods: {
+    async initData() {
+      //对整个表单进行重置,将所有字段值重置为初始值并移除校验结果
+      this.$nextTick(() => {
+        this.$refs["dataForm"].resetFields();
+      });
+
+      await dynamicTree().then(response => {
+        const data = response.data;
+        this.orgGroupList = response.data;
+      });
+      if (this.addPositionData.status === "update") {
+        const data = { ...this.addPositionData.orgData };
+        this.formData = data;
+      }
+    },
+    createData() {
+      //保存组织
+      this.$refs["dataForm"].validate(valid => {
+        if (valid) {
+          this.btnloading = true;
+          createPosition(this.formData)
+            .then(() => {
+              this.$notify({
+                title: "成功",
+                message: "新建成功",
+                type: "success",
+                duration: 3000
+              });
+              //重新加载 -- 调用父节点
+              this.$emit("refreshTable");
+            })
+            .finally(() => {
+              this.btnloading = false;
+            });
+        }
+      });
+    },
+    updateData() {
+      //提交更新
+      this.$refs["dataForm"].validate(valid => {
+        if (valid) {
+          updatePosition(this.formData)
+            .then(() => {
+              this.$notify({
+                title: "成功",
+                message: "编辑成功",
+                type: "success",
+                duration: 3000
+              });
+              //重新加载 -- 调用父节点
+              this.$emit("refreshTable");
+            })
+            .finally(() => {
+              this.btnloading = false;
+            });
+        }
+      });
+    },
+    handleClose() {
+      this.$refs["dataForm"].resetFields();
+      this.addPositionData.visible = false;
+      this.formData = {
+        orgId: null,
+        name: null,
+        category: null,
+        sortCode: null
+      };
+    }
+  }
+};
+</script>
+
+<style rel="stylesheet/scss" lang="scss" scoped>
+.el-cascader,
+.el-select {
+  width: 100%;
+}
+</style>

+ 317 - 0
src/views/auth/position/index.vue

@@ -0,0 +1,317 @@
+<template>
+  <div class="app-container">
+    <el-container>
+      <el-aside width="20%">
+        <div class="slot-tree">
+          <!-- 异步加载树   -->
+          <h2 class="tree-title" @click="refreshTree">组织目录</h2>
+          <el-tree
+            ref="treeRef"
+            node-key="id"
+            :props="resPorp"
+            :data="orgtreeNodes"
+            accordion
+            :highlight-current="true"
+            @node-click="handleNodeClick"
+          />
+        </div>
+      </el-aside>
+
+      <el-main>
+        <el-card class="box-card">
+          <div slot="header" class="clearfix">
+            <div class="filter-container">
+              <el-input
+                placeholder="职位名称"
+                style="width: 200px;"
+                class="filter-item"
+                clearable
+                v-model="listQuery.searchKey"
+                @keyup.enter.native="handleFilter"
+              />
+              <el-button
+                v-waves
+                class="filter-item"
+                type="primary"
+                icon="el-icon-search"
+                @click="handleFilter"
+                >搜索</el-button
+              >
+              <el-button
+                class="filter-item"
+                style="margin-left: 10px;"
+                type="primary"
+                icon="el-icon-circle-plus-outline"
+                @click="handleCreate"
+                >新建</el-button
+              >
+            </div>
+          </div>
+          <div>
+            <el-table
+              v-loading="listLoading"
+              :key="tableKey"
+              :data="list"
+              size="mini"
+              stripe
+              border
+              fit
+              highlight-current-row
+              style="width: 100%;"
+            >
+              <el-table-column
+                type="index"
+                label="序号"
+                align="center"
+                width="120"
+              />
+              <el-table-column
+                label="职位名称"
+                min-width="100"
+                align="center"
+                prop="name"
+              />
+
+              <el-table-column
+                label="职位分类"
+                align="center"
+                width="180"
+                prop="category"
+              >
+                <template slot-scope="scope">
+                  {{ getValueByKey(scope.row.category, positionCategory) }}
+                </template>
+              </el-table-column>
+              <el-table-column
+                label="排序"
+                align="center"
+                width="150"
+                prop="sortCode"
+              />
+              <el-table-column
+                label="创建时间"
+                align="center"
+                width="150"
+                prop="createTime"
+              />
+              <el-table-column
+                label="更新时间"
+                align="center"
+                width="150"
+                prop="updateTime"
+              />
+
+              <el-table-column
+                fixed="right"
+                label="操作"
+                align="center"
+                width="200"
+              >
+                <template slot-scope="scope">
+                  <el-button
+                    type="primary"
+                    size="mini"
+                    icon="el-icon-edit"
+                    circle
+                    title="编辑"
+                    @click="handleUpdate(scope.row)"
+                  />
+
+                  <el-button
+                    size="mini"
+                    type="danger"
+                    icon="el-icon-delete"
+                    circle
+                    title="删除"
+                    @click="handleDelete(scope.row)"
+                  />
+                </template>
+              </el-table-column>
+            </el-table>
+
+            <!-- 分页 -->
+            <swPage
+              v-if="total > 0"
+              key="2"
+              :listQuery="listQuery"
+              :total="total"
+              pos="btmRight"
+              @retPage="retPage"
+            />
+          </div>
+        </el-card>
+      </el-main>
+    </el-container>
+     <!-- 新增或编辑对话框-->
+     <addPositionEditDialog
+      :addPositionData="addPositionData"
+      @refreshTable="refreshData"
+    />
+  </div>
+</template>
+
+<script>
+import waves from "@/directive/waves";
+import swPage from "@/views/common/swPage";
+import { dynamicTree, fetchList, deletePosition } from "@/api/auth/position";
+import { positionCategory } from "@/constants/index";
+import { getValueByKey } from "@/utils/index";
+import addPositionEditDialog from "./components/addPositionEditDialog";
+
+export default {
+  inject: ["reload"], //刷新
+  name: "positionIndex",
+  directives: {
+    waves
+  },
+  components: {
+    swPage,
+    addPositionEditDialog
+  },
+  data() {
+    return {
+      positionCategory,
+      tableKey: 0,
+      orgtreeNodes: [], //组织树节点
+      currentNode: null,
+      currNodeData: null, //当前属性的数据
+      resPorp: {
+        //树结构
+        label: "name",
+        isLeaf: "leaf"
+      },
+      list: [],
+      total: null,
+      listLoading: false,
+      listQuery: {
+        currentPage: 1,
+        pageSize: 10,
+        searchKey: null,
+        orgId: null
+      },
+      addPositionData: {
+        //添加 或者 编辑 dialog 数据
+        status: "create", //[create ,update]
+        visible: false,
+        orgData: null //选中的组织
+      }
+    };
+  },
+  created() {
+    this.syncLoadResLabel();
+    this.getList();
+  },
+  methods: {
+    getValueByKey,
+    refreshData() {
+      this.addPositionData.status = "create";
+      this.addPositionData.visible = false;
+      this.addPositionData.orgData = null; //选中的组织
+      this.handleFilter();
+    },
+    refreshTree() {
+      this.syncLoadResLabel();
+      this.listQuery.currentPage = 1;
+      this.listQuery.orgId = null;
+      this.getList();
+    },
+    syncLoadResLabel() {
+      //同步目录
+      dynamicTree().then(response => {
+        this.orgtreeNodes = response.data;
+      });
+    },
+    handleNodeClick(data, node) {
+      //点击node触发
+      if (this.currentNode && this.currentNode.name === data.name) {
+        node.checked = !node.checked;
+      } else {
+        node.checked = true;
+      }
+      if (node.checked) {
+        // 选中
+        this.currentNode = data;
+        this.listQuery.orgId = data.id;
+      } else {
+        // 取消选中
+        this.$refs.treeRef.setCurrentKey(null);
+        this.currentNode = null;
+        this.listQuery.orgId = null;
+      }
+      this.listQuery.currentPage = 1;
+      this.getList();
+    },
+    getList() {
+      this.listLoading = true;
+      fetchList(this.listQuery)
+        .then(response => {
+          this.list = response.data.rows;
+          this.total = response.data.total;
+        })
+        .finally(() => {
+          this.listLoading = false;
+        });
+    },
+    retPage() {
+      //分页
+      this.getList();
+    },
+    handleFilter() {
+      this.listQuery.currentPage = 1;
+      this.getList();
+    },
+    handleCreate() {
+      //查询组织 - 角色
+      this.addPositionData.status = "create";
+      this.addPositionData.visible = true;
+      this.addPositionData.orgData = null;
+    },
+    handleUpdate(row) {
+      //触发更新Dialog和创建的dialog共用一个dialog
+      this.addPositionData.status = "update";
+      this.addPositionData.visible = true;
+      this.addPositionData.orgData = row;
+    },
+
+    handleDelete(row) {
+      //删除
+      this.$confirm("确定删除此职位?", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning"
+      }).then(() => {
+        deletePosition([{ id: row.id }]).then(() => {
+          this.$notify({
+            title: "成功",
+            message: "删除成功",
+            type: "success",
+            duration: 3000
+          });
+          const index = this.list.indexOf(row);
+          this.list.splice(index, 1); //数值删除
+        });
+      });
+    },
+  }
+};
+</script>
+
+<style scoped>
+.el-aside {
+  max-width: 200px;
+}
+.box-card {
+  margin-left: 10px;
+}
+.tree-title {
+  color: #ae8877;
+  font-size: 14px;
+  cursor: pointer;
+}
+.el-tree-node__content:hover .append {
+  display: inline !important;
+}
+.append {
+  display: none;
+}
+</style>

+ 205 - 0
src/views/auth/user/components/addUserEditDialog.vue

@@ -0,0 +1,205 @@
+<template>
+  <el-dialog
+    :title="textMap[propsData.status]"
+    :visible.sync="propsData.visible"
+    @opened="initData"
+    width="600px"
+    top="10%"
+  >
+    <el-form
+      ref="dataForm"
+      :rules="rules"
+      :model="formData"
+      label-width="90px"
+      style="width: 400px; margin-left:30px;"
+    >
+      <el-form-item label="账号" prop="account">
+        <el-input v-model="formData.account" clearable />
+      </el-form-item>
+      <el-form-item label="姓名" prop="name">
+        <el-input v-model="formData.name" clearable />
+      </el-form-item>
+      <el-form-item label="性别" prop="gender">
+        <el-radio-group v-model="formData.gender">
+          <el-radio label="男">男</el-radio>
+          <el-radio label="女">女</el-radio>
+        </el-radio-group>
+      </el-form-item>
+      <el-form-item label="手机号" prop="phone">
+        <el-input v-model="formData.phone" clearable />
+      </el-form-item>
+      <el-form-item label="邮箱" prop="email">
+        <el-input v-model="formData.email" clearable />
+      </el-form-item>
+      <el-form-item label="选择组织" prop="orgId">
+        <el-cascader
+          v-model="formData.orgId"
+          :options="orgGroupList"
+          :props="defaultProps"
+          :show-all-levels="false"
+          @change="handleOrgChange"
+          clearable
+        />
+      </el-form-item>
+
+      <el-form-item label="选择职位" prop="positionId">
+        <el-select v-model="formData.positionId" class="filter-item" clearable>
+          <el-option
+            v-for="position in positionList"
+            :key="position.id"
+            :label="position.name"
+            :value="position.id"
+          />
+        </el-select>
+      </el-form-item>
+    </el-form>
+    <div slot="footer" class="dialog-footer">
+      <el-button @click="handleClose">取消</el-button>
+      <el-button
+        type="primary"
+        :loading="btnloading"
+        @click="propsData.status === 'create' ? createData() : updateData()"
+        >确认</el-button
+      >
+    </div>
+  </el-dialog>
+</template>
+
+<script>
+import waves from "@/directive/waves"; // 水波纹指令
+import { positionCategory } from "@/constants/index";
+/* 组织 */
+import { dynamicTree } from "@/api/auth/position";
+import { createUser, fetchPositionList, updateUser } from "@/api/auth/user";
+export default {
+  name: "addOrEditOrgDialog", //添加 或 编辑组织信息
+  directives: {
+    waves
+  },
+  props: ["propsData"],
+  data() {
+    return {
+      positionCategory,
+      btnloading: false,
+      defaultProps: {
+        label: "name",
+        value: "id",
+        checkStrictly: true,
+        emitPath: false
+      },
+      formData: {
+        orgId: null,
+        name: null,
+        account: null,
+        gender: null,
+        phone:null,
+        email:null,
+        positionId: null
+      },
+      textMap: {
+        create: "新建用户",
+        update: "编辑用户"
+      },
+      orgGroupList: [],
+      positionList: [],
+      rules: {
+        accountVal: [{ required: true, message: "请填写账号", trigger: "blur" }],
+        name: [{ required: true, message: "请填写职位名称", trigger: "blur" }],
+        orgId: [{ required: true, message: "请选择组织", trigger: "change" }],
+        positionId: [
+          { required: true, message: "请选择职位", trigger: "change" }
+        ]
+      }
+    };
+  },
+  methods: {
+    async initData() {
+      //对整个表单进行重置,将所有字段值重置为初始值并移除校验结果
+      this.$nextTick(() => {
+        this.$refs["dataForm"].resetFields();
+      });
+
+      await dynamicTree().then(response => {
+        this.orgGroupList = response.data;
+      });
+      if (this.propsData.status === "update") {
+        const data = { ...this.propsData.orgData };
+        this.formData = data;
+      }
+    },
+    handleOrgChange(value) {
+      // 选择组织后,自动选择所属组织的第一个职位
+      console.log(value);
+      if (value && value.length > 0) {
+        this.fetchPositionList(value);
+      }
+    },
+    fetchPositionList(orgId) {
+      const query = { orgId };
+      fetchPositionList(query).then(response => {
+        this.positionList = response.data.rows;
+      });
+    },
+    createData() {
+      //保存组织
+      this.$refs["dataForm"].validate(valid => {
+        if (valid) {
+          this.btnloading = true;
+          createUser(this.formData)
+            .then(() => {
+              this.$notify({
+                title: "成功",
+                message: "新建成功",
+                type: "success",
+                duration: 3000
+              });
+              //重新加载 -- 调用父节点
+              this.$emit("refreshTable");
+            })
+            .finally(() => {
+              this.btnloading = false;
+            });
+        }
+      });
+    },
+    updateData() {
+      //提交更新
+      this.$refs["dataForm"].validate(valid => {
+        if (valid) {
+          updateUser(this.formData)
+            .then(() => {
+              this.$notify({
+                title: "成功",
+                message: "编辑成功",
+                type: "success",
+                duration: 3000
+              });
+              //重新加载 -- 调用父节点
+              this.$emit("refreshTable");
+            })
+            .finally(() => {
+              this.btnloading = false;
+            });
+        }
+      });
+    },
+    handleClose() {
+      this.$refs["dataForm"].resetFields();
+      this.propsData.visible = false;
+      this.formData = {
+        orgId: null,
+        name: null,
+        category: null,
+        sortCode: null
+      };
+    }
+  }
+};
+</script>
+
+<style rel="stylesheet/scss" lang="scss" scoped>
+.el-cascader,
+.el-select {
+  width: 100%;
+}
+</style>

+ 420 - 0
src/views/auth/user/index.vue

@@ -0,0 +1,420 @@
+<template>
+  <div class="app-container">
+    <el-container>
+      <el-aside width="20%">
+        <div class="slot-tree">
+          <!-- 异步加载树   -->
+          <h2 class="tree-title" @click="refreshTree">组织目录</h2>
+          <el-tree
+            ref="treeRef"
+            node-key="id"
+            :props="resPorp"
+            :data="orgtreeNodes"
+            accordion
+            :highlight-current="true"
+            @node-click="handleNodeClick"
+          />
+        </div>
+      </el-aside>
+
+      <el-main>
+        <el-card class="box-card">
+          <div slot="header" class="clearfix">
+            <div class="filter-container">
+              <el-input
+                placeholder="姓名"
+                style="width: 200px;"
+                clearable
+                v-model="listQuery.searchKey"
+                @keyup.enter.native="handleFilter"
+              />
+              <el-select
+                v-model="listQuery.userStatus"
+                placeholder="用户状态"
+                clearable
+              >
+                <el-option
+                  v-for="item in userStatus"
+                  :key="item.value"
+                  :label="item.label"
+                  :value="item.value"
+                >
+                </el-option>
+              </el-select>
+              <el-button
+                v-waves
+                type="primary"
+                icon="el-icon-search"
+                @click="handleFilter"
+                >搜索</el-button
+              >
+              <el-button
+                style="margin-left: 10px;"
+                type="primary"
+                icon="el-icon-circle-plus-outline"
+                @click="handleCreate"
+                >新建</el-button
+              >
+            </div>
+          </div>
+          <div>
+            <el-table
+              v-loading="listLoading"
+              :key="tableKey"
+              :data="list"
+              size="mini"
+              stripe
+              border
+              fit
+              highlight-current-row
+              style="width: 100%;"
+            >
+              <el-table-column
+                type="index"
+                label="序号"
+                align="center"
+                width="80"
+              />
+              <el-table-column
+                label="头像"
+                min-width="80"
+                align="center"
+                prop="avatar"
+              >
+                <template slot-scope="scope">
+                  <img class="avatar" :src="scope.row.avatar" alt="头像" />
+                </template>
+              </el-table-column>
+              <el-table-column
+                label="账号"
+                align="center"
+                width="180"
+                prop="account"
+              />
+              <el-table-column
+                label="姓名"
+                min-width="150"
+                align="center"
+                prop="name"
+              />
+
+              <el-table-column
+                label="性别"
+                align="center"
+                width="100"
+                prop="gender"
+              />
+
+              <el-table-column
+                label="手机"
+                align="center"
+                width="150"
+                prop="phone"
+              />
+              <el-table-column
+                label="组织"
+                align="center"
+                width="150"
+                prop="orgName"
+              />
+              <el-table-column
+                label="职位"
+                align="center"
+                width="150"
+                prop="positionName"
+              />
+
+              <el-table-column
+                label="状态"
+                align="center"
+                width="150"
+                prop="userStatus"
+              >
+                <template slot-scope="scope">
+                  <el-switch
+                    :value="scope.row.userStatus === 'ENABLE'"
+                    active-color="#13ce66"
+                    inactive-color="#ff4949"
+                  >
+                  </el-switch>
+                </template>
+              </el-table-column>
+
+              <el-table-column
+                fixed="right"
+                label="操作"
+                align="center"
+                width="200"
+              >
+                <template slot-scope="scope">
+                  <el-tooltip
+                    class="item"
+                    effect="dark"
+                    content="编辑"
+                    placement="top"
+                  >
+                    <el-button
+                      type="primary"
+                      size="mini"
+                      icon="el-icon-edit"
+                      circle
+                      title="编辑"
+                      @click="handleUpdate(scope.row)"
+                    />
+                  </el-tooltip>
+                  <el-tooltip
+                    class="item"
+                    effect="dark"
+                    content="删除"
+                    placement="top"
+                  >
+                    <el-button
+                      size="mini"
+                      type="danger"
+                      icon="el-icon-delete"
+                      circle
+                      title="删除"
+                      @click="handleDelete(scope.row)"
+                    />
+                  </el-tooltip>
+                  <el-tooltip
+                    class="more"
+                    effect="dark"
+                    content="更多"
+                    placement="top"
+                  >
+                    <el-dropdown trigger="click">
+                      <el-button
+                        size="mini"
+                        type="primary"
+                        icon="el-icon-more"
+                        circle
+                        title="更多"
+                      />
+                      <el-dropdown-menu class="dropdown-menu" slot="dropdown">
+                        <el-dropdown-item>重置密码</el-dropdown-item>
+                        <el-popconfirm
+                          icon="el-icon-info"
+                          icon-color="red"
+                          title="确定要重置吗?"
+                        >
+                        </el-popconfirm>
+                      </el-dropdown-menu>
+                    </el-dropdown>
+                  </el-tooltip>
+                </template>
+              </el-table-column>
+            </el-table>
+
+            <!-- 分页 -->
+            <swPage
+              v-if="total > 0"
+              key="2"
+              :listQuery="listQuery"
+              :total="total"
+              pos="btmRight"
+              @retPage="retPage"
+            />
+          </div>
+        </el-card>
+      </el-main>
+    </el-container>
+    <!-- 新增或编辑对话框-->
+    <addUserEditDialog
+      :propsData="addUserEditDialogDatas"
+      @refreshTable="refreshData"
+    />
+  </div>
+</template>
+
+<script>
+import waves from "@/directive/waves";
+import swPage from "@/views/common/swPage";
+import { dynamicTree } from "@/api/auth/position";
+import { fetchList, deleteUser } from "@/api/auth/user";
+import { positionCategory, userStatus } from "@/constants/index";
+import { getValueByKey } from "@/utils/index";
+import addUserEditDialog from "./components/addUserEditDialog";
+
+export default {
+  inject: ["reload"], //刷新
+  name: "userIndex",
+  directives: {
+    waves
+  },
+  components: {
+    swPage,
+    addUserEditDialog
+  },
+  data() {
+    return {
+      positionCategory,
+      userStatus,
+      tableKey: 0,
+      orgtreeNodes: [], //组织树节点
+      currentNode: null,
+      currNodeData: null, //当前属性的数据
+      resPorp: {
+        //树结构
+        label: "name",
+        isLeaf: "leaf"
+      },
+      list: [],
+      total: null,
+      listLoading: false,
+      listQuery: {
+        currentPage: 1,
+        pageSize: 10,
+        searchKey: null,
+        orgId: null
+      },
+      addUserEditDialogDatas: {
+        //添加 或者 编辑 dialog 数据
+        status: "create", //[create ,update]
+        visible: false,
+        orgData: null //选中的组织
+      }
+    };
+  },
+  created() {
+    this.syncLoadResLabel();
+    this.getList();
+  },
+  methods: {
+    getValueByKey,
+    refreshData() {
+      this.addUserEditDialogDatas.status = "create";
+      this.addUserEditDialogDatas.visible = false;
+      this.addUserEditDialogDatas.orgData = null; //选中的组织
+      this.handleFilter();
+    },
+    refreshTree() {
+      this.syncLoadResLabel();
+      this.listQuery.currentPage = 1;
+      this.listQuery.orgId = null;
+      this.getList();
+    },
+    syncLoadResLabel() {
+      //同步目录
+      dynamicTree().then(response => {
+        this.orgtreeNodes = response.data;
+      });
+    },
+    handleNodeClick(data, node) {
+      //点击node触发
+      if (this.currentNode && this.currentNode.name === data.name) {
+        node.checked = !node.checked;
+      } else {
+        node.checked = true;
+      }
+      if (node.checked) {
+        // 选中
+        this.currentNode = data;
+        this.listQuery.orgId = data.id;
+      } else {
+        // 取消选中
+        this.$refs.treeRef.setCurrentKey(null);
+        this.currentNode = null;
+        this.listQuery.orgId = null;
+      }
+      this.listQuery.currentPage = 1;
+      this.getList();
+    },
+    getList() {
+      this.listLoading = true;
+      fetchList(this.listQuery)
+        .then(response => {
+          this.list = response.data.rows;
+          this.total = response.data.total;
+        })
+        .finally(() => {
+          this.listLoading = false;
+        });
+    },
+    retPage() {
+      //分页
+      this.getList();
+    },
+    handleFilter() {
+      this.listQuery.currentPage = 1;
+      this.getList();
+    },
+    handleCreate() {
+      //查询组织 - 角色
+      this.addUserEditDialogDatas.status = "create";
+      this.addUserEditDialogDatas.visible = true;
+      this.addUserEditDialogDatas.orgData = null;
+    },
+    handleUpdate(row) {
+      //触发更新Dialog和创建的dialog共用一个dialog
+      this.addUserEditDialogDatas.status = "update";
+      this.addUserEditDialogDatas.visible = true;
+      this.addUserEditDialogDatas.orgData = row;
+    },
+
+    handleDelete(row) {
+      //删除
+      this.$confirm("确定删除用户?", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning"
+      }).then(() => {
+        deleteUser([{ userId: row.id }]).then(() => {
+          this.$notify({
+            title: "成功",
+            message: "删除成功",
+            type: "success",
+            duration: 3000
+          });
+          const index = this.list.indexOf(row);
+          this.list.splice(index, 1); //数值删除
+        });
+      });
+    }
+  }
+};
+</script>
+
+<style scoped>
+.el-aside {
+  max-width: 200px;
+}
+/* .filter-container{
+  display: flex;
+  align-items: center;
+} */
+.box-card {
+  margin-left: 10px;
+}
+
+.tree-title {
+  color: #ae8877;
+  font-size: 14px;
+  cursor: pointer;
+}
+
+.el-tree-node__content:hover .append {
+  display: inline !important;
+}
+
+.append {
+  display: none;
+}
+
+.avatar {
+  width: 40px;
+  height: 40px;
+  border-radius: 50%;
+  border: 1px solid #eee;
+  object-fit: cover;
+  cursor: pointer;
+}
+.more {
+  margin-left: 10px;
+}
+.dropdown-menu {
+  .el-dropdown-menu__item {
+    font-size: 12px;
+  }
+}
+</style>

+ 3 - 3
src/views/common/swPage.vue

@@ -41,12 +41,12 @@ export default {
   	}
   },
   methods:{
-	 	handleSizeChange(val) {
-      this.listQuery.limit = val;
+	handleSizeChange(val) {
+      this.listQuery.pageSize = val;
       this.$emit("retPage");
     },
     handleCurrentChange(val) {
-      this.listQuery.page = val;
+      this.listQuery.currentPage = val;
       this.$emit("retPage");
     },
   }

+ 0 - 4
src/views/login/index.vue

@@ -161,10 +161,6 @@ export default {
       });
     },
     handleLogin() {
-      // this.$router.push({
-      //   path: "/",
-      //   query: this.otherQuery
-      // });
       this.$refs.loginForm.validate(valid => {
         if (valid) {
           this.loading = true;

+ 8 - 2
src/views/video/oral-video.vue

@@ -63,6 +63,12 @@
         fit
         highlight-current-row
       >
+      <el-table-column
+          label="序号"
+          type="index"
+          width="60"
+          align="center"
+        />
         <el-table-column
           label="视频ID"
           min-width="100"
@@ -304,8 +310,8 @@ export default {
       listLoading: false,
       downloadingRows: {},
       listQuery: {
-        page: 1,
-        limit: 10,
+        currentPage: 1,
+        pageSize: 10,
         videoTitle: null
       },
       currentVideoUrl: null,