|
|
@@ -4,6 +4,109 @@
|
|
|
|
|
|
---
|
|
|
|
|
|
+## v1.0.1910 (2026-10-31)
|
|
|
+
|
|
|
+### 文档
|
|
|
+- 套餐独立模型重写实施计划(9任务) + PROJECT-OVERVIEW 登记
|
|
|
+- 商品套餐独立模型重写设计(2026-10-31)
|
|
|
+
|
|
|
+### Bug 修复
|
|
|
+- Dashboard 图表初始化与停留区模板判空防白屏
|
|
|
+- COUPON-C3 领券中心数据源改为「可取券模板」,解除 B1 阻断
|
|
|
+- COUPON-P2 优惠券 P2 技术债打包(核查报告 §四 P2 各项)
|
|
|
+
|
|
|
+### 其他
|
|
|
+- - 模板 dwell/hot 空态检测 this[sec.key].length 未兜底 → (this[sec.key] || []).length
|
|
|
+- - 根因:浏览器缓存旧 chunk 与新 webpack runtime 混用触发(生产当前数据路径已安全,此为防御加固)
|
|
|
+-
|
|
|
+- /api/coupon/list(返回本家庭已拥有 AVAILABLE 券实例),claim() 去重
|
|
|
+- (family_id+coupon_id 任意状态有记录即拦)必然命中 → 「立即领取」100% 500。
|
|
|
+- 根因解耦(数据源选错 → 换数据源):
|
|
|
+- - 后端新增 POST /api/coupon/available-templates(CouponService.listAvailableTemplates):
|
|
|
+- 当前家庭可领取的券模板「上架且未领」——过滤口径与 /claim 去重完全对齐:
|
|
|
+- ① status 空/ACTIVE(有效上架)② valid_from<=now<=valid_until(有效期内)
|
|
|
+- ③ total_count 空/<=0 视为不限量,否则 used_count<total_count(未领完)
|
|
|
+- ④ grant_type 为空(排除 JOIN/PERIODIC/POPULATION/REGISTER/EXCHANGE 自动发放/兑换)
|
|
|
+- ⑤ family_id 为空(全平台模板,排除家庭专属)⑥ 本家庭未领取(family_coupon 任意状态有记录即排除)
|
|
|
+- - 前端 coupon-center.vue 数据源 getCouponList → getAvailableCouponTemplates;
|
|
|
+- claim 传参 item.couponId||item.id → item.id(新端点返回 List<Coupon>,字段为 id)
|
|
|
+- - utils/api.js 新增 getAvailableCouponTemplates() = POST /api/coupon/available-templates
|
|
|
+- - pages.json 在 profile-extra 分包注册 coupon-center(导航标题:领券中心)
|
|
|
+- - coupons.vue 空状态入口由纯文案改为可点击跳转 goToCouponCenter(/pages/profile-extra/coupon-center)
|
|
|
+- - docs/superpowers/api/API_REFERENCE.md 登记 /api/coupon/available-templates
|
|
|
+- 范围纪律:不改 claim 本身(契约保持),不动 AdminCouponController,无 DDL/迁移/新表。
|
|
|
+- 未领取模板领取后因去重被排除 → 「已领取模板不再出现」。
|
|
|
+- 验证:cfc-backend mvn -DskipTests compile SUCCESS(1958 源文件);
|
|
|
+- cfc-frontend npm run build:mp-weixin DONE(dist/dev/mp-weixin app.json 含 coupon-center 分包,
|
|
|
+- 产物 coupon-center.js/json/wxml/wxss 齐全;警告均为预存问题,无本修复引入);
|
|
|
+- 小程序反模式检查通过(无 ?. / 无 grid / :key 均为简单绑定)。
|
|
|
+-
|
|
|
+- - 新增 CouponService.pageCoupons(keyword,page,size,sortSpecs),
|
|
|
+- keyword 对名称/ID 模糊匹配,selectPage 真分页,无排序时按 id 倒序
|
|
|
+- - /list 改返回 Result<Page<Coupon>>(records/total/current/size),
|
|
|
+- size 上限 999、page/size 非法值兜底为 1/20
|
|
|
+- - cfc-web CouponManagement.vue 原本已按 records/total 消费,无需改动
|
|
|
+- ② 用户端券类型/适用对象枚举补全 + 发券流水家庭名 N+1 消除:
|
|
|
+- - 小程序 coupons.vue:getTypeLabel 补 DISCOUNT/CASH,getScopeText 补
|
|
|
+- PRODUCT/ASSESSMENT,getCouponDesc/getCardValue 兼容 PERCENT
|
|
|
+- (折扣券不再显示原始值 PERCENT/PRODUCT,卡片面值区折扣券显示「x折」)
|
|
|
+- - 小程序 upgrade.vue / wealth-cf/index.vue:券描述兼容 PERCENT
|
|
|
+- - 后端 FamilyCouponGrantLog 增 @TableField(exist=false) familyName,
|
|
|
+- /api/admin/coupon/grant-log 用 FamilyMapper.selectBatchIds 批量填充
|
|
|
+- - cfc-web CouponGrantLog.vue 删除逐个 getFamilyDetail 的 resolveFamilyNames
|
|
|
+- ③ 后台优惠券接口改用 @PreAuthorize("hasRole('admin')"):
|
|
|
+- - 新增 spring-boot-starter-security 依赖 + SecurityConfig
|
|
|
+- (STATELESS + anyRequest().permitAll() + @EnableGlobalMethodSecurity,
|
|
|
+- 认证仍由 JwtInterceptor 负责,不改变既有接口可达性)
|
|
|
+- - JwtInterceptor 把角色发布为 ROLE_<role> 权限到 SecurityContextHolder,
|
|
|
+- 匿名请求发布 ROLE_ANONYMOUS;请求前后清理上下文防线程复用泄漏
|
|
|
+- - GlobalExceptionHandler 增 AccessDeniedException → Result.error(403,"无权限"),
|
|
|
+- 与原「手写 if(!admin) 返回无权限」前端体验一致
|
|
|
+- - AdminCouponController 全部 12 个接口移除手写角色判断
|
|
|
+- ④ Coupon.java 与 schema.sql 已对齐:coupon.family_id 列已存在
|
|
|
+- (schema.sql:2342 + 迁移 282/411),实体已有 familyId 字段,无需改动
|
|
|
+- ⑤ DISCOUNT 抵扣整数截断分位误差修复:
|
|
|
+- orderAmount*(10000-rate)/10000 → Math.round(double),
|
|
|
+- 19.99 元 8 折由 399 修正为 400(1 元 8 折仍为 20),并规避 int 溢出
|
|
|
+- ⑥ apply applicableTo 为 null 时 NPE 修复:
|
|
|
+- null 视为 ALL(全场通用),不再对 null 调用 equals
|
|
|
+- 验证:cfc-backend mvn clean compile BUILD SUCCESS;cfc-web npm run build
|
|
|
+- DONE(该工程未配置 lint 脚本);测试库实跑:admin 分页/keyword/sort 正常、
|
|
|
+- operator 与匿名访问后台券接口均返回 403「无权限」、公开接口与 CORS 预检正常。
|
|
|
+- 未新增 DB 迁移/表,未合并 cfclub。
|
|
|
+- Refs: COUPON-P2
|
|
|
+-
|
|
|
+- 背景:pub-iwintrue 实例上已完成的 C2 提交(be16b8eb3 删死代码 /
|
|
|
+- 3379d4ad1 used_count 递减)已丢失(本地提交被 auto-bump/仓库重置,origin 无
|
|
|
+- 对应对象),按核查文档 §五 C2 重新实现。
|
|
|
+- 改动(6 文件,仅 cfc-backend):
|
|
|
+- - 删除 entity/UserCoupon.java、mapper/UserCouponMapper.java
|
|
|
+- (user_coupon 旧维度实例表,08-31 起由 family_coupon 承接,无业务引用)
|
|
|
+- - 删除 entity/CouponGrantLog.java、mapper/CouponGrantLogMapper.java
|
|
|
+- (coupon_grant_log 旧维度流水表;C1 起统计源已改 family_coupon_grant_log)
|
|
|
+- - AdminCouponController:移除 CouponGrantLog / CouponGrantLogMapper 的
|
|
|
+- import 与未使用的 couponGrantLogMapper 字段(grant-log 端点本就查
|
|
|
+- family_coupon_grant_log,对外行为不变)
|
|
|
+- - CouponService:
|
|
|
+- · 新增 decrementUsedCount():原子递减 coupon.used_count(used_count>0 才减,
|
|
|
+- 避免减成负数;NULL 视为未知不动)
|
|
|
+- · revert():还券(USED/RESERVED → AVAILABLE)时同步递减 used_count
|
|
|
+- · revokeFamilyPopulationCoupons():收回人口券时同步递减 used_count
|
|
|
+- 约束遵守:
|
|
|
+- - 表不 DROP(user_coupon / coupon_grant_log 保留,遵循 08-31「保留不迁移」)
|
|
|
+- - 不新增 DB 迁移;未按他表 id 列表做主键 DELETE(仅删 Java 死代码 + 递减)
|
|
|
+- - cfc-web / cfc-frontend 未改动
|
|
|
+- 验证:cfc-backend mvn compile 通过;mvn test-compile 通过;
|
|
|
+- cfc-web vue-cli-service build 通过
|
|
|
+-
|
|
|
+
|
|
|
+### 测试
|
|
|
+- 接口冒烟闭环 2026-10-31 23:28 — 通过率 45% (fix=0 reg=0); 测试用例 360/387 完成(文档化202)
|
|
|
+
|
|
|
+### 新功能
|
|
|
+- COUPON-C2 清理优惠券死代码 + used_count 还券收回递减
|
|
|
+
|
|
|
+
|
|
|
## v1.0.1909 (2026-10-31)
|
|
|
|
|
|
### 测试
|