plan.md 8.0 KB

摊位资质审核实施计划

工作分支:test-202609v2,不创建新分支。 日期:2026-10-09 规格:spec.md 进度:已验证(本地定向检查);四组资料、存量营业门禁及两个 PC 已实现,部署/真实联调尚未执行。见 quickstart.md。

技术约束

沿用 Java/JDK 21、Spring Boot、MyBatis 和 MySQL;模块依赖保持 ruoyi-admin -> ruoyi-system。商家 PC 和平台沿用 Vue 2、现有请求封装;敏感材料使用专用私有上传,不复用公开上传。实体、Mapper/XML 放 ruoyi-system,业务编排和明确请求 DTO 放 ruoyi-admin;登录身份采用现有认证机制,禁止信任客户端提交的操作人或归属 ID。

.specify/memory/constitution.md 当前仍为未填写模板,本功能以项目 AGENTS.md、用户确认范围和本规格为约束,不修改全局模板。

顺序

  1. 按 spec.md 的四组统一资料实现人工审核;不收集商业/税籍登记、保险等补充证明,不做自动查证或证照到期提醒。明确存量上线方式,补齐接口契约和验收边界。
  2. 登记认证主表、申请表、唯一约束、权限与菜单 SQL;不执行。
  3. 实现草稿保存、提交、分页查询、详情、审核及版本保护。保存草稿与正式提交使用不同校验;已提交/已审核快照不可修改。
  4. 商家 PC 新增摊位认证页面;夜市主管理页展示旗下摊位状态。平台新增摊位审核列表及材料详情、审核操作;新增文案同时维护四语言。
  5. 按已确认的存量与新增一律审核后营业策略,将有效资质校验接到开店及新订单入口,保留已存在订单履约;排查 C 端摊位与商品展示入口避免仅前端隐藏。
  6. 完成定向测试、模块编译、前端检查和变更审查;更新任务进度及部署说明。

数据与事务

主表按 store_id 唯一,分别指向有效已通过版本和当前申请。申请保存统一字段及服务端读取的摊位展示快照。提交和审核必须在事务内完成,结合主表锁/版本和申请状态条件更新,避免两个管理员重复审核或多个摊主同时提交。审核失败不得更新有效资料指针。

已有普通商家认证字段留在原表,不把整个 InfoUser 审核系统改成摊位审核。现有通用 setuser 不能写入新认证状态或材料版本。

验证

  • 服务校验:统一必填、草稿不完整保存、归属/禁用校验、驳回重提、重复操作与版本竞争。
  • Mapper:结果映射、提交和审核条件更新、当前申请唯一性、历史不可变及事务回滚。
  • 经营门禁:新未认证摊位、通过、修改待审核但旧资质有效、已有订单继续履约及存量策略。
  • 前端:表单统一、进度/驳回原因/历史回显、四语言键一致和 Vue 编译。
  • 实际数据库并发、文件访问权限与跨端联调如未执行,交付时明确列出,不以模拟测试代替真实验证。

本轮执行批次(2026-10-09)

沿用当前三个仓库的 test-202609v2,直接在本会话实施,不新建分支/工作树、不自动提交。按 executing-plans 和 test-driven-development 执行,进度写入本目录 tasks.md,而不是另建技能工作目录。

批次一:后端资料及审核闭环

  • 新建 ruoyi-system 的 StallQualification、StallQualificationApplication、StallQualificationMapper 和对应 XML。主表 storeId 唯一,申请版本唯一。
  • 新建 ruoyi-admin/com/ruoyi/app/stall/qualification 的服务、DTO、商家 Controller 和平台 Controller;草稿状态 0、待审核 1、通过 2、驳回 3,未提交仅为查询展示态 -1。
  • GET /stall/qualification 返回当前申请、有效申请和不含材料的历史摘要;POST /draft 保存,POST /submit 提交,GET /applications/{id} 查看己方历史。
  • 平台 /system/stallQualification 分页列表、详情和 /applications/{id}/review;权限分别为 stall:qualification:list/query/review。
  • 保存/提交请求都携带主表 version(首次为 0)。先建立主表、锁住主表再验证版本和待审核状态;提交之后冻结申请,重提新建版本,审核条件更新只允许处理待审核版本。
  • 附件仅接收 JPEG/PNG(每张不超过 5MB、每类不超过 5 张),保存在 profile 同级独立私有目录,不进入公开 profile 映射;上传和预览都校验摊位归属或平台材料查询权限,不将身份证明放到公开接口或业务日志。
  • 定向测试 StallQualificationServiceTest、StallQualificationFileServiceTest 覆盖越权、缺资料、空草稿、版本竞争、重复提交/审核、有效版本保留、私有文件路径和非法附件。
  • DDL 及菜单登记 updatesql/sql.md,不执行数据库操作。

批次二:两个 PC 页面

  • 商家新建 src/views/StallQualification.vue、src/api/stallQualification.js、私有图片组件;路由及 Aside 仅 type=4 展示;StallManage 调用夜市进度接口展示不含材料的认证状态。
  • 平台新建 src/views/stallQualification/index.vue、src/api/stallQualification.js,列表不返回证件号/图片,详情按权限加载;审核携带申请 version,驳回原因必填。
  • 两端均维护四语言;组件测试先运行缺实现的断言,再补组件和页面;使用真实 Vue 模板编译及可用构建验证。

批次三:营业门禁及收口

  • 用户已明确存量同样须审核后营业。新建 ruoyi-system/service/StallQualificationGateService;存量和新增、无记录/草稿/待审核/驳回统一拒绝营业和新下单;有旧有效认证的新申请不影响有效资格。
  • 接入 PosStoreServiceImpl 的营业状态保存及新建摊位默认关闭;接入 UserOrderController、PosOrderShOprateController.createOrder 和仍可调用的 PosOrderController.addorder 新订单入口。addorder 源码标记废弃而项目指令列为仍使用,故仅补最小门禁,不复用/扩展旧逻辑。C端列表/详情将未认证摊位表示为关闭,扫码列表隐藏,不阻断既有订单履约。SQL 登记将未认证存量摊位设置为关闭,不自动批准。
  • 材料接口不标注 @Log,材料 Mapper 单独设 WARN 防止 SQL DEBUG/TRACE 泄露证件字段;部署环境不得覆盖该日志级别。
  • 审查发现全局绑定异常日志与 Druid 慢 SQL 参数也会泄露材料:为两个材料 Controller 加专用绑定异常处理,DruidConfig 注册唯一的专用 StatFilter,仅材料两表 SQL 参数脱敏,同时保护日志和监控缓存。
  • 当前 MyBatis-Plus 3.5.10 的 saveOrUpdate 直接调用 Mapper;单独覆盖该入口,不依赖 save/updateById 间接拦截。PosStore XML insert/update 补实际 state 写入,闭店完整表单编辑不能被误判为开店。
  • 运行定向 Maven 测试及受影响模块编译,检查 SQL/XML、前端编译、差异、换行和全部四语言 key;记录尚未执行的部署/浏览器联调。

图片组件增量(2026-10-09)

用户确认摊位上传与门店管理统一、平台材料展示与商品管理统一。商家现有门店页直接使用 el-upload.avatar-uploader,资料组件复用该方框加号交互与 100px 缩略图,保留多图、删除、上传互斥和私有 multipart 接口。平台 PrivateImages 改用现有 ImagePreview;共享组件只补 blob: 原样解析和选填 previewSrcList,未传时商品等原调用保持原行为,同组私有图片可放大切换。

两端私有图片加载比较去掉参数的媒体类型,只接受 JPEG/PNG,不放宽为任意二进制,也不把令牌放到图片地址中。先用真实 Vue 组件回归复现 blob 前缀错误和参数化 MIME 被拒绝,再验证修正、只读/数量限制及原商品地址兼容。无后端接口、数据字段或 SQL 变更。截图中的部署失败仍须按实际请求状态、响应类型、权限和私有目录确认,不把本地兼容测试等同于线上根因已确认。