销售辅助SOP自动提醒功能
销售辅助SOP自动提醒功能
以下是针对销售辅助SOP自动提醒功能的Java系统设计方案,涵盖数据结构、核心算法、工作流程及可视化逻辑图,结合定时任务调度与状态机管理实现多节点触发机制。
一、核心数据结构设计
- SOP模板实体类(SopTemplate)
定义SOP的触发条件、节点序列及执行动作:
public class SopTemplate {
private String sopId; // SOP唯一标识(如:"客户关怀"、"资料激活")
private String triggerEvent; // 触发事件(如:"ADD_CLIENT"、"SUBMIT_APPLICATION")
private List<SopNode> nodes; // SOP节点列表
// 其他字段:名称、描述、是否启用等
}
- SOP节点类(SopNode)
描述每个任务节点的执行规则:
public class SopNode {
private String nodeId;
private int delayHours; // 相对于触发事件的延迟时间(如1天=24小时)
private String actionType; // 任务类型(如:"SEND_GREETING"、"PUSH_CASE")
private Map<String, String> actionParams; // 动态参数(如消息模板、链接URL)
private int retryCount; // 失败重试次数
}
- 任务实例类(SopTask)
记录待执行任务的状态与上下文:
public class SopTask {
private String taskId;
private String sopId;
private String nodeId;
private String clientId; // 关联的客户ID
private Date triggerTime; // 计划执行时间
private TaskStatus status; // 状态(PENDING, EXECUTED, FAILED)
}
- 客户事件队列(ClientEventQueue)
存储触发SOP的事件(线程安全队列):
BlockingQueue<ClientEvent> eventQueue = new LinkedBlockingQueue<>();
public class ClientEvent {
private String eventType; // 事件类型(如添加档案、提交报名)
private String clientId;
private Date eventTime;
}
二、任务调度算法与执行流程
- 整体架构
采用 生产者-消费者模型 结合 时间轮算法(Time Wheel):
• 生产者:监听客户事件(如添加档案、提交报名),生成初始SOP任务并插入队列。
• 消费者:任务执行器(Executor)每分钟扫描待处理任务,执行符合条件的任务。
- 核心算法流程
sequenceDiagram
participant EventListener as 事件监听器
participant TaskQueue as 任务队列
participant Executor as 任务执行器
participant ActionService as 动作服务
EventListener->>TaskQueue: 客户添加档案 → 生成SOP任务
loop 每分钟扫描
Executor->>TaskQueue: 拉取待执行任务(triggerTime <= now)
Executor->>ActionService: 执行任务(发消息/推送链接)
ActionService-->>Executor: 返回执行结果
alt 成功
Executor->>TaskQueue: 标记任务为已完成
else 失败
Executor->>TaskQueue: 重试或标记失败
end
end
- 关键代码实现
任务执行器(每分钟触发)
使用 ScheduledExecutorService 实现高精度定时调度:
ScheduledExecutorService executor = Executors.newScheduledThreadPool(4);
executor.scheduleAtFixedRate(() -> {
List<SopTask> pendingTasks = taskRepository.findPendingTasks(new Date());
pendingTasks.forEach(this::executeTask);
}, 0, 1, TimeUnit.MINUTES); // 每分钟执行一次
任务执行逻辑
private void executeTask(SopTask task) {
try {
// 1. 根据actionType选择执行器(如邮件、短信、推送)
ActionExecutor action = ActionFactory.getExecutor(task.getActionType());
action.execute(task.getClientId(), task.getActionParams());
// 2. 更新任务状态
task.setStatus(TaskStatus.EXECUTED);
taskRepository.save(task);
// 3. 触发下一个节点(如有)
sopEngine.triggerNextNode(task);
} catch (Exception e) {
task.setRetryCount(task.getRetryCount() + 1);
if (task.getRetryCount() > MAX_RETRY) task.setStatus(TaskStatus.FAILED);
}
}
三、状态机与SOP流转逻辑
- SOP激活规则
• 客户关怀SOP:添加客户档案 → 立即激活 → 生成第1天(24h)、第3天(72h)、第7天(168h)任务节点。
• 资料SOP:提交报名链接 → 生成即时任务 + 第3天(72h)提醒任务。
- 节点依赖管理
通过 SopTemplate 的节点列表顺序确定执行链,每个任务完成后触发下一节点:
public void triggerNextNode(SopTask completedTask) {
SopTemplate template = templateRepository.findById(completedTask.getSopId());
SopNode nextNode = template.getNextNode(completedTask.getNodeId());
if (nextNode != null) {
SopTask nextTask = new SopTask(completedTask.getClientId(), nextNode);
taskRepository.add(nextTask);
}
}
四、性能优化与容错机制
任务分片
按客户ID哈希分片任务队列,避免单点瓶颈。失败重试与告警
• 任务失败时延迟重试(指数退避策略)。• 连续失败超过阈值触发告警(集成邮件/Slack通知)。
异步非阻塞
使用 CompletableFuture 异步执行耗时操作(如HTTP调用),避免阻塞调度线程。
第二部分 配置代码执行
一、SOP流程配置(YAML格式)
定义客户关怀SOP的节点序列、延迟规则与执行动作:
# 客户关怀SOP配置 (care_sop.yml)
id: "customer_care_sop"
nodes:
- id: "node1"
type: "delay" # 延迟节点
delay: "24h" # 触发后24小时执行(第1天)
action: "SEND_GREETING"
params:
template: "WELCOME_MSG"
next: "node2"
- id: "node2"
type: "delay"
delay: "72h" # 触发后72小时执行(第3天)
action: "PUSH_CASE"
params:
case_id: "CASE_001"
next: "node3"
- id: "node3"
type: "delay"
delay: "96h" # 触发后96小时执行(第4天)
action: "SEND_REG_LINK"
params:
url: "/register/event123"
next: "node4"
- id: "node4"
type: "delay"
delay: "168h" # 触发后168小时执行(第7天)
action: "FOLLOW_UP"
params:
message: "是否查阅案例?"
二、事件监听与任务触发(Java实现)
- 事件定义(领域事件)
// 客户档案创建事件
public class ClientCreatedEvent {
private String clientId;
private Date createTime;
// getters & setters
}
// 客户报名事件
public class RegistrationSubmittedEvent {
private String clientId;
private String formData;
// getters & setters
}
- 事件监听器(Spring Kafka示例)
@Component
public class SopEventListener {
@Autowired
private SopEngine sopEngine; // SOP流程引擎
// 监听客户创建事件 → 激活客户关怀SOP
@KafkaListener(topics = "client_events")
public void handleClientCreated(ClientCreatedEvent event) {
sopEngine.activateSop("customer_care_sop", event.getClientId());
}
// 监听报名事件 → 激活资料SOP
@KafkaListener(topics = "registration_events")
public void handleRegistration(RegistrationSubmittedEvent event) {
sopEngine.activateSop("material_sop", event.getClientId());
}
}
三、任务执行引擎(Java核心逻辑)
- SOP引擎服务
@Service
public class SopEngine {
@Autowired
private TaskScheduler taskScheduler; // 任务调度器
@Autowired
private ActionExecutor actionExecutor; // 动作执行器
// SOP配置缓存(实际可从DB或配置中心加载)
private Map<String, SopConfig> sopConfigs = loadSopConfigs();
// 激活SOP流程
public void activateSop(String sopId, String clientId) {
SopConfig config = sopConfigs.get(sopId);
if (config != null) {
scheduleNextNode(config.getStartNode(), clientId, new Date());
}
}
// 调度下一个节点
private void scheduleNextNode(SopNode node, String clientId, Date baseTime) {
long delayMillis = parseDelayToMillis(node.getDelay()); // 将"24h"转为毫秒
Date triggerTime = new Date(baseTime.getTime() + delayMillis);
// 创建待执行任务实例
SopTask task = new SopTask(node.getId(), node.getAction(), clientId, triggerTime);
taskRepository.save(task);
// 定时触发任务执行
taskScheduler.schedule(() -> executeTask(task), triggerTime);
}
// 执行具体任务
private void executeTask(SopTask task) {
actionExecutor.execute(task.getActionType(), task.getParams());
task.setStatus(TaskStatus.COMPLETED);
taskRepository.update(task);
// 触发后续节点(如有)
SopNode nextNode = getNextNode(task.getNodeId());
if (nextNode != null) {
scheduleNextNode(nextNode, task.getClientId(), new Date());
}
}
}
- 动作执行器(策略模式)
@Component
public class ActionExecutor {
// 注册所有动作处理器
private Map<String, ActionHandler> handlers = Map.of(
"SEND_GREETING", new GreetingHandler(),
"PUSH_CASE", new CasePushHandler(),
"SEND_REG_LINK", new RegistrationLinkHandler()
);
public void execute(String actionType, Map<String, String> params) {
ActionHandler handler = handlers.get(actionType);
if (handler != null) {
handler.execute(params);
}
}
}
// 示例:发送问候语处理器
public class GreetingHandler implements ActionHandler {
@Override
public void execute(Map<String, String> params) {
String templateId = params.get("template");
String message = MessageTemplate.get(templateId);
SmsService.send(message); // 实际调用短信/邮件服务
}
}
四、关键数据结构
// SOP配置实体
public class SopConfig {
private String id;
private List<SopNode> nodes;
// getters & setters
}
// SOP节点定义
public class SopNode {
private String id;
private String type; // delay/condition/end
private String delay; // 延迟时间(如 "24h")
private String action; // 执行动作类型
private Map<String, String> params;
private String next; // 下一个节点ID
}
// 任务实例
public class SopTask {
private String taskId;
private String nodeId;
private String clientId;
private String actionType;
private Date triggerTime;
private TaskStatus status;
}
五、可视化逻辑图
六、扩展设计说明
- 动态配置
SOP节点支持热更新,修改YAML后引擎自动重载配置。 - 失败重试
在executeTask()中增加重试机制,失败后按指数退避策略重新调度。 - 分布式协调
使用Redis分布式锁确保集群环境下任务仅被一个节点执行。 - 监控埋点
在ActionExecutor中集成Micrometer指标,监控任务执行耗时与成功率。
代码基于事件驱动架构(参考Kafka监听)和流程编排引擎(Solon Flow设计思想)实现,通过YAML配置实现业务逻辑与代码解耦。