# Tasks: Table QR Code (餐桌码) **Input**: Design documents from `/specs/002-table-qrcode/` **Prerequisites**: plan.md, spec.md, data-model.md, contracts/api.md, research.md ## 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, US4) --- ## Phase 1: Setup **Purpose**: 添加依赖和创建数据库表 - [x] T001 Add ZXing dependencies to `ruoyi-admin/pom.xml` (core 3.5.2 + javase 3.5.2) - [x] T002 Execute DDL to create `table_qrcode` table per data-model.md (SQL file created at sql/table_qrcode.sql) --- ## Phase 2: Foundational (Backend Core Layer) **Purpose**: 后端核心层 — Entity、Mapper、Service,所有用户故事的前置依赖 **CRITICAL**: Phase 3+ 的所有工作必须在本阶段完成后才能开始 - [x] T003 Create `TableQrcode` entity class in `ruoyi-system/src/main/java/com/ruoyi/system/domain/TableQrcode.java` following PosStore pattern (@Data, @TableName, @TableId with IdType.AUTO) - [x] T004 [P] Create `TableQrcodeMapper` interface in `ruoyi-system/src/main/java/com/ruoyi/system/mapper/TableQrcodeMapper.java` extending BaseMapper - [x] T005 [P] Create `TableQrcodeMapper.xml` in `ruoyi-system/src/main/resources/mapper/chanting/TableQrcodeMapper.xml` with resultMap and selectTableQrcodeList query (support filter by storeId, type, status, useStatus, nightMarketId) - [x] T006 Create `ITableQrcodeService` interface in `ruoyi-system/src/main/java/com/ruoyi/system/service/ITableQrcodeService.java` extending IService with CRUD methods - [x] T007 Create `TableQrcodeServiceImpl` in `ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TableQrcodeServiceImpl.java` extending ServiceImpl, autowire TableQrcodeMapper, implement all interface methods **Checkpoint**: 后端核心层就绪,可以开始实现 API 和前端 --- ## Phase 3: User Story 1 — 餐桌码 CRUD API (Priority: P1) MVP **Goal**: 摊主和夜市管理员可以通过 API 创建/查询/编辑/删除餐桌码 **Independent Test**: 通过 Postman/curl 调用 CRUD 接口,验证创建、列表、详情、更新、删除功能正常,权限控制正确 ### Implementation - [x] T008 [US1] Create `TableQrcodeController` in `ruoyi-admin/src/main/java/com/ruoyi/app/tableqrcode/TableQrcodeController.java` with @RestController, @RequestMapping("/table-qrcode"), extends BaseController, autowire ITableQrcodeService + IInfoUserService + IPosStoreService - [x] T009 [US1] Implement POST `/table-qrcode/add` — validate tableNo required, type=0 requires storeId, type=1 no storeId; get userId from JwtUtil, lookup InfoUser for userType; stall owner (type=4) auto-fills storeId from user info; night market admin (type=3) gets nightMarketId from user info; check duplicate tableNo under same store/night market; generate qrCode URL and save - [x] T010 [US1] Implement GET `/table-qrcode/list` — support query params (storeId, type, status, useStatus); stall owner only sees own storeId; night market admin sees all under nightMarketId; return list with storeName join - [x] T011 [US1] Implement GET `/table-qrcode/{id}` — return detail with storeName; verify ownership (stall owner can only get own codes) - [x] T012 [US1] Implement PUT `/table-qrcode/update` — allow updating tableNo and remark only (not type or storeId); verify ownership - [x] T013 [US1] Implement DELETE `/table-qrcode/delete/{id}` — reject if useStatus=1 (in use); verify ownership - [x] T014 [US1] Implement PUT `/table-qrcode/changeStatus` — toggle status between 0 and 1; verify ownership **Checkpoint**: 所有 CRUD API 可通过 HTTP 工具独立测试 --- ## Phase 4: User Story 2 — 二维码生成与展示 (Priority: P2) **Goal**: 可以查看和下载餐桌二维码图片 **Independent Test**: 调用二维码接口,返回 Base64 图片数据,可解码还原为 URL ### Implementation - [x] T015 [US2] Implement QR code generation utility in `TableQrcodeServiceImpl` — use ZXing BitMatrix → PNG → Base64 encode; generate 300x300 QR image from qrCode URL field - [x] T016 [US2] Implement GET `/table-qrcode/qrcode/{id}` endpoint — if qrCode field is null, generate URL and save first; return Base64 encoded PNG image in AjaxResult data field **Checkpoint**: 通过 API 可以获取到 Base64 格式的二维码图片 --- ## Phase 5: User Story 3 — 扫码跳转入口 (Priority: P3) **Goal**: 顾客扫码后跳转到对应的页面(摊位商品或摊位选择) **Independent Test**: 浏览器访问 scan URL,验证重定向到正确页面 ### Implementation - [x] T017 [US3] Implement GET `/table-qrcode/scan` endpoint — validate tableId exists and status=0 (enabled); update useStatus to 1; type=0 redirect to store product page with storeId + tableId; type=1 redirect to stall selection page with nightMarketId + tableId **Checkpoint**: 浏览器访问 scan URL 能正确重定向 --- ## Phase 6: User Story 4 — 前端管理页面 (Priority: P2) **Goal**: 商家端有完整的餐桌码管理页面 **Independent Test**: 启动 foodie-store 前端,访问 /table-qrcode 页面,完成创建→列表→查看二维码→编辑→删除完整流程 ### Implementation - [x] T018 [P] [US4] Create API module `foodie-store/src/api/tableQrcode.js` — define all API calls (add, list, getById, update, delete, changeStatus, getQrcodeImage) using axios request util from src/router/request.js - [x] T019 [US4] Create `foodie-store/src/views/TableQRCode.vue` management page with: - Filter section: type select, status select, query button - Data table: tableNo, type (摊位码/公用码 tag), storeName, useStatus (空闲/使用中 tag), status (el-switch toggle), operations (查看二维码, 编辑, 删除) - Create/Edit dialog: tableNo input, type select (el-radio), remark textarea - QR code dialog: el-image showing base64 QR code, download button - Follow existing patterns from StallManage.vue (Element UI components, layout, loading states) - [x] T020 [US4] Register `/table-qrcode` route in `foodie-store/src/router/index.js` pointing to TableQRCode.vue component **Checkpoint**: 前端完整功能可用,可以完成 CRUD + 查看二维码全流程 --- ## Phase 7: Polish & Cross-Cutting Concerns **Purpose**: 集成测试和优化 - [ ] T021 Verify backend compilation with no errors (mvn compile) - [ ] T022 Verify frontend build with no errors (npm run build) - [ ] T023 Run quickstart.md validation — test complete flow: create → list → QR code → edit → disable → delete - [ ] T024 Verify permission isolation — stall owner cannot access other stalls' codes, night market admin can view all --- ## Dependencies & Execution Order ### Phase Dependencies - **Setup (Phase 1)**: No dependencies — start immediately - **Foundational (Phase 2)**: Depends on Phase 1 completion — BLOCKS all user stories - **US1 CRUD (Phase 3)**: Depends on Phase 2 - **US2 二维码 (Phase 4)**: Depends on Phase 2 and Phase 3 (needs CRUD to create data first) - **US3 扫码 (Phase 5)**: Depends on Phase 2 - **US4 前端 (Phase 6)**: Depends on Phase 3 + Phase 4 (needs working backend APIs) - **Polish (Phase 7)**: Depends on all phases ### User Story Dependencies - **US1 (CRUD)**: Depends on Foundational — no dependency on other stories - **US2 (二维码)**: Depends on US1 (needs data to generate QR codes for) - **US3 (扫码)**: Depends on Foundational only — can parallel with US1 - **US4 (前端)**: Depends on US1 + US2 (needs backend APIs ready) ### Parallel Opportunities - T004 + T005 can run in parallel (different files) - T018 can start in parallel with Phase 3/4 backend work (API module independent) - T017 (scan endpoint) can be developed in parallel with US2 (二维码) --- ## Implementation Strategy ### MVP (US1 + US2) 1. Phase 1: Setup (dependencies + table) 2. Phase 2: Foundational (Entity, Mapper, Service) 3. Phase 3: US1 CRUD API 4. Phase 4: US2 二维码生成 5. Phase 6: US4 前端页面 (T018 → T019 → T020) 6. Phase 7: Polish (T021-T024) 7. **STOP and VALIDATE**: 完整流程测试 ### Full Delivery (add US3) 8. Phase 5: US3 扫码入口 9. Final integration test --- ## Notes - [P] tasks = different files, no dependencies - [Story] label maps task to specific user story for traceability - Backend paths use forward slashes in Java packages - Frontend is a separate project at E:\QtwCode\foodie\foodie-store - Follow existing project patterns exactly (see research.md for pattern decisions) - Commit after each task or logical group - Stop at any checkpoint to validate independently