快乐的梦鱼 1 месяц назад
Родитель
Сommit
285a5199e8

+ 82 - 4
src/scripts/UpdateScript/auth.mjs

@@ -26,6 +26,7 @@ export const constant = {
 
 let currentData = {
   token: '',
+  refreshToken: '',
   identifier: '',
 };
 
@@ -38,6 +39,10 @@ function getErrorMessage(e) {
   return e instanceof Error ? e.message : (typeof e === 'object' ? e : '' + e);
 }
 
+async function saveCurrentData() {
+  await writeFile(constant.TokenSave, JSON.stringify(currentData));
+}
+
 // Axios 实例
 // ========================================
 
@@ -64,16 +69,73 @@ axiosInstance.interceptors.request.use((value) => {
   return value;
 });
 
+let refreshPromise = null;
+
+async function tryRefreshToken() {
+  if (!currentData.refreshToken) return false;
+  if (refreshPromise) return refreshPromise;
+  refreshPromise = (async () => {
+    try {
+      const res = await axios.post(
+        `${constant.ServerUrl}/auth/refresh?identifier=${currentData.identifier}`,
+        { refreshToken: currentData.refreshToken },
+        { responseType: 'json', validateStatus: () => true }
+      );
+      if (res.data && res.data.success) {
+        currentData.token = {
+          authName: res.data.data.authName,
+          authKey: res.data.data.authKey,
+        };
+        if (res.data.data.refreshToken)
+          currentData.refreshToken = res.data.data.refreshToken;
+        await saveCurrentData();
+        return true;
+      }
+    } catch {
+      // 刷新失败
+    }
+    return false;
+  })();
+  try {
+    return await refreshPromise;
+  } finally {
+    refreshPromise = null;
+  }
+}
+
 axiosInstance.interceptors.response.use((value) => {
   if (value.data.success) return value.data;
-  else return Promise.reject(value.data);
+  const err = value.data;
+  err.__config = value.config;
+  return Promise.reject(err);
+}, (error) => {
+  return Promise.reject(error);
+});
+
+axiosInstance.interceptors.response.use(null, async (error) => {
+  const code = error?.code;
+  if (
+    (code === 40102 || code === 40103) &&
+    currentData.refreshToken &&
+    !error.__retried
+  ) {
+    const refreshed = await tryRefreshToken();
+    if (refreshed) {
+      const cfg = error.__config || error.config;
+      if (cfg) {
+        error.__retried = true;
+        return axiosInstance.request(cfg);
+      }
+    }
+  }
+  return Promise.reject(error);
 });
 
 // 认证初始化
 // ========================================
 
 /**
- * 初始化认证模块,从本地加载 token
+ * 初始化认证模块,从本地加载 token,并检查登录状态
  * @returns {Promise<void>}
  */
 export async function initAuth() {
@@ -87,6 +149,19 @@ export async function initAuth() {
     // 无 token 文件时使用默认值
   }
   initIdentifier();
+
+  if (currentData.token) {
+    try {
+      const res = await axiosInstance.get('/user/user-info');
+      if (res?.data) {
+        console.log(`当前登录用户: ${res.data.name || res.data.user} (ID: ${res.data.id})`);
+      }
+    } catch {
+      console.log('未登录或登录已过期');
+    }
+  } else {
+    console.log('未登录');
+  }
 }
 
 /**
@@ -126,7 +201,9 @@ export async function login(user) {
       authName: res.data.authName,
       authKey: res.data.authKey,
     };
-    await writeFile(constant.TokenSave, JSON.stringify(currentData));
+    if (res.data.refreshToken)
+      currentData.refreshToken = res.data.refreshToken;
+    await saveCurrentData();
     console.log('登录成功');
   } catch (e) {
     console.error('登录失败', getErrorMessage(e));
@@ -138,7 +215,8 @@ export async function login(user) {
  */
 export async function logout() {
   currentData.token = '';
-  await writeFile(constant.TokenSave, JSON.stringify(currentData));
+  currentData.refreshToken = '';
+  await saveCurrentData();
   try {
     await axiosInstance.delete('/auth');
     console.log('退出登录成功');

+ 14 - 3
src/scripts/UpdateScript/index.mjs

@@ -46,6 +46,17 @@ function start() {
 
 initAuth().then(start);
 
-process.on('unhandledRejection', (reason, p) => {
-  console.error('Promise: ', p, 'Reason: ', reason)
-})
+process.on('unhandledRejection', (reason) => {
+  let reasonStr = '';
+  if (typeof reason === 'string') {
+    reasonStr = reason;
+  } else if (typeof reason === 'object') {
+    if (reason.message) {
+      reasonStr = reason.message;
+    }
+  } else {
+    reasonStr = reason.toString();
+  }
+  console.error('UnhandledRejection:', reasonStr)
+})
+

+ 7 - 5
src/scripts/UpdateScript/postUpdate.mjs

@@ -46,13 +46,15 @@ async function saveConfig(postConfig) {
 }
 
 async function getUpdateInfo(postConfig) {
+  let lastUseGit = false;
   let updateInfo = await input({ message: '输入更新信息', default: postConfig.lastUpdateInfo });
   if (updateInfo === 'git') {
     console.log('开始获取git提交信息');
+    lastUseGit = true;
     updateInfo = await execAsync('git log -1 --pretty=format:"%h %s"');
     console.log('使用git提交信息 "' + updateInfo + '" 作为更新信息');
   }
-  return updateInfo;
+  return { updateInfo, lastUseGit };
 }
 export async function uploadMulitPartLarge(axiosInstance, fileInfo, filePath) {
 
@@ -146,7 +148,7 @@ async function aliOSSMultipartUpload(client, fileName, uploadFile, progressCallb
 export async function postAppUpdate(axiosInstance, param) {
   const postConfig = await getConfig();
   const { versionId, versionName } = await selectVersion(postConfig.lastVersion);
-  const updateInfo = await getUpdateInfo(postConfig);
+  const { updateInfo, lastUseGit } = await getUpdateInfo(postConfig);
 
   const serverConfig = await axiosInstance.post('/update/update-post', { 
     config: { 
@@ -159,7 +161,7 @@ export async function postAppUpdate(axiosInstance, param) {
   });
 
   postConfig.lastVersion = versionId;
-  postConfig.lastUpdateInfo = updateInfo;
+  postConfig.lastUpdateInfo = lastUseGit ? 'git': updateInfo;
   postConfig.lastTodaySubVersion++;
 
   const updateSource = (await select({
@@ -340,10 +342,10 @@ export async function postWebUpdate(axiosInstance, param) {
   
   const postConfig = await getConfig();
   const { versionId, versionName } = await selectVersion(postConfig.lastVersion);
-  const updateInfo = await getUpdateInfo(postConfig);
+  const { updateInfo, lastUseGit } = await getUpdateInfo(postConfig);
 
   postConfig.lastVersion = versionId;
-  postConfig.lastUpdateInfo = updateInfo;
+  postConfig.lastUpdateInfo = lastUseGit ? 'git': updateInfo;
   postConfig.lastTodaySubVersion++;
 
   await axiosInstance.post('/update/update-post', { config: { type: 1, test: true, versionId, uploadWebConfig: config.uploadWebConfig, submitKey: config.submitKey } });