工单短信触达需求文档

基于DDD领域驱动设计,实现工单短信自动触达、手动回复、回访处理及统计报表功能

页面内容

📋 需求概述

项目背景

投诉工单系统需要新增短信通知功能,实现工单受理、结案、回访的短信触达,并改造直通率统计报表。

核心目标

  1. 自动发送受理短信:新建工单后自动发送受理通知
  2. 手动短信回复:支持处理人员手动发送结案通知短信
  3. 短信回访:工单结案后自动发送回访短信,处理客户回复
  4. 统计报表改造:基于主办机构计算直通办理率

🏗️ 领域模型设计

核心领域(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)
  • 更新回访日期时间:visitDatevisitTime = 短信发送时间
  • 仅统计首次客户回复(多次发送只统计第一次)

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领域驱动设计思想,详细拆解了每个功能点的开发任务和单元测试点,便于开发团队按阶段实施和测试验证。