user.ts 11 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 { getUserInfo, getTokenByCode, loginOut, refreshToken, editPasswordInterface } 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 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 = 'https://idaas-test.csbr.cn/login';
    const timer: any = ref(null);
        //获取token.
    function getToken(data, state) {
          data.platformGuid = "6646dcad76c411eea911fa163e419da9";
          data.userType = 2;
          isLogin.value = true;
          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.access_token || "");
              token.value = res.data.access_token;
              localStorage.setItem('refresh_token', res.data.refresh_token || "");
              const expiresIn = (Date.now() + 1700000) + "";
              localStorage.setItem('expiresIn', expiresIn);
              refreshUserToken();
              //获取用户信息
              localStorage.setItem('account', res.data.logonUser)
              localStorage.setItem('userId', res.data.userId)
              localStorage.setItem('userName', res.data.userName)
              localStorage.setItem('userData', JSON.stringify(res.data.data))
              account.value = res.data.logonUser
              userId.value = res.data.userId
              userName.value = res.data.userName
              userData.value = JSON.stringify(res.data.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)
                }
              })
            } else {
              isLogin.value = false;
             // ElMessage.error(res.msg);//授权码被重复使用,不抛出异常。
            }
          });
    }

    function refreshUserToken() {
      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');
          }
        }
      }
      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.access_token);
          token.value = resInfo.data.access_token;
          localStorage.setItem('refresh_token',resInfo.data.refresh_token);
          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 = ''
        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-asset-index'
        } else if (item.meta.title == '数据服务') {
          mark = 'data-service'
        } else if (item.meta.title == '首页') {
          mark = 'data-asset-index'
        } 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-product'
        } else if (item.meta.title == '合作伙伴管理') {
          mark = 'data-partners'
        } 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