feat: v1.5 安全加固与体验优化

- 后端添加 express-rate-limit 限流(登录 10次/分钟,API 200次/分钟)
- H5 演示登录:自动获取 demo token,401 时自动重试
- 分类删除前查询关联记录数,提示用户影响范围
- 分类添加支持 8 色选择器,替代随机颜色
- 首页 overview card 改为日均+收入+笔数,避免重复显示支出
- 请求模块 401 处理优化:H5 自动刷新 token 并重试原请求
This commit is contained in:
2026-06-01 17:01:19 +08:00
parent 4737f160b7
commit 36baa9a2b5
10 changed files with 219 additions and 39 deletions

View File

@@ -33,19 +33,29 @@ export function request<T = any>(options: RequestOptions): Promise<T> {
uni.removeStorageSync('xc:userId')
if (!isRedirectingToLogin) {
isRedirectingToLogin = true
uni.showToast({ title: '请重新登录', icon: 'none' })
setTimeout(() => {
// #ifdef H5
window.location.reload()
// #endif
// #ifdef MP-WEIXIN
// 重新触发 wx.login
reLogin()
// #endif
isRedirectingToLogin = false
}, 1500)
// H5 环境自动获取 demo token 并重试
if (typeof window !== 'undefined') {
request<{ token: string; userId: number }>({
url: '/auth/demo-login',
method: 'POST'
}).then((data) => {
uni.setStorageSync('xc:token', data.token)
uni.setStorageSync('xc:userId', data.userId)
// 重试原请求
request(options).then(resolve).catch(reject)
}).catch(() => {
uni.showToast({ title: '登录失败,请刷新页面', icon: 'none' })
reject({ code: 40100, message: '未登录' })
}).finally(() => { isRedirectingToLogin = false })
} else {
// 小程序环境重新触发 wx.login
uni.showToast({ title: '请重新登录', icon: 'none' })
setTimeout(() => { reLogin(); isRedirectingToLogin = false }, 1500)
reject({ code: 40100, message: '未登录' })
}
} else {
reject({ code: 40100, message: '未登录' })
}
reject({ code: 40100, message: '未登录' })
return
}