bindbox-game/.trae/documents/删除级联逻辑优化方案.md
邹方成 45815bfb7d chore: 清理无用文件与优化代码结构
refactor(utils): 修复密码哈希比较逻辑错误
feat(user): 新增按状态筛选优惠券接口
docs: 添加虚拟发货与任务中心相关文档
fix(wechat): 修正Code2Session上下文传递问题
test: 补充订单折扣与积分转换测试用例
build: 更新配置文件与构建脚本
style: 清理多余的空行与注释
2025-12-18 17:35:55 +08:00

87 lines
6.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

## 背景
- 当前不启用数据库外键约束FK删除由业务逻辑驱动。
- 现有删除实现多为单表删除,未做级联:如删除活动 `internal/service/activity/activity_delete.go:9`、删除期 `internal/service/activity/issue_delete.go:9`、删除用户 `internal/service/user/batch_user.go:32`
- GORM 初始化未声明外键或级联:`internal/repository/mysql/mysql.go:97`
## 目标
- 在业务层实现“逻辑级联删除”,保证删除主实体时,同步清理其关联业务数据,且性能与可控性优于 FK 级联。
## 级联清单
### 删除活动Activities.ID
- 删除活动期:`activity_issues``activity_id``internal/repository/mysql/model/activity_issues.gen.go:18`
- 期下配置与承诺:
- 奖励配置 `activity_reward_settings``issue_id``internal/repository/mysql/model/activity_reward_settings.gen.go:18`
- 活动承诺字段:`activities.commitment_*`(活动维度,已统一使用活动级承诺,不存在期级承诺表)
- 期下抽奖相关:
- 抽奖日志 `activity_draw_logs``issue_id``internal/repository/mysql/model/activity_draw_logs.gen.go:18`
- 抽奖效果 `activity_draw_effects``draw_log_id`/`issue_id``internal/repository/mysql/model/activity_draw_effects.gen.go:17,29`
- 抽奖凭据 `activity_draw_receipts``draw_log_id``internal/repository/mysql/model/activity_draw_receipts.gen.go:17`
- 活动范围效果与道具:
- 用户道具使用记录 `user_item_cards``used_activity_id` / `used_issue_id` / `used_draw_log_id``internal/repository/mysql/model/user_item_cards.gen.go:24,25,23`
- 抽奖效果快照 `activity_draw_effects``activity_id`/`issue_id``internal/repository/mysql/model/activity_draw_effects.gen.go:28,29`
- 资产与日志:
- 用户资产 `user_inventory``activity_id``internal/repository/mysql/model/user_inventory.gen.go:21`
- 公会贡献日志 `guild_contribute_logs``activity_id` / `issues_id``internal/repository/mysql/model/guild_contribute_logs.gen.go:19,20`
- 系统模板:
- 系统道具卡 `system_item_cards``activity_id` / `issue_id``internal/repository/mysql/model/system_item_cards.gen.go:23,24`
- 系统优惠券 `system_coupons``activity_id``internal/repository/mysql/model/system_coupons.gen.go:20`
- 最后删除活动主表:`activities``internal/repository/mysql/model/activities.gen.go:15`
### 删除用户Users.ID
- 用户身份与权益:
- 头衔 `user_titles``user_id``internal/repository/mysql/model/user_titles.gen.go:16`
- 领取型权益限流 `user_title_effect_claims``user_id``internal/repository/mysql/model/user_title_effect_claims.gen.go:16`
- 用户账户与地址:
- 地址 `user_addresses``user_id``internal/repository/mysql/model/user_addresses.gen.go:18`
- 积分余额 `user_points``user_id``internal/repository/mysql/model/user_points.gen.go:18`
- 积分流水 `user_points_ledger``user_id``internal/repository/mysql/model/user_points_ledger.gen.go:17`
- 用户订单与优惠:
- 订单 `orders``user_id``internal/repository/mysql/model/orders.gen.go:18`
- 用户优惠券 `user_coupons``user_id``internal/repository/mysql/model/user_coupons.gen.go:18`
- 用户资产与道具:
- 用户资产 `user_inventory``user_id``internal/repository/mysql/model/user_inventory.gen.go:18`
- 用户道具卡 `user_item_cards``user_id``internal/repository/mysql/model/user_item_cards.gen.go:18`
- 与抽奖相关:
- 抽奖效果 `activity_draw_effects``user_id` 或关联 `draw_log_id``internal/repository/mysql/model/activity_draw_effects.gen.go:18,17`
- 抽奖凭据 `activity_draw_receipts` 关联 `draw_log_id``internal/repository/mysql/model/activity_draw_receipts.gen.go:17`
- 抽奖日志 `activity_draw_logs``user_id``internal/repository/mysql/model/activity_draw_logs.gen.go:17`
- 公会关联:
- 公会成员 `guild_members``user_id``internal/repository/mysql/model/guild_members.gen.go:18`
- 公会贡献日志 `guild_contribute_logs``user_id``internal/repository/mysql/model/guild_contribute_logs.gen.go:18`
- 履约/发货:
- 发货记录 `shipping_records``user_id``internal/repository/mysql/model/shipping_records.gen.go:18`
- 运营发货统计 `ops_shipping_stats``user_id``internal/repository/mysql/model/ops_shipping_stats.gen.go:21`
- 最后软删用户:`users.deleted_at``internal/repository/mysql/model/users.gen.go:20`
## 删除顺序(事务内)
- 统一采用“从叶到根”的顺序:
1) 以日志/效果/凭据等子表为先(`activity_draw_effects``activity_draw_receipts``activity_draw_logs`
2) 再清理资产/权益/模板(`user_inventory``user_item_cards``user_titles``system_*`
3) 清理期与期下配置(`activity_issues``activity_reward_settings`
4) 删除根实体(`activities` 或软删 `users`
- 全过程包裹在单事务中,任何一步失败则回滚。
## 实现策略
- 新增业务服务方法:
- `DeleteActivityCascade(ctx, activityID)`:按“删除活动”清单顺序删除
- `DeleteUserCascade(ctx, userID)`:按“删除用户”清单顺序删除
- 技术要点:
- 批量删除使用分批(如 5k/批)避免长事务与大锁;必要时按时间/ID 片段迭代
- 统一 `WHERE` 条件与索引列(`user_id`/`activity_id`/`issue_id`/`draw_log_id`)确保扫描性能
- 软删与硬删:保留用户软删(合规与审计),其余按当前表定义硬删;如需统一软删,可后续逐表补充 `gorm.DeletedAt`
- 幂等性:每个子删除操作按条件删除,无记录时直接通过;重复调用不报错
- 审计记录操作日志操作者、对象ID、影响行数便于回溯
## 验收标准
- 删除活动时,任一期及其抽奖日志/效果/凭据、奖励配置、承诺、资产、贡献日志与相关模板均被清理;根活动删除成功。
- 删除用户时,地址/订单/优惠券/积分(余额+流水)/资产/道具/抽奖相关/公会关系/发货记录及统计均被清理;根用户软删成功。
- 全流程事务保障、失败回滚;批量删除性能稳定,无显著锁表或超时。
## 需要改造的现有入口(参考)
- 活动删除入口:`internal/service/activity/activity_delete.go:9` → 升级为调用 `DeleteActivityCascade`
- 期删除入口:`internal/service/activity/issue_delete.go:9` → 被 `DeleteActivityCascade` 内部调用(或保留独立级联)
- 用户删除入口:`internal/service/user/batch_user.go:32` → 升级为调用 `DeleteUserCascade`
## 后续动作
- 我将基于以上清单与顺序,补充两套事务级联删除实现,并为关键入口替换调用;同时补充单元测试覆盖正常/边界/异常三类用例,验证幂等与性能。