Input: Design documents from /specs/002-table-qrcode/
Prerequisites: plan.md, spec.md, data-model.md, contracts/api.md, research.md
[ID] [P?] [Story] DescriptionPurpose: 添加依赖和创建数据库表
ruoyi-admin/pom.xml (core 3.5.2 + javase 3.5.2)table_qrcode table per data-model.md (SQL file created at sql/table_qrcode.sql)Purpose: 后端核心层 — Entity、Mapper、Service,所有用户故事的前置依赖
CRITICAL: Phase 3+ 的所有工作必须在本阶段完成后才能开始
TableQrcode entity class in ruoyi-system/src/main/java/com/ruoyi/system/domain/TableQrcode.java following PosStore pattern (@Data, @TableName, @TableId with IdType.AUTO)TableQrcodeMapper interface in ruoyi-system/src/main/java/com/ruoyi/system/mapper/TableQrcodeMapper.java extending BaseMapper
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)ITableQrcodeService interface in ruoyi-system/src/main/java/com/ruoyi/system/service/ITableQrcodeService.java extending IService with CRUD methods
TableQrcodeServiceImpl in ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TableQrcodeServiceImpl.java extending ServiceImpl, autowire TableQrcodeMapper, implement all interface methodsCheckpoint: 后端核心层就绪,可以开始实现 API 和前端
Goal: 摊主和夜市管理员可以通过 API 创建/查询/编辑/删除餐桌码
Independent Test: 通过 Postman/curl 调用 CRUD 接口,验证创建、列表、详情、更新、删除功能正常,权限控制正确
TableQrcodeController in ruoyi-admin/src/main/java/com/ruoyi/app/tableqrcode/TableQrcodeController.java with @RestController, @RequestMapping("/table-qrcode"), extends BaseController, autowire ITableQrcodeService + IInfoUserService + IPosStoreService/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/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/table-qrcode/{id} — return detail with storeName; verify ownership (stall owner can only get own codes)/table-qrcode/update — allow updating tableNo and remark only (not type or storeId); verify ownership/table-qrcode/delete/{id} — reject if useStatus=1 (in use); verify ownership/table-qrcode/changeStatus — toggle status between 0 and 1; verify ownershipCheckpoint: 所有 CRUD API 可通过 HTTP 工具独立测试
Goal: 可以查看和下载餐桌二维码图片
Independent Test: 调用二维码接口,返回 Base64 图片数据,可解码还原为 URL
TableQrcodeServiceImpl — use ZXing BitMatrix → PNG → Base64 encode; generate 300x300 QR image from qrCode URL field/table-qrcode/qrcode/{id} endpoint — if qrCode field is null, generate URL and save first; return Base64 encoded PNG image in AjaxResult data fieldCheckpoint: 通过 API 可以获取到 Base64 格式的二维码图片
Goal: 顾客扫码后跳转到对应的页面(摊位商品或摊位选择)
Independent Test: 浏览器访问 scan URL,验证重定向到正确页面
/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 + tableIdCheckpoint: 浏览器访问 scan URL 能正确重定向
Goal: 商家端有完整的餐桌码管理页面
Independent Test: 启动 foodie-store 前端,访问 /table-qrcode 页面,完成创建→列表→查看二维码→编辑→删除完整流程
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.jsfoodie-store/src/views/TableQRCode.vue management page with:
/table-qrcode route in foodie-store/src/router/index.js pointing to TableQRCode.vue componentCheckpoint: 前端完整功能可用,可以完成 CRUD + 查看二维码全流程
Purpose: 集成测试和优化