# Bug 与问题总结 基于代码分析,发现并已修复/待关注的问题如下。 --- ## 一、已修复的 Bug ### 1. digital 首页登录注册异常 | 问题 | 原因 | 修复 | |------|------|------| | 登录/注册后状态异常 | Cookie 未设置 domain,跨子域失效 | 新增 `auth-cookie.ts`,生产环境支持 `AUTH_COOKIE_DOMAIN` | | auth/me 校验失败 | 使用已废弃的 `/api/users/refresh` | 改为 `POST /api/collections/users/auth-refresh` | | AuthModal 类型错误 | `pbSaveAuth` 传入 record 的 email 可能为 undefined | 显式传入 `{ id, email: email ?? "" }` | ### 2. cnomadcna 首页「加入游牧中国」流程不完整 | 问题 | 原因 | 修复 | |------|------|------| | 老用户有 VIP 仍被要求支付 | check-user 只返回 exists,未返回 vip | payjsapi 扩展 check-user 返回 `vip`、`user_id` | | 无 VIP 状态判断 | 前端未按 vip 分支处理 | HeroSection 在 exists 且 vip 时提示「您已是会员」 | ### 3. cnomadcna 支付成功后首页未显示登录 | 问题 | 原因 | 修复 | |------|------|------| | 支付完成返回首页仍显示未登录 | join/paid 未同步 localStorage,Navbar 不刷新 | join/paid 调用 `pbSaveAuth` 并派发 `auth:updated`,Navbar 监听并 refetch | ### 4. cnomadcna /join 提交申请 | 问题 | 原因 | 修复 | |------|------|------| | 未登录可提交 | getOrCreateUserId 无 cookie 时返回假 ID | 未登录返回 401,强制先登录 | | solan 未关联真实用户 | 使用 `user${Date.now()}` 作为 user_id | 使用 cookie 中的真实 userId | ### 5. 环境与配置 | 问题 | 原因 | 修复 | |------|------|------| | payjsapi 端口不一致 | 默认 8700,用户期望 8007 | run.py 支持 `PORT` 环境变量,默认 8007 | | 各项目默认支付 API 端口 | domain.config 使用 8700 | 统一改为 127.0.0.1:8007 | --- ## 二、潜在风险与待关注点 ### 1. PocketBase 管理员认证 - **现象**:check-user、ensure-user、vip/check 依赖 `POCKETBASE_EMAIL`、`POCKETBASE_PASSWORD` - **风险**:未配置时返回「服务配置错误」或 vip 始终为 false - **建议**:确保各项目 `.env.local` 中正确配置管理员账号 ### 2. ZPAY 回调地址 - **现象**:payjsapi 的 `BASE_URL` 需为 ZPAY 可访问的公网地址 - **风险**:本地调试时 ZPAY 无法回调 localhost/内网,支付成功但 PocketBase 不更新 - **建议**:本地测试可用 ngrok 暴露 8007,或部署到公网后测试回调 ### 3. 跨域 Cookie - **现象**:digital/meetup/vip 三站共享登录需 `AUTH_COOKIE_DOMAIN=.hackrobot.cn` - **风险**:生产环境未配置时,各子域登录态不共享 - **建议**:生产部署时在 `.env.local` 中设置 `AUTH_COOKIE_DOMAIN=.hackrobot.cn` ### 4. cnomadcna 新用户预创建逻辑 - **现象**:`isPrivateDevHost` 时新用户会先 ensure-user 再支付,生产环境用 `pending_hex(email)` 作为 user_id - **风险**:生产环境新用户支付成功后才创建 users,逻辑正确;本地预创建可能掩盖问题 - **建议**:保持现状,本地与生产流程略有差异 ### 5. digital 支付 return_url - **现象**:course 页「立即报名」的 return_url 为 `/course/0/0` - **风险**:支付返回后需轮询支付状态,usePayStatusPoll 依赖 `join_pay_order` cookie;digital 的 pay 路由可能未设置该 cookie - **建议**:确认 digital 支付返回后 course 页能正确轮询并刷新 VIP 状态 --- ## 三、代码质量与结构 | 类型 | 说明 | |------|------| | 重复逻辑 | 三个前端的 auth、pay、vip 逻辑相似,可考虑抽公共库 | | 硬编码 | 部分文案、金额、URL 散落代码中,建议集中到 config | | 错误处理 | 部分 API 的 catch 仅 `console.error`,未统一错误格式 | | 类型安全 | AuthModal 等处的 record 类型可再收紧 | --- ## 四、本次修改项(当前会话) 1. **支付测试价格**:所有前端默认 1 元(100 分) 2. **默认 zpay 渠道**:各项目 `.env.local` 设置 `PAYMENT_PROVIDER=zpay`,cnomadcna 默认 channel 改为 alipay 3. **.env.local**:为 digital、cnomadcna、nomadvip、payjsapi 创建本地调试配置 4. **cnomadcna 支付页**:/api/pay 返回的 HTML 使用 `opacity:0` 隐藏「正在跳转」提示,直接进入支付流程