---

description: "Task list for 夜市摊位管理 feature implementation"
---

# Tasks: 夜市摊位管理

**Input**: Design documents from `specs/001-food-stall/`
**Prerequisites**: plan.md, spec.md

**Tests**: 手动测试（项目无自动化测试框架）

**Organization**: Tasks are grouped by user story to enable independent implementation and testing of each story.

## Format: `[ID] [P?] [Story] Description`

- **[P]**: Can run in parallel (different files, no dependencies)
- **[Story]**: Which user story this task belongs to (e.g., US1, US2, US3)
- Include exact file paths in descriptions

---

## Phase 1: Setup (数据库变更)

**Purpose**: 所有用户故事依赖的数据库 schema 变更

- [x] T001 执行 SQL 为 pos_store 表添加 is_stall 字段: `ALTER TABLE pos_store ADD COLUMN is_stall TINYINT DEFAULT 0 COMMENT '是否摊位 0=店铺 1=摊位';`
- [x] T002 执行 SQL 为 info_user 表添加 store_id 字段: `ALTER TABLE info_user ADD COLUMN store_id BIGINT DEFAULT NULL COMMENT '关联摊位ID（摊位主使用）';`
- [ ] T003 执行 SQL 为 user_wallet 表添加 store_id 字段: `ALTER TABLE user_wallet ADD COLUMN store_id BIGINT DEFAULT NULL COMMENT '关联摊位id，非摊位钱包为NULL';`

---

## Phase 2: Foundational (数据模型层变更)

**Purpose**: 所有用户故事依赖的 Domain 和 Mapper 变更，MUST 完成后再开始用户故事实现

- [x] T004 [P] [US1] PosStore.java 新增 isStall 字段及 getter/setter — `ruoyi-system/src/main/java/com/ruoyi/system/domain/PosStore.java`
- [x] T005 [P] [US1] PosStoreMapper.xml 更新: resultMap 添加 `is_stall` 映射，select/insert/update 添加 isStall 支持 — `ruoyi-system/src/main/resources/mapper/chanting/PosStoreMapper.xml`
- [x] T006 [P] [US2] InfoUser.java 新增 storeId 字段及 getter/setter — `ruoyi-system/src/main/java/com/ruoyi/system/domain/InfoUser.java`
- [x] T007 [P] [US2] InfoUserMapper.xml 更新: resultMap 添加 `store_id` 映射，select/insert/update 添加 storeId 支持，新增 `selectStallOwnersByStoreId` 查询 — `ruoyi-system/src/main/resources/mapper/infouser/InfoUserMapper.xml`
- [x] T008 [P] [US3] UserWallet.java 新增 storeId 字段及 getter/setter — `ruoyi-system/src/main/java/com/ruoyi/system/domain/UserWallet.java`
- [x] T009 [P] [US3] UserWalletMapper.xml 更新: resultMap 添加 `store_id` 映射，select/insert/update 添加 storeId 支持 — `ruoyi-system/src/main/resources/mapper/system/UserWalletMapper.xml`

**Checkpoint**: 数据模型层就绪，用户故事实现可以开始

---

## Phase 3: User Story 1 — 摊位 CRUD（Priority: P1）🎯 MVP

**Goal**: 夜市用户可以创建、查看、管理自己的摊位（PosStore where isStall=1）

**Independent Test**: 夜市用户登录商家端 → 摊位管理 → 能看到摊位列表、能创建新摊位

### Implementation for User Story 1

- [x] T010 [US1] 创建 StallController.java 实现摊位 CRUD 接口: GET /stall/list、POST /stall/add — `ruoyi-admin/src/main/java/com/ruoyi/app/stall/StallController.java`
- [x] T011 [P] [US1] 创建前端 API 层 stall.js — `foodie-store/src/api/stall.js`
- [x] T012 [US1] 创建 StallManage.vue 摊位管理页面（摊位列表 + 创建摊位弹窗） — `foodie-store/src/views/StallManage.vue`
- [x] T013 [US1] router/index.js 添加摊位管理路由 /stall-manage — `foodie-store/src/router/index.js`
- [x] T014 [US1] Aside.vue 添加「摊位管理」菜单项（仅 userType=3 可见） — `foodie-store/src/components/Aside.vue`

**Checkpoint**: 夜市用户可以登录 → 看到摊位管理菜单 → 创建/查看摊位

---

## Phase 4: User Story 2 — 摊位主管理（Priority: P2）

**Goal**: 夜市用户可以为每个摊位创建、查看、启用/禁用/删除摊位主账号

**Independent Test**: 在摊位列表中点击「管理摊位主」→ 能添加/禁用/删除摊位主

### Implementation for User Story 2

- [x] T015 [US2] StallController.java 添加摊位主管理接口: POST /stall/addOwner、GET /stall/owners、PUT /stall/disableOwner、PUT /stall/enableOwner、DELETE /stall/deleteOwner — `ruoyi-admin/src/main/java/com/ruoyi/app/stall/StallController.java`
- [x] T016 [US2] InfoUserMapper.java 添加 `selectStallOwnersByStoreId` 方法 — `ruoyi-system/src/main/java/com/ruoyi/system/mapper/InfoUserMapper.java`
- [x] T017 [US2] IInfoUserService.java / InfoUserServiceImpl.java 添加按 storeId 查询摊位主方法 — `ruoyi-system/src/main/java/com/ruoyi/system/service/IInfoUserService.java`, `ruoyi-system/src/main/java/com/ruoyi/system/service/impl/InfoUserServiceImpl.java`
- [x] T018 [US2] stall.js 添加摊位主管理 API 方法: getStallOwners, addStallOwner, disableStallOwner, enableStallOwner, deleteStallOwner — `foodie-store/src/api/stall.js`
- [x] T019 [US2] StallManage.vue 添加摊位主管理弹窗: 摊位主列表表格、添加摊位主按钮、禁用/删除操作 — `foodie-store/src/views/StallManage.vue`

**Checkpoint**: 夜市用户可以为摊位添加多个摊位主，启用/禁用/删除摊位主

---

## Phase 5: User Story 3 — 摊位钱包（Priority: P3）

**Goal**: 每个摊位拥有独立钱包，摊位收入进入共同池子，创建摊位时自动创建钱包

**Independent Test**: 创建摊位后查询 user_wallet 表确认 store_id 关联的钱包已自动创建；查询用户钱包不包含摊位钱包

### Implementation for User Story 3

- [x] T020 [US3] StallController.java addStall 方法中添加创建摊位后自动创建摊位钱包逻辑 — `ruoyi-admin/src/main/java/com/ruoyi/app/stall/StallController.java`
- [x] T021 [US3] UserWalletMapper.xml 修改所有通过 user_id 查钱包的 SQL 加上 `store_id IS NULL` 条件，新增通过 `store_id` 查摊位钱包的 selectByStoreId 方法 — `ruoyi-system/src/main/resources/mapper/system/UserWalletMapper.xml`
- [x] T022 [US3] UserWalletMapper.java 添加 `selectByStoreId` 方法，IUserWalletService.java / UserWalletServiceImpl.java 添加对应接口和实现 — `ruoyi-system/src/main/java/com/ruoyi/system/mapper/UserWalletMapper.java`, `ruoyi-system/src/main/java/com/ruoyi/system/service/IUserWalletService.java`, `ruoyi-system/src/main/java/com/ruoyi/system/service/impl/UserWalletServiceImpl.java`
- [x] T023 [US3] 检查所有现有钱包查询入口确保不误查摊位钱包: 订单结算、提现、余额查询等 — 搜索所有调用 UserWalletMapper/Service 的代码

**Checkpoint**: 创建摊位 → 钱包自动创建；用户钱包查询不包含摊位钱包；摊位钱包可通过 store_id 独立查询

---

## Phase 6: Polish & 收尾

**Purpose**: 最终验证和提交

- [ ] T024 端到端验证: 夜市用户登录 → 创建摊位 → 确认钱包自动创建 → 添加多个摊位主 → 禁用/启用摊位主 → 确认权限隔离正常
- [ ] T025 更新 spec.md 记录实现中确认的细节
- [ ] T026 提交代码: `git commit -m "feat: 夜市摊位管理功能 — 创建摊位、管理摊位主、摊位钱包"`

---

## Dependencies & Execution Order

### Phase Dependencies

- **Phase 1 (SQL)**: 无依赖，立即开始
- **Phase 2 (Model)**: 依赖 Phase 1 完成 — BLOCKS 所有用户故事
- **Phase 3 (US1 摊位CRUD)**: 依赖 Phase 2 — MVP
- **Phase 4 (US2 摊位主)**: 依赖 Phase 2 和 Phase 3（StallController 已存在）
- **Phase 5 (US3 钱包)**: 依赖 Phase 2 和 Phase 3（需在 StallController.addStall 中加逻辑）
- **Phase 6 (收尾)**: 依赖所有用户故事完成

### User Story Dependencies

- **US1 (摊位CRUD)**: 依赖 Foundational — 无其他故事依赖
- **US2 (摊位主管理)**: 依赖 US1（需要 StallController 和摊位存在）
- **US3 (摊位钱包)**: 依赖 US1（需要 StallController.addStall 方法）

### Parallel Opportunities

- Phase 1: T001, T002, T003 可并行执行（不同表的 SQL）
- Phase 2: T004+T005, T006+T007, T008+T009 可三组并行（不同 Domain/Mapper 文件）
- Phase 3: T011 可与 T010 并行（不同文件）

---

## Parallel Example: Phase 2

```bash
# 并行执行三组 Domain + Mapper 变更:
Task: "PosStore.java isStall + PosStoreMapper.xml"     # US1 相关
Task: "InfoUser.java storeId + InfoUserMapper.xml"     # US2 相关
Task: "UserWallet.java storeId + UserWalletMapper.xml" # US3 相关
```

---

## Implementation Strategy

### MVP First (US1 Only)

1. Complete Phase 1: SQL 变更
2. Complete Phase 2: T004+T005 (PosStore 模型层)
3. Complete Phase 3: US1 摊位 CRUD
4. **STOP and VALIDATE**: 夜市用户能创建/查看摊位
5. 可选择先部署 MVP

### Incremental Delivery

1. Phase 1+2 → 基础就绪
2. Phase 3 (US1) → 摊位 CRUD 可用（MVP）
3. Phase 4 (US2) → 摊位主管理可用
4. Phase 5 (US3) → 摊位钱包可用
5. Phase 6 → 完整验证和提交

---

## Notes

- 项目无自动化测试，所有验证通过手动测试
- PosStore 已有 isNightMarket/nightMarketId 字段可复用
- StallController 已部分实现（已有 addStall, addStallOwner 等方法）
- 用户钱包查询加 `store_id IS NULL` 条件是防止误查摊位钱包的关键
- 摊位主权限通过 info_user 表判断，不通过钱包关联判断

---

## Phase 7: 普通商家新增门店审核门禁（2026-08-24）

- [x] T027 为 `PosStoreController.addmendian` 新增控制器测试，覆盖未审核拒绝、已审核新增时强制绑定 token 用户、编辑不触发新增审核门禁 — `ruoyi-admin/src/test/java/com/ruoyi/app/mendian/PosStoreControllerTest.java`
- [x] T028 修改 `PosStoreController.addmendian`：显式接收 `@RequestHeader String token`，仅新增时解析当前用户、调用 `UserService.checkUserStatus` 并覆盖 `PosStore.userId` — `ruoyi-admin/src/main/java/com/ruoyi/app/mendian/PosStoreController.java`
- [x] T029 使用 JDK 21 运行 `PosStoreControllerTest` 和 `ruoyi-admin` 模块构建，检查差异中无无关文件或整文件换行变化
