feat: 完善鉴权和密码功能,添加飞书通知模块

- 完善Token过期/不存在时跳转登录重新认证
- 实现正常的账号密码登录验证(邮箱/手机号+密码)
- 用户初始化密码设为工号(sn)
- 添加修改密码功能(API+前端页面)
- 修复扫码登录后跳转问题(zustand persist格式)
- 创建飞书通知服务 FeishuNotificationService
- 设置页面添加修改密码入口

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
root
2026-02-26 15:19:37 +08:00
parent ba555a59b7
commit 2e5f570b40
26 changed files with 2925 additions and 158 deletions
+56 -2
View File
@@ -1,7 +1,34 @@
import axios from 'axios'
import { Toast } from 'antd-mobile'
const API_BASE = '/api/v1'
// 标记是否正在处理登出(防止重复跳转)
let isLoggingOut = false
// 处理 401 未授权错误
const handleUnauthorized = () => {
if (isLoggingOut) return
isLoggingOut = true
// 清除本地存储
localStorage.removeItem('token')
localStorage.removeItem('user-storage')
// 显示提示
Toast.show({
content: '登录已过期,请重新登录',
duration: 2000,
})
// 延迟跳转,确保提示显示
setTimeout(() => {
isLoggingOut = false
// 跳转到登录页,并清除历史记录
window.location.href = '/login'
}, 2000)
}
// 创建 axios 实例
const api = axios.create({
baseURL: API_BASE,
@@ -38,6 +65,13 @@ api.interceptors.response.use(
return Promise.reject(new Error(data.message || '请求失败'))
},
(error) => {
// 处理 401 未授权错误
if (error.response?.status === 401 || error.response?.data?.code === 401) {
handleUnauthorized()
return Promise.reject(new Error('登录已过期'))
}
// 处理其他错误
const message = error.response?.data?.message || error.message || '网络错误'
return Promise.reject(new Error(message))
}
@@ -48,8 +82,24 @@ export const authApi = {
login: (username: string, password: string) =>
api.post('/auth/login', { username, password }),
feishuLogin: (authCode: string, tenantKey: string) =>
api.post('/auth/feishu-login', { auth_code: authCode, tenant_key: tenantKey }),
// 飞书免登(支持 app_id 或 tenant_key)
feishuLogin: (authCode: string, options?: { appId?: string; tenantKey?: string }) =>
api.post('/auth/feishu-login', {
auth_code: authCode,
app_id: options?.appId,
tenant_key: options?.tenantKey,
}),
// 生成二维码登录会话
qrcodeLogin: (appId?: string, tenantKey?: string) =>
api.post('/auth/qrcode-login', {
app_id: appId,
tenant_key: tenantKey,
}),
// 轮询二维码登录状态
qrcodeLoginStatus: (sessionId: string) =>
api.get('/auth/qrcode-login-status', { params: { session_id: sessionId } }),
}
// ========== 用户 API ==========
@@ -63,6 +113,10 @@ export const userApi = {
// 获取用户列表
getUsers: (params: { keyword?: string; page?: number; page_size?: number }) =>
api.get('/user/list', { params }),
// 修改密码
changePassword: (data: { old_password: string; new_password: string; confirm_password: string }) =>
api.post('/user/change-password', data),
}
// ========== 出差申请 API ==========