mirror of
https://codeup.aliyun.com/67c68d4e484ca2f0a13ac3c1/ydc/jsowell-charger-web.git
synced 2026-06-15 04:39:50 +08:00
129 lines
4.9 KiB
Markdown
129 lines
4.9 KiB
Markdown
|
|
# 优惠券功能实现进度
|
|||
|
|
|
|||
|
|
**需求文档**: [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 1:Domain 实体类
|
|||
|
|
|
|||
|
|
**状态**: ✅ 完成
|
|||
|
|
|
|||
|
|
### 文件清单
|
|||
|
|
|
|||
|
|
| 文件 | 路径 |
|
|||
|
|
|------|------|
|
|||
|
|
| `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 2:Mapper 接口和 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 3:Service 层
|
|||
|
|
|
|||
|
|
**状态**: ✅ 完成
|
|||
|
|
|
|||
|
|
### 文件清单
|
|||
|
|
|
|||
|
|
| 文件 | 路径 |
|
|||
|
|
|------|------|
|
|||
|
|
| `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 6:Quartz 过期归档任务
|
|||
|
|
|
|||
|
|
**状态**: ✅ 完成
|
|||
|
|
|
|||
|
|
方法 `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. **二维码安全**:券详情接口返回短时签名 token(HMAC-SHA256,5分钟有效),核销接口接受 token 或 couponNo 两种方式
|