# 017 任务清单 ## 2026-09-08 增量(实现中) - [x] T23 骑手/商家 Apple、Google 独立凭证配置、角色绑定、会话签发及用户端兼容回归。 - [x] T24 兼容用户旧 LINE provider、无 provider 回调与旧/新绑定数据。 - [x] T25 更新三端接入文档、环境配置与 SQL 人工执行边界。 - [ ] T26 JDK 21 定向测试、关联回归、模块构建与最终差异检查。 - [x] T27 业务 LINE 服务端 state 签发/单次消费、两条 code 入口校验及旧用户协议兼容。 - [ ] T28 骑手/商家 App 页面、SDK、四语言和回跳 state 比对接入;源码路径待提供。 ### 本轮验证记录 - JDK 21 定向测试及 package:79 tests,0 failures/errors,所有 reactor 模块 SUCCESS。覆盖账号角色、短信绑定、用户原登录/注册、旧 LINE 协议、三端 audience、签名与 state。日志:`ruoyi-admin/target/oauth-final-verification.log`。 - 另运行完整 `mvn -pl ruoyi-admin -am package`:`ruoyi-system` 83 tests 全通过,`ruoyi-admin` 419 tests 中 418 通过、1 error。仍是既有 `PosOrderQsOprateControllerTest` 未注入 `UserService` 导致 NPE,未修改该无关测试,T26 保留未勾选。日志:`ruoyi-admin/target/oauth-regression.log`。 - 新业务账号绑定必须验证实际短信码,用户原校验行为保持兼容;固定短信码拒绝用例已先观察失败再验证修复。 - 用户 App 源码未修改。业务 App 源码、真实渠道配置和真机端到端验证未完成;未执行任何数据库 SQL、部署或密钥轮换。 - 既有实现已包含在 `af8cc41`;本轮增量保留工作区,尚未提交。 > 顺序执行;每步完成后编译验证。 - [x] T1 数据模型:`updatesql/sql.md` 加 `info_user_oauth` 建表(含 uk_provider_uid 唯一索引、idx_user_id)。 - [x] T2 实体:`InfoUserOauth.java`(@TableName=info_user_oauth,字段 id/userId/provider/providerUid/createTime)。 - [x] T3 mapper:`InfoUserOauthMapper extends BaseMapper`(无 XML)。 - [x] T4 LoginUserDto 加 `provider` 字段。 - [x] T5 JwtUtil.setToken(tokenKey, LoginUserDto) 加 `provider` claim(非空才写)。 - [x] T6 配置:application.yml 加 `oauth.apple.clientId/jwks-url`、`oauth.google.clientId/tokeninfo-url`、`oauth.line.profile-url`。 - [x] T7 依赖:ruoyi-admin/pom.xml 加 `nimbus-jose-jwt`。 - [x] T8 OAuthVerifyService:`verify(provider, credential)` → providerUid;Apple(nimbus 验 ES256)、Google(tokeninfo)、LINE(v2/profile),校 audience/iss/exp。 - [x] T9 DTO:OAuthLoginDto、OAuthBindDto。 - [x] T10 InfoUserController.oauthLogin:校验→查 oauth→命中签 token / 未命中缓存 tempKey 返 needPhone。 - [x] T11 InfoUserController.oauthBindPhone:取 providerUid + 验短信→关联/新建→写 oauth→签 token。 - [x] T12 编译验证(JDK21):ruoyi-admin + ruoyi-system + ruoyi-common。 ## 联调待办(开发提供配置后) - [ ] 部署环境提供真实 Apple bundleId/clientId、Google clientId,以及 `LINE_USER_CLIENT_SECRET`、`LINE_RIDER_CLIENT_SECRET`、`LINE_MERCHANT_CLIENT_SECRET`;Secret 不写入仓库。 - [ ] 部署前轮换 Git 历史中曾出现的旧 LINE Channel Secret。 - [ ] 使用真实 Apple、Google、三套 LINE Channel token/code 完成端到端验证(Apple 需真机/测试机 Sign in with Apple)。 - [ ] 三个前端 App 完成登录入口、首次绑手机、provider/回跳 scheme 分流及 i18n 联调。 - [ ] 三端统一升级 `state` CSRF 协议:服务端签发并单次消费,App 保存发起值并在回跳时比对。 ## 代码评审修复 (2026-07-30) 评审发现并修复(均已 JDK21 编译通过): - [x] **HTTP 超时**:`OAuthVerifyService.httpGet` 原用 `HttpClients.createDefault()` 无超时,provider 慢/不可达会拖垮请求线程池 → 加 `RequestConfig`(连接 5s / 读取 10s / 获取连接 5s)。 - [x] **停用账号拦截**:`oauthBindPhone` 用 `getuser(phone)` 只滤 del_flag、不滤 status,停用账号(status≠0)能通过三方绑定绕过停用 → 加 `status!=0` 拦截(与 `lodeing` / `oauthLogin` 已绑定路径一致),文案复用 `no.user.stop`。 - [x] **Apple audience**:原 `aud.get(0)` 在多 audience 时可能漏判 → 改 `aud.contains(appleClientId)`。 - [x] **i18n 化(裸中文 → message key)**:新增 `no.oauth.*` 共 10 个 key,写入 5 份 properties(`messages` / `zh_CN` / `zh_TW` / `en_US` / `vi`);`OAuthVerifyService` 异常文案与 `InfoUserController` 提示全部走 `MessageUtils.message`,与 `lodeing` 风格一致。新增 key: - 控制器:`no.oauth.provider.blank` / `needphone` / `tempkey.missing` / `tempkey.expired` - 校验服务:`no.oauth.credential.blank` / `provider.unsupported` / `token.invalid` / `token.expired` / `audience.mismatch` / `verify.fail`(带 `{0}` 渠道名;异常详情仅记录在服务端日志,不返回客户端) ## 用户/骑手/商家 LINE 登录增量(2026-09-04) - [x] T13 配置三组 LINE Channel:`line_user`、`line_rider`、`line_merchant`,共用 token/profile URL,分别配置 redirect URI 和 App scheme。 - [x] T14 `OAuthVerifyService` 按 provider 白名单选择对应 Channel ID、Secret、redirect URI,并使用完全相同的 redirect URI 换 token。 - [x] T15 共用 `GET /auth/line/callback`,接收 provider/code/state,按 provider 分流验证、绑定查询、token key 和 App 回跳。 - [x] T16 `oauthLogin` / `oauthBindPhone` 支持三个 LINE provider;骑手只绑定 `userType=2`,商家只绑定 `userType=1/3/4/5`,均不得自动创建。 - [x] T17 商家/骑手/子账号统一使用 `tel_phone`;业务层增加有效账号手机号唯一检查,修改时排除自身,软删除后允许复用。 - [x] T18 覆盖 `addqishou`、`addshanghu`、`Bindingphone`、`setuser`、平台新增/修改、`stall/addOwner` 及商家子账号新增入口。 - [x] T19 SQL:先预检 provider 和有效业务账号手机号冲突,再将现有 `info_user_oauth.provider='line'` 迁移为 `line_user`,并把业务账号 `phone` 补入 `tel_phone`,不清除原字段。 - [x] T20 更新 LINE 前端接入说明:原授权方式不变,三个端分别增加 provider 参数并使用对应 Channel ID/回跳 scheme。 - [x] T21 编写并运行定向测试,覆盖 provider 分流、角色限制、手机号唯一规则(2026-09-04:31 tests,0 failures/errors)。 - [x] T22 使用 JDK 21 编译 `ruoyi-common`、`ruoyi-system`、`ruoyi-admin`(2026-09-04 reactor package SUCCESS);真实 LINE 端到端联调保留为外部待办。 > 2026-09-04 另执行完整 reactor test:`ruoyi-system` 53 tests 全通过,`ruoyi-admin` 371 tests 中 370 通过、1 error。失败项为既有 `PosOrderQsOprateControllerTest.newTasksContainOnlyPaidOrdersWaitingForRiderBeforeMerchantAcceptance` 未注入 `UserService` 导致 NPE,与 017 修改文件及定向测试无关,本次不跨范围修改。 > 交付记录(2026-09-04):最终代码复核未发现剩余 Critical/Important;`git diff --check` 通过;数据库迁移未执行,须先运行 `updatesql/sql.md` 中两项冲突预检再由开发者手工执行;017 修改当前保留在工作区,尚未提交。