工单短信触达需求文档
基于DDD领域驱动设计,实现工单短信自动触达、手动回复、回访处理及统计报表功能
页面内容
📋 需求概述
项目背景
投诉工单系统需要新增短信通知功能,实现工单受理、结案、回访的短信触达,并改造直通率统计报表。
核心目标
- 自动发送受理短信:新建工单后自动发送受理通知
- 手动短信回复:支持处理人员手动发送结案通知短信
- 短信回访:工单结案后自动发送回访短信,处理客户回复
- 统计报表改造:基于主办机构计算直通办理率
🏗️ 领域模型设计
核心领域(Core Domain)
1. 投诉工单实体(ComplaintOrder)
// 核心字段
- orderId: 工单ID
- orderType: 工单类型(12378、监管转办、消保转送、咨询等)
- contactName: 联系人姓名
- contactPhone: 联系人电话
- complainantPhone: 投诉人电话
- mainOrg: 主办机构(总行/信用卡中心/分行/其他)
- mainOperator: 主办人员
- isSmsReply: 是否短信回复(是/否)
- smsReplyTime: 回复时间
- isSmsVisit: 是否短信回访(是/否)
- visitDate: 回访日期
- visitTime: 回访时间
- visitResult: 回访效果(满意/不满意)
- processNotifyType: 处理决定告知方式(短信/其他)
- processNotifyTime: 处理决定告知时间
2. 短信交互实体(SmsInteraction)
- smsId: 短信记录ID
- orderId: 关联工单
- smsType: 短信类型(受理通知/结案通知/回访)
- templateId: 短信模板
- phone: 发送手机号
- customerName: 客户姓名
- sendTime: 短信发送时间
- sendOperator: 发送人
- replyContent: 客户回复内容
- replyTime: 客户回复时间
3. 短信模板实体(SmsTemplate)
- templateId: 模板ID
- templateName: 模板名称
- templateContent: 模板内容
- templateType: 类型(受理/结案/回访)
- approvedStatus: 业务审核状态
- visibleRoles: 可见角色(总行/分行)
- enabled: 是否启用
🎯 功能需求与开发任务
功能一:新建工单自动发送受理短信
📌 功能描述
投诉工单新建成功后,系统自动发送受理短信给联系人。
🔧 开发功能点
1.1 工单创建事件监听
- 实现工单创建领域事件(OrderCreatedEvent)
- 配置事件监听器(OrderCreatedEventListener)
- 事件发布机制(EventPublisher)
1.2 短信发送服务
- 实现短信发送服务接口(SmsSendService)
- 手机号格式校验(PhoneValidator)
- 短信模板加载(TemplateLoader)
- 短信网关调用(SmsGatewayClient)
- 发送失败重试机制(RetryHandler)
1.3 短信记录持久化
- 创建短信发送记录(SmsRecordRepository.save)
- 记录发送状态(成功/失败)
- 记录发送时间、操作人等信息
1.4 异常处理
- 非手机号跳过发送(日志记录)
- 短信网关异常捕获与日志
- 发送失败告警通知
✅ 单元测试点
// 测试类:OrderCreatedEventListenerTest
@Test
void test_工单创建后自动发送受理短信_成功() {
// Given: 创建工单事件,联系人为手机号
// When: 触发事件监听
// Then: 验证短信发送服务被调用,记录已保存
}
@Test
void test_工单创建后自动发送受理短信_非手机号跳过() {
// Given: 创建工单事件,联系人为座机
// When: 触发事件监听
// Then: 验证短信发送服务未被调用,记录日志
}
@Test
void test_工单创建后自动发送受理短信_发送失败重试() {
// Given: 短信网关首次调用失败
// When: 触发重试机制
// Then: 验证重试3次,最终记录失败状态
}
@Test
void test_短信模板加载_模板不存在() {
// Given: 受理短信模板未配置
// When: 尝试加载模板
// Then: 抛出业务异常,记录错误日志
}
功能二:工单结案短信回复(人工触发)
📌 功能描述
工单处理页面新增【短信回复】按钮,支持处理人员手动发送结案通知短信。
🔧 开发功能点
2.1 前端UI开发
- 工单处理页面添加【短信回复】按钮
- 实现短信发送弹窗组件(SmsReplyModal)
- 弹窗字段:客户姓名(只读)、手机号(只读)、模板选择(单选)
- 模板列表按角色过滤(总行/分行)
2.2 后端API开发
- 创建短信回复接口(POST /api/orders/{orderId}/sms-reply)
- 参数校验:工单ID、模板ID、手机号一致性校验
- 权限校验:派单处理人员权限
- 业务规则校验:每个工单仅允许发送一次
2.3 短信模板权限控制
- 实现模板可见性过滤(TemplateVisibilityFilter)
- 总行角色:仅显示总行模板
- 分行角色:仅显示分行模板
- 模板审核状态校验(仅已审核通过可用)
2.4 工单状态更新
- 更新工单字段:
isSmsReply = true - 更新工单字段:
smsReplyTime = 当前时间 - 更新工单字段:
processNotifyType = "短信" - 更新工单字段:
processNotifyTime = 当前时间
2.5 短信发送与记录
- 调用短信发送服务
- 保存短信发送记录
- 返回发送结果
✅ 单元测试点
// 测试类:OrderSmsReplyControllerTest
@Test
void test_发送短信回复_成功() {
// Given: 工单存在,未发送过短信,模板已审核
// When: 调用短信回复接口
// Then: 验证短信发送成功,工单状态已更新
}
@Test
void test_发送短信回复_工单已发送过短信() {
// Given: 工单已发送过短信回复
// When: 再次调用短信回复接口
// Then: 返回业务异常:"每个工单仅允许发送一次"
}
@Test
void test_发送短信回复_手机号不一致() {
// Given: 请求中的手机号与工单联系人手机号不一致
// When: 调用短信回复接口
// Then: 返回参数校验异常
}
@Test
void test_发送短信回复_模板未审核() {
// Given: 选择的模板审核状态为"待审核"
// When: 调用短信回复接口
// Then: 返回业务异常:"模板未审核通过"
}
@Test
void test_发送短信回复_无权限() {
// Given: 当前用户无派单处理权限
// When: 调用短信回复接口
// Then: 返回权限异常
}
// 测试类:TemplateVisibilityFilterTest
@Test
void test_模板可见性过滤_总行角色() {
// Given: 当前用户为总行角色
// When: 获取可用模板列表
// Then: 仅返回总行模板
}
@Test
void test_模板可见性过滤_分行角色() {
// Given: 当前用户为分行角色
// When: 获取可用模板列表
// Then: 仅返回分行模板
}
功能三:短信回访
📌 功能描述
工单办结后,自动发送回访短信。客户回复"BMY"表示不满意。
🔧 开发功能点
3.1 回访触发机制
- 实现工单结案事件监听(OrderClosedEvent)
- 校验回访条件:
isSmsVisit = true且联系电话为手机号 - 触发回访短信发送
3.2 回访短信发送
- 加载回访短信模板
- 调用短信发送服务
- 记录回访短信发送记录
- 设置回访有效期:发送时间 T + 3 自然日
3.3 客户回复处理
- 实现短信回复接收接口(POST /api/sms/reply)
- 解析回复内容:识别"BMY"关键字
- 更新回访效果:
visitResult = "不满意"(回复BMY) - 更新回访日期时间:
visitDate、visitTime= 短信发送时间 - 仅统计首次客户回复(多次发送只统计第一次)
3.4 回访有效期管理
- 实现回访有效期校验(VisitValidityChecker)
- 超过有效期(T+3天)的回复不处理
- 记录过期回复日志
✅ 单元测试点
// 测试类:OrderClosedEventListenerTest
@Test
void test_工单结案后自动发送回访短信_满足条件() {
// Given: 工单结案,isSmsVisit=true,联系电话为手机号
// When: 触发结案事件
// Then: 验证回访短信已发送
}
@Test
void test_工单结案后自动发送回访短信_不满足条件() {
// Given: 工单结案,isSmsVisit=false
// When: 触发结案事件
// Then: 验证回访短信未发送
}
// 测试类:SmsReplyHandlerTest
@Test
void test_处理客户回复_BMY表示不满意() {
// Given: 收到客户回复"BMY"
// When: 处理回复
// Then: 验证回访效果更新为"不满意",回访日期时间已更新
}
@Test
void test_处理客户回复_非BMY内容() {
// Given: 收到客户回复"谢谢"
// When: 处理回复
// Then: 验证回访效果未更新(保持原值或默认值)
}
@Test
void test_处理客户回复_仅统计首次回复() {
// Given: 已处理过首次回复
// When: 收到第二次回复
// Then: 验证第二次回复被忽略,不更新回访效果
}
@Test
void test_处理客户回复_超过有效期() {
// Given: 回访短信发送时间超过3天
// When: 收到客户回复
// Then: 验证回复被忽略,记录过期日志
}
// 测试类:VisitValidityCheckerTest
@Test
void test_回访有效期校验_在有效期内() {
// Given: 发送时间T,当前时间T+2天
// When: 校验有效期
// Then: 返回true
}
@Test
void test_回访有效期校验_超过有效期() {
// Given: 发送时间T,当前时间T+4天
// When: 校验有效期
// Then: 返回false
}
功能四:工单流程与字段改造
📌 功能描述
针对不同工单类型(12378投诉、监管转办、消保转送、咨询问题)进行字段和流程改造。
🔧 开发功能点
4.1 12378投诉工单改造
- 主办人员字段:主办机构=总行时默认当前经办人,支持修改
- 回复时间字段:
isSmsReply=是时必填校验 - 工单转办类型:转办时显示"投诉转办部门"字段
- 流程处理方式:选"本节点处理"时显示"机构投诉办理情况表"
- 表单新增字段:“投诉处理过程及下一步整改措施”
4.2 消保转送工单改造
- 新增"主办人员"字段
- “处理决定是否告知"字段:新增"是(短信)“选项
- “告知时间"字段:短信发送时自动填充
- “告知方式"字段:选择短信时显示为"短信”
4.3 咨询问题工单改造
- 新增"主办机构"字段
- 新增"主办人员"字段
4.4 字段显示控制
- 实现动态表单字段显示逻辑(DynamicFormFieldController)
- 根据工单类型、流程状态控制字段显示/隐藏
- 实现字段必填校验规则(FieldValidationRule)
✅ 单元测试点
// 测试类:ComplaintOrderServiceTest
@Test
void test_12378工单_主办机构为总行时默认主办人员() {
// Given: 创建12378工单,主办机构=总行,当前经办人=张三
// When: 保存工单
// Then: 验证主办人员自动填充为"张三",支持手动修改
}
@Test
void test_12378工单_回复时间必填校验() {
// Given: 12378工单,isSmsReply=是,回复时间为空
// When: 保存工单
// Then: 返回字段校验异常:"回复时间必填"
}
@Test
void test_消保转送工单_处理决定告知方式为短信() {
// Given: 消保转送工单,处理决定告知方式选择"是(短信)"
// When: 发送短信后保存工单
// Then: 验证告知方式显示为"短信",告知时间已填充
}
// 测试类:DynamicFormFieldControllerTest
@Test
void test_字段显示控制_转办类型为转办时显示投诉转办部门() {
// Given: 监管转办工单,转办类型="转办"
// When: 获取表单字段配置
// Then: 验证"投诉转办部门"字段可见
}
@Test
void test_字段显示控制_流程处理方式为本节点处理时显示情况表() {
// Given: 监管转办工单,流程处理方式="本节点处理"
// When: 获取表单字段配置
// Then: 验证"机构投诉办理情况表"字段可见
}
功能五:直通率统计报表
📌 功能描述
基于主办机构计算直通办理率,包括总直通率、总行直通率、分行直通率。
🔧 开发功能点
5.1 数据查询服务
- 实现工单统计查询接口(OrderStatisticsService)
- 按主办机构分类统计工单量
- 支持时间范围筛选
- 支持工单类型筛选
5.2 直通率计算逻辑
- 实现总直通率计算:各主办机构工单量 / 工单总量
- 实现总行直通率计算:(总行+信用卡中心工单量)/ 工单总量
- 实现分行直通率计算:分行工单量 / 分行经办过的(分行+其他)工单量
- 实现分类逻辑:总行直通/分行直通/非直通
5.3 报表数据聚合
- 实现报表数据聚合服务(ReportAggregationService)
- 按主办机构分组统计
- 计算各维度直通率指标
- 数据格式化输出
5.4 报表API开发
- 创建直通率统计接口(GET /api/reports/throughput-rate)
- 支持查询参数:时间范围、工单类型
- 返回JSON格式统计数据
✅ 单元测试点
// 测试类:ThroughputRateCalculatorTest
@Test
void test_总直通率计算() {
// Given: 工单总量100,各主办机构工单量80
// When: 计算总直通率
// Then: 验证结果=80%
}
@Test
void test_总行直通率计算() {
// Given: 工单总量100,总行工单30,信用卡中心工单20
// When: 计算总行直通率
// Then: 验证结果=(30+20)/100=50%
}
@Test
void test_分行直通率计算() {
// Given: 分行经办过的工单:分行50,其他10
// When: 计算分行直通率
// Then: 验证结果=50/(50+10)=83.33%
}
@Test
void test_直通率分类_总行直通() {
// Given: 主办机构=总行
// When: 判断直通类型
// Then: 验证返回"总行直通"
}
@Test
void test_直通率分类_分行直通() {
// Given: 主办机构=分行
// When: 判断直通类型
// Then: 验证返回"分行直通"
}
@Test
void test_直通率分类_非直通() {
// Given: 主办机构=其他
// When: 判断直通类型
// Then: 验证返回"非直通"
}
// 测试类:OrderStatisticsServiceTest
@Test
void test_按主办机构统计工单量() {
// Given: 数据库中存在不同主办机构的工单
// When: 调用统计服务
// Then: 验证按主办机构正确分组统计
}
@Test
void test_统计查询_时间范围筛选() {
// Given: 设置时间范围2024-01-01至2024-01-31
// When: 调用统计服务
// Then: 验证仅统计该时间范围内的工单
}
📊 数据模型设计
数据库表结构
1. 投诉工单表(complaint_order)
CREATE TABLE complaint_order (
order_id VARCHAR(64) PRIMARY KEY,
order_type VARCHAR(32) NOT NULL,
contact_name VARCHAR(64),
contact_phone VARCHAR(32),
complainant_phone VARCHAR(32),
main_org VARCHAR(32),
main_operator VARCHAR(64),
is_sms_reply CHAR(1) DEFAULT 'N',
sms_reply_time DATETIME,
is_sms_visit CHAR(1) DEFAULT 'N',
visit_date DATE,
visit_time DATETIME,
visit_result VARCHAR(16),
process_notify_type VARCHAR(16),
process_notify_time DATETIME,
created_time DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
2. 短信发送记录表(sms_record)
CREATE TABLE sms_record (
sms_id VARCHAR(64) PRIMARY KEY,
order_id VARCHAR(64) NOT NULL,
sms_type VARCHAR(16) NOT NULL,
template_id VARCHAR(64),
phone VARCHAR(32) NOT NULL,
customer_name VARCHAR(64),
send_time DATETIME NOT NULL,
send_operator VARCHAR(64),
send_status VARCHAR(16) NOT NULL,
reply_content TEXT,
reply_time DATETIME,
validity_end_time DATETIME,
created_time DATETIME DEFAULT CURRENT_TIMESTAMP,
INDEX idx_order_id (order_id),
INDEX idx_phone (phone),
INDEX idx_send_time (send_time)
);
3. 短信模板表(sms_template)
CREATE TABLE sms_template (
template_id VARCHAR(64) PRIMARY KEY,
template_name VARCHAR(128) NOT NULL,
template_content TEXT NOT NULL,
template_type VARCHAR(16) NOT NULL,
approved_status VARCHAR(16) NOT NULL,
visible_roles VARCHAR(128),
enabled CHAR(1) DEFAULT 'Y',
created_time DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
🔐 权限控制
角色权限矩阵
| 功能 | 总行角色 | 分行角色 | 派单处理人员 |
|---|---|---|---|
| 查看总行模板 | ✅ | ❌ | 根据角色 |
| 查看分行模板 | ❌ | ✅ | 根据角色 |
| 发送短信回复 | ✅ | ✅ | ✅ |
| 查看统计报表 | ✅ | ✅ | ❌ |
🚨 非功能性需求
性能要求
- 短信发送接口响应时间 < 2秒
- 统计报表查询响应时间 < 5秒(数据量10万以内)
- 支持并发发送短信:100条/秒
可靠性要求
- 短信发送失败重试机制:最多重试3次,间隔5秒
- 短信发送记录完整保存,支持追溯
- 系统异常不影响工单主流程
安全性要求
- 短信模板内容需业务审核
- 短信发送操作需记录审计日志
- 敏感信息(手机号)需脱敏显示
📝 开发里程碑
Phase 1: 基础功能(2周)
- 领域模型设计
- 数据库表结构创建
- 短信发送服务基础功能
- 工单创建自动发送受理短信
Phase 2: 核心功能(3周)
- 短信回复功能(前端+后端)
- 短信回访功能
- 工单字段改造
Phase 3: 统计报表(1周)
- 直通率统计计算
- 报表API开发
- 报表前端展示
Phase 4: 测试与优化(1周)
- 单元测试覆盖
- 集成测试
- 性能优化
- 文档完善
📚 参考资料
领域驱动设计
- 工单是聚合根(Aggregate Root)
- 短信回复、短信回访是工单下的子领域能力
- 字段变更影响:流程、报表、权限
业务规则总结
- 报表统计必须以主办机构为唯一判断依据
- 每个工单仅允许发送一次短信回复
- 短信回访有效期:发送时间 T + 3 自然日
- 多次发送只统计首次客户回复
本文档基于GPT和DeepSeek整理,采用DDD领域驱动设计思想,详细拆解了每个功能点的开发任务和单元测试点,便于开发团队按阶段实施和测试验证。
