# 通知事件触发时机备忘录

本文用于记录当前项目内通知事件码的实际触发时机，便于后续配置“通知策略中心”、排查通知链路和补齐模板。

## 1. 已实现事件

| 事件码 | 业务含义 | 触发时机 | 触发位置 | 业务对象 | 主要变量 | 默认接收人建议 | 备注 |
| --- | --- | --- | --- | --- | --- | --- | --- |
| `AUDIT_TASK_ASSIGNED` | 审核任务已分配 | 会议提交后创建首个审核任务时触发 | `backend/src/main/java/com/writeoff/module/meeting/service/MeetingService.java:477` | `MEETING` | `meetingId` `meetingTopic` `auditNode` `auditTaskId` `assigneeUserId` | `AUDITOR` | 仅在存在明确审核人时触发，实际派发封装在 `MeetingService.triggerAuditTaskAssignedNotification()` |
| `AUDIT_TASK_ASSIGNED` | 审核任务已分配 | 某一审核节点通过后，创建下一审核节点任务时触发 | `backend/src/main/java/com/writeoff/module/audit/service/AuditService.java:294` | `MEETING` | `meetingId` `meetingTopic` `auditNode` `auditTaskId` `assigneeUserId` | `AUDITOR` | 适用于初审通过进入复审、复审通过进入终审 |
| `AUDIT_TASK_ASSIGNED` | 审核任务已分配 | 复审或终审拒绝后，流程回到首节点并重新创建首节点任务时触发 | `backend/src/main/java/com/writeoff/module/audit/service/AuditService.java:336` | `MEETING` | `meetingId` `meetingTopic` `auditNode` `auditTaskId` `assigneeUserId` | `AUDITOR` | 这里是“重新发起首审任务”的提醒，不是给提交人的结果通知 |
| `AUDIT_APPROVED_FINAL` | 终审通过 | 审核通过且不存在下一审核节点时触发 | `backend/src/main/java/com/writeoff/module/audit/service/AuditService.java:288` | `MEETING` | `meetingId` `meetingTopic` `auditNode` `auditTaskId` `result` `opinion` | `SUBMITTER` | 当前用于“最终审核通过”通知提交人；`result` 固定解析为“通过” |
| `AUDIT_REJECTED` | 审核拒绝 | 初审节点执行拒绝，且本轮审核直接结束时触发 | `backend/src/main/java/com/writeoff/module/audit/service/AuditService.java:312` | `MEETING` | `meetingId` `meetingTopic` `auditNode` `auditTaskId` `result` `opinion` | `SUBMITTER` | 当前只在初审拒绝时触发；`result` 固定解析为“不通过” |
| `AUDIT_RETURNED` | 审核退回 | 审核人员执行“退回修改”动作时触发 | `backend/src/main/java/com/writeoff/module/audit/service/AuditService.java:350` | `MEETING` | `meetingId` `meetingTopic` `auditNode` `auditTaskId` `result` `opinion` | `SUBMITTER` | 与“拒绝”分开建码；`result` 固定解析为“退回” |
| `USER_CREATED` | 用户创建成功 | 新用户创建完成后自动触发 | `backend/src/main/java/com/writeoff/module/system/service/SystemUserService.java:778` | `USER` | `email` `validFrom` `validTo` `tenantCode` `tenantName` `loginPath` | `TARGET_USER` | 与会议审核无关，但已是现网实际触发事件 |

## 2. 兼容保留事件

| 事件码 | 当前状态 | 说明 | 备注 |
| --- | --- | --- | --- |
| `AUDIT_APPROVED` | 兼容保留，不再作为主触发事件 | 前端通知策略页和状态文案仍保留该选项，用于兼容历史策略或历史数据 | 后端审核主流程已改为触发 `AUDIT_APPROVED_FINAL`；`AuditService.resolveAuditResultText()` 仍兼容识别该旧码 |

## 3. 预留未接入事件

| 事件码 | 当前状态 | 说明 | 建议 |
| --- | --- | --- | --- |
| `FINANCE_CONFIRMED` | 前端已展示，后端未发现实际触发点 | 当前代码扫描只发现状态文案和通知策略下拉选项，未发现自动派发逻辑 | 后续确定“财务确认”的真实业务动作后，再补后端触发点和变量定义 |

## 4. 审核事件变量说明

### 4.1 审核任务分配类

`AUDIT_TASK_ASSIGNED` 当前由 `MeetingService.triggerAuditTaskAssignedNotification()` 统一派发，变量如下：

| 变量名 | 含义 |
| --- | --- |
| `meetingId` | 会议 ID |
| `meetingTopic` | 会议主题 |
| `auditNode` | 当前审核节点，如 `INIT_REVIEW`、`RE_REVIEW`、`FINAL_REVIEW` |
| `auditTaskId` | 审核任务 ID |
| `assigneeUserId` | 被分配审核人的用户 ID |

### 4.2 审核结果类

`AUDIT_APPROVED_FINAL`、`AUDIT_REJECTED`、`AUDIT_RETURNED` 当前由 `AuditService.triggerAuditNotification()` 派发，变量如下：

| 变量名 | 含义 |
| --- | --- |
| `meetingId` | 会议 ID |
| `meetingTopic` | 会议主题 |
| `auditNode` | 触发该动作的审核节点 |
| `auditTaskId` | 审核任务 ID |
| `result` | 结果文案，当前可能为“通过”“不通过”“退回” |
| `opinion` | 审核意见 |

## 5. 当前落地口径

1. “提醒审核人员”统一使用 `AUDIT_TASK_ASSIGNED`，由通知策略决定站内信、邮件等发送方式。
2. “审核结果提醒提交人”当前拆分为三个结果事件：`AUDIT_APPROVED_FINAL`、`AUDIT_REJECTED`、`AUDIT_RETURNED`。
3. 复审通过本身不会直接通知提交人，因为流程仍未结束；它会触发下一节点的 `AUDIT_TASK_ASSIGNED`，通知下一位审核人。
4. 复审或终审拒绝时，当前实现是重置到首审并重新派发首审任务，因此会触发 `AUDIT_TASK_ASSIGNED`，但不会额外触发 `AUDIT_REJECTED`。
5. 前端当前默认接收人规则已对齐：
   - `AUDIT_TASK_ASSIGNED` -> `AUDITOR`
   - `AUDIT_APPROVED_FINAL` -> `SUBMITTER`
   - `AUDIT_REJECTED` -> `SUBMITTER`
   - `AUDIT_RETURNED` -> `SUBMITTER`
   - `USER_CREATED` -> `TARGET_USER`

## 6. 后续建议

1. 在“通知策略中心”中为上述事件分别配置默认模板，避免事件已触发但无可用策略。
2. 若业务上希望“复审拒绝/终审拒绝”同时通知提交人，需要补充一个新的结果事件，或调整现有拒绝分支逻辑。
3. 若后续启用 `FINANCE_CONFIRMED`，应先明确触发动作、接收人、变量字段，再补后端派发。

## 7. 建议通知文案模板

### 7.1 使用说明

1. 系统当前通知模板占位符语法为 `${变量名}`。
2. 以下模板均只使用当前后端已实际传递的变量，可以直接用于现有通知模板配置。
3. `auditNode` 当前是英文枚举值，如 `INIT_REVIEW`、`RE_REVIEW`、`FINAL_REVIEW`。如果希望直接展示“初审 / 复审 / 终审”中文名称，建议后续补充 `auditNodeName` 变量。
4. 以下内容更适合站内信和邮件；如果后续要接短信，建议再单独准备精简版。

### 7.2 `AUDIT_TASK_ASSIGNED`

- 模板名称：会议审核任务提醒
- 适用场景：会议提交审核后、审核通过流转到下一节点后、复审/终审拒绝后重新回到初审时
- `subjectTemplate`：`会议审核任务待处理`
- `titleTemplate`：`会议《${meetingTopic}》待您审核`
- `contentTemplate`：

```text
您有一条新的会议审核任务待处理。
会议主题：${meetingTopic}
会议ID：${meetingId}
当前审核节点：${auditNode}
审核任务ID：${auditTaskId}
请尽快登录系统完成审核处理。
```

### 7.3 `AUDIT_REJECTED`

- 模板名称：会议初审拒绝通知
- 适用场景：初审拒绝时触发
- `subjectTemplate`：`会议初审未通过通知`
- `titleTemplate`：`您提交的会议《${meetingTopic}》初审未通过`
- `contentTemplate`：

```text
您提交的会议审核未通过。
会议主题：${meetingTopic}
会议ID：${meetingId}
处理节点：${auditNode}
审核结果：${result}
审核意见：${opinion}
请根据审核意见修改后重新提交。
```

### 7.4 `AUDIT_RETURNED`

- 模板名称：会议退回修改通知
- 适用场景：退回修改时触发
- `subjectTemplate`：`会议已退回修改`
- `titleTemplate`：`您提交的会议《${meetingTopic}》已退回修改`
- `contentTemplate`：

```text
您提交的会议已被退回修改。
会议主题：${meetingTopic}
会议ID：${meetingId}
处理节点：${auditNode}
审核结果：${result}
审核意见：${opinion}
请根据审核意见完成修改后再次提交审核。
```

### 7.5 `AUDIT_APPROVED_FINAL`

- 模板名称：会议终审通过通知
- 适用场景：最后一个审核节点通过时触发
- `subjectTemplate`：`会议终审通过通知`
- `titleTemplate`：`您提交的会议《${meetingTopic}》已审核通过`
- `contentTemplate`：

```text
您提交的会议已完成审核并通过。
会议主题：${meetingTopic}
会议ID：${meetingId}
通过节点：${auditNode}
审核结果：${result}
审核意见：${opinion}
您可以继续后续业务处理。
```

### 7.6 模板命名建议

1. `AUDIT_TASK_ASSIGNED`：会议审核任务提醒
2. `AUDIT_REJECTED`：会议初审拒绝通知
3. `AUDIT_RETURNED`：会议退回修改通知
4. `AUDIT_APPROVED_FINAL`：会议终审通过通知
