user.ts 12.3 KB
import useRouteStore from './route'
import useMenuStore from './menu'
import router from '@/router'
import { ElMessage } from 'element-plus'
import apiUser from '@/api/modules/user'
import { getCurrentTime } from '@/utils/common'
import { getSystemMenu, getUserInfo, getTokenByCode, loginOut, refreshToken, editPasswordInterface, getCurrentUserInfo } from '@/api/modules/queryService'

const useUserStore = defineStore(
  // 唯一ID
  'user',
  () => {
    const routeStore = useRouteStore()
    const menuStore = useMenuStore()
    const currentTime = getCurrentTime()
    const account = ref(localStorage.account ?? '')
    const userId = ref(localStorage.userId ?? '')
    const userName = ref(localStorage.userName ?? '')
    const userData = ref(localStorage.userData ?? '{}')
    const currentTenantGuid = ref(localStorage.currentTenantGuid ?? '');
    const userInfoData = ref(JSON.parse(localStorage.userInfoData ?? "[]"))
    const token = ref(localStorage.token ?? '')
    const tabbarMap: any = ref({})
    const tabbar = ref([])
    const permissions = ref<string[]>([])
    const isLoginOut = ref(false);
    const isLogin = ref(token.value ? true : false);//退出登录。
    const getTokenPromise: any = ref(null);
    /* idass的登录页面url,退出登录需要跳转到登录页。*/
    const idassLoginUrl = import.meta.env.VITE_IDASS_BASEURL;
    const timer: any = ref(null);
    //获取token.
    function getToken(data, state) {
          data.platformGuid = "7f16f697aec111ef8656fa163e60becd";
          data.userType = 2;
          data.appKey = '672c2c38e4b0cac8732a6106';
          data.validateUri = location.origin == 'http://localhost:9000' ? 'http://localhost:9000/' : location.origin + '/';
          return getTokenPromise.value = getTokenByCode(data).then((res: any) => {
            getTokenPromise.value = null;
            console.log(res);
            if (res.code == '00000') {
              console.log(res.data);
              isLogin.value = true;
              localStorage.setItem('code', `${data.code}`);
              localStorage.setItem('state', state);
              localStorage.setItem('token', res.data.token || "");
              token.value = res.data.access_token;
              localStorage.setItem('refresh_token', res.data.refreshToken || "");
              const expiresIn = (Date.now() + 1700000) + "";
              localStorage.setItem('expiresIn', expiresIn);
              refreshUserToken(false);
              //获取用户信息
              account.value = res.data.logonUser
              userId.value = res.data.userId
              currentTenantGuid.value = res.data.tenantInfoList && res.data.tenantInfoList.length ? res.data.tenantInfoList[0].guid : '';
              localStorage.setItem('currentTenantGuid', currentTenantGuid.value);
              let currentTenant = res.data.tenantInfoList?.[0];
              return getCurrentUserInfo({tenantGuid: currentTenantGuid.value}).then((res: any) => {
                console.log(res, 'getCurrentUserInfo');
                if (res.code == '00000') {
                  userName.value = res.data.staffName;
                  localStorage.setItem('userName', res.data?.staffName);
                  localStorage.setItem('userData', JSON.stringify(res.data));
                  userData.value = localStorage.getItem('userData');
                  return getSystemMenu({ tenantGuid: currentTenantGuid.value }, res.data?.isAdmin == 'Y' && (!res.data?.superTubeFlag || res.data?.superTubeFlag == 'Y')).then((info: any) => { //解决页面调用流程接口传递staffGuid,为空的问题
                    if (info.code == '00000') {
                      localStorage.setItem('userInfoData', JSON.stringify(info.data));
                      userInfoData.value = info.data;
                    //  window.location.href = location.origin + info.data[0].menuList[0].path
                    } else {
                      ElMessage.error(info.msg)
                    }
                  })
                } else {
                  ElMessage.error(res.msg)
                }
              })
            } else {
              isLogin.value = false;
             // ElMessage.error(res.msg);//授权码被重复使用,不抛出异常。
            }
          });
    }

    function refreshUserToken(isExec = true) {
      let expiresIn = localStorage.getItem('expiresIn');
      if (!expiresIn) {
        return;
      }
      const process = async () => {
        if (parseInt(expiresIn) - Date.now() < 600000) {
          const refreshing = localStorage.getItem('refreshing');
          let now = new Date();
          if (!refreshing || new Date(refreshing) < now) {//确保多个页面只刷新一次。
            localStorage.setItem('refreshing', now.toISOString());
            await refresh();
            localStorage.removeItem('refreshing');
          }
        }
      }
      isExec && process();
      /** 轮询是否需要刷新token。如果是同步多个调用,则不处理错误的信息。 */
      setInterval(async () => {
        process();
      }, 600000);
    }

    function refresh() {
      return getTokenPromise.value = refreshToken({
        refreshToken: localStorage.getItem('refresh_token')
      }).then((resInfo: any) => {
        getTokenPromise.value = null;
        if (resInfo.code == '00000') {
          localStorage.setItem('token', resInfo.data.accessToken);
          token.value = resInfo.data.accessToken;
          localStorage.setItem('refresh_token', resInfo.data.refreshToken);
          const expiresIn = (Date.now() + 1700000) + "";
          localStorage.setItem('expiresIn', expiresIn);
        } else {
          //会出现同步刷新token就退出登录的问题,去掉这个代码。
          //logout(true)
        }
      }).catch(() => {
        localStorage.removeItem('refreshing');
      });
    }

    // 登录
    async function login(data: {
      logonUser: string
      pwd: string
      userType: number
      platformGuid: string
    }) {
      // 通过 mock 进行登录
      const res = await apiUser.login(data)
      //等菜单返回之后再设置已登录状态,否则会出现菜单还未请求到,但是动态路由已经显示。
      const resData = res.data
      isLogin.value = true;
      localStorage.setItem('account', data.logonUser)
      localStorage.setItem('userId', resData.userId)
      localStorage.setItem('userName', resData.userName)
      localStorage.setItem('token', resData.token)
      /** 非idaas code登录的,清除code */
      localStorage.setItem('code', '')
      localStorage.setItem('userData', JSON.stringify(resData.data))
      account.value = data.logonUser
      userId.value = resData.userId
      userName.value = resData.userName
      token.value = resData.token
      userData.value = JSON.stringify(resData.data)
      return getUserInfo().then((info: any) => {
        if (info.code == '00000') {
          localStorage.setItem('userInfoData', JSON.stringify(info.data))
          userInfoData.value = info.data
        } else {
          ElMessage.error(info.msg)
        }
      })
    }
    // 登出
    async function logout(isErrorReturn = false, redirect = router.currentRoute.value.fullPath) {
      if (!isErrorReturn && localStorage.getItem('code')) {
        isLoginOut.value = true;
        loginOut().then(() => {
          localStorage.clear()
          account.value = ''
          userId.value = ''
          userName.value = ''
          userData.value = ''
          token.value = '';
          timer.value && clearInterval(timer.value);
          isLogin.value = false;
          userInfoData.value = [];
          routeStore.removeRoutes()
          menuStore.setActived(0)
          tabbar.value = []
          tabbarMap.value = {}
          window.location.href = idassLoginUrl + '?logout=1';
        });
      } else {
        let hasCode = localStorage.getItem('code');
        isLoginOut.value = true;
        localStorage.clear()
        account.value = ''
        userId.value = ''
        userName.value = ''
        userData.value = ''
        token.value = '';
        timer.value && clearInterval(timer.value);
        isLogin.value = false;
        userInfoData.value = [];
        routeStore.removeRoutes()
        menuStore.setActived(0)
        tabbar.value = []
        tabbarMap.value = {}
        if (hasCode) {
          window.location.href = idassLoginUrl + '?logout=1';
        } else {
          router.push({
            name: 'login',
            query: {
              ...(router.currentRoute.value.path !== '/' && router.currentRoute.value.name !== 'login' && { redirect }),
            },
          })
        }
      }
    }
    // 获取我的权限
    async function getPermissions() {
      // 通过 mock 获取权限
      // const res = await apiUser.permission()
      permissions.value = [account.value]
      return permissions.value
    }
    // 修改密码
    async function editPassword(data) {
      await editPasswordInterface(data).then((info: any) => {
        if (info.code == '00000') {
          ElMessage.success('密码修改成功,请重新登录')
        } else {
          ElMessage.error(info.msg)
        }
      });
    }
    // 根据路由设置tabbar
    async function setTabbarInfo(list) {
      let obj: any = {}
      list.map(item => {
        let mark = item.path.split('/')[1];
        obj.activePath = ''
        obj.tabbar = []
        tabbarMap.value[mark] = obj
        // let mark = ''
        // if (item.meta.title == '数据标准') {
        //   mark = 'data-standards'
        // } else if (item.meta.title == '元数据') {
        //   mark = 'data-meta'
        // } else if (item.meta.title == '数据目录') {
        //   mark = 'data-catalog'
        // } else if (item.meta.title == '数据同步') {
        //   mark = 'data-sync'
        // } else if (item.meta.title == '数据质量') {
        //   mark = 'data-quality'
        // } else if (item.meta.title == '数据盘点') {
        //   mark = 'data-inventory'
        // } else if (item.meta.title == '数据资产看板') {
        //   mark = 'data-asset-index'
        // } else if (item.meta.title == '数据资产登记') {
        //   mark = 'data-asset-register'
        // }  else if (item.meta.title == '数据产品管理') {
        //   mark = 'data-asset'
        // } else if (item.meta.title == '入表交易融资') {
        //   mark = 'data-transaction'
        // } else if (item.meta.title == '入表融资指南') {
        //   mark = 'data-guide'
        // } else if (item.meta.title == '入表服务管理') {
        //   mark = 'data-entry'
        // } else if (item.meta.title == '数据资产入表') {
        //   mark = 'data-entry'
        // } else if (item.meta.title == '法律风险意见') {
        //   mark = 'data-security'
        // } else if (item.meta.title == '金融服务') {
        //   mark = 'data-finance'
        // } else if (item.meta.title == '系统管理') {
        //   mark = 'system-manage'
        // } else {
        //   mark = 'app-scenes'
        // }
        // obj.activePath = ''
        // obj.tabbar = []
        // tabbarMap.value[mark] = obj
      })
    }
    function setTabbar(val: any = null) {
      if (val == 'menu') {
        tabbar.value.map((item: any) => {
          item.visible = false
        })
      } else {
        tabbar.value = val
      }
    }
    function setActiveTabbar(mark, val) {
      const tMap = JSON.parse(JSON.stringify(tabbarMap.value))
      if (tMap[mark] != undefined) {
        tMap[mark].activePath = val
      }
      tabbarMap.value = tMap
    }
    /** 是否有新建资产登记的权限。 */
    function hasPermission(menuName, path, btnCaption) {
      let menu = userInfoData.value.find(u => u.productName == menuName);
      if (!menu) {
        return true;
      }
      let m = menu.menuList?.find(m => m.path == path);
      if (!m || m.children == null) {
        return true;
      }
      return m.children.some(c => c.menuType == 'F' && c.menuName == btnCaption);
    }
    return {
      account,
      userId,
      userName,
      userData,
      token,
      userInfoData,
      tabbar,
      tabbarMap,
      currentTime,
      permissions,
      isLogin,
      isLoginOut,
      getTokenPromise,
      getToken,
      login,
      logout,
      getPermissions,
      editPassword,
      setTabbar,
      setActiveTabbar,
      setTabbarInfo,
      hasPermission,
      refreshUserToken
    }
  },
)

export default useUserStore