# 首次登录修改密码 - 调试指南 ## 如何验证功能是否正常工作 ### 1. 检查数据库 ```sql -- 查看管理员的 is_paw 状态 SELECT id, account, name, is_paw FROM la_admin WHERE id = 1; ``` 确认 `is_paw` 字段存在且值为 0。 ### 2. 检查后端 API #### 2.1 登录接口 打开浏览器开发者工具(F12),切换到 Network 标签。 登录后查看 `/adminapi/login/account` 接口的响应: ```json { "code": 1, "msg": "success", "data": { "name": "管理员", "avatar": "...", "role_name": "超级管理员", "token": "...", "is_paw": 0 // ← 确认这个字段存在且为 0 } } ``` #### 2.2 获取用户信息接口 刷新页面后,查看 `/adminapi/auth.admin/mySelf` 接口的响应: ```json { "code": 1, "msg": "success", "data": { "user": { "id": 1, "account": "admin", "name": "管理员", "is_paw": 0, // ← 确认这个字段存在且为 0 // ... 其他字段 }, "menu": [...], "permissions": [...] } } ``` ### 3. 检查前端状态 在浏览器控制台(Console)中输入: ```javascript // 查看 userStore 的状态 const userStore = window.$nuxt?.$store?.state?.user || JSON.parse(localStorage.getItem('pinia-user') || '{}') console.log('isPaw:', userStore.isPaw) console.log('userInfo:', userStore.userInfo) ``` 或者在 Vue DevTools 中查看 Pinia store 的状态。 ### 4. 检查路由守卫 在 `admin/src/permission.ts` 文件中添加调试日志: ```typescript router.beforeEach(async (to, from, next) => { const userStore = useUserStore() console.log('=== 路由守卫 ===') console.log('目标路径:', to.path) console.log('isPaw:', userStore.isPaw) console.log('hasUserInfo:', Object.keys(userStore.userInfo).length !== 0) // ... 其他代码 }) ``` 刷新页面,在控制台查看输出。 ### 5. 完整测试流程 #### 步骤 1:设置测试账号 ```sql UPDATE la_admin SET is_paw = 0 WHERE id = 1; ``` #### 步骤 2:清除浏览器缓存 - 清除 localStorage - 清除 sessionStorage - 清除 Cookies - 或者使用无痕模式 #### 步骤 3:登录 1. 打开浏览器开发者工具(F12) 2. 切换到 Network 标签 3. 登录系统 4. 查看 `/adminapi/login/account` 接口响应,确认 `is_paw: 0` 5. 观察是否跳转到 `/change-password` #### 步骤 4:测试 URL 绕过 1. 在地址栏输入 `/workbench/index` 2. 按回车 3. 观察是否被拦截并跳转回 `/change-password` #### 步骤 5:测试刷新 1. 在修改密码页面按 F5 刷新 2. 查看 Network 标签,确认调用了 `/adminapi/auth.admin/mySelf` 接口 3. 查看接口响应,确认 `is_paw: 0` 4. 观察是否仍然停留在 `/change-password` #### 步骤 6:修改密码 1. 输入新密码(至少 6 位) 2. 点击"确认修改" 3. 观察是否提示"密码修改成功,请重新登录" 4. 观察是否跳转到登录页 #### 步骤 7:验证数据库 ```sql SELECT id, account, is_paw FROM la_admin WHERE id = 1; -- 应该显示 is_paw = 1 ``` #### 步骤 8:使用新密码登录 1. 使用新密码登录 2. 观察是否直接进入系统(不跳转到修改密码页面) ## 常见问题排查 ### 问题:登录后没有跳转到修改密码页面 **排查步骤:** 1. 检查登录接口响应是否包含 `is_paw` 字段 ```javascript // 在 Network 标签查看 /adminapi/login/account 响应 ``` 2. 检查前端是否保存了 `isPaw` 状态 ```javascript // 在 Console 输入 console.log(useUserStore().isPaw) ``` 3. 检查登录页面代码 ```typescript // admin/src/views/account/login.vue const result: any = await userStore.login(formData) if (result.is_paw === 0) { router.push('/change-password') } ``` ### 问题:刷新后进入系统 **排查步骤:** 1. 检查 `getUserInfo` 接口是否返回 `is_paw` ```javascript // 在 Network 标签查看 /adminapi/auth.admin/mySelf 响应 // 确认 data.user.is_paw 存在 ``` 2. 检查后端代码 ```php // server/app/adminapi/logic/auth/AdminLogic.php // detail() 方法的 field 数组中是否包含 'is_paw' ``` 3. 检查前端是否更新状态 ```typescript // admin/src/stores/modules/user.ts getUserInfo() { return new Promise((resolve, reject) => { getUserInfo().then((data) => { this.isPaw = data.user.is_paw ?? 1 // 确认这行存在 }) }) } ``` 4. 检查路由守卫逻辑 ```typescript // admin/src/permission.ts // 确认在 getUserInfo() 之后检查 isPaw await userStore.getUserInfo() if (userStore.isPaw === 0) { next({ path: changePasswordPath }) return } ``` ### 问题:可以通过 URL 绕过 **排查步骤:** 1. 检查路由守卫是否正确配置 ```typescript // admin/src/permission.ts // 确认路由守卫在所有路由跳转时都会执行 ``` 2. 在路由守卫中添加日志 ```typescript router.beforeEach(async (to, from, next) => { console.log('路由守卫执行:', to.path, 'isPaw:', userStore.isPaw) // ... }) ``` 3. 检查是否有其他路由配置覆盖了守卫 ## 调试技巧 ### 1. 使用 Vue DevTools 安装 Vue DevTools 浏览器插件,可以实时查看: - Pinia store 状态 - 路由信息 - 组件状态 ### 2. 添加断点 在关键位置添加 `debugger` 语句: ```typescript // admin/src/permission.ts router.beforeEach(async (to, from, next) => { debugger // 浏览器会在这里暂停 const userStore = useUserStore() // ... }) ``` ### 3. 查看完整的请求响应 在 Network 标签中: - 点击请求 - 查看 Response 标签 - 确认返回的数据结构 ### 4. 清除缓存测试 每次测试前清除缓存,确保测试环境干净: ```javascript // 在 Console 中执行 localStorage.clear() sessionStorage.clear() location.reload() ``` ## 成功标准 ✅ 登录后自动跳转到修改密码页面 ✅ 无法通过输入 URL 绕过 ✅ 刷新后仍然在修改密码页面 ✅ 修改密码后 `is_paw` 更新为 1 ✅ 使用新密码登录后正常进入系统