This commit is contained in:
Guoqs
2026-03-04 16:06:55 +08:00
parent 100ca67ad6
commit c231c322f8
21 changed files with 1766 additions and 0 deletions

View File

@@ -0,0 +1,128 @@
# 优惠券功能实现进度
**需求文档**: [PRD-积分兑换洗车券功能.md](./PRD-积分兑换洗车券功能.md)
**开始日期**: 2026-03-04
**当前版本**: v1.0(首期洗车券)
---
## 进度总览
| # | 子任务 | 状态 | 文件 |
|---|--------|------|------|
| 1 | Domain 实体类 | ✅ 完成 | `jsowell-pile/.../domain/` |
| 2 | Mapper 接口和 XML | ✅ 完成 | `jsowell-pile/.../mapper/` + `resources/mapper/pile/` |
| 3 | Service 层 | ✅ 完成 | `jsowell-pile/.../service/` |
| 4 | 管理后台 Controller | ✅ 完成 | `jsowell-admin/.../web/controller/pile/` |
| 5 | 用户端 API Controller | ✅ 完成 | `jsowell-admin/.../api/uniapp/customer/` |
| 6 | Quartz 过期归档任务 | ✅ 完成 | `jsowell-quartz/.../task/JsowellTask.java`(方法 `expireCoupons` |
> 状态图例:⬜ 待开始 / 🔄 进行中 / ✅ 完成
---
## Task 1Domain 实体类
**状态**: ✅ 完成
### 文件清单
| 文件 | 路径 |
|------|------|
| `CouponTemplate.java` | `jsowell-pile/src/main/java/com/jsowell/pile/domain/` |
| `CouponTemplateScope.java` | `jsowell-pile/src/main/java/com/jsowell/pile/domain/` |
| `MemberCoupon.java` | `jsowell-pile/src/main/java/com/jsowell/pile/domain/` |
| `CouponVerifyRecord.java` | `jsowell-pile/src/main/java/com/jsowell/pile/domain/` |
---
## Task 2Mapper 接口和 XML
**状态**: ✅ 完成
### 文件清单
| 文件 | 路径 |
|------|------|
| `CouponTemplateMapper.java` | `jsowell-pile/src/main/java/com/jsowell/pile/mapper/` |
| `CouponTemplateScopeMapper.java` | `jsowell-pile/src/main/java/com/jsowell/pile/mapper/` |
| `MemberCouponMapper.java` | `jsowell-pile/src/main/java/com/jsowell/pile/mapper/` |
| `CouponVerifyRecordMapper.java` | `jsowell-pile/src/main/java/com/jsowell/pile/mapper/` |
| `CouponTemplateMapper.xml` | `jsowell-pile/src/main/resources/mapper/pile/` |
| `CouponTemplateScopeMapper.xml` | `jsowell-pile/src/main/resources/mapper/pile/` |
| `MemberCouponMapper.xml` | `jsowell-pile/src/main/resources/mapper/pile/` |
| `CouponVerifyRecordMapper.xml` | `jsowell-pile/src/main/resources/mapper/pile/` |
---
## Task 3Service 层
**状态**: ✅ 完成
### 文件清单
| 文件 | 路径 |
|------|------|
| `CouponTemplateService.java` | `jsowell-pile/src/main/java/com/jsowell/pile/service/` |
| `CouponTemplateServiceImpl.java` | `jsowell-pile/src/main/java/com/jsowell/pile/service/impl/` |
| `MemberCouponService.java` | `jsowell-pile/src/main/java/com/jsowell/pile/service/` |
| `MemberCouponServiceImpl.java` | `jsowell-pile/src/main/java/com/jsowell/pile/service/impl/` |
### 核心方法
**CouponTemplateService**
- `listForAdmin(CouponTemplate query, String merchantId)` - 后台列表(带权限过滤)
- `add(CouponTemplate template, String loginMerchantId, boolean isPlatformAdmin)` - 新增(含 scope 校验)
- `edit(CouponTemplate template, String loginMerchantId, boolean isPlatformAdmin)` - 编辑(含冻结字段校验)
- `changeStatus(Long id, Integer status, String loginMerchantId)` - 上下架
**MemberCouponService**
- `listAvailableTemplates(String memberId, Long stationId, int pageNum, int pageSize)` - 用户可兑换列表
- `exchange(String memberId, Long templateId, String requestId)` - 兑换(原子:扣积分+生成券)
- `myList(String memberId, Integer status, int pageNum, int pageSize)` - 我的券包
- `detail(String memberId, String couponNo)` - 券详情
- `verify(String couponNo, Long storeId, String requestId, String operatorId)` - 核销
---
## Task 4管理后台 Controller
**状态**: ✅ 完成
### 文件清单
| 文件 | 路径 |
|------|------|
| `CouponTemplateController.java` | `jsowell-admin/src/main/java/com/jsowell/web/controller/pile/` |
| `CouponRecordController.java` | `jsowell-admin/src/main/java/com/jsowell/web/controller/pile/` |
---
## Task 5用户端 API Controller
**状态**: ✅ 完成
### 文件清单
| 文件 | 路径 |
|------|------|
| `CouponController.java` | `jsowell-admin/src/main/java/com/jsowell/api/uniapp/customer/` |
---
## Task 6Quartz 过期归档任务
**状态**: ✅ 完成
方法 `expireCoupons()` 已合并到 `JsowellTask.java`,调用目标:`jsowellTask.expireCoupons()`Cron`0 5 0 * * ?`
---
## 关键设计决策
1. **兑换幂等**`member_coupon.exchange_request_id` 唯一索引,捕获 `DuplicateKeyException` 返回已有结果
2. **库存扣减**`UPDATE ... SET stock_remain=stock_remain-1 WHERE id=? AND (stock_remain>0 OR stock_remain=-1)`
3. **积分扣减**:复用现有 `MemberPointsInfoService.deductPoints()``type=3`(兑换消耗)
4. **scope 校验**:查询用户可见券时 JOIN `coupon_template_scope`,通过 `idx_scope_lookup` 索引反查
5. **过期判断**:查询侧用 `expire_time > NOW()` 动态判断Quartz 仅做离线归档
6. **二维码安全**:券详情接口返回短时签名 tokenHMAC-SHA2565分钟有效核销接口接受 token 或 couponNo 两种方式