需求背景
pipipen-api 通知系统全量盘点),批准方案「新增 2 个开关 + 节点确认并入既有开关」。work_task.confirm_stage 语义扩展,并在默认清单新增 4 个 key(响应数组新增 key);本次不改 HTTP 方法/路径/请求参数/错误码,也不改任何场景的发送条件与通知模板。WorkTask(委托);Open Call = Project(对外展示名)。更新记录
2026-09-22 首次发布:SystemNotificationSwitchScene 新增 commission_cancellation.updated / commission_refund.updated,work_task.confirm_stage 语义扩展为节点确认全生命周期(开发阶段契约,后端未发版)。2026-09-23 修订:字段表去除 emoji 前缀(按在途同域迭代规则,展示形式调整,契约无变化)。建议阅读顺序:第 1 章(一分钟上手)→ 第 2 章(接口变更总览)→ 第 3 章(接口示例)→ 第 4 章(场景登记口径)→ 第 5 章(兼容性与前端跟进清单)。遇到「某个场景到底归哪个开关」先看第 4 章登记清单。
| 章 | 内容 | 什么时候看 |
|---|---|---|
| 1. 一分钟上手 | 开关→通道决策图 + 存量合并图 + 七条对接要点 | 刚拿到文档 |
| 2. 接口变更 | 通知设置两个接口的变更摘要 | 找接口 |
| 3. 接口示例 | 请求参数、响应示例与错误语义 | 对接具体接口 |
| 4. 接口/字段补充说明 | 登记 / 不登记 / 暂缓场景口径与映射去重 | 查具体归属 |
| 5. 兼容性说明 | 兼容结论与前端跟进清单 | 发布前确认 |
先看两张图理解「用户开关如何决定一条通知走哪些通道」,再读七条对接要点即可开始对接。 本次是纯增量:新增 3 个开关 key(2 个新开关 + 1 个既有开关补入客户侧),没有新增/删除/改名的 HTTP 接口,也没有改动任何场景的发送条件。
登记开关只增加「可自定义」能力:登记前后「用户未设置」都走默认渠道,行为一致;无兼容性突变。
POST /api/notification_setting/list、POST /api/notification_setting/update 的路径、参数、错误码全部不变;只是响应里的开关数组多了元素,属向后兼容的纯增量。user 角色新增 commission_cancellation.updated、commission_refund.updated、work_task.confirm_stage;artist 角色新增 commission_cancellation.updated。当前前端设置页的开关清单是前端硬编码(pages/account/inform.vue 的 user_list / artist_list),只渲染本地清单里存在的 key——后端响应里有、前端清单里没有的 key 不会自动出现。前端需按第 5 章清单补齐。commission_cancellation.updated / commission_refund.updated / work_task.confirm_stage 的 email / site_msg / sms 默认均为 true;存量用户无需重新保存,读取响应即包含这些 key 与默认值。work_task.confirm_stage 语义扩展为「节点确认」:该开关现覆盖交稿待确认、到期提醒、自动确认(共 3 个新场景)与既有节点确认场景;前端文案 set.inform.confirm_stage 需由「客户确认节点」改为「节点确认」,并在客户(user)角色的设置页新增渲染该开关(此前只在画师侧展示)。commission_refund.updated 的两个场景都只发客户,artist 角色的默认清单不含该 key,前端画师侧不要渲染。POST /api/notification_setting/list
user(客户)/ artist(画师)两套通知开关设置user 3 个、artist 1 个),存量用户读取时自动按默认清单合并出新 keyPOST /api/notification_setting/update
user / artist 通知开关设置两个接口共用同一套
NotificationChannelSetting(key/site_msg/sms)响应结构,只是list为只读、update为写后回读。
POST /api/notification_setting/listuser(客户)与 artist(画师)两套通知开关设置。非画师用户的 artist 为 null。user 新增 commission_cancellation.updated、commission_refund.updated、work_task.confirm_stage;artist 新增 commission_cancellation.updated;⚠️ 既有开关 work_task.confirm_stage 语义扩展为节点确认全生命周期。存量用户已保存的旧 key 值保持不变,新 key 以三通道全开的默认值补齐。无。
上面只截取部分 key 示意,完整清单以
NotificationSettingService::getDefaultSettings()为准。非画师用户的artist返回null。
无新增,沿用原有错误语义(未登录为既有鉴权错误)。
POST /api/notification_setting/updateuser / artist 通知开关设置,写入后回读最新设置。user.*.key / artist.*.key 正常提交,未提交的新 key 在响应里保留默认值。| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
user | array | 否 | 客户角色开关数组;仅提交需要修改的项即可 |
user.*.key | string | 是(有 user 时) | 开关 key,例如 commission_cancellation.updated |
user.*.email | boolean | 否 | 邮件通道开关 |
user.*.site_msg | boolean | 否 | 站内信通道开关 |
user.*.sms | boolean | 否 | 短信通道开关 |
artist | array | 否 | 画师角色开关数组;仅画师用户生效 |
artist.*.key | string | 是(有 artist 时) | 开关 key,例如 commission_cancellation.updated |
artist.*.email | boolean | 否 | 邮件通道开关 |
artist.*.site_msg | boolean | 否 | 站内信通道开关 |
artist.*.sms | boolean | 否 | 短信通道开关 |
key 不在默认清单内的项会被忽略,不写入存储;不会报错。artist 会被忽略,不影响 user 设置。响应为写后回读的完整设置(此处只截取被修改的 key);结构同
list。
422:参数类型校验失败
无新增错误码。
开关枚举 SystemNotificationSwitchScene 新增 2 个 case,映射 NotificationSettingService::getMapSwitchToScene() 新增 2 组、扩展 1 组。
| 开关 key | 展示角色 | 聚合场景 | 场景数 |
|---|---|---|---|
commission_cancellation.updated | user + artist | commission_cancellation.user_created / artist_created / rejected / withdrawn / accepted / completed;worktask.user_canceled / admin_canceled / artist_canceled | 9 |
commission_refund.updated | 仅 user | commission_refund.awaiting_destination / completed | 2 |
work_task.confirm_stage(既有开关,语义扩展) | user + artist | 既有 worktask.user_confirm_stage / worktask.stage_finished;新增 worktask.stage_awaiting_confirmation / stage_auto_confirm_reminder / stage_auto_confirmed | 5(+3) |
说明:
commission_cancellation.updated 在客户与画师两个角色都展示。commission_refund.updated 不加入画师默认清单。work_task.confirm_stage 并入节点确认 3 场景后覆盖节点确认全生命周期(画师交稿请求确认 → 到期提醒 → 自动确认 / 客户确认 → 节点完成),粒度与既有「稿酬变更」(一个开关聚合 10 个场景)一致;客户侧新增展示该开关。保持始终发送,用户设置页不展示对应开关:
| 场景 | 理由 |
|---|---|
worktask.refresh | 前端实时刷新的技术广播,非用户通知 |
wallet.need_rebind / wallet.kyc / wallet.alipay_publish | 钱包安全与合规提醒,必须送达 |
activity.christmas_event | 运营活动推送,运营侧控制 |
admin.joined_group | 管理员入群的系统事件 |
worktask.artist_rejected | 死场景(全库无发送代码,仅枚举定义),另行立项清理 |
本轮不动,避免设置页一次性膨胀:
project_request.created / user_choosen / artist_exited / user_canceled / artist_rejected / artist_accepted / user_paid,以及 project.user_canceled / project.artist_canceledservice_request.user_canceled / admin_canceledproduct_order.paid、product.refreshartist_rec_review.created、user_rec_review.createduser_applicant.accepted / rejectedgroup.created、group.reminderworktask.created、report.processed上述未登记场景在
NotificationSettingService::getMapSwitchToScene()中无映射,SystemNotification::via()直接走默认渠道(站内信 + 邮件 + 短信 + 用户动作),行为与本次改动前一致。
worktask.stage_finished 同时出现在 work_task.user_paid 与 work_task.confirm_stage 映射里,worktask.finished 同时出现在 work_task.user_paid 与 work_task.confirm_last_stage 里。buildSceneToSwitchCache() 对同一场景后写覆盖,实际归属一直是 work_task.confirm_stage / work_task.confirm_last_stage。work_task.user_paid 列表移除这两个场景(去重),不改变实际归属与发送行为,仅消除歧义;work_task.user_paid 仍聚合 service_request.user_paid / worktask.wait_pay / worktask.working。getRoleSettings() 按默认清单合并,已保存的旧 key 值保持不变,新 key 以三通道全开补齐。SystemNotification.php 的 via() / getCustomChannels() 逻辑不变,未登记场景仍走默认渠道。notification_templates seeder 与任何场景值。pipipen-front,本任务不实施)当前设置页 pages/account/inform.vue 的 user_list / artist_list 为硬编码清单,fetch_list() 只把后端响应值回填到本地清单已有的 key 上。后端新增 key 后,前端必须显式补齐以下内容:
commission_cancellation.updated:「取消与退款协商」(建议 locale key set.inform.commission_cancellation)commission_refund.updated:「退款进度」(建议 locale key set.inform.commission_refund)set.inform.confirm_stage:中文「客户确认节点」→「节点确认」;同步调整英文(现为 Client confirmed a stage)与日文(现为 クライアントによるステージ確認),避免与并入后的语义不符。user_list(客户角色)新增 3 个 key
commission_cancellation.updated → 文案见第 1 条commission_refund.updated → 文案见第 1 条work_task.confirm_stage → 文案用改后的 set.inform.confirm_stage(此前只在画师侧渲染,客户侧需新增)artist_list(画师角色)新增 1 个 key
commission_cancellation.updated → 文案见第 1 条(退款开关不在画师侧展示,勿加)新 key 默认三通道全开,前端无需为默认值做兼容处理;仅需补齐清单与文案。
fetch_list 回填时需注意旧前端对缺失 key 的空值处理,见下条注意事项)。注意事项:当前前端
fetch_list()对本地清单里的每个 key 直接执行data.user.find(...)后取item.site_msg,未做空值判断。若前端清单已加 key 而后端未上线(或回滚),会因item为undefined报错。发布顺序请保证后端先上线,或由前端补上空值兜底。