## 目标

* 移除无关的“客服组”等错误效果类型与字段，严格对齐后端模型定义（SystemTitles/SystemTitleEffects/UserTitles）。

* 统一“效果类型/参数/叠加策略/封顶/作用范围”配置为后端可用的结构，确保抽奖逻辑（effect\_type=5/6）准确生效。

* 优化前端管理界面与 API 交互，保证运营可视化配置与后端运行一致。

## 范围

* 前端文件：

  * `web/admin/src/views/operations/titles/components/EffectEditDialog.vue`

  * `web/admin/src/views/operations/titles/components/EffectManagerDialog.vue`

  * `web/admin/src/views/operations/titles/components/RuleConfigDialog.vue`

  * `web/admin/src/views/operations/titles/index.vue`

  * `web/admin/src/api/titles.ts`

* 后端仅对齐说明，不改动逻辑（模型/服务已正确）：

  * `internal/service/activity/draw_with_effects.go`（抽奖应用）

  * `internal/service/title/effects_resolver.go`（效果范围）

  * `internal/api/admin/titles_admin.go`（创建/修改/分配）

## 重构设计（按模型对齐）

### 效果类型与参数（替换现有 UI 与默认值）

* 1 领券（优惠券使者）

  * `params_json`：`{ "template_id": number, "frequency": { "period": "day|week|month", "times": number } }`

* 2 抽奖折扣

  * `params_json`：`{ "discount_type": "percentage|fixed", "value_x1000": number, "max_discount_x1000": number }`

* 3 签到倍数

  * `params_json`：`{ "multiplier_x1000": number, "daily_cap_points": number }`

* 4 领道具卡

  * `params_json`：`{ "template_id": number, "frequency": { "period": "week|month", "times": number } }`

* 5 概率加成（抽奖）

  * `params_json`：`{ "target_prize_ids": number[], "boost_x1000": number, "cap_x1000": number? }`

* 6 奖品双倍概率（抽奖）

  * `params_json`：`{ "target_prize_ids": number[], "chance_x1000": number, "period_cap_times": number? }`

* 移除：`生日特权/专属客服` 效果类型与全部相关字段（UI/默认值/展示/说明）。

### 叠加策略与封顶（严格按模型）

* `stacking_strategy` 取值与文案：

  * 0：最大值（max\_only）

  * 1：累加封顶（sum\_with\_cap）

  * 2：首个匹配（first\_match）

* `cap_value_x1000`：统一封顶，单位千分比（用于 5/6 合并时的全局封顶）。

* 统一前端控件与默认值（默认建议：1 累加封顶；`cap_value_x1000`=0 表示不封顶）。

### 效果作用范围（效果级 scopes\_json）

* 字段：`activity_ids/issue_ids/category_ids` 与 `exclude.*`

* 在效果编辑对话框中新增“作用范围”折叠面板：

  * 多选输入上述集合；支持排除列表；空集合视为全局。

* 展示格式：在效果列表中将 `scopes_json` 可视化为“包含/排除”标签。

### 获得规则（标题级 obtain\_rules\_json）

* 保留 UI（方便运营标注），明确说明其仅存储，不参与当前自动授予；后续如接入事件评估器再使用。

* JSON 结构：`{ methods: string[], conditions: object }`；维持现有 RuleConfigDialog 保存逻辑。

## 具体改动点（不执行，供审核）

* `EffectEditDialog.vue`

  * 替换效果类型下拉项为 1\~6 正确枚举；删除“生日特权/专属客服”。

  * 重写各类型的表单字段与 `getDefaultParams()` 返回值，改为上述模型参数结构。

  * 调整 `stacking_strategy` 单选值为 0/1/2；文案与后端一致。

  * 新增“作用范围”字段并在提交时携带 `scopes_json`。

* `EffectManagerDialog.vue`

  * 更新 `effectTypes` 名称与 Tag 映射为正确文案：`领券/抽奖折扣/签到倍数/领道具卡/概率加成/双倍概率`。

  * 调整 `stackingStrategies` 文案为 0/1/2；去掉无模型项。

  * 更新参数格式化 `formatParam()`，支持 `template_id/frequency/discount_type/value_x1000/...`。

  * 增加对 `scopes_json` 的展示：包含/排除集合标签。

* `RuleConfigDialog.vue`

  * 保留现有 UI；在文档中明确“标题级范围不参与运行时判定”，避免误解。

* `titles.ts`

  * 校验请求参数与后端一致：`effect_type/params_json/stacking_strategy(0|1|2)/cap_value_x1000/scopes_json/sort/status`。

## 数据迁移与兼容

* 已存在的效果记录：

  * 运营检查并手动改为新结构（通过管理端编辑），或提供一次性迁移脚本：按 `effect_type` 将旧 `params_json` 映射为新字段。

* 前端：

  * 旧页面中“生日特权/客服组”等效果无法再新建；编辑时提示需切换为模型定义效果。

## 测试与验收

* 配置与展示：创建每一种效果，检查列表显示与 JSON 持久化。

* 抽奖逻辑：

  * `effect_type=5`：目标奖品权重按 `boost_x1000` 调整，叠加与封顶正确；参见 `internal/service/activity/draw_with_effects.go`。

  * `effect_type=6`：双倍概率按 `chance_x1000` 合并封顶；命中后倍数 x2；名称后缀标识；参见同文件。

* 作用范围：在 issueID 不同期下验证包含/排除命中行为；参见 `effects_resolver.go` 与抽奖文件。

* 运营页面每个功能或者配置字段需要详细描述

## 交付物

* 代码层面的重构（上述文件修改）。

* 文档更新：已在 `docs/称号系统/说明文档.md` 完成字段级详解与代码绑定点，重构后同步补充“字段校验与默认值”章节与新 UI 截图位点。

## 风险与注意

* 现有错误效果类型的数据需运营确认是否迁移或删除。

* 前端表单字段与后端参数必须完全对齐，否则抽奖效果不会生效。

确认后我将开始实施重构并提供测试用例与验证记录。
