Просмотр исходного кода

Merge remote-tracking branch 'origin/dev' into dev

# Conflicts:
#	src/views/login/index.vue
Z 1 год назад
Родитель
Сommit
27fd95597b

+ 18 - 8
src/api/layout/index.js

@@ -3,8 +3,8 @@ import request from '@/utils/request';
 /**
  * 获取当前登录的菜单、按钮权限
  */
-export async function getResourcesTree () {
-  const res = await request.get('/system/resources/getResourcesTree');
+export async function getResourcesTree({ groupId, roleId }) {
+  const res = await request.get('/system/resources/getResourcesTree?groupId=' + groupId + '&roleId=' + roleId);
   if (res.data.code == 0 && res.data.data) {
     return res.data.data;
   }
@@ -14,18 +14,28 @@ export async function getResourcesTree () {
 /**
  * 修改当前登录的用户密码
  */
-export async function updatePassword (data) {
+export async function updatePassword(data) {
   const res = await request.put('/auth/password', data);
   if (res.data.code === 0) {
     return res.data.message ?? '修改成功';
   }
   return Promise.reject(new Error(res.data.message));
 }
+/**
+ * 角色切换 重新获取token
+ */
+export async function changeRole(data) {
+  const res = await request.post('/main/user/changeRole', data);
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
 
 /**
  * 查询未读通知
  */
-export async function getUnreadNotice () {
+export async function getUnreadNotice() {
   const res = await request.get('/sys/notifymessage/getUnreadNotifyMessageList');
   if (res.data.code == 0) {
     return res.data.data;
@@ -35,7 +45,7 @@ export async function getUnreadNotice () {
 /**
  * 获取某用户的未读消息条数
  */
-export async function getUnreadNotifyMessageCountAPI () {
+export async function getUnreadNotifyMessageCountAPI() {
   const res = await request.get('/sys/notifymessage/getUnreadNotifyMessageCount');
   if (res.data.code == 0) {
     return res.data.data;
@@ -46,8 +56,8 @@ export async function getUnreadNotifyMessageCountAPI () {
 /**
  * 更新已读-指定消息ID
  */
-export async function updateNotifyMessageReadByIdAPI (data) {
-  const res = await request.post('/sys/notifymessage/updateNotifyMessageRead',data);
+export async function updateNotifyMessageReadByIdAPI(data) {
+  const res = await request.post('/sys/notifymessage/updateNotifyMessageRead', data);
   if (res.data.code == 0) {
     return res.data.data;
   }
@@ -56,7 +66,7 @@ export async function updateNotifyMessageReadByIdAPI (data) {
 /**
  * 全部更新已读
  */
-export async function updateAllNotifyMessageReadAPI () {
+export async function updateAllNotifyMessageReadAPI() {
   const res = await request.post('/sys/notifymessage/updateAllNotifyMessageRead');
   if (res.data.code == 0) {
     return res.data.data;

+ 1 - 1
src/config/setting.js

@@ -18,7 +18,7 @@ export const HIDE_FOOTERS = [
 export const REPEATABLE_TABS = [];
 
 // 不需要登录的路由
-export const WHITE_LIST = ['/login', '/forget','/fromQRCode/designDrawing.html',,'/3DViewer/view.html','/2DViewer/view.html'];
+export const WHITE_LIST = ['/login', '/forget','/fromQRCode/designDrawing.html','/3DViewer/view.html','/2DViewer/view.html'];
 
 // 开启 KeepAlive 后仍然不需要缓存的路由地址
 export const KEEP_ALIVE_EXCLUDES = ['/vis-page/index', '/vis-page/page2'];

+ 116 - 56
src/layout/components/header-tools.vue

@@ -17,6 +17,28 @@
     <div class="ele-admin-header-tool-item">
       <header-notice />
     </div>
+    <div class="ele-admin-header-tool-item">
+      <el-select v-model="groupId" @change="groupIdChange" style="width: 180px;padding:0 5px">
+        <el-option
+          v-for="item in loginChangeGroupVOList"
+          :key="item.groupId"
+          :label="item.groupName"
+          :value="item.groupId"
+        >
+        </el-option>
+      </el-select>
+    </div>
+    <div class="ele-admin-header-tool-item">
+      <el-select v-model="roleId" @change="roleChange" style="width: 130px;padding:0 5px">
+        <el-option
+          v-for="item in loginChangeRoleVOList"
+          :key="item.roleId"
+          :label="item.roleName"
+          :value="item.roleId"
+        >
+        </el-option>
+      </el-select>
+    </div>
     <!-- 用户信息 -->
     <div class="ele-admin-header-tool-item">
       <el-dropdown @command="onUserDropClick">
@@ -64,67 +86,105 @@
 </template>
 
 <script>
-  import HeaderNotice from './header-notice.vue';
-  import PasswordModal from './password-modal.vue';
-  import SettingDrawer from './setting-drawer.vue';
-  import { logout } from '@/utils/page-tab-util';
-  import { userLogout } from '@/api/system/user';
+import HeaderNotice from './header-notice.vue';
+import PasswordModal from './password-modal.vue';
+import SettingDrawer from './setting-drawer.vue';
+import { logout } from '@/utils/page-tab-util';
+import { userLogout } from '@/api/system/user';
+import router from '@/router/index';
+
+export default {
+  components: { HeaderNotice, PasswordModal, SettingDrawer },
+  props: {
+    // 是否是全屏
+    fullscreen: Boolean
+  },
+  data() {
+    return {
+      // 是否显示修改密码弹窗
+      passwordVisible: false,
+      // 是否显示主题设置抽屉
+      settingVisible: false,
+      groupId: '',
+      roleId: '',
+      currentUser: {
+        currentGroupId: '',
+        currentRoleId: ''
+      }
+    };
+  },
+  created() {
+    this.currentUser = JSON.parse(sessionStorage['currentUser']);
+    this.groupId = this.currentUser.currentGroupId;
+    this.roleId = this.currentUser.currentRoleId;
+  },
 
-  export default {
-    components: { HeaderNotice, PasswordModal, SettingDrawer },
-    props: {
-      // 是否是全屏
-      fullscreen: Boolean
+  computed: {
+    // 当前用户信息
+    loginUser() {
+      return this.$store.state.user.info;
     },
-    data() {
-      return {
-        // 是否显示修改密码弹窗
-        passwordVisible: false,
-        // 是否显示主题设置抽屉
-        settingVisible: false
-      };
+    // 部门下拉
+    loginChangeGroupVOList() {
+      return this.$store.state.user?.info?.loginChangeGroupVOList;
     },
-    computed: {
-      // 当前用户信息
-      loginUser() {
-        return this.$store.state.user.info;
-      }
+    // 角色下拉
+    loginChangeRoleVOList() {
+      return this.$store.state.user?.info?.loginChangeGroupVOList.find(
+        (item) => item.groupId == this.groupId
+      )?.loginChangeRoleVOList;
+    }
+  },
+  methods: {
+    groupIdChange(val) {
+      this.roleChange(this.loginChangeRoleVOList[0].roleId);
+    },
+    roleChange(val) {
+    
+      this.roleId = val;
+      this.currentUser.currentGroupId = this.groupId;
+      this.currentUser.currentRoleId = val;
+      sessionStorage['currentUser'] = JSON.stringify(this.currentUser);
+      this.$store
+        .dispatch('user/fetchUserInfo')
+        .then(({ menus, homePath, authoritiesRouter }) => {
+          router.roleChange({ menus, homePath, authoritiesRouter });
+        });
     },
-    methods: {
-      /* 用户信息下拉点击事件 */
-      onUserDropClick(command) {
-        if (command === 'password') {
-          this.passwordVisible = true;
-        } else if (command === 'profile') {
-          if (this.$route.fullPath !== '/user/profile') {
-            // this.$router.push('/user/profile');
-            window.history.pushState(null, '', '/page-wt/user/profile');
-          }
-        } else if (command === 'logout') {
-          // 退出登录
-          this.$confirm(
-            this.$t('layout.logout.message'),
-            this.$t('layout.logout.title'),
-            { type: 'warning' }
-          )
-            .then(() => {
-              userLogout().then((res) => {
-                localStorage.removeItem('userId');
-                localStorage.removeItem('LogoName');
-                logout();
-              });
-            })
-            .catch(() => {});
+    /* 用户信息下拉点击事件 */
+    onUserDropClick(command) {
+      if (command === 'password') {
+        this.passwordVisible = true;
+      } else if (command === 'profile') {
+        if (this.$route.fullPath !== '/user/profile') {
+          // this.$router.push('/user/profile');
+          window.history.pushState(null, '', '/page-wt/user/profile');
         }
-      },
-      /* 全屏切换 */
-      toggleFullscreen() {
-        this.$emit('fullscreen');
-      },
-      /* 打开设置抽屉 */
-      openSetting() {
-        this.settingVisible = true;
+      } else if (command === 'logout') {
+        // 退出登录
+        this.$confirm(
+          this.$t('layout.logout.message'),
+          this.$t('layout.logout.title'),
+          { type: 'warning' }
+        )
+          .then(() => {
+            userLogout().then((res) => {
+              localStorage.removeItem('userId');
+              localStorage.removeItem('LogoName');
+              logout();
+            });
+          })
+          .catch(() => {});
       }
+    },
+    /* 全屏切换 */
+    toggleFullscreen() {
+      this.$emit('fullscreen');
+    },
+    /* 打开设置抽屉 */
+    openSetting() {
+      this.settingVisible = true;
     }
-  };
+  }
+};
 </script>

+ 28 - 2
src/router/index.js

@@ -6,16 +6,17 @@ import NProgress from 'nprogress';
 import VueRouter from 'vue-router';
 import { WHITE_LIST, REDIRECT_PATH, LAYOUT_PATH } from '@/config/setting';
 import store from '@/store';
-import { getToken } from '@/utils/token-util';
+import { getToken, setToken } from '@/utils/token-util';
 import { routes, getMenuRoutes } from './routes';
 import { getLoginUser } from '@/api/login';
+import { changeRole } from '@/api/layout/index';
 
 Vue.use(VueRouter);
 
 const router = new VueRouter({
   routes,
   mode: 'history',
-  scrollBehavior () {
+  scrollBehavior() {
     return { y: 0 };
   }
 });
@@ -82,5 +83,30 @@ router.afterEach((to) => {
     }, 200);
   }
 });
+router.roleChange = async ({ menus, homePath, authoritiesRouter }) => {
+  const currentUser = JSON.parse(sessionStorage['currentUser']);
 
+  if (menus && menus.length > 0) {
+    router.addRoute(
+      getMenuRoutes([...menus, ...authoritiesRouter], homePath)
+    );
+    if (router.currentRoute.path != (menus[0].redirect || menus[0].path)) {
+      await router.replace({
+        path: menus[0].redirect || menus[0].path,
+      })
+    }
+   
+    const newToken = await changeRole({ groupId: currentUser.currentGroupId, roleId: currentUser.currentRoleId })
+    setToken(newToken)
+    setTimeout(() => {
+      ['vuex-eos','vuex-wt','vuex-aps','vuex-mes','vuex-eam','vuex-pro','vuex-fm','vuex-main-data','vuex-wms','vuex-qms','vuex-vis'].forEach((key) => {
+        sessionStorage.removeItem(key);
+      });
+      window.location.reload()
+     
+    }, 100);
+  }
+
+  // next({ ...to, replace: true });
+};
 export default router;

+ 13 - 12
src/store/modules/user.js

@@ -127,8 +127,9 @@ export default {
     //   return { menus, homePath };
     // },
     //动态路由
-    async fetchUserInfo({ commit }) {
-      const result = await getResourcesTree().catch(() => {});
+    async fetchUserInfo({ commit, state }) {
+      let currentUser = JSON.parse(sessionStorage['currentUser'])
+      const result = await getResourcesTree({ groupId: currentUser.currentGroupId, roleId: currentUser.currentRoleId }).catch(() => { });
       if (!result) {
         return {};
       }
@@ -148,20 +149,20 @@ export default {
       // 用户菜单, 过滤掉按钮类型并转为 children 形式
       const { menus, homePath } = formatMenus(
         USER_MENUS ??
-          toTreeData({
-            data: menuList,
-            idField: 'id',
-            parentIdField: 'parentId'
-          })
+        toTreeData({
+          data: menuList,
+          idField: 'id',
+          parentIdField: 'parentId'
+        })
       );
       // 用户路由按钮
       const { menus: authoritiesRouter } = formatMenus(
         USER_MENUS ??
-          toTreeData({
-            data: authorities.filter((i) => i.path),
-            idField: 'id',
-            parentIdField: 'parentId'
-          })
+        toTreeData({
+          data: authorities.filter((i) => i.path),
+          idField: 'id',
+          parentIdField: 'parentId'
+        })
       );
       console.log('menus--', menus);
       commit('setMenus', menus);

+ 26 - 0
src/styles/transition/common.scss

@@ -57,3 +57,29 @@
   border-top: 4px solid #157a2c;
   color: #157a2c;
 }
+
+
+.el-dialog {
+  margin-top: 5vh !important;
+}
+
+.el-table--medium .el-table__cell {
+  padding: 2px 0 !important;
+}
+
+.el-button--medium {
+  padding: 7px 10px  !important;
+  font-size: 12px  !important;
+  border-radius: 3px  !important;
+}
+.el-button--small {
+  padding: 7px 10px  !important;
+  font-size: 12px  !important;
+  border-radius: 3px  !important;
+}
+
+.el-input--medium .el-input__inner {
+  // height: 32px  !important;
+  // line-height: 32px  !important;
+}
+

+ 111 - 56
src/views/login/index.vue

@@ -1,18 +1,36 @@
 <template>
-  <div :class="[
-    'login-wrapper',
-    ['', 'login-form-right', 'login-form-left'][direction]
-  ]">
-    <el-form ref="form" size="large" :model="form" :rules="rules" class="login-form ele-bg-white"
-             @keyup.enter.native="submit">
+  <div
+    :class="[
+      'login-wrapper',
+      ['', 'login-form-right', 'login-form-left'][direction]
+    ]"
+  >
+    <el-form
+      ref="form"
+      size="large"
+      :model="form"
+      :rules="rules"
+      class="login-form ele-bg-white"
+      @keyup.enter.native="submit"
+    >
       <h4>{{ $t('login.title') }}</h4>
       <el-form-item prop="loginName">
-        <el-input clearable v-model="form.loginName" prefix-icon="el-icon-user" placeholder="请输入登录账号"/>
+        <el-input
+          clearable
+          v-model="form.loginName"
+          prefix-icon="el-icon-user"
+          placeholder="请输入登录账号"
+        />
       </el-form-item>
       <el-form-item prop="loginPwd">
-        <el-input show-password v-model="form.loginPwd" prefix-icon="el-icon-lock" placeholder="请输入登录密码"/>
+        <el-input
+          show-password
+          v-model="form.loginPwd"
+          prefix-icon="el-icon-lock"
+          placeholder="请输入登录密码"
+        />
       </el-form-item>
-       <el-form-item prop="captcha">
+      <el-form-item prop="captcha">
         <div class="login-input-group">
           <el-input
             clearable
@@ -32,19 +50,36 @@
         <el-checkbox v-model="form.remember">
           {{ $t('login.remember') }}
         </el-checkbox>
-        <el-link type="primary" :underline="false" class="ele-pull-right" @click="$router.push('/forget')">
+        <el-link
+          type="primary"
+          :underline="false"
+          class="ele-pull-right"
+          @click="$router.push('/forget')"
+        >
           忘记密码
         </el-link>
       </div>
       <div class="el-form-item">
-        <el-button size="large" type="primary" class="login-btn" :loading="loading" @click="submit">
+        <el-button
+          size="large"
+          type="primary"
+          class="login-btn"
+          :loading="loading"
+          @click="submit"
+        >
           {{ loading ? $t('login.loading') : $t('login.login') }}
         </el-button>
       </div>
       <div class="ele-text-center" style="margin-bottom: 10px">
-        <i class="login-oauth-icon el-icon-_qq" style="background: #3492ed"></i>
-        <i class="login-oauth-icon el-icon-_wechat" style="background: #4daf29"></i>
-        <i class="login-oauth-icon el-icon-_weibo" style="background: #cf1900"></i>
+        <!-- <i class="login-oauth-icon el-icon-_qq" style="background: #3492ed"></i>
+        <i
+          class="login-oauth-icon el-icon-_wechat"
+          style="background: #4daf29"
+        ></i>
+        <i
+          class="login-oauth-icon el-icon-_weibo"
+          style="background: #cf1900"
+        ></i> -->
       </div>
     </el-form>
     <div class="login-copyright">
@@ -52,10 +87,15 @@
     </div>
     <!-- 多语言切换 -->
     <div style="position: absolute; right: 30px; top: 20px">
-      <i18n-icon :icon-style="{ fontSize: '22px', color: '#fff', cursor: 'pointer' }"/>
+      <i18n-icon
+        :icon-style="{ fontSize: '22px', color: '#fff', cursor: 'pointer' }"
+      />
     </div>
     <!-- 实际项目去掉这段 -->
-    <div class="hidden-xs-only" style="position: absolute; right: 30px; bottom: 20px; z-index: 9">
+    <div
+      class="hidden-xs-only"
+      style="position: absolute; right: 30px; bottom: 20px; z-index: 9"
+    >
       <el-radio-group v-model="direction" size="mini">
         <el-radio-button label="2">居左</el-radio-button>
         <el-radio-button label="0">居中</el-radio-button>
@@ -67,15 +107,15 @@
 
 <script>
 import I18nIcon from '@/layout/components/i18n-icon.vue';
-import {getToken} from '@/utils/token-util';
-import {login, getCaptcha} from '@/api/login';
-import xyy from '@/assets/xyy.jpg'
-import {getPathAddress} from "@/api/system/file";
+import { getToken } from '@/utils/token-util';
+import { login, getCaptcha } from '@/api/login';
+import xyy from '@/assets/xyy.jpg';
+import { getPathAddress } from '@/api/system/file';
 
 export default {
   // eslint-disable-next-line vue/multi-word-component-names
   name: 'Login',
-  components: {I18nIcon},
+  components: { I18nIcon },
   data() {
     return {
       // 登录框方向, 0居中, 1居右, 2居左
@@ -85,17 +125,22 @@ export default {
       loading: false,
       // 表单数据
       form: {
-        loginName: localStorage.getItem('accountInfo') ? JSON.parse(localStorage.getItem('accountInfo')).loginName : '',
-        loginPwd: localStorage.getItem('accountInfo') ? JSON.parse(localStorage.getItem('accountInfo')).loginPwd : '',
-        remember: localStorage.getItem('accountInfo') ? JSON.parse(localStorage.getItem('accountInfo')).remember : false,
+        loginName: localStorage.getItem('accountInfo')
+          ? JSON.parse(localStorage.getItem('accountInfo')).loginName
+          : '',
+        loginPwd: localStorage.getItem('accountInfo')
+          ? JSON.parse(localStorage.getItem('accountInfo')).loginPwd
+          : '',
+        remember: localStorage.getItem('accountInfo')
+          ? JSON.parse(localStorage.getItem('accountInfo')).remember
+          : false,
         captcha: '',
         uuid: ''
       },
       // 验证码base64数据
       captcha: '',
       // 验证码内容, 实际项目去掉
-      text: '',
-
+      text: ''
     };
   },
   computed: {
@@ -120,7 +165,7 @@ export default {
         ],
 
         captcha: [
-        {
+          {
             required: true,
             message: '验证码不能为空',
             type: 'string',
@@ -131,7 +176,7 @@ export default {
     }
   },
   created() {
-    this.changeCaptcha()
+    this.changeCaptcha();
     if (getToken()) {
       this.goHome();
     } else {
@@ -151,8 +196,19 @@ export default {
           .then(async (res) => {
             localStorage.setItem('userId', res.data.userId);
             // 用户信息
-            const filePath = await getPathAddress()
-            res.data.avatarAddress = res.data.avatar && res.data.avatar.length ? filePath + res.data.avatar[0].storePath : xyy
+            if (res.data?.loginChangeGroupVOList.length > 0) {
+              sessionStorage['currentUser'] = JSON.stringify({
+                currentGroupId: res.data.loginChangeGroupVOList[0].groupId,
+                currentRoleId:
+                  res.data.loginChangeGroupVOList[0].loginChangeRoleVOList[0]
+                    .roleId
+              });
+            }
+            const filePath = await getPathAddress();
+            res.data.avatarAddress =
+              res.data.avatar && res.data.avatar.length
+                ? filePath + res.data.avatar[0].storePath
+                : xyy;
             this.$store.commit('user/setUserInfo', res.data);
             this.loading = false;
             this.$message.success(res.message);
@@ -162,14 +218,13 @@ export default {
             } else {
               localStorage.removeItem('accountInfo');
             }
-            console.log('我是登陆');
+
             await this.$store.dispatch('user/getCurrentUserAuthorityDept');
             await this.$store.dispatch('paramsSetData/setParamsDataInfo');
             this.goHome();
-
           })
           .catch((e) => {
-            this.changeCaptcha()
+            this.changeCaptcha();
             this.loading = false;
             // this.$message.error(e.message);
           });
@@ -177,14 +232,13 @@ export default {
     },
     /* 跳转到首页 */
     goHome() {
-      this.$router.push(this.$route?.query?.from ?? '/').catch(() => {
-      });
+      this.$router.push(this.$route?.query?.from ?? '/').catch(() => {});
     },
     /* 更换图形验证码 */
     changeCaptcha() {
-      this.form.uuid = this.generateUUID()
+      this.form.uuid = this.generateUUID();
       // 这里演示的验证码是后端返回base64格式的形式, 如果后端地址直接是图片请参考忘记密码页面
-      getCaptcha({uuid:  this.form.uuid})
+      getCaptcha({ uuid: this.form.uuid })
         .then((data) => {
           this.captcha = URL.createObjectURL(data.data);
           this.$refs?.form?.clearValidate();
@@ -193,25 +247,27 @@ export default {
           // this.$message.error(e.message);
         });
     },
- generateUUID() {
-    var d = new Date().getTime(); //Timestamp
-    var d2 = (performance && performance.now && (performance.now()*1000)) || 0; //Time in microseconds since page-load or 0 if unsupported
-    return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
-        var r = Math.random() * 16; //random number between 0 and 16
-        if(d > 0) { //Use timestamp until depleted
-            r = (d + r)%16 | 0;
-            d = Math.floor(d/16);
-        } else { //Use microseconds since page-load if supported
-            r = (d2 + r)%16 | 0;
-            d2 = Math.floor(d2/16);
+    generateUUID() {
+      var d = new Date().getTime(); //Timestamp
+      var d2 =
+        (performance && performance.now && performance.now() * 1000) || 0; //Time in microseconds since page-load or 0 if unsupported
+      return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(
+        /[xy]/g,
+        function (c) {
+          var r = Math.random() * 16; //random number between 0 and 16
+          if (d > 0) {
+            //Use timestamp until depleted
+            r = (d + r) % 16 | 0;
+            d = Math.floor(d / 16);
+          } else {
+            //Use microseconds since page-load if supported
+            r = (d2 + r) % 16 | 0;
+            d2 = Math.floor(d2 / 16);
+          }
+          return (c === 'x' ? r : (r & 0x3) | 0x8).toString(16);
         }
-        return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);
-    });
-}
-
-
-
-
+      );
+    }
   }
 };
 </script>
@@ -348,7 +404,6 @@ export default {
 }
 
 @media screen and (max-width: 768px) {
-
   .login-form-right .login-form,
   .login-form-left .login-form {
     left: 50%;