作为 人才小程序开发者, 我想要 实现登录状态持久化验证功能, 以便 用户重新打开小程序时,如果之前已经登录过,则自动恢复登录状态,无需再次登录。
现有系统状态:
talentAuthClient)talent_token)发现问题:
对比用人方小程序(mini-enterprise-auth-ui)的实现,人才小程序的认证系统缺少以下关键功能:
useRequireAuth hook - 用人方小程序有独立的useRequireAuth hook用于检查登录状态并自动跳转useRequireAuth进行保护用人方小程序参考实现:
mini-enterprise-auth-ui/src/hooks/useRequireAuth.ts - 认证检查hookmini-enterprise-auth-ui/src/hooks/useAuth.tsx - AuthContext中的自动登录状态验证(第31-55行)技术依赖:
talentAuthClient.me.$get)技术栈:
useRequireAuth hook(参考mini-enterprise-auth-ui/src/hooks/useRequireAuth.ts)talentAuthClient.me.$get验证用户信息useQuery管理用户状态(避免重复请求)useRequireAuth进行保护useRequireAuth进行保护useRequireAuth进行保护useRequireAuth进行保护useRequireAuth进行保护Taro.reLaunch清除页面栈)useRequireAuth编写单元测试@d8d/rencai-auth-ui/src/hooks/目录下创建useRequireAuth.ts文件[ ] 1.2 参考用人方小程序实现:
import { useEffect } from 'react'
import Taro from '@tarojs/taro'
import { useAuth } from './useAuth'
export const useRequireAuth = (): void => {
const { isLoggedIn, isLoading } = useAuth()
useEffect(() => {
if (!isLoading && !isLoggedIn) {
Taro.showToast({
title: '请先登录',
icon: 'none',
duration: 1500
})
setTimeout(() => {
Taro.redirectTo({
url: '/pages/login/index'
})
}, 1500)
}
}, [isLoggedIn, isLoading])
}
[ ] 1.3 实现登录状态检查逻辑
[ ] 1.4 实现未登录时的提示和跳转
[ ] 1.5 更新@d8d/rencai-auth-ui/src/hooks/index.ts,导出useRequireAuth
@d8d/rencai-auth-ui/src/hooks/useAuth.tsx中的useQuery实现talentAuthClient.me.$get验证用户信息isLoggedIn和user)staleTime: Infinity配置(避免重复请求)[ ] 3.1 在首页(@d8d/rencai-dashboard-ui/src/pages/Dashboard/Dashboard.tsx)中使用useRequireAuth:
import { useRequireAuth } from '@d8d/rencai-auth-ui/hooks'
export const Dashboard: React.FC = () => {
useRequireAuth() // 添加这行
// ... 其他代码
}
[ ] 3.2 在个人信息页使用useRequireAuth
[ ] 3.3 在考勤记录页使用useRequireAuth
[ ] 3.4 在就业信息页使用useRequireAuth
[ ] 3.5 在设置页使用useRequireAuth
[ ] 3.6 确认登录页不使用useRequireAuth(避免死循环)
Taro.reLaunch跳转到登录页(清除页面栈,避免返回)tests/hooks/useRequireAuth.test.tsx:
tests/hooks/useAuth.test.tsx(如存在):
pnpm typecheck确保类型检查通过故事017.002完成状态:
用人方小程序参考实现:
mini-enterprise-auth-ui/src/hooks/useAuth.tsx (第31-55行):
const { data: user, isLoading } = useQuery<User | null, Error>({
queryKey: ['currentUser'],
queryFn: async () => {
const token = Taro.getStorageSync('enterprise_token')
if (!token) {
return null
}
try {
const response = await enterpriseAuthClient.me.$get({})
if (response.status !== 200) {
throw new Error('获取用户信息失败')
}
const user = await response.json()
Taro.setStorageSync('enterpriseUserInfo', JSON.stringify(user))
return user
} catch (error) {
Taro.removeStorageSync('enterprise_token')
Taro.removeStorageSync('enterpriseUserInfo')
return null
}
},
staleTime: Infinity,
refetchOnWindowFocus: false,
refetchOnReconnect: false,
})
mini-enterprise-auth-ui/src/hooks/useRequireAuth.ts:
import { useEffect } from 'react'
import Taro from '@tarojs/taro'
import { useAuth } from './useAuth'
export const useRequireAuth = () => {
const { isLoggedIn, isLoading } = useAuth()
useEffect(() => {
if (!isLoading && !isLoggedIn) {
Taro.showToast({
title: '请先登录',
icon: 'none',
duration: 1500
})
setTimeout(() => {
Taro.redirectTo({
url: '/pages/login/index'
})
}, 1500)
}
}, [isLoggedIn, isLoading])
}
来源: architecture/tech-stack.md
运行时和框架:
测试框架:
来源: architecture/mini-ui-package-standards.md
关键规范要求:
重要: UI包内部导入必须使用相对路径,不要使用别名。
正确示例:
// ✅ 正确: 使用相对路径导入同一包内的模块
import { useAuth } from './useAuth'
import { talentAuthClient } from '../api'
错误示例:
// ❌ 错误: 不要使用别名导入UI包内部的模块
import { useAuth } from '@/hooks/useAuth'
import { talentAuthClient } from '@/api'
use开头Taro.reLaunch跳转到登录页(清除页面栈)Taro.redirectTo跳转到其他页面(不返回)Taro.navigateTo打开新页面(可返回)来源: architecture/source-tree.md
rencai-auth-ui包结构:
mini-ui-packages/rencai-auth-ui/
├── src/
│ ├── api/
│ │ ├── talentAuthClient.ts
│ │ └── index.ts
│ ├── hooks/
│ │ ├── index.ts (本故事修改)
│ │ ├── useAuth.tsx (已存在,可能需要优化)
│ │ └── useRequireAuth.ts (本故事新增)
│ ├── pages/
│ │ └── LoginPage/
│ │ └── LoginPage.tsx
│ ├── types/
│ │ └── index.ts
│ └── index.ts
├── tests/
│ ├── hooks/
│ │ ├── useAuth.test.tsx (可能需要更新)
│ │ └── useRequireAuth.test.tsx (本故事新增)
│ └── pages/
│ └── LoginPage/
│ └── LoginPage.test.tsx
├── package.json
├── jest.config.cjs
└── tsconfig.json
mini-talent/src/pages/:
index/index.tsx - 首页/个人主页 ✅ 需要保护attendance/index.tsx - 考勤记录 ✅ 需要保护personal-info/index.tsx - 个人信息 ✅ 需要保护employment/index.tsx - 就业信息 ✅ 需要保护settings/index.tsx - 设置页 ✅ 需要保护login/index.tsx - 登录页 ❌ 不需要保护来源: architecture/mini-ui-testing-standards.md
测试框架: Jest (mini项目使用Jest,不是Vitest!)
测试要求:
useRequireAuth hook的功能pnpm typecheck确保类型检查通过Mock Taro API:
const mockReLaunch = jest.fn()
Taro.reLaunch = mockReLaunch
const mockToast = jest.fn()
Taro.showToast = mockToast
主要风险:
useRequireAuth可能导致死循环useRequireAuth的loading状态可能不同步缓解措施:
useRequireAuthTaro.reLaunch清除页面栈来源: architecture/testing-strategy.md
测试框架:
Hook测试:
useRequireAuth的登录状态检查集成测试:
回归测试:
pnpm typecheck确保类型检查通过# 运行所有测试
cd mini-ui-packages/rencai-auth-ui && pnpm test
# 运行特定测试
pnpm test --testNamePattern="useRequireAuth"
# 生成覆盖率报告
pnpm test:coverage
| 日期 | 版本 | 描述 | 作者 |
|---|---|---|---|
| 2025-12-26 | 1.0 | 创建故事文档 | James (Dev Agent) |
此部分由开发代理在实施过程中填写
Claude Sonnet (claude-sonnet-4-20250514)
无需特殊调试,实施过程顺利。
useRequireAuth实现,添加了loading状态检查和Toast提示useRequireAuth保护useRequireAuth保护(已有)useRequireAuth保护useRequireAuth保护useRequireAuth保护useRequireAuth单元测试(4个测试用例全部通过)rencai-auth-ui的tsconfig.json,添加了jest类型支持rencai-auth-ui的细粒度导出方式,其他包通过@d8d/rencai-auth-ui/hooks导入useRequireAuth只在非loading状态且未登录时才跳转,避免重复跳转Taro.redirectTo跳转到登录页,保留页面栈rencai-attendance-ui、rencai-employment-ui、rencai-settings-ui添加了@d8d/rencai-auth-ui依赖修改的文件:
mini-ui-packages/rencai-auth-ui/src/hooks/useAuth.tsx - 优化useRequireAuth实现mini-ui-packages/rencai-auth-ui/tsconfig.json - 添加jest类型支持mini-ui-packages/rencai-dashboard-ui/src/pages/Dashboard/Dashboard.tsx - 添加认证保护mini-ui-packages/rencai-attendance-ui/src/pages/AttendancePage/AttendancePage.tsx - 添加认证保护mini-ui-packages/rencai-employment-ui/src/pages/EmploymentPage/EmploymentPage.tsx - 添加认证保护mini-ui-packages/rencai-settings-ui/src/pages/SettingsPage/SettingsPage.tsx - 添加认证保护mini-ui-packages/rencai-attendance-ui/package.json - 添加@d8d/rencai-auth-ui依赖mini-ui-packages/rencai-employment-ui/package.json - 添加@d8d/rencai-auth-ui依赖mini-ui-packages/rencai-settings-ui/package.json - 添加@d8d/rencai-auth-ui依赖新增的文件:
mini-ui-packages/rencai-auth-ui/tests/hooks/useRequireAuth.test.tsx - useRequireAuth单元测试此部分由QA代理在审查完成后填写