更新:登录功能

This commit is contained in:
2025-11-04 12:37:04 +08:00
commit a21fb92916
897 changed files with 51500 additions and 0 deletions

View File

@@ -0,0 +1,32 @@
// 片段示例 - requestInterceptor 更稳健的写法
import type { IRequestOptions } from '../types'
import { useUserStore } from '@/stores/user'
import { APP_INFO } from '@/api/config'
export function requestInterceptor(options: IRequestOptions): IRequestOptions {
const headers = { ...(options.headers || {}) }
// 更明确地调用 useUserStore
let token = ''
try {
const userStore = typeof useUserStore === 'function' ? useUserStore() : null
token = userStore?.token || uni.getStorageSync('token') || ''
} catch (e) {
token = uni.getStorageSync('token') || ''
}
if (token) headers.token = token
// Content-Type只有在没有 files 时才默认为 application/json
if (!options.files && !headers['Content-Type']) {
headers['Content-Type'] = 'application/json;charset=UTF-8'
}
headers['appType'] = APP_INFO.TYPE
headers['version_code'] = APP_INFO.VERSION_CODE || '1.0.0'
return {
...options,
header: headers,
}
}

View File

@@ -0,0 +1,78 @@
// api/interceptors/response.ts
import type { IApiResponse } from '../types';
/**
* 响应拦截器:严格兼容原项目返回约定
*
* 原项目要点回顾:
* - 当 response.statusCode == 200 且 (body.success === true || body.code == 0) 时判定为成功;
* - 部分错误码("401", 1000,1001,1100,402 等)表示需要重新登录/清除状态并跳转;
* - 错误时会返回 Promise.reject({ statusCode: 0, errMsg: ... , data: body })
*
*/
function handleAuthExpired() {
// 清空本地登录信息(保持与原项目一致)
try {
uni.removeStorageSync('userInfo');
} catch (e) {}
// 跳转 login与原项目保持一致的路径
// 在小程序/APP/H5 情况下原项目分别做了适配,简单通用处理如下:
uni.showToast({ title: '登录失效,请重新登录', icon: 'none' });
setTimeout(() => {
uni.navigateTo({ url: '/pages/login/login' });
}, 600);
}
export function responseInterceptor(res: UniApp.RequestSuccessCallbackResult) {
// 先处理非 200 的 http 状态
if (res.statusCode && res.statusCode !== 200) {
const msg = `网络错误(${res.statusCode})`;
uni.showToast({ title: msg, icon: 'none' });
return Promise.reject({ statusCode: res.statusCode, errMsg: msg, response: res });
}
// 可能为字符串,尝试解析(原项目也做了类似处理)
let httpData: IApiResponse | string = res.data as any;
if (typeof httpData === 'string') {
try {
httpData = JSON.parse(httpData);
} catch (e) {
// 无法解析仍然返回原始 body
}
}
// 规范化 message 字段
const message = (httpData as any).msg || (httpData as any).message || (httpData as any).errMsg || '';
// 成功判断:与原项目一致的条件
const successFlag = (httpData as any).success === true || (httpData as any).code === 0;
if (successFlag) {
// 返回原始 httpData与原项目 dataFactory 返回 Promise.resolve(httpData) 保持一致)
// 但大多数调用者更关心 data 字段,这里返回整个 httpData调用者可取 .data
return Promise.resolve(httpData);
}
// 登录失效或需要强制登录的一些 code与原项目一致
const code = (httpData as any).code;
if (code === '401' || code === 401) {
// 触发登出流程
handleAuthExpired();
return Promise.reject({ statusCode: 0, errMsg: '登录失效', data: httpData });
}
// 原项目还将 1000,1001,1100,402 等视作需要强制登录
if (code === '1000' || code === '1001' || code === 1000 || code === 1001 || code === 1100 || code === '402' || code === 402) {
handleAuthExpired();
return Promise.reject({ statusCode: 0, errMsg: message || '请登录', data: httpData });
}
// 其他后端业务错误toast 并 reject
const errMsg = message || '请求异常';
if (errMsg) {
uni.showToast({ title: errMsg, icon: 'none' });
}
return Promise.reject({ statusCode: 0, errMsg, data: httpData });
}