feat(ops): 新增手动操作枚举与模型定义

引入统一手动动作基础设施:
- ManualActionTypeEnum: 手动动作类型(创建/派单/取消/完单/升级)
- OrderActionSourceEnum: 动作来源(管理后台/开放接口)
- OrderAuditPayloadKeys: 审计 payload 标准化 key
- OrderEventTypeEnum: 事件类型枚举值对齐状态机(DISPATCHED/QUEUED/CONFIRMED)
- OperatorContext: 统一操作人上下文
- *Command: 手动动作命令模型(Dispatch/Cancel/Complete/UpgradePriority)
- OrderBusinessStrategy: 条线策略接口

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
lzh
2026-03-27 15:53:20 +08:00
parent 4dffd21751
commit e1d967a65e
21 changed files with 1176 additions and 0 deletions

View File

@@ -0,0 +1,63 @@
package com.viewsh.module.ops.security.service.manual;
import com.viewsh.module.ops.api.queue.OrderQueueService;
import com.viewsh.module.ops.core.manual.model.*;
import com.viewsh.module.ops.core.manual.strategy.OrderBusinessStrategy;
import com.viewsh.module.ops.dal.dataobject.workorder.OpsOrderDO;
import com.viewsh.module.ops.enums.WorkOrderStatusEnum;
import com.viewsh.module.ops.enums.WorkOrderTypeEnum;
import com.viewsh.module.ops.security.dal.dataobject.area.OpsAreaSecurityUserDO;
import com.viewsh.module.ops.security.dal.mysql.area.OpsAreaSecurityUserMapper;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import static com.viewsh.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.viewsh.module.ops.enums.ErrorCodeConstants.SECURITY_ASSIGNEE_NOT_BOUND_TO_AREA;
/**
* 安保条线策略
* <p>
* 处理安保特有的前置校验和后置副作用。
*
* @author lzh
*/
@Slf4j
@Component
public class SecurityOrderBusinessStrategy implements OrderBusinessStrategy {
@Resource
private OpsAreaSecurityUserMapper areaSecurityUserMapper;
@Resource
private OrderQueueService orderQueueService;
@Override
public boolean supports(String businessType) {
return WorkOrderTypeEnum.SECURITY.getType().equals(businessType);
}
@Override
public void validateDispatch(DispatchOrderCommand cmd, OpsOrderDO order) {
// 校验目标安保人员:必须绑定到工单所属区域且已启用
OpsAreaSecurityUserDO binding = areaSecurityUserMapper.selectByAreaIdAndUserId(
order.getAreaId(), cmd.getAssigneeId());
if (binding == null || !Boolean.TRUE.equals(binding.getEnabled())) {
throw exception(SECURITY_ASSIGNEE_NOT_BOUND_TO_AREA);
}
// 使用绑定记录中的冗余姓名
if (cmd.getAssigneeName() == null && binding.getUserName() != null) {
cmd.setAssigneeName(binding.getUserName());
}
}
@Override
public void afterUpgradePriority(UpgradePriorityCommand cmd, OpsOrderDO order) {
// 如果工单在队列中,触发队列分数重算
if (WorkOrderStatusEnum.QUEUED.getStatus().equals(order.getStatus()) && order.getAssigneeId() != null) {
orderQueueService.rebuildWaitingTasksByUserId(order.getAssigneeId(), order.getAreaId());
log.info("[SecurityStrategy] 升级优先级后重算队列: orderId={}, assigneeId={}",
cmd.getOrderId(), order.getAssigneeId());
}
}
}