|
|
@@ -0,0 +1,342 @@
|
|
|
+# 商家门店分管账号任务清单
|
|
|
+
|
|
|
+> **执行要求:** 按任务顺序实施;每个后端任务遵循测试先行,先确认定向测试失败,再写最小实现并复测。提交标题和正文使用中文。
|
|
|
+
|
|
|
+**输入**:[spec.md](spec.md)、[plan.md](plan.md)、[research.md](research.md)、[data-model.md](data-model.md)、[API 契约](contracts/api.md)
|
|
|
+
|
|
|
+## 全局约束
|
|
|
+
|
|
|
+- JDK 使用 `C:\Users\qmj\.jdks\graalvm-jdk-21.0.7`。
|
|
|
+- 模块依赖保持 `ruoyi-admin -> ruoyi-system`。
|
|
|
+- Controller 请求使用明确 DTO、`@RequestBody`、`@RequestHeader` 和显式查询参数,不使用 `Map`。
|
|
|
+- 数据库变更只写入 `updatesql/sql.md`,不直接执行。
|
|
|
+- 两个 Vue 仓库新增文案同步维护简中、繁中、英文、越南语并保持 CRLF。
|
|
|
+- 保留工作区已有订单状态和推送调整;暂存前逐文件核对,禁止混入 `.claude/homunculus/observations.jsonl`。
|
|
|
+- 密码、Token、CID 和支付资料不得出现在日志、错误响应或测试快照中。
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## Phase 1:数据模型与授权基础
|
|
|
+
|
|
|
+### T001 [US1] 建立分管账号字段和账号—店铺关联模型
|
|
|
+
|
|
|
+**文件:**
|
|
|
+
|
|
|
+- 修改:`ruoyi-system/src/main/java/com/ruoyi/system/domain/InfoUser.java`
|
|
|
+- 创建:`ruoyi-system/src/main/java/com/ruoyi/system/domain/constants/MerchantAccountConstants.java`
|
|
|
+- 修改:`ruoyi-system/src/main/resources/mapper/infouser/InfoUserMapper.xml`
|
|
|
+- 创建:`ruoyi-system/src/main/java/com/ruoyi/system/domain/MerchantSubaccountStore.java`
|
|
|
+- 创建:`ruoyi-system/src/main/java/com/ruoyi/system/mapper/MerchantSubaccountStoreMapper.java`
|
|
|
+- 创建:`ruoyi-system/src/main/resources/mapper/infouser/MerchantSubaccountStoreMapper.xml`
|
|
|
+- 创建:`ruoyi-system/src/main/java/com/ruoyi/system/service/IMerchantSubaccountStoreService.java`
|
|
|
+- 创建:`ruoyi-system/src/main/java/com/ruoyi/system/service/impl/MerchantSubaccountStoreServiceImpl.java`
|
|
|
+- 创建:`ruoyi-system/src/test/java/com/ruoyi/system/mapper/MerchantSubaccountStoreMapperXmlTest.java`
|
|
|
+- 修改:`updatesql/sql.md`
|
|
|
+
|
|
|
+**产出接口:**
|
|
|
+
|
|
|
+```java
|
|
|
+public static final String MerchantAccountConstants.SUBACCOUNT_USER_TYPE = "5";
|
|
|
+
|
|
|
+Long InfoUser.getMerchantOwnerId();
|
|
|
+String InfoUser.getSubaccountStatus();
|
|
|
+Date InfoUser.getLastLoginAt();
|
|
|
+
|
|
|
+List<Long> MerchantSubaccountStoreMapper.selectStoreIdsBySubaccountUserId(Long subaccountUserId);
|
|
|
+List<InfoUser> MerchantSubaccountStoreMapper.selectEligibleSubaccountsByStoreId(Long storeId);
|
|
|
+int MerchantSubaccountStoreMapper.deleteBySubaccountUserId(Long subaccountUserId);
|
|
|
+int MerchantSubaccountStoreMapper.insertBatch(List<MerchantSubaccountStore> relations);
|
|
|
+```
|
|
|
+
|
|
|
+- [ ] 写 XML 结构测试,断言 `merchant_owner_id`、`subaccount_status`、`last_login_at` 映射存在,并断言关联表查询使用参数绑定和唯一字段。
|
|
|
+- [ ] 运行 `mvn -pl ruoyi-system -Dtest=MerchantSubaccountStoreMapperXmlTest test`,确认因实体、Mapper 或 XML 尚不存在而失败。
|
|
|
+- [ ] 为 `InfoUser` 增加三个字段、访问器和 `toString()` 映射;在 `MerchantAccountConstants` 定义类型 1/5 和双重状态常量,禁止在多个 Controller 重复魔法字符串。
|
|
|
+- [ ] 实现关联实体、Mapper XML 和 Service;批量插入为空集合时直接返回,不生成非法 SQL。
|
|
|
+- [ ] 在 `updatesql/sql.md` 追加 2026-08-28 迁移:三个 `info_user` 字段、所属主账号索引、关联表和两个索引,不执行 SQL。
|
|
|
+- [ ] 复跑定向测试并执行 `git diff --check -- ruoyi-system updatesql/sql.md`。
|
|
|
+- [ ] 暂存本任务文件并提交:`git commit -m "建立商家分管账号数据模型"`。
|
|
|
+
|
|
|
+### T002 [US2][US4] 实现集中式商家门店访问服务
|
|
|
+
|
|
|
+**文件:**
|
|
|
+
|
|
|
+- 创建:`ruoyi-system/src/main/java/com/ruoyi/system/service/MerchantStoreAccessService.java`
|
|
|
+- 创建:`ruoyi-system/src/test/java/com/ruoyi/system/service/MerchantStoreAccessServiceTest.java`
|
|
|
+- 按需修改:`ruoyi-system/src/main/java/com/ruoyi/system/mapper/InfoUserMapper.java`
|
|
|
+- 按需修改:`ruoyi-system/src/main/java/com/ruoyi/system/mapper/PosStoreMapper.java`
|
|
|
+
|
|
|
+**产出接口:**
|
|
|
+
|
|
|
+```java
|
|
|
+public final class MerchantAccessContext {
|
|
|
+ Long loginUserId();
|
|
|
+ Long ownerUserId();
|
|
|
+ boolean owner();
|
|
|
+ Set<Long> storeIds();
|
|
|
+}
|
|
|
+
|
|
|
+MerchantAccessContext resolve(Long loginUserId);
|
|
|
+void requireOwner(Long loginUserId);
|
|
|
+Set<Long> getAccessibleStoreIds(Long loginUserId);
|
|
|
+void requireStoreAccess(Long loginUserId, Long storeId);
|
|
|
+PosOrder requireOrderAccess(Long loginUserId, Long orderId);
|
|
|
+PosFood requireFoodAccess(Long loginUserId, Long foodId);
|
|
|
+```
|
|
|
+
|
|
|
+- [ ] 写单元测试覆盖:类型 1 主账号获得全部自有店铺;类型 5 只获得授权店铺;类型 5 双重状态任一停用、所属主账号停用、跨商家关系、门店所有者变化均拒绝。
|
|
|
+- [ ] 增加订单和商品测试:请求参数中的 `mdId` 与实体真实归属不一致时,以数据库实体的 `mdId` 为准拒绝越权。
|
|
|
+- [ ] 运行 `mvn -pl ruoyi-system -Dtest=MerchantStoreAccessServiceTest test`,确认服务尚不存在而失败。
|
|
|
+- [ ] 实现服务并使用 `ServiceException` 返回国际化键;每次调用重新读取当前账号和授权,不把 `storeIds` 缓存进 Token。
|
|
|
+- [ ] 复跑测试,确认授权取消后无需重新登录即可生效。
|
|
|
+- [ ] 暂存本任务文件并提交:`git commit -m "集中商家门店数据权限校验"`。
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## Phase 2:账号生命周期、平台隔离与登录
|
|
|
+
|
|
|
+### T003 [US1][US4] 实现商家端分管账号管理接口
|
|
|
+
|
|
|
+**文件:**
|
|
|
+
|
|
|
+- 创建:`ruoyi-admin/src/main/java/com/ruoyi/app/user/MerchantSubaccountController.java`
|
|
|
+- 创建:`ruoyi-admin/src/main/java/com/ruoyi/app/user/MerchantSubaccountApplicationService.java`
|
|
|
+- 创建:`ruoyi-admin/src/main/java/com/ruoyi/app/user/dto/MerchantSubaccountCreateRequest.java`
|
|
|
+- 创建:`ruoyi-admin/src/main/java/com/ruoyi/app/user/dto/MerchantSubaccountUpdateRequest.java`
|
|
|
+- 创建:`ruoyi-admin/src/main/java/com/ruoyi/app/user/dto/MerchantSubaccountPasswordRequest.java`
|
|
|
+- 创建:`ruoyi-admin/src/main/java/com/ruoyi/app/user/dto/MerchantSubaccountStatusRequest.java`
|
|
|
+- 创建:`ruoyi-admin/src/main/java/com/ruoyi/app/user/dto/MerchantSubaccountView.java`
|
|
|
+- 创建:`ruoyi-admin/src/test/java/com/ruoyi/app/user/MerchantSubaccountControllerTest.java`
|
|
|
+- 修改:四个 `ruoyi-admin/src/main/resources/i18n/messages_*.properties`
|
|
|
+
|
|
|
+**接口:**
|
|
|
+
|
|
|
+```text
|
|
|
+GET /merchant/subaccounts
|
|
|
+POST /merchant/subaccounts
|
|
|
+PUT /merchant/subaccounts/{subaccountUserId}
|
|
|
+PUT /merchant/subaccounts/{subaccountUserId}/password
|
|
|
+PUT /merchant/subaccounts/{subaccountUserId}/status
|
|
|
+```
|
|
|
+
|
|
|
+- [ ] 写 Controller/Service 测试,覆盖手机号全局重复、空姓名、空密码、空店铺、跨商家店铺、非主账号调用、修改他人分管账号、事务中任一授权失败整体回滚。
|
|
|
+- [ ] 写状态测试,断言主账号启停只修改 `subaccountStatus`,不能修改平台 `status`;密码重置和停用必须撤销 App/PC Redis 会话。
|
|
|
+- [ ] 运行 `mvn -pl ruoyi-admin -am -Dtest=MerchantSubaccountControllerTest -Dsurefire.failIfNoSpecifiedTests=false test`,确认 RED。
|
|
|
+- [ ] 实现 DTO 和接口;手机号规范化后同时写入 `user_name` 与 `phone`,固定 `user_type=5`、`audit_status=1`、`status=0`、`subaccount_status=0`,不创建钱包和商户资质。
|
|
|
+- [ ] 账号插入与授权批量写入使用同一事务;更新授权先验证完整店铺集合,再替换关系。
|
|
|
+- [ ] 四语种补齐账号重复、无权管理、店铺越权、平台停用等业务错误。
|
|
|
+- [ ] 复跑测试并提交:`git commit -m "新增商家分管账号管理接口"`。
|
|
|
+
|
|
|
+### T004 [US5] 实现平台下属账号视图并隔离商家管理
|
|
|
+
|
|
|
+**文件:**
|
|
|
+
|
|
|
+- 创建:`ruoyi-admin/src/main/java/com/ruoyi/app/user/MerchantSubaccountAdminController.java`
|
|
|
+- 创建:`ruoyi-admin/src/test/java/com/ruoyi/app/user/MerchantSubaccountAdminControllerTest.java`
|
|
|
+- 修改:`ruoyi-admin/src/test/java/com/ruoyi/app/user/InfoUserControllerTest.java`
|
|
|
+- 按需修改:`ruoyi-admin/src/main/java/com/ruoyi/app/user/InfoUserController.java`
|
|
|
+
|
|
|
+**接口:**
|
|
|
+
|
|
|
+```text
|
|
|
+GET /infouser/merchant-subaccounts?merchantUserId={id}
|
|
|
+PUT /infouser/merchant-subaccounts/{subaccountUserId}/platform-status
|
|
|
+```
|
|
|
+
|
|
|
+- [ ] 写平台接口测试:列表只接受类型 1 主账号;只返回其类型 5 子账号;响应不含密码、CID、Token 和商户资质。
|
|
|
+- [ ] 写平台状态测试:只修改 `status`,停用撤销会话;平台恢复不能覆盖 `subaccountStatus=1`。
|
|
|
+- [ ] 扩展平台商家列表/导出服务测试,插入或模拟类型 5 后,`userType=1` 结果和总数不包含分管账号;平台通用新增/编辑不能把账号类型写成 5。
|
|
|
+- [ ] 运行两个定向测试类确认 RED,再实现 `@PreAuthorize` 列表/编辑权限和类型保护。
|
|
|
+- [ ] 复跑测试并提交:`git commit -m "隔离平台商家与分管账号管理"`。
|
|
|
+
|
|
|
+### T005 [US1][US4][US5] 扩展商家登录、退出和会话失效
|
|
|
+
|
|
|
+**文件:**
|
|
|
+
|
|
|
+- 修改:`ruoyi-admin/src/main/java/com/ruoyi/app/user/InfoUserController.java`
|
|
|
+- 修改:`ruoyi-admin/src/test/java/com/ruoyi/app/user/InfoUserControllerTest.java`
|
|
|
+
|
|
|
+**行为:**
|
|
|
+
|
|
|
+```java
|
|
|
+// shanglodeing 在签发 token 前必须满足
|
|
|
+user.getStatus().equals("0");
|
|
|
+// 类型 5 还必须满足 subaccountStatus=0 且 owner.status=0
|
|
|
+```
|
|
|
+
|
|
|
+- [ ] 写测试覆盖:类型 5 正常登录;自身平台停用、主账号停用、主账号控制停用分别拒绝;类型 1 被平台停用也拒绝;失败分支不能返回成功响应或 Token。
|
|
|
+- [ ] 写成功测试,断言更新 CID 和 `lastLoginAt`,使用商家 App/PC token 前缀;退出只删除当前 JTI 会话。
|
|
|
+- [ ] 运行 `InfoUserControllerTest` 确认 RED。
|
|
|
+- [ ] 将 `shanglodeing` 的类型集合扩展为 1、3、4、5,并在密码验证成功、Token 签发前调用账号可用性校验;修正当前捕获异常后落入成功响应的分支。
|
|
|
+- [ ] 新增 `POST /infouser/user/merchantLogout`,使用 `@RequestHeader String token`,验证并删除 JTI,不记录 token。
|
|
|
+- [ ] 复跑测试并提交:`git commit -m "完善商家账号登录与停用校验"`。
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## Phase 3:店铺、商品、订单与退款权限
|
|
|
+
|
|
|
+### T006 [US2] 收口店铺和商品权限
|
|
|
+
|
|
|
+**文件:**
|
|
|
+
|
|
|
+- 修改:`ruoyi-admin/src/main/java/com/ruoyi/app/mendian/PosStoreController.java`
|
|
|
+- 修改:`ruoyi-admin/src/main/java/com/ruoyi/app/mendian/PosFoodController.java`
|
|
|
+- 修改:`ruoyi-admin/src/main/java/com/ruoyi/app/mendian/PosFenleiController.java`
|
|
|
+- 修改:`ruoyi-admin/src/main/java/com/ruoyi/app/mendian/FoodSpecController.java`
|
|
|
+- 修改:`ruoyi-admin/src/test/java/com/ruoyi/app/mendian/PosStoreControllerTest.java`
|
|
|
+- 创建:`ruoyi-admin/src/test/java/com/ruoyi/app/mendian/PosFoodControllerAccessTest.java`
|
|
|
+
|
|
|
+**必须保护的有效商家端能力:**
|
|
|
+
|
|
|
+```text
|
|
|
+店铺:getmystorelist、storelistlist、getstore、addmendian、delemendian、saveMdBusinessHours、营业状态/资料修改
|
|
|
+商品:getidlist、getFoodPageList、setposfood、delefood、changerecommend
|
|
|
+分类:getfenlei、addfenlei、delefenlei
|
|
|
+规格:foodSpecPageList、saveFoodSpec、deleteFoodSpec、changeOpen、changeSpecValueOpen
|
|
|
+```
|
|
|
+
|
|
|
+- [ ] 为主账号和类型 5 分别写列表测试:主账号返回全部自有店铺,分管账号返回所有授权店铺且不需要当前店铺。
|
|
|
+- [ ] 写越权测试:分管账号新增/删除店铺被拒;可编辑授权店铺;伪造 `userId`、`mdId`、商品 ID、分类 ID 或规格 ID 不能访问未授权店铺。
|
|
|
+- [ ] 运行 `PosStoreControllerTest,PosFoodControllerAccessTest` 确认 RED。
|
|
|
+- [ ] 为有效写接口补 `@RequestHeader String token` 和明确 DTO/参数;授权使用目标实体真实门店,忽略请求体中的所有者字段。
|
|
|
+- [ ] `addmendian` 调用 `requireOwner` 并由后端写入当前主账号 ID;分管账号前端隐藏入口不能替代该校验。
|
|
|
+- [ ] 复跑测试并提交:`git commit -m "限制店铺商品操作到授权门店"`。
|
|
|
+
|
|
|
+### T007 [US2] 收口商家订单操作和退款权限
|
|
|
+
|
|
|
+**文件:**
|
|
|
+
|
|
|
+- 修改:`ruoyi-admin/src/main/java/com/ruoyi/app/order/PosOrderShOprateController.java`
|
|
|
+- 修改:`ruoyi-admin/src/main/java/com/ruoyi/app/order/PosOrderController.java`
|
|
|
+- 修改:`ruoyi-admin/src/test/java/com/ruoyi/app/order/PosOrderShOprateControllerTest.java`
|
|
|
+- 按实际有效退款调用修改对应支付 Controller/Service 的授权入口,不改变支付渠道状态机。
|
|
|
+
|
|
|
+**必须保护的能力:**
|
|
|
+
|
|
|
+```text
|
|
|
+orderList、getstoreorderlist、订单详情、商家确认/出餐/取消、现金确认、发票查看/作废、现有退款入口
|
|
|
+```
|
|
|
+
|
|
|
+- [ ] 写列表测试:类型 5 按授权 `md_id IN (...)` 查询;同主商家的未授权店铺订单不返回。
|
|
|
+- [ ] 写操作测试:订单的 `shId` 属于主账号但 `mdId` 未授权时仍拒绝;授权门店订单继续执行现有骑手先接单、支付成功后开放和状态流转规则。
|
|
|
+- [ ] 写退款测试:先通过 `requireOrderAccess`,再进入现有渠道退款校验;越权请求不得创建退款记录或改变订单状态。
|
|
|
+- [ ] 运行 `PosOrderShOprateControllerTest` 确认 RED。
|
|
|
+- [ ] 用集中权限服务替换仅按当前 `userId=shId` 的判断;主账号使用 owner ID,分管账号使用授权门店集合。
|
|
|
+- [ ] 复跑订单定向测试及现有支付退款测试,提交:`git commit -m "限制订单退款操作到授权门店"`。
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## Phase 4:通知路由
|
|
|
+
|
|
|
+### T008 [US3] 将商家通知路由到在线分管账号
|
|
|
+
|
|
|
+**文件:**
|
|
|
+
|
|
|
+- 创建:`ruoyi-admin/src/main/java/com/ruoyi/app/order/MerchantNotificationRouter.java`
|
|
|
+- 创建:`ruoyi-admin/src/test/java/com/ruoyi/app/order/MerchantNotificationRouterTest.java`
|
|
|
+- 修改:`ruoyi-admin/src/main/java/com/ruoyi/app/order/UserOrderController.java`
|
|
|
+- 修改:`ruoyi-admin/src/main/java/com/ruoyi/app/order/PosOrderQsOprateController.java`
|
|
|
+- 修改:`ruoyi-admin/src/main/java/com/ruoyi/app/order/PosOrderController.java`
|
|
|
+- 修改:`ruoyi-admin/src/main/java/com/ruoyi/app/order/DeliveryOrderNotificationService.java`
|
|
|
+- 修改:`ruoyi-admin/src/test/java/com/ruoyi/app/order/DeliveryOrderNotificationServiceTest.java`
|
|
|
+
|
|
|
+**产出接口:**
|
|
|
+
|
|
|
+```java
|
|
|
+void sendStoreNotification(Long storeId, Long ownerUserId,
|
|
|
+ String titleKey, String contentKey,
|
|
|
+ String body, String orderNo);
|
|
|
+```
|
|
|
+
|
|
|
+- [ ] 写测试覆盖:两个符合条件分管账号全部收到各自消息;主账号不重复;无人具有 App 会话/CID 时主账号兜底;平台或主账号停用的分管账号排除;相同 CID 外部推送去重。
|
|
|
+- [ ] 写失败隔离测试:一个接收者推送抛异常,其他账号仍写消息并尝试推送;门店为空时只向 owner 兜底。
|
|
|
+- [ ] 运行 `MerchantNotificationRouterTest,DeliveryOrderNotificationServiceTest` 确认 RED。
|
|
|
+- [ ] 实现接收者解析、Redis App 会话检查、逐账号 `PushEvent` 入库和 CID 去重;不要新增 Android FCM。
|
|
|
+- [ ] 将支付成功/订单开放、骑手接单、订单取消等当前有效商家推送调用替换为路由服务,并保留现有订单状态调整。
|
|
|
+- [ ] 复跑通知和订单生命周期测试,提交:`git commit -m "按门店分管账号路由商家通知"`。
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## Phase 5:商家端与平台端
|
|
|
+
|
|
|
+### T009 [US1][US2] 增加商家端分管账号管理与角色界面
|
|
|
+
|
|
|
+**文件:**
|
|
|
+
|
|
|
+- 创建:`E:/QtwCode/foodie/foodie-store/src/api/subaccount.js`
|
|
|
+- 创建:`E:/QtwCode/foodie/foodie-store/src/views/MerchantSubaccount.vue`
|
|
|
+- 修改:`E:/QtwCode/foodie/foodie-store/src/router/index.js`
|
|
|
+- 修改:`E:/QtwCode/foodie/foodie-store/src/components/Aside.vue`
|
|
|
+- 修改:`E:/QtwCode/foodie/foodie-store/src/components/Header.vue`
|
|
|
+- 修改:`E:/QtwCode/foodie/foodie-store/src/views/AcidrollingCapacity.vue`
|
|
|
+- 修改:`E:/QtwCode/foodie/foodie-store/src/api/store.js`
|
|
|
+- 修改:`E:/QtwCode/foodie/foodie-store/src/api/food.js`
|
|
|
+- 修改:四个 `E:/QtwCode/foodie/foodie-store/src/lang/*.js`
|
|
|
+
|
|
|
+- [ ] 新增 API 封装,所有分管账号、店铺和商品写请求设置 `isToken: true`;密码沿用现有 RSA 加密工具后提交。
|
|
|
+- [ ] 新增管理页:列表、创建、编辑、多店选择、主账号启停和密码重置;平台停用时展示状态且主账号启用按钮不能宣称已恢复。
|
|
|
+- [ ] 仅类型 1 显示“分管账号”菜单;类型 5 显示订单、授权店铺和商品入口,隐藏新增/删除店铺、分管账号、账单、支付配置及其他敏感模块。
|
|
|
+- [ ] 店铺列表类型 5 不显示新增/删除按钮,但允许编辑授权店铺;退出登录先调用后端退出接口,再清理本地 token。
|
|
|
+- [ ] 在 `zh.js/tw.js/en.js/vi.js` 同一嵌套对象增加语义化英文驼峰 key,不新增 `text1` 类编号。
|
|
|
+- [ ] 使用 `git diff --check` 和换行检查确认相关 Vue/JS 仍为 CRLF,运行 `npm run build`。
|
|
|
+- [ ] 在 `foodie-store` 仓库提交:`git commit -m "增加商家分管账号管理页面"`。
|
|
|
+
|
|
|
+### T010 [US5] 在平台主商家下呈现分管账号
|
|
|
+
|
|
|
+**文件:**
|
|
|
+
|
|
|
+- 修改:`E:/QtwCode/foodie/foodie-admin-vue/src/views/infouser/user/sjuser.vue`
|
|
|
+- 修改:`E:/QtwCode/foodie/foodie-admin-vue/src/api/infouser/user.js`
|
|
|
+- 修改:四个 `E:/QtwCode/foodie/foodie-admin-vue/src/api/language/language.*.js`
|
|
|
+
|
|
|
+- [ ] 在商家行增加“分管账号”按钮,打开抽屉或对话框并传当前类型 1 主账号 ID,不新增顶级商家行或商家审核入口。
|
|
|
+- [ ] 展示姓名、手机号、双重状态、在线/最近登录、负责店铺和创建时间;不展示密码、CID 或资质字段。
|
|
|
+- [ ] 平台只提供强制停用/恢复按钮;不提供新增、密码重置和店铺授权编辑。
|
|
|
+- [ ] 四语种补齐文案并保持 CRLF,运行 `npm run build:prod`。
|
|
|
+- [ ] 在 `foodie-admin-vue` 仓库提交:`git commit -m "在主商家下展示分管账号"`。
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## Phase 6:集成验证与交付
|
|
|
+
|
|
|
+### T011 全量验证、规格回填与推送
|
|
|
+
|
|
|
+**文件:**
|
|
|
+
|
|
|
+- 修改:`specs/022-merchant-store-subaccounts/tasks.md`(完成状态)
|
|
|
+- 按实际结果修改:`specs/022-merchant-store-subaccounts/quickstart.md`
|
|
|
+
|
|
|
+- [ ] 使用 JDK 21 运行 `quickstart.md` 中全部定向测试,记录测试数和结果。
|
|
|
+- [ ] 运行 `mvn -pl ruoyi-admin -am -DskipTests package`,再运行项目约定完整回归;如有失败,区分本功能回归与既有失败并记录证据。
|
|
|
+- [ ] 构建 `foodie-store` 和 `foodie-admin-vue`,确认四语言文件解析成功。
|
|
|
+- [ ] 执行手工验收:多店授权、越权拒绝、授权即时撤销、双重停用、主商家停用、通知全发、CID 去重、主账号兜底、平台商家数量不变。
|
|
|
+- [ ] 检查三个仓库 `git diff --check`、换行、编码和暂存清单;后端不得混入 `.claude/homunculus/observations.jsonl` 或其他原有脏文件。
|
|
|
+- [ ] 更新任务勾选和验证结果,后端规格/SQL/源码/测试形成中文提交;分别推送三个仓库当前分支。
|
|
|
+
|
|
|
+## 依赖关系
|
|
|
+
|
|
|
+```text
|
|
|
+T001 -> T002 -> T003 -> T004 -> T005
|
|
|
+ | |
|
|
|
+ +------>T006 -> T007 -> T008
|
|
|
+ | |
|
|
|
+ +-----------> T009
|
|
|
+ |
|
|
|
+T004 --------------------------------> T010
|
|
|
+T001..T010 --------------------------> T011
|
|
|
+```
|
|
|
+
|
|
|
+- T001、T002 是所有业务故事的阻塞基础。
|
|
|
+- T003 完成后可开发商家端页面;T004 完成后可开发平台页面。
|
|
|
+- T006、T007 必须先于通知路由最终接入,确保通知目标与实际门店权限一致。
|
|
|
+- T009 和 T010 位于不同仓库,可独立构建,但不得在未完成后端契约前联调。
|
|
|
+
|
|
|
+## 需求覆盖
|
|
|
+
|
|
|
+| 需求 | 任务 |
|
|
|
+|---|---|
|
|
|
+| FR-001、FR-002、FR-003、FR-004、FR-005、FR-006、FR-007、FR-008 | T001、T003、T005 |
|
|
|
+| FR-009、FR-010、FR-011、FR-012、FR-013、FR-014、FR-015、FR-016 | T002、T006、T007、T009 |
|
|
|
+| FR-017、FR-018、FR-019、FR-020、FR-021、FR-022、FR-023 | T008 |
|
|
|
+| FR-024、FR-025、FR-026、FR-027 | T007、T009、T011 |
|
|
|
+| FR-028、FR-029、FR-030、FR-031、FR-032、FR-033、FR-034、FR-035 | T004、T005、T010 |
|
|
|
+| SC-001、SC-002、SC-003、SC-004、SC-005、SC-006、SC-007、SC-008、SC-009 | T003~T011 |
|