auth-guard.ts 5.0 KB
Newer Older
1
import { CoreConst, OrgData } from '@ibiz-template/core';
2
import { ModelUtil } from '@ibiz-template/model';
3
import { getCookie, setCookie } from 'qx-util';
4
import { UnauthorizedHandler } from '../unauthorized-handler/unauthorized-handler';
5 6
import { PluginFactory } from '@/plugin';

7 8 9 10 11 12 13 14
/**
 * 刷新token定时器id
 *
 * @author: zhujiamin
 * @Date: 2023-12-15 11:27:16
 */
let refreshTokenTimeId: NodeJS.Timeout | undefined;

15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
/**
 * 预加载应用级引用插件
 *
 * @description 临时解决方式
 * @author chitanda
 * @date 2022-10-31 16:10:57
 * @return {*}  {Promise<void>}
 */
async function loadAppPlugins(): Promise<void> {
  const modelService = await ModelUtil.getModelService();
  const { app } = modelService;
  const pluginRefs = app.getAllPSAppPFPluginRefs();
  const map = new Map();
  const plugin = ibiz.plugin as PluginFactory;
  const all = pluginRefs?.map(async pluginRef => {
    if (
      pluginRef &&
      pluginRef.runtimeObject &&
      pluginRef.rTObjectName &&
      pluginRef.rTObjectRepo
    ) {
      const { rTObjectName, rTObjectRepo } = pluginRef;
      if (
        plugin.appPlugins.indexOf(rTObjectRepo) !== -1 &&
        map.has(rTObjectRepo) !== true
      ) {
        map.set(rTObjectRepo, true);
        await ibiz.plugin.loadPluginRef(rTObjectName, rTObjectRepo);
      }
    }
  });
  if (all) {
    await Promise.all(all);
  }
}
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66

/**
 * 初始化模型
 *
 * @author chitanda
 * @date 2022-07-20 20:07:58
 * @return {*}  {Promise<void>}
 */
async function loadModel(): Promise<void> {
  await ModelUtil.create(async modelPath => {
    const url = `${ibiz.env.remoteModelUrl}${modelPath}`;
    const res = await ibiz.net.get(url);
    if (res.ok) {
      return res.data as IModel;
    }
    return {};
  });
67
  await loadAppPlugins();
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
}

/**
 * 加载应用数据
 *
 * @author chitanda
 * @date 2022-07-20 20:07:50
 * @return {*}  {Promise<void>}
 */
async function loadAppData(): Promise<void> {
  const res = await ibiz.net.get('/appdata');
  if (res.ok) {
    ibiz.appData = res.data;
  }
}

/**
 * 加载组织数据
 *
 * @author chitanda
 * @date 2022-07-20 20:07:44
 * @return {*}  {Promise<void>}
 */
async function loadOrgData(): Promise<void> {
  const res = await ibiz.net.get(`/uaa/getbydcsystem/${ibiz.env.dcSystem}`);
  if (res.ok) {
    const orgDataItems = res.data as OrgData[];
    if (orgDataItems) {
      const [data] = orgDataItems;
      ibiz.orgData = data;
    }
  }
}

102 103 104 105 106 107
/**
 * 设置token刷新定时器
 *
 * @author lxm
 * @date 2023-02-13 09:09:23
 */
108
function setRefreshToken() {
109 110 111 112
  // 清除之前的定时器
  if (refreshTokenTimeId) {
    clearTimeout(refreshTokenTimeId);
  }
113 114 115 116 117 118 119
  const token = getCookie(CoreConst.TOKEN);
  const expirein = getCookie(CoreConst.TOKEN_EXPIRES);
  if (token && expirein) {
    // 计算到过期时间所需的延时毫秒数,预留提前量
    let wait = Number(expirein) - new Date().getTime();
    const early = 5 * 60 * 1000;
    wait = wait > early ? wait - early : 0;
120
    refreshTokenTimeId = setTimeout(async () => {
121 122 123 124 125 126 127 128 129 130 131 132 133
      const res = await ibiz.net.get(`/uaa/refreshtoken2`);
      if (res.ok) {
        setCookie(CoreConst.TOKEN, res.data.token, 0, true);
        const expiredDate =
          new Date().getTime() + (res.data.expirein || 7199) * 1000;
        setCookie(CoreConst.TOKEN_EXPIRES, `${expiredDate}`, 0, true);
      }
      // 下一次延时做准备
      setRefreshToken();
    }, wait);
  }
}

134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
/**
 * 加载应用模型全局样式
 *
 * @author chitanda
 * @date 2023-07-24 20:07:41
 * @protected
 * @return {*}  {Promise<void>}
 */
async function loadAppModelStyle(): Promise<void> {
  await ibiz.net
    .get(`${ibiz.env.remoteModelUrl}/PSSYSAPP.json.css`)
    .then(res => {
      const dom = document.createElement('style');
      dom.setAttribute('type', 'text/css');
      if (res.request && res.request.responseURL) {
        const url = new URL(res.request.responseURL);
        dom.id = url.pathname;
      }
      dom.innerHTML = res.data as unknown as string;
      document.head.appendChild(dom);
    })
    .catch(err => {
      ibiz.log.error(`应用模型全局样式加载失败:${err.message}`);
    });
}

160 161 162 163 164 165 166 167 168 169 170 171
/**
 * 应用参数初始化
 *
 * @author chitanda
 * @date 2022-07-20 19:07:54
 * @return {*}  {Promise<void>}
 */
async function appInit(): Promise<void> {
  try {
    await loadOrgData();
    await loadAppData();
    await loadModel();
172
    setRefreshToken();
173
    await loadAppModelStyle();
174 175
    // 设置权限服务需要的appData里的数据
    await ibiz.authority.init();
176 177
    // TODO临时 多应用适配时需要修改 资源路径计算,资源路径上下文计算工具类
    await ibiz.resourcePathUtil.init();
178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199
  } catch (error) {
    const { response } = error as IData;
    if (response?.status === 401) {
      await UnauthorizedHandler.handle();
    } else {
      ibiz.log.error(error);
    }
  }
}

/**
 * 应用权限守卫
 *
 * @author chitanda
 * @date 2022-10-28 10:10:29
 * @export
 * @return {*}  {Promise<boolean>}
 */
export async function AuthGuard(): Promise<boolean> {
  await appInit();
  return true;
}