|
|
@@ -1,4 +1,185 @@
|
|
|
import axios from 'axios'; // 引入axios
|
|
|
+import { hasPriv } from './gw_hasPriv';
|
|
|
+
|
|
|
+// 挂到 window 和宿主 Vue app 上,确保所有组件 this.ownPriv / this.hasPriv 可用
|
|
|
+window.ownPriv = hasPriv;
|
|
|
+window.hasPriv = hasPriv;
|
|
|
+function injectHasPriv() {
|
|
|
+ const app = document.querySelector('#app')?.__vue_app__ || document.querySelector('#root')?.__vue_app__;
|
|
|
+ if (app?.config?.globalProperties) {
|
|
|
+ app.config.globalProperties.ownPriv = hasPriv;
|
|
|
+ app.config.globalProperties.hasPriv = hasPriv;
|
|
|
+ }
|
|
|
+}
|
|
|
+injectHasPriv(); // 模块加载时注入
|
|
|
+setTimeout(injectHasPriv, 100); // 兜底:宿主 app 可能稍晚挂载
|
|
|
+
|
|
|
+// 宿主环境下 index.ts 不执行,Element Plus 全局组件/指令未注册
|
|
|
+// 此处注入到宿主 app,避免所有 el- 组件白屏
|
|
|
+import ElementPlus from 'element-plus';
|
|
|
+import 'element-plus/dist/index.css';
|
|
|
+function injectElementPlus() {
|
|
|
+ const app = document.querySelector('#app')?.__vue_app__ || document.querySelector('#root')?.__vue_app__;
|
|
|
+ if (app && !app._context?.installedPlugins?.includes(ElementPlus)) {
|
|
|
+ app.use(ElementPlus);
|
|
|
+ console.log('[gw_ajax] ElementPlus 已注入宿主 app');
|
|
|
+ }
|
|
|
+}
|
|
|
+injectElementPlus();
|
|
|
+setTimeout(injectElementPlus, 100);
|
|
|
+
|
|
|
+// ========== 登录初始化(自执行) ==========
|
|
|
+let loginInitialized = false;
|
|
|
+let loginResolve;
|
|
|
+// loginPromise: 所有请求在登录完成前都会等待此 promise
|
|
|
+const loginPromise = new Promise((resolve) => {
|
|
|
+ loginResolve = resolve;
|
|
|
+});
|
|
|
+
|
|
|
+async function findHostStore() {
|
|
|
+ const win = window;
|
|
|
+
|
|
|
+ // 1. window 全局变量
|
|
|
+ if (win.__HOST_STORE__) return win.__HOST_STORE__;
|
|
|
+ if (win.$store) return win.$store;
|
|
|
+
|
|
|
+ // 2. DOM -> Vue 3 app
|
|
|
+ const appRoot = document.querySelector('#app') || document.querySelector('#root');
|
|
|
+ const vueApp = appRoot?.__vue_app__;
|
|
|
+ const gp = vueApp?.config?.globalProperties;
|
|
|
+
|
|
|
+ // 2a. Vuex
|
|
|
+ if (gp?.$store) return gp.$store;
|
|
|
+
|
|
|
+ // 2b. Pinia (globalProperties.$pinia)
|
|
|
+ // 宿主 Pinia 结构:
|
|
|
+ // state.user.info → { mobile, name, ... } → 对应旧框架 userInfo
|
|
|
+ // state.portal.currentBusiness → { id, areaPermission, ... } → 对应旧框架 currentBusiness
|
|
|
+ // state.user.thirdToken → JWT token → 对应旧框架 token
|
|
|
+ if (gp?.$pinia) {
|
|
|
+ const piniaState = gp.$pinia.state?.value || {};
|
|
|
+ console.log('[gw_ajax] $pinia state keys:', Object.keys(piniaState));
|
|
|
+
|
|
|
+ const userInfo = piniaState.user?.info;
|
|
|
+ const currentBusiness = piniaState.portal?.currentBusiness;
|
|
|
+ if (userInfo?.mobile && currentBusiness) {
|
|
|
+ console.log('[gw_ajax] 从 $pinia 构建 wrapper, mobile:', userInfo.mobile);
|
|
|
+ return {
|
|
|
+ getters: {
|
|
|
+ userInfo,
|
|
|
+ currentBusiness,
|
|
|
+ token: piniaState.user?.thirdToken || win.__TOKEN__ || '',
|
|
|
+ },
|
|
|
+ };
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 3. Vue 2 兼容
|
|
|
+ const vue2Vm = appRoot?.__vue__;
|
|
|
+ if (vue2Vm?.$store) return vue2Vm.$store;
|
|
|
+
|
|
|
+ // 4. getActivePinia() 兜底
|
|
|
+ try {
|
|
|
+ const { getActivePinia } = await import('pinia');
|
|
|
+ const pinia = getActivePinia();
|
|
|
+ if (pinia) {
|
|
|
+ const piniaState = pinia.state?.value || {};
|
|
|
+ const storeKeys = Object.keys(piniaState);
|
|
|
+ console.log('[gw_ajax] getActivePinia state keys:', storeKeys);
|
|
|
+ for (const key of storeKeys) {
|
|
|
+ const s = piniaState[key];
|
|
|
+ if (s?.userInfo?.mobile && s?.currentBusiness) {
|
|
|
+ console.log('[gw_ajax] 从 getActivePinia store', key, '构建 wrapper');
|
|
|
+ return {
|
|
|
+ getters: {
|
|
|
+ userInfo: s.userInfo,
|
|
|
+ currentBusiness: s.currentBusiness,
|
|
|
+ token: s.token || win.__TOKEN__ || '',
|
|
|
+ },
|
|
|
+ };
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (e) {
|
|
|
+ console.warn('[gw_ajax] getActivePinia 检测失败:', e);
|
|
|
+ }
|
|
|
+
|
|
|
+ return null;
|
|
|
+}
|
|
|
+
|
|
|
+async function ensureLogin() {
|
|
|
+ console.log('[gw_ajax] ===== ensureLogin 开始 =====');
|
|
|
+ try {
|
|
|
+ // 开发模式:App.vue 的 onMounted 会通过硬编码手机号完成登录,此处跳过
|
|
|
+ if (import.meta.env.MODE === 'development') {
|
|
|
+ console.log('[gw_ajax] 开发模式,跳过(由 App.vue 负责登录)');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (loginInitialized) return;
|
|
|
+
|
|
|
+ // 已登录且权限已获取则跳过(privCollect 在 sessionStorage,重启浏览器会丢失)
|
|
|
+ if (localStorage.getItem('persId') && localStorage.getItem('accessToken') && sessionStorage.getItem('privCollect')) {
|
|
|
+ console.log('[gw_ajax] 已登录且有权限,跳过');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 已登录但缺少权限数据,只刷新权限
|
|
|
+ if (localStorage.getItem('persId') && localStorage.getItem('accessToken')) {
|
|
|
+ console.log('[gw_ajax] 已登录但无权限数据,刷新 getPriv...');
|
|
|
+ loginInitialized = true;
|
|
|
+ const params = {
|
|
|
+ userId: localStorage.getItem('persId'),
|
|
|
+ ownApp: localStorage.getItem('ownApp') || '1',
|
|
|
+ };
|
|
|
+ try {
|
|
|
+ const { getPriv } = await import('../api/loginAPI');
|
|
|
+ const privRes = await getPriv(params);
|
|
|
+ console.log('[gw_ajax] getPriv 响应:', privRes);
|
|
|
+ if (privRes.success && privRes.data) {
|
|
|
+ sessionStorage.setItem('privCollect', JSON.stringify(privRes.data.priv));
|
|
|
+ }
|
|
|
+ } catch (e) {
|
|
|
+ console.error('[gw_ajax] 刷新权限异常:', e);
|
|
|
+ }
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ loginInitialized = true;
|
|
|
+
|
|
|
+ const hostStore = await findHostStore();
|
|
|
+ console.log('[gw_ajax] 找到的 hostStore:', !!hostStore);
|
|
|
+
|
|
|
+ if (!hostStore) {
|
|
|
+ console.error('[gw_ajax] 未找到宿主 store');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ const userInfo = hostStore.getters.userInfo;
|
|
|
+ const currentBusiness = hostStore.getters.currentBusiness;
|
|
|
+ console.log('[gw_ajax] userInfo:', userInfo);
|
|
|
+ console.log('[gw_ajax] currentBusiness:', currentBusiness);
|
|
|
+
|
|
|
+ if (!userInfo?.mobile) {
|
|
|
+ console.error('[gw_ajax] userInfo.mobile 不存在');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 动态导入避免循环依赖 (gw_ajax → gw_login → loginAPI → gw_ajax)
|
|
|
+ const { getLogin } = await import('./gw_login.js');
|
|
|
+ await getLogin(hostStore, userInfo, currentBusiness);
|
|
|
+ console.log('[gw_ajax] 登录完成');
|
|
|
+ } catch (e) {
|
|
|
+ console.error('[gw_ajax] 登录异常:', e);
|
|
|
+ } finally {
|
|
|
+ loginInitialized = true;
|
|
|
+ loginResolve();
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// 自执行
|
|
|
+ensureLogin();
|
|
|
+// ========== 登录初始化结束 ==========
|
|
|
|
|
|
// const userid = localStorage.getItem('userid') ? localStorage.getItem('userid') : ''
|
|
|
const userid = localStorage.getItem('persId')
|
|
|
@@ -19,12 +200,12 @@ const RESOURCE_CODE =
|
|
|
if (import.meta.env.MODE === 'development') {
|
|
|
baseURL = '/pdcApi';
|
|
|
} else {
|
|
|
- baseURL = '/modular-source/' + RESOURCE_CODE + '/pdcApi';
|
|
|
+ baseURL = '/modular-dev-source/' + RESOURCE_CODE + '/pdcApi';
|
|
|
}
|
|
|
// 创建axios实例
|
|
|
const service = axios.create({
|
|
|
// api的base_url 目前开发阶段使用本机代理
|
|
|
- // baseURL: '/modular-source/7446637943aa4c50b5d69c814517fca0/pdcApi',
|
|
|
+ // baseURL: '/modular-dev-source/7446637943aa4c50b5d69c814517fca0/pdcApi',
|
|
|
baseURL,
|
|
|
headers: {
|
|
|
persId: userid, // 从缓存中取出
|
|
|
@@ -38,7 +219,13 @@ const service = axios.create({
|
|
|
|
|
|
// request interceptor 请求拦截器,在每次ajax请求之前调用
|
|
|
service.interceptors.request.use(
|
|
|
- (config) => {
|
|
|
+ async (config) => {
|
|
|
+ // 登录 / 权限相关接口不走阻塞,否则会死锁
|
|
|
+ const isLoginApi = /getTokenByTel|getPrivByUserId/.test(config.url || '');
|
|
|
+ if (!isLoginApi) {
|
|
|
+ await loginPromise;
|
|
|
+ }
|
|
|
+
|
|
|
// config.headers['persId'] = localStorage.getItem('userid') ? localStorage.getItem('userid') : ''
|
|
|
config.headers['persId'] = localStorage.getItem('persId')
|
|
|
? localStorage.getItem('persId')
|