package com.atta.csorder.service.impl;
/**
* @author caozhongsheng
* @date 2024-12-06
*/
@Slf4j
@Service
public class CSWorkOrderServiceImpl implements CSWorkOrderService {
private static final Pattern phonePattern = Pattern.compile("[1][1-9][0-9]{9}");
private static final Pattern HKPhonePattern = Pattern.compile("^([6|9])\\d{7}$");
@Value("${atta.crm.workOrder.autoCancelledDays}")
private int autoCancelledDays;
@Value("${atta.crm.pre.workOrder.form.version:v3}")
private String preWorkOrderFormVersion;
@Value("${atta.crm.leads.workorderEndDay:1}")
private int workorderEndDay;
@Value("${atta.crm.leads.workorderEndHour:21}")
private int workorderEndHour;
@Value("${atta.crm.leads.max.SuspendOrderCount:3}")
private int maxSuspendOrderCount;
@Value("${atta.workorder.survey.questionnaireId}")
private String questionnaireId;
@Value("${atta.crm.workOrder.primaryGroup}")
private String primaryGroup;
@Value("${atta.crm.workOrder.consultWorkOrderLimit:100}")
private int consultWorkOrderLimit;
@Value("${atta.crm.workOrder.preDayLimit:90}")
private Integer preDayLimit;
@Value("${atta.crm.workOrder.secondGroup}")
private String secondGroup;
//true: 取查询数据, false: 取数仓数据
@Value("${crm.customer.partner.data.enable:true}")
private boolean CRM_CUSTOMER_PARTNER_DATA_ENABLE;
@Value("${crm.workOrder.appointment.remarkLength:100}")
private Integer remarkLength;
@Value("#{${crm.workOrder.consultingTypeMap:null}}")
private HashMap<String, String> consultingTypeMap;
@Value("#{'${atta.crm.workOrder.preAuditConfigIds:13990100165000022070400016401}'.split(',')}")
private Set<String> preAuditConfigIds;
@Value("#{'${atta.crm.workOrder.preWorkOrderConfigIds:13990100165000020052200020001,13990100165000022030100010105,13990100165000023031600024001}'.split(',')}")
private Set<String> preWorkOrderConfigIds;
@Value("#{'${atta.crm.workOrder.customerAuditConfigId:13990100165000020052200020001,13990100165000022030100010105,13990100165000022072100017601,13990100165000022112300021801,13990100165000023011000023401}'.split(',')}")
private Set<String> customerAuditConfigId;
@Value("#{'${atta.crm.workOrder.allowedEditFirmInfoConfigId:13990100165000020052200020001,13990100165000022030200000541}'.split(',')}")
private Set<String> allowedEditFirmInfoConfigId;
@Value("#{'${crm.coop.workorder.notify.dingIds:}'.empty ? null : '${crm.coop.workorder.notify.dingIds:}'.split(',')}")
public List<String> dingUserIds;
@Value("#{'${crm.workorder.complete.check.configIds:123}'.split(',')}")
private Set<String> needCheckWorkConfigIds = Sets.newHashSet();
@Value("${atta.crm.work.order.submit.bossUserId:04990100116000021033000019079}")
private String submitBossUserId;
@Value("${atta.crm.work.order.submit.bossUserName:刘智平}")
private String submitBossUserName;
@Value("#{${cswo.email.work.order.email.account.map}}")
private Map<String, String> emailWorkOrderEmailAccountMap = new HashMap<>();
/**
* 客服工单查询是否走doris
*/
@Value("${atta.crm.customer.work.order.switch:true}")
private boolean customerOrderSwitch;
@Value("${atta.crm.customer.coop.work.order.limit:9000}")
private int coop_workoder_query_limit;
@Value("#{'${cswo.email.config.ids}'.split(',')}")
private Set<String> emailCsWorkOrderConfigIds = new HashSet<>();
@Value("${cswo.event.center.enabled:false}")
private boolean openEventCenterEnabled;
@Value("${crm.workOrder.url.pre:https://sitxt47.xtrfr.cn/boss2/magpiebridge/customerservice/edit-customer-service-order?orderId=}")
private String workOrderUrlPre;
private static final String REQUEST_SOURCE = "crmserv";
private static final String APP_NAME = "xtransfer";
private static final String DING_NOTIFY_TYPE = "1";
private static final String CHANGE_USER_MASTER_PHONE = "更换用户主手机号";
private static final String ACCOUNT_SECURITY = "账户安全";
private static final String UN_BIND_X = "解绑X盾";
private static final String PRE_AUDIT_RESULT = "preAuditResult";
private static final String PASS_RESULT = "Pass";
private static final String NO_PASS_RESULT = "NoPass";
private static final String FIRST_AUDIT = "首次认证预审核";
private static final String WEALTH_MANAGEMENT_AUDIT = "理财业务预审核";
private static final String FIRST_AUDIT_TOW = "首次认证预审";
private static final String UPDATE_AUDIT = "更新认证预审";
private static final String CUSTOMER_ANNUAL_AUDIT = "客户年审预审";
private static final String FIRM_SHAREHOLDER_AUDIT = "大陆企业股东结汇预审";
private static final String WEALTH_MANAGEMENT_AUDIT_PRE = "理财业务预审";
private static final String DEFAULT_MESSAGE_TEMPLATE = "DEFAULT_MESSAGE_TEMPLATE";
private static final String PRE_AUDIT_RESULT_KEY = "preAuditResult";
private static final String PRE_AUDIT_SUGGESTION_KEY = "preAuditSuggestion";
private static final String TODO_TITLE = "客服工单跟进提醒";
private static final String TODO_DESC = "您负责的工单有新的跟进记录,请及时查看处理%s%s";
private static final String SALE_SESSION_WORK_ORDER_TODO_DESC = "销售%s提交材料,留言%s,工单id:%s";
private static final Map<CooperationDomain, BizType> COOPERATION_DOMAIN_BIZ_TYPE_MAP = new HashMap<CooperationDomain, BizType>() {{
put(CooperationDomain.risk, BizType.RISK_CONTROL);
put(CooperationDomain.customer_asset, BizType.CUSTOMER_ASSET);
put(CooperationDomain.sale, BizType.SALE);
}};
private final Set<CSWorkOrderStatus> processCSWorkOrderStatus = Sets.newHashSet(CSWorkOrderStatus.Processing
, CSWorkOrderStatus.UpgradeProcessing);
@Autowired
private CSOrderConfig csOrderConfig;
@Autowired
private RedissonLock redissonLock;
@Autowired
private IMQProvider imqProvider;
@Autowired
private EventProducer eventProducer;
@Autowired
private WorkorderMessageProducer workorderMessageProducer;
@Autowired
private TransactionLazyExecutor transactionLazyExecutor;
@Autowired
private TransactionUtil transactionUtil;
@Autowired
private UserSecretClient userSecretClient;
@Autowired
private EmailSendClient emailSendClient;
@Autowired
private UserClient userClient;
@Autowired
private FirmClient firmClient;
@Autowired
private FirmProfileClient firmProfileClient;
@Autowired
private FundAccountClient fundAccountClient;
@Autowired
private BossUserClient bossUserClient;
@Autowired
private BossUserGroupClient bossUserGroupClient;
@Autowired
private FormServAnswerClient formServAnswerClient;
@Autowired
private CallCenterClient callCenterClient;
@Autowired
private CSWorkOrderSearchClient csWorkOrderSearchClient;
@Autowired
private RiskWorkOrderClient riskWorkOrderClient;
@Autowired
private ManualAuditSnapshotClient manualAuditSnapshotClient;
@Autowired
private FormServClient formServClient;
@Autowired
private GwDingTalkTodoClient gwDingTalkTodoClient;
@Autowired
private MessageFacadeClient messageFacadeClient;
@Autowired
private CSWorkOrderLogService csWorkOrderLogService;
@Autowired
private CSWorkOrderConfigService cSWorkOrderConfigService;
@Autowired
private CSWorkOrderCommRecordService commRecordService;
@Autowired
private FeedbackMessageInstructionService feedbackMessageInstructionService;
@Autowired
private SLAEscalationService slaEscalationService;
@Resource
private SLAOrganizerService slaOrganizerService;
@Autowired
private ConsultProgressPushService consultProgressPushService;
@Autowired
private FileStorageUtils fileStorageUtils;
@Autowired
private AttachmentFacadeImpl attachmentFacade;
@Autowired
private SkylarkManager skylarkManager;
@Autowired
private CSWorkOrderUserService csWorkOrderUserService;
@Autowired
private CSWorkOrderAutomaticAllocationService csWorkOrderAutomaticAllocationService;
@Autowired
private WorkOrderConfigAndTagRelationService workOrderConfigAndTagRelationService;
@Autowired
private CSWorkOrderInstructionService cSWorkOrderInstructionService;
@Autowired
private MongoTransactionTemplate mongoTransactionTemplate;
@Autowired
private CSWorkOrderDAO csWorkOrderDAO;
@Autowired
private CSWorkOrderConfigDAO csWorkOrderConfigDAO;
@Autowired
private CSWorkOrderOpLogDAO csWorkOrderOpLogDAO;
@Autowired
private CSWorkOrderCommRecordDAO csWorkOrderCommRecordDAO;
@Autowired
private WorkOrderInstructionDAO workOrderInstructionDAO;
@Autowired
private ActionDAO actionDAO;
@Autowired
private CSWorkOrderReceiveEmailRecordDAO csWorkOrderReceiveEmailRecordDAO;
@Autowired
private CSWorkOrderRecordTemplateDAO csWorkOrderRecordTemplateDAO;
@Autowired
private CSWorkOrderRecdTmplOpLogDAO csWorkOrderRecdTmplOpLogDAO;
@Autowired
private CoopWorkOrderMessageHolder coopWorkOrderMessageHolder;
@Autowired
private MessageManager messageManager;
@Autowired
private TodoTaskManager todoTaskManager;
@Autowired
private QuestionnaireManager questionnaireManager;
@Autowired
private WorkOrderConfig workOrderConfig;
@Autowired
private CSWOSlaEventService cswoSlaEventService;
@Autowired
private AllocateRouteService allocateHandleService;
@Autowired
private IntelligentHostingService hostingService;
@Autowired
private AssignBindProducer assignBindProducer;
@Autowired
private CSWorkOrderHostingEndProducer csWorkOrderHostingEndProducer;
@Resource(name = "commonExecutor")
private ExecutorService commonExecutor;
@Autowired
private StudioClient studioClient;
@Autowired
private CSWorkOrderAITopicService csWorkOrderAITopicService;
@Override
public String create(CSWorkOrderCreateRequest request) {
currentWorkOrderConfigIsUsable(request.getWorkorderTypeId(), request.getCreateUserId());
//校验跟进方式
checkWorkOrderTrackWay(request);
List<DataPersistenceCommander> commanders = new ArrayList<>();
String accountName = request.getAccountName();
String userId = request.getUserId();
String accountType = request.getAccountType();
String userAccountId = request.getUserAccountId();
if (Objects.equals(request.getAccountType(), FundAccountTypeEnum.PERSONAL.name())
&& StringUtils.isNotBlank(request.getUserAccountId())) {
if (StringUtils.isBlank(accountName)) {
FacadeResponse<FundAccountVO> response = fundAccountClient.queryAccountByAccountId(request.getUserAccountId());
if (response.isSucceeded() && Objects.nonNull(response.getValue())) {
accountName = response.getValue().getAccountName();
userId = response.getValue().getUserId();
}
}
}
if (StringUtils.isNotBlank(userId) && !CollectionUtils.isEmpty(request.getBusinessInfoVOList())) {
Optional<BusinessInfoVO> optional = request.getBusinessInfoVOList().stream()
.filter(item -> Objects.equals(item.getType(), BusinessInfoType.FeedbackWorkOrderAttachment))
.findAny();
if (optional.isPresent()) {
FacadeResponse<FundAccountVO> defaultAccount = fundAccountClient.getDefaultAccount(userId);
if (defaultAccount.isSucceeded() && Objects.nonNull(defaultAccount.getValue())) {
accountType = defaultAccount.getValue().getAccountType();
accountName = defaultAccount.getValue().getAccountName();
userAccountId = defaultAccount.getValue().getAccountId();
}
}
}
WorkOrderAddRequest addRequest = WorkOrderAddRequest.builder()
.userId(userId)
.workOrderConfigId(request.getWorkorderTypeId())
.sceneConfigId(request.getSceneConfigId())
.problemScene(request.getProblemScene())
.createUserId(request.getCreateUserId())
.businessInfoVOList(request.getBusinessInfoVOList())
.email(request.getEmail())
.feedbackTime(request.getFeedbackTime())
.firmId(request.getFirmId())
.firmName(request.getFirmName())
.principalUserId(request.getPrincipalUserId())
.source(request.getSource())
.currentDealUserId(request.getCurrentDealUserId())
.workOrderEndTime(request.getWorkorderEndTime())
.invitationCode(request.getInvitationCode())
.phone(request.getPhone())
.orderLevel(request.getOrderLevel())
.referenceId(request.getReferenceId())
.generatedReason(request.getGeneratedReason())
.vaAccount(request.getVaAccount())
.currency(request.getCurrency())
.amount(request.getAmount())
.serviceProvider(request.getServiceProvider())
.assignId(request.getAssignId())
.phoneAreaCode(request.getPhoneAreaCode())
.newPhoneAreaCode(request.getNewPhoneAreaCode())
.site(request.getSite())
.serviceObject(StringUtils.isNotBlank(request.getSaleBossUserId()) ? "sale" : "user")
.callCenterId(request.getCallCenterId())
.skylarkCollaborationId(request.getSkylarkCollaborationId())
.accountType(accountType)
.userAccountId(userAccountId)
.accountName(accountName)
.receiptTradeId(request.getReceiptTradeId())
.customerShowSwitch(request.getCustomerShowSwitch())
.upgradeSource(request.getUpgradeSource())
.consultTopic(request.getConsultTopic())
.build();
if (StringUtils.isNotBlank(request.getSaleBossUserId())) {
User user = bossUserClient.queryByBossUserId(request.getSaleBossUserId());
addRequest.setSaleBossUserId(Optional.ofNullable(user).map(User::getBossUserId).orElse(null));
addRequest.setSaleBossUserName(Optional.ofNullable(user).map(User::getUserName).orElse(null));
}
// 打标 判断升级来源
addRequest.setUpgradeSource(allocateHandleService.judgeSourceByWorkOrderTypeId(addRequest));
// 插入 workOrderDO
CSWorkOrderDO insertWorkOrder = insertWorkOrder(commanders, addRequest);
String workOrderId = insertWorkOrder.getWorkorderId();
// 关联问卷
relateQuestionnaire(workOrderId, request.getWorkorderTypeId(), request.getSceneConfigId());
// 插入跟踪记录
csWorkOrderLogService.insertOpLog(commanders,
buildOpLogAddRequest(workOrderId, CSWorkOrderStatus.Created, request.getCreateUserId(), "创建工单"));
// 插入沟通记录
ComRecordAddRequest comRecordAddRequest = ComRecordAddRequest.builder()
.attachments(request.getAttachments())
.workOrderId(workOrderId)
.callCenterIds(request.getCallCenterIds())
.operatorUserId(request.getCurrentDealUserId())
.commMode(request.getCommMode())
.content(request.getCommRecord())
.recordTemplateId(request.getRecordTemplateId())
.sessionIds(StringUtils.isNotEmpty(request.getAssignId()) ? Sets.newHashSet(request.getAssignId()) : request.getSessionIds())
.workOrderTrackWay(request.getWorkOrderTrackWay())
.csWorkOrderEmailRequest(request.getCsWorkOrderEmailRequest())
.buttonSource(CsWoButtonSource.NEW_SUBMIT.name())
.feedbackTime(request.getFeedbackTime())
.build();
String recordId = commRecordService.insertCommRecord(commanders, comRecordAddRequest);
FormAnswerRequest formAnswerRequest = request.getFormAnswer();
if (formAnswerRequest != null) {
formAnswerRequest.setBizId(workOrderId);
FacadeResponse formAnswerResponse = formServAnswerClient.commitAnswer(formAnswerRequest);
CSExceptionAssert.isTrue(formAnswerResponse.isSucceeded()
, CSOrderBizErrorCode.VALIDATION_ERROR
, "commit answer failed!");
}
if (request.getFeedbackTime() != null && StringUtils.isNotBlank(request.getPrincipalUserId())) {
FeedbackMessageInstructionReq messageInstructionReq = FeedbackMessageInstructionReq.builder()
.workerOrderId(workOrderId)
.feedbackTime(request.getFeedbackTime())
.principalUserId(request.getPrincipalUserId())
.build();
feedbackMessageInstructionService.addWorkOrderInstructions(commanders, messageInstructionReq);
}
transactionLazyExecutor.executeCommanders(commanders);
if (Objects.equals(request.getWorkOrderTrackWay(), WorkOrderTrackWay.EMAIL.name()) && Objects.nonNull(request.getCsWorkOrderEmailRequest())) {
sendWorkOrderEmail(request.getCsWorkOrderEmailRequest(), workOrderId, request.getWorkorderTypeId());
}
TodoTaskEvent todoTaskEvent = new TodoTaskEvent();
convertWorkOrderAddRequest2TodoTaskEvent(addRequest, todoTaskEvent);
todoTaskEvent.setReferenceId(workOrderId);
todoTaskEvent.setActionId(workOrderId);
//工单完成后给代办发送消息
if (StringUtils.isNotEmpty(todoTaskEvent.getPrincipalUserId())) {
imqProvider.push(TodoTaskEvent.QUEUE_NAME, todoTaskEvent, QueueType.TOPIC);
}
//TODO 迁移变更:此处废弃了【优质客户计划】相关的跟进记录同步到客户池的逻辑
createWorkOrderIntoEventCenter(workOrderId, addRequest.getSource(), request.getWorkorderTypeId());
//上报sla数据
slaEscalationService.escalationNewWorkOrderSla(insertWorkOrder);
consultProgressPushService.newWorkOrder(insertWorkOrder, request.getButtonSource());
// 创建工单时发送会话绑定消息
CSAssignBindEvent assignBindEvent = new CSAssignBindEvent();
// 创建工单时兼容老逻辑-先判断assignId是否有值,否则取sessionIds
Set<String> assignBindEventAssignIds = StringUtils.isNotEmpty(request.getAssignId()) ? Sets.newHashSet(request.getAssignId()) : request.getSessionIds();
assignBindEvent.setAssignIds(assignBindEventAssignIds);
assignBindEvent.setWorkOrderId(workOrderId);
assignBindEvent.setFirmId(request.getFirmId());
assignBindProducer.sendAssignBind(assignBindEvent);
return workOrderId;
}
@Override
public String edit(CSWorkOrderEditRequest request) {
CSWorkOrderDO csWorkOrderDO = csWorkOrderDAO.queryCSWorkOrderByWorkOrderId(request.getWorkOrderId());
if (csWorkOrderDO == null) {
CSExceptionAssert.fail(CSOrderBizErrorCode.VALIDATION_ERROR, "工单不存在");
}
String oldCustomerShowSwitch = csWorkOrderDO.getCustomerShowSwitch() == null ? CsWoCustomerShowSwitchEnum.CLOSE.name() : csWorkOrderDO.getCustomerShowSwitch();
CsWoCustomerShowSwitchEnum oldCustomerShowSwitchEnum = CsWoCustomerShowSwitchEnum.valOf(oldCustomerShowSwitch);
CsWoCustomerShowSwitchEnum customerShowSwitchEnum = CsWoCustomerShowSwitchEnum.valOf(request.getCustomerShowSwitch());
csWorkOrderDO.setCustomerShowSwitch(customerShowSwitchEnum.name());
List<DataPersistenceCommander> commanders = new ArrayList<>();
OpLogAddRequest logAddRequest = OpLogAddRequest.builder()
.workOrderId(request.getWorkOrderId())
.status(csWorkOrderDO.getStatus())
.operatorUserId(request.getCurrentDealUserId())
.suggestion(String.format("对客展示开关由【%s】变更为【%s】", covertCustomerShowSwitch(oldCustomerShowSwitchEnum), covertCustomerShowSwitch(customerShowSwitchEnum)))
.build();
csWorkOrderLogService.insertOpLog(commanders, logAddRequest);
commanders.add(() -> {
CSExceptionAssert.isTrue(csWorkOrderDAO.updateByIdSelective(csWorkOrderDO) != null
, CSOrderBizErrorCode.SYSTEM_ERROR, "更新失败");
});
try {
transactionLazyExecutor.executeWithRequire(commanders);
consultProgressPushService.sendCustomerShowSwitchChange(csWorkOrderDO, customerShowSwitchEnum);
} catch (Exception e) {
log.error("edit workOrder failed. e is: ", e);
CSExceptionAssert.fail(CSOrderBizErrorCode.SYSTEM_ERROR, "edit workOrder failed");
}
return request.getWorkOrderId();
}
@Override
public String extractTopic(CSWorkOrderExtractTopicRequest request) {
// 根据会话id获取会话内容
String imMessage = getIMMessageByScene(request);
if (StringUtils.isBlank(imMessage)) {
log.warn("Failed to get IM message for session id: {}", request.getSessionId());
return null;
}
// 封装调用模型接口参数
Map<String, Object> inputMap = new HashMap<>();
inputMap.put(CsOrderConstants.WORKFLOW_INPUT_WORKORDER_TYPE, request.getWorkorderType());
inputMap.put(CsOrderConstants.WORKFLOW_INPUT_WORKORDER_PROBLEM_TYPE, request.getProblemType());
inputMap.put(CsOrderConstants.WORKFLOW_INPUT_CONVERSATION, imMessage);
WorkFlowRunRequest workFlow = WorkFlowRunRequest.createSync(
CsOrderConstants.WORKFLOW_CONSULTATION_THEME_EXTRACTION,
null,
UUID.randomUUID().toString(),
inputMap);
// 执行工作流
FacadeResponse<WorkFlowRunResponse> facadeResponse = studioClient.workflowRun(workFlow);
if (!facadeResponse.isSucceeded() || null == facadeResponse.getValue()) {
log.error("extractTopic workflow invoke failed, request: {}, response: {}",
request.getSessionId(), facadeResponse.getResponseMsg());
return null;
}
// 处理大模型返回结果,提取theme字段
return getConsultTheme(facadeResponse.getValue().getOutputJson());
}
private String getConsultTheme(String outputJson) {
// 如果输出JSON为空,直接返回null
if (StringUtils.isBlank(outputJson)) {
return null;
}
try {
Map<String, String> resultMap = JSON.parseObject(outputJson, new TypeReference<Map<String, String>>() {});
// 获取theme字段值
String theme = resultMap.get(WORKFLOW_OUTPUT_THEME);
if (StringUtils.isBlank(theme)) {
log.warn("getConsultTheme theme field is null in outputJson: {}", outputJson);
return null;
}
return theme;
} catch (Exception e) {
log.warn("getConsultTheme Failed to parse outputJson or extract theme, returning null. OutputJson: {}",
outputJson, e);
return null;
}
}
/**
* 根据场景获取IM消息/400消息
*
* @param request 请求参数
* @return IM消息内容/400消息
*/
private String getIMMessageByScene(CSWorkOrderExtractTopicRequest request) {
if (CSWorkOrderAISummaryScene.IM.equals(request.getScene())) {
// 获取im会话消息
return csWorkOrderAITopicService.getIMTopicBySessionId(request.getSessionId());
} else if (CSWorkOrderAISummaryScene.CALL_CENTER_400.equals(request.getScene())) {
// 获取400会话记录
return csWorkOrderAITopicService.get400TopicBySessionId(request.getSessionId());
} else {
log.warn("Unsupported scene: {}", request.getScene());
return null;
}
}
private String covertCustomerShowSwitch(CsWoCustomerShowSwitchEnum customerShowSwitchEnum) {
return CsWoCustomerShowSwitchEnum.OPEN.equals(customerShowSwitchEnum) ? "展示" : "不展示";
}
/**
* 该创建协同单的方法已经由云雀平台承接
* SLA客服工单工作台无需上报信息
*
* @param request
* @return
*/
@Override
@Deprecated
public String createCoop(CSWorkOrderCreateRequest request) {
currentWorkOrderConfigIsUsable(request.getWorkorderTypeId(), request.getCreateUserId());
WorkOrderAddRequest addRequest = WorkOrderAddRequest.builder()
.userId(request.getUserId())
.workOrderConfigId(request.getWorkorderTypeId())
.createUserId(request.getCreateUserId())
.businessInfoVOList(request.getBusinessInfoVOList())
.email(request.getEmail())
.feedbackTime(request.getFeedbackTime())
.firmId(request.getFirmId())
.firmName(request.getFirmName())
.principalUserId(request.getPrincipalUserId())
.source(request.getSource())
.currentDealUserId(request.getCurrentDealUserId())
.workOrderEndTime(request.getWorkorderEndTime())
.invitationCode(request.getInvitationCode())
.phone(request.getPhone())
.orderLevel(request.getOrderLevel())
.referenceId(request.getReferenceId())
.generatedReason(request.getGeneratedReason())
.vaAccount(request.getVaAccount())
.serviceProvider(request.getServiceProvider())
.amount(request.getAmount())
.currency(request.getCurrency())
.build();
// 插入 workOrderDO
CSWorkOrderDO csWorkOrderDO = insertWorkOrder(addRequest);
// 关联问卷
relateQuestionnaire(csWorkOrderDO.getWorkorderId(), request.getWorkorderTypeId(), request.getSceneConfigId());
CSWorkOrderOpLogDO opLog = csWorkOrderLogService.createOpLog(buildOpLogAddRequest(csWorkOrderDO.getWorkorderId(),
CSWorkOrderStatus.Created, "system", "创建工单"));
FormAnswerRequest formAnswerRequest = request.getFormAnswer();
if (formAnswerRequest != null) {
//此处关联工单id
formAnswerRequest.setBizId(csWorkOrderDO.getWorkorderId());
FacadeResponse formAnswerResponse = formServAnswerClient.commitAnswer(formAnswerRequest);
CSExceptionAssert.isTrue(formAnswerResponse.isSucceeded()
, CSOrderBizErrorCode.VALIDATION_ERROR
, "commit answer failed!");
}
Boolean execute = mongoTransactionTemplate.execute(status -> {
try {
CSExceptionAssert.isTrue(csWorkOrderDAO.insert(csWorkOrderDO) != null
, CSOrderBizErrorCode.SYSTEM_ERROR
, "insert workOrderDO failed.");
CSExceptionAssert.isTrue(csWorkOrderOpLogDAO.insert(opLog) != null
, CSOrderBizErrorCode.INSERT__FAILED
, "insert oplog failed.");
return true;
} catch (Exception e) {
log.error(e.getMessage());
status.setRollbackOnly();
return false;
}
});
if (Boolean.FALSE.equals(execute)) {
return null;
}
return csWorkOrderDO.getWorkorderId();
}
@Override
public PageSerializable<CSWorkOrderVO> pageQueryBySales(CSWorkOrderBySalesRequest request) {
PageSerializable<CSWorkOrderVO> pageSerializable = new PageSerializable<>();
if (Objects.isNull(request)) {
return pageSerializable;
}
if (StringUtils.isEmpty(request.getSaleBossUserId())) {
log.error("query sales work order failed, sales bossUseId is empty.");
return pageSerializable;
}
Page<CSWorkOrderDO> csWorkOrderDOS = csWorkOrderDAO.pageQueryBySales(request.getSaleBossUserId(),
request.getSearchText(), request.getPage(), request.getSize());
if (CollectionUtils.isEmpty(csWorkOrderDOS.getResult()) || csWorkOrderDOS.getTotal() == 0) {
return pageSerializable;
}
List<CSWorkOrderVO> csWorkOrderVOS = new ArrayList<>();
for (CSWorkOrderDO csWorkOrderDO : csWorkOrderDOS.getResult()) {
FacadeResponse<CSWorkOrderVO> facadeResponse = toWorkOrderVOList(csWorkOrderDO);
if (!facadeResponse.isSucceeded()) {
CSExceptionAssert.fail(CSOrderBizErrorCode.SYSTEM_ERROR, facadeResponse.getResponseMsg());
continue;
}
if (Objects.isNull(facadeResponse.getValue())) {
continue;
}
csWorkOrderVOS.add(facadeResponse.getValue());
}
pageSerializable.setTotal(csWorkOrderDOS.getTotal());
pageSerializable.setList(csWorkOrderVOS);
return pageSerializable;
}
@Override
public void own(CSWorkOrderOwnRequest request) {
ValidateResult validateResult = ValidateUtil.validate(request);
CSExceptionAssert.isTrue(validateResult.isPassed()
, CSOrderBizErrorCode.VALIDATION_ERROR
, validateResult.getField() + validateResult.getReason());
List<CSWorkOrderDO> csWorkOrderDOS = csWorkOrderDAO.queryOrdersByWorkOrderIds(request.getWorkorderIds());
List<DataPersistenceCommander> commanders = new ArrayList<>();
for (CSWorkOrderDO csWorkOrderDO : csWorkOrderDOS) {
if (csWorkOrderDO == null || !CSWorkOrderStatus.Created.equals(csWorkOrderDO.getStatus())) {
continue;
}
OrderAssignReq assignReq = OrderAssignReq.builder()
.workOrderId(csWorkOrderDO.getWorkorderId())
.reason("申领工单")
.toPrincipalUserId(request.getCurrentDealUserId())
.operatorUserId(request.getCurrentDealUserId())
.build();
try {
transferPrincipal(commanders, assignReq);
} catch (Exception e) {
log.warn("apply fail,workOrderId is: {}.principalUserId is :{},", csWorkOrderDO.getWorkorderId(), assignReq.getOperatorUserId());
}
}
try {
transactionLazyExecutor.executeWithRequire(commanders);
} catch (Exception e) {
log.error("own workOrder failed. e is: ", e);
CSExceptionAssert.fail(CSOrderBizErrorCode.SYSTEM_ERROR, "own workOrder failed");
}
log.info("Leads assign workOrder complete. {}", request);
}
@Override
public void transfer(CSWorkOrderTransferRequest request) {
User principalUser = bossUserClient.queryByBossUserId(request.getToPrincipalUserId());
if (principalUser == null) {
throw new CustomerServiceException(CSOrderSystemErrorCode.ValidationError, CSOrderBizErrorCode.ILLEGAL_ARGUMENT, "unable to obtain transferee information, modification failed");
}
List<CSWorkOrderDO> workOrderDOS = csWorkOrderDAO.find(new Query().addCriteria(Criteria.where("workorderId").in(request.getWorkorderIds())));
String suggestion;
List<DataPersistenceCommander> commanders = new ArrayList<>();
for (CSWorkOrderDO workOrderDO : workOrderDOS) {
//撤销和结案状态的工单不能转移
if (finalCSWorkOrderStatus.contains(workOrderDO.getStatus())) {
throw new CustomerServiceException(CSOrderSystemErrorCode.ValidationError, CSOrderBizErrorCode.NOT_SUPPORT, "撤销和结案状态的工单不能转移");
}
//不能转移给原工单负责人
if (request.getToPrincipalUserId().equals(workOrderDO.getPrincipalUserId())) {
throw new CustomerServiceException(CSOrderSystemErrorCode.ValidationError, CSOrderBizErrorCode.NOT_SUPPORT, "不能转移给原工单负责人");
}
suggestion = String.format("转移负责人至【%s】,分配理由:%s", principalUser.getNick(), request.getReason());
OrderAssignReq assignReq = OrderAssignReq.builder()
.workOrderId(workOrderDO.getWorkorderId())
.toPrincipalUserId(request.getToPrincipalUserId())
.reason(suggestion)
.operatorUserId(request.getCurrentDealUserId())
.build();
try {
transferPrincipal(commanders, assignReq);
} catch (Exception e) {
log.warn("transfer failed. e is: ", e);
}
}
try {
transactionLazyExecutor.executeWithRequire(commanders);
} catch (Exception e) {
log.error("transfer workOrder failed. e is: ", e);
CSExceptionAssert.fail(CSOrderBizErrorCode.SYSTEM_ERROR, "transfer workOrder failed");
}
}
@Override
public void saveCommRecordAndAttachments(CSWorkOrderCommRecordSaveRequest request) {
CSWorkOrderDO workOrderDO = csWorkOrderDAO.queryCSWorkOrderByWorkOrderId(request.getWorkorderId());
CSExceptionAssert.isTrue(workOrderDO != null
, CSOrderBizErrorCode.VALIDATION_ERROR
, "work order on end state, can't edit");
CSExceptionAssert.isTrue(!finalCSWorkOrderStatus.contains(workOrderDO.getStatus())
, CSOrderBizErrorCode.VALIDATION_ERROR
, "work order on end state, can't edit");
//校验一下:结案工单时对客处理意见必选情况
CsWoCustomerShowSwitchEnum oldCustomerShowSwitch = CsWoCustomerShowSwitchEnum.valOf(workOrderDO.getCustomerShowSwitch());
if(StringUtils.isNotBlank(request.getButtonSource()) && CsWoButtonSource.EDIT_COMPLETE.name().equalsIgnoreCase(request.getButtonSource())
&& CsWoCustomerShowSwitchEnum.OPEN.equals(oldCustomerShowSwitch) && StringUtils.isBlank(request.getCustomerShowSuggestion())){
CSExceptionAssert.fail(CSOrderBizErrorCode.VALIDATION_ERROR
, "结案必须选择对客处理意见!!!");
}
CSWorkorderConfigVO configVO = cSWorkOrderConfigService.getConfigVOByConfigIdIgnoreStatus(workOrderDO.getWorkOrderConfigId());
List<DataPersistenceCommander> commanders = new ArrayList<>();
ComRecordAddRequest addRequest = ComRecordAddRequest.builder()
.attachments(request.getAttachments())
.workOrderId(request.getWorkorderId())
.callCenterIds(request.getCallCenterIds())
.content(request.getCommRecord())
.operatorUserId(request.getCurrentDealUserId())
.commMode(request.getCommMode())
.recordTemplateId(request.getRecordTemplateId())
.sessionIds(request.getSessionIds())
.workOrderTrackWay(request.getWorkOrderTrackWay())
.csWorkOrderEmailRequest(request.getCsWorkOrderEmailRequest())
.optBySale(request.isOptBySale())
.feedbackTime(request.getFeedbackTime())
.customerShowSuggestion(request.getCustomerShowSuggestion())
.customerShowNotify(request.getCustomerShowNotify())
.buttonSource(request.getButtonSource())
.showToSale(request.getShowToSale() == null ? Boolean.FALSE : request.getShowToSale())
.attachmentsToCustomer(request.getAttachmentsToCustomer())
.build();
String recordId = commRecordService.insertCommRecord(commanders, addRequest);
FormAnswerRequest formAnswerRequest = request.getFormAnswer();
if (formAnswerRequest != null) {
formAnswerRequest.setBizId(recordId);
FacadeResponse formAnswerResponse = formServAnswerClient.commitAnswer(formAnswerRequest);
CSExceptionAssert.isTrue(formAnswerResponse.isSucceeded()
, CSOrderBizErrorCode.VALIDATION_ERROR
, "commit answer failed!");
}
if (request.getFeedbackTime() != null && StringUtils.isNotBlank(workOrderDO.getPrincipalUserId())) {
FeedbackMessageInstructionReq messageInstructionReq = FeedbackMessageInstructionReq.builder()
.workerOrderId(workOrderDO.getWorkorderId())
.feedbackTime(request.getFeedbackTime())
.principalUserId(workOrderDO.getPrincipalUserId())
.build();
feedbackMessageInstructionService.addWorkOrderInstructions(commanders, messageInstructionReq);
}
OpLogAddRequest opLogAddRequest = OpLogAddRequest.builder()
.status(workOrderDO.getStatus())
.suggestion("添加沟通记录/附件")
.workOrderId(request.getWorkorderId())
.operatorUserId(request.getCurrentDealUserId())
.commRecordId(recordId)
.build();
if (Objects.equals(request.getWorkOrderTrackWay(), WorkOrderTrackWay.EMAIL.name())) {
if (request.getCsWorkOrderEmailRequest() != null && StringUtils.isNotBlank(request.getCsWorkOrderEmailRequest().getSubject())) {
opLogAddRequest.setSuggestion(request.getCsWorkOrderEmailRequest().getSubject());
} else {
opLogAddRequest.setSuggestion("发送service邮件");
}
}
csWorkOrderLogService.insertOpLog(commanders, opLogAddRequest);
workOrderDO.setConsultingType(request.getConsultingType());
// workOrderDO.setShowToCustomer(request.getShowToCustomer());
workOrderDO.setCurrentDealUserId(request.getCurrentDealUserId());
workOrderDO.setFeedbackTime(request.getFeedbackTime());
workOrderDO.setLastFollowedTime(new Date());
if (CollectionUtils.isEmpty(workOrderDO.getHistoryDealUsers()) || !workOrderDO.getHistoryDealUsers().contains(request.getCurrentDealUserId())) {
if (CollectionUtils.isEmpty(workOrderDO.getHistoryDealUsers())) {
workOrderDO.setHistoryDealUsers(Sets.newHashSet());
}
workOrderDO.getHistoryDealUsers().add(request.getCurrentDealUserId());
}
//销售留言自动绑定销售
if (request.isOptBySale()) {
bindSaleBySaleOpt(workOrderDO, request.getCurrentDealUserId());
}
commanders.add(() -> CSExceptionAssert.isTrue(csWorkOrderDAO.updateByIdSelective(workOrderDO) != null
, CSOrderBizErrorCode.SYSTEM_ERROR, "update workOrderDO failed."));
transactionLazyExecutor.executeCommanders(commanders);
if (Objects.equals(request.getWorkOrderTrackWay(), WorkOrderTrackWay.EMAIL.name()) && Objects.nonNull(request.getCsWorkOrderEmailRequest())) {
sendWorkOrderEmail(request.getCsWorkOrderEmailRequest(), request.getWorkorderId(), workOrderDO.getWorkOrderConfigId());
}
//TODO 迁移变更:此处废弃了【优质客户计划】相关的跟进记录同步到客户池的逻辑
CompletableFuture.runAsync(() -> judgeAndSendAgent(recordId, request.getCurrentDealUserId(), workOrderDO.getPrincipalUserId(), workOrderDO.getWorkorderId()), commonExecutor);
if (request.isOptBySale()) {
CompletableFuture.runAsync(() -> judgeSaleSessionWorkOrderAndSendAgent(recordId, request.getCurrentDealUserId(), workOrderDO.getPrincipalUserId(),
workOrderDO.getWorkorderId(), request.getCommRecord()), commonExecutor);
}
slaEscalationService.escalationFollowUpWorkOrderSla(workOrderDO, request.getFeedbackTime());
consultProgressPushService.followUpWorkOrder(workOrderDO, addRequest);
// 跟进工单时-发送会话绑定消息
if(!CollectionUtils.isEmpty(request.getSessionIds())) {
CSAssignBindEvent assignBindEvent = new CSAssignBindEvent();
assignBindEvent.setAssignIds(addRequest.getSessionIds());
assignBindEvent.setWorkOrderId(addRequest.getWorkOrderId());
assignBindEvent.setFirmId(workOrderDO.getFirmId());
assignBindProducer.sendAssignBind(assignBindEvent);
}
// 推送mq-判断是否需要结束托管
pushHostingComplete(request);
}
private void bindSaleBySaleOpt(CSWorkOrderDO workOrderDO, String currentDealUserId){
if(StringUtils.isNotBlank(workOrderDO.getSaleBossUserId())){
return;
}
User user = bossUserClient.queryByBossUserId(currentDealUserId);
if(user == null){
log.warn("CSWorkOrder bindSaleBySaleOpt 销售不存在 currentDealUserId:{}", currentDealUserId);
return;
}
workOrderDO.setSaleBossUserId(user.getBossUserId());
workOrderDO.setSaleUserName(user.getUserName());
log.warn("CSWorkOrder bindSaleBySaleOpt 绑定销售 工单ID:{},currentDealUserId:{}", workOrderDO.getWorkorderId(), currentDealUserId);
}
@Override
public void cancelRelate(CSWorkOrderCallRecordCancelRequest request) {
CSWorkOrderCommRecordDO commRecordDO = csWorkOrderCommRecordDAO.getCommRecordsByRecordId(request.getReferenceId());
CSWorkOrderDO workOrderDO = findWorkOrderOne(commRecordDO.getWorkorderId());
if (workOrderDO == null || workOrderDO.getStatus() == CSWorkOrderStatus.Completed || CSWorkOrderStatus.Cancelled == workOrderDO.getStatus()) {
CSExceptionAssert.fail(CSOrderBizErrorCode.VALIDATION_ERROR
, "WorkOrder does not exist or the status is cancelled! referenceId: " + request.getReferenceId());
}
CancelCallRecordRelateRequest cancelRelationRequest = new CancelCallRecordRelateRequest();
cancelRelationRequest.setCallRecordRelationId(request.getCallRecordRelationId());
cancelRelationRequest.setOperatorUserId(request.getCurrentDealUserId());
FacadeResponse<Void> success = callCenterClient.cancelRelate(cancelRelationRequest);
if (!success.isSucceeded()) {
CSExceptionAssert.fail(CSOrderBizErrorCode.SYSTEM_ERROR
, "cancel relate failed.");
}
}
@Override
public PageSerializable<RecordTemplateVO> queryRecordTemplatePageList(RecordTemplateQueryRequest request) {
Page<RecordTemplateDO> recordTemplateDOs = csWorkOrderRecordTemplateDAO.findPageByNameAndStatus(request.getRecordTemplateName(), request.getStatus()
, request.getPage()
, request.getSize());
List<RecordTemplateVO> recordTemplateVOS = new ArrayList<>();
if (!CollectionUtils.isEmpty(recordTemplateDOs)) {
recordTemplateVOS = recordTemplateDOs
.stream().map(recordTemplateDO -> {
RecordTemplateVO recordTemplateVO = WorkOrderConverter.toRecordTemplateVO(recordTemplateDO);
if (StringUtils.isNotEmpty(recordTemplateDO.getFormId())) {
FacadeResponse<FormVO> facadeResponse = formServClient.queryDetails(recordTemplateDO.getFormId());
if (facadeResponse.isSucceeded() && null != facadeResponse.getValue()) {
recordTemplateVO.setFormVO(facadeResponse.getValue());
}
}
if (!CollectionUtils.isEmpty(recordTemplateDO.getRelatedGroupId())) {
List<String> groupNames = new ArrayList<>();
List<String> groupIds = new ArrayList<>();
for (String groupId : recordTemplateDO.getRelatedGroupId()) {
BossUserGroupQueryRequest bossUserGroupQueryRequest = new BossUserGroupQueryRequest();
bossUserGroupQueryRequest.setPage(1);
bossUserGroupQueryRequest.setSize(1);
bossUserGroupQueryRequest.setGroupId(groupId);
FacadeResponse<PageSerializable<BossUserGroupVO>> facadeResponse = bossUserClient.listGroups(bossUserGroupQueryRequest);
if (facadeResponse.isSucceeded() && !CollectionUtils.isEmpty(facadeResponse.getValue().getList())) {
groupNames.add(facadeResponse.getValue().getList().get(0).getGroupName());
groupIds.add(facadeResponse.getValue().getList().get(0).getGroupId());
}
}
recordTemplateVO.setRelatedGroupName(groupNames);
recordTemplateVO.setRelatedGroupId(groupIds);
}
return recordTemplateVO;
}).collect(Collectors.toList());
}
PageSerializable<RecordTemplateVO> pageSerializable = PageSerializable.of(recordTemplateVOS);
pageSerializable.setTotal(recordTemplateDOs.getTotal());
return pageSerializable;
}
@Override
public String createRecordTemplate(RecordTemplateCreateRequest request) {
List<RecordTemplateDO> recordTemplateDOLocal = csWorkOrderRecordTemplateDAO.findByTemplateName(request.getRecordTemplateName());
CSExceptionAssert.isTrue(recordTemplateDOLocal.size() == 0, CSOrderBizErrorCode.RECORD_TEMPLATE_EXIST, "跟进记录模版名称重复,请调整!");
RecordTemplateDO recordTemplateDO = WorkOrderConverter.createRequest2RecordTemplateDO(request);
recordTemplateDO.setTemplateId(AttaIdUtils.getByProdCode(AttaIdUtils.ProdCode.CUSTOMER_SERVICE_WORKORDER_RECORD_TEMPLATE));
List<DataPersistenceCommander> commanders = new ArrayList<>();
commanders.add(() -> {
CSExceptionAssert.isTrue(csWorkOrderRecordTemplateDAO.insert(recordTemplateDO) != null
, CSOrderBizErrorCode.SYSTEM_ERROR
, "insert recordTemplateDO failed.");
});
insertRecordTemplateLog(commanders, recordTemplateDO, request);
transactionLazyExecutor.executeCommanders(commanders);
return recordTemplateDO.getTemplateId();
}
@Override
public void editRecordTemplate(RecordTemplateEditRequest request) {
RecordTemplateDO recordTemplateDO = csWorkOrderRecordTemplateDAO.findByTemplateId(request.getRecordTemplateId());
CSExceptionAssert.isTrue(recordTemplateDO != null
, CSOrderBizErrorCode.SYSTEM_ERROR, " recordTemplate not fund!");
if (!request.getRecordTemplateName().equals(recordTemplateDO.getTemplateName())) {
List<RecordTemplateDO> recordTemplateDOs = csWorkOrderRecordTemplateDAO.findByTemplateName(request.getRecordTemplateName());
CSExceptionAssert.isTrue(recordTemplateDOs.size() == 0
|| (recordTemplateDOs.size() == 1 && request.getRecordTemplateName().equals(recordTemplateDOs.get(0).getTemplateName()))
, CSOrderBizErrorCode.RECORD_TEMPLATE_EXIST, "edit recordTemplate failed,templateName is exited");
}
recordTemplateDO.setTemplateName(request.getRecordTemplateName());
recordTemplateDO.setFormId(request.getFormId());
recordTemplateDO.setRelatedGroupId(request.getRelatedGroupId());
recordTemplateDO.setStatus(request.getStatus());
List<DataPersistenceCommander> commanders = new ArrayList<>();
commanders.add(() -> {
CSExceptionAssert.isTrue(csWorkOrderRecordTemplateDAO.updateByIdSelective(recordTemplateDO) != null
, CSOrderBizErrorCode.SYSTEM_ERROR
, "update recordTemplateDO failed.");
});
updateRecordTemplateLog(commanders, recordTemplateDO, request);
transactionLazyExecutor.executeCommanders(commanders);
}
@Override
public List<RecordTemplateVO> queryRecordTemplateByName(String recordTemplateName) {
List<RecordTemplateDO> recordTemplateDOs = csWorkOrderRecordTemplateDAO.findByTemplateLikeName(recordTemplateName);
List<RecordTemplateVO> recordTemplateVOS = new ArrayList<>();
if (!CollectionUtils.isEmpty(recordTemplateDOs)) {
recordTemplateVOS = recordTemplateDOs
.stream().map(recordTemplateDO -> {
RecordTemplateVO recordTemplateVO = WorkOrderConverter.toRecordTemplateVO(recordTemplateDO);
if (StringUtils.isNotEmpty(recordTemplateDO.getFormId())) {
FacadeResponse<FormVO> facadeResponse = formServClient.queryDetails(recordTemplateDO.getFormId());
if (facadeResponse.isSucceeded() && null != facadeResponse.getValue()) {
recordTemplateVO.setFormVO(facadeResponse.getValue());
}
}
return recordTemplateVO;
}).collect(Collectors.toList());
}
return recordTemplateVOS;
}
@Override
public RecordDetailVO queryRecordDetail(String recordId) {
CSWorkOrderCommRecordDO csWorkOrderCommRecordDO = csWorkOrderCommRecordDAO.getCommRecordsByRecordId(recordId);
CSExceptionAssert.isTrue(csWorkOrderCommRecordDO != null
, CSOrderBizErrorCode.SYSTEM_ERROR
, "record not found!");
RecordDetailVO recordDetailVO = WorkOrderConverter.toRecordDetailVO(csWorkOrderCommRecordDO);
User user = bossUserClient.queryByBossUserId(csWorkOrderCommRecordDO.getOperator());
if (user != null) {
recordDetailVO.setOperator(user.getUserName());
}
try {
List<AttachmentVO> attachmentVOList = attachmentFacade.getFileByReferenceId(csWorkOrderCommRecordDO.getRecordId());
recordDetailVO.setAttachmentVOS(attachmentVOList);
} catch (Exception e) {
log.error("upload attachment failed.e:", e);
}
if (StringUtils.isNotEmpty(recordDetailVO.getRecordTemplateId())) {
RecordTemplateDO recordTemplateDO = csWorkOrderRecordTemplateDAO.findByTemplateId(recordDetailVO.getRecordTemplateId());
CSExceptionAssert.isTrue(recordTemplateDO != null
, CSOrderBizErrorCode.SYSTEM_ERROR
, "recordTemplate not found!");
FormAnswerQueryReq formAnswerQueryReq = FormAnswerQueryReq
.builder()
.formId(recordTemplateDO.getFormId())
.formVersion(recordTemplateDO.getFormVersion())
.bizId(recordId)
.build();
FacadeResponse<FormAnswerVO> facadeResponse = formServAnswerClient.getFormAnswerByBizId(formAnswerQueryReq);
if (facadeResponse.isSucceeded() && facadeResponse.getValue() != null) {
recordDetailVO.setFormAnswerVO(facadeResponse.getValue());
}
}
return recordDetailVO;
}
@Override
public List<RecordTemplateVO> queryRecordTemplateList(RecordTemplateInGroupQuery request) {
BossUserGroupListQueryRequest bossUserGroupQueryRequest = new BossUserGroupListQueryRequest();
bossUserGroupQueryRequest.setUserId(request.getUserId());
bossUserGroupQueryRequest.setStatus(CfgStatus.Enabled);
FacadeResponse<List<BossUserGroupVO>> facadeResponse = bossUserClient.listGroupsByUserId(bossUserGroupQueryRequest);
List<RecordTemplateVO> recordTemplateVOS = new ArrayList<>();
if (facadeResponse.isSucceeded() && facadeResponse.getValue() != null) {
List<String> groupIds = facadeResponse.getValue().stream().map(BossUserGroupVO::getGroupId).collect(Collectors.toList());
List<RecordTemplateDO> recordTemplateDOs = csWorkOrderRecordTemplateDAO.findByRelatedGroupIds(groupIds);
if (!CollectionUtils.isEmpty(recordTemplateDOs)) {
recordTemplateVOS = recordTemplateDOs
.stream().map(recordTemplateDO -> {
RecordTemplateVO recordTemplateVO = WorkOrderConverter.toRecordTemplateVO(recordTemplateDO);
if (StringUtils.isNotEmpty(recordTemplateDO.getFormId())) {
FacadeResponse<FormVO> formFacadeResponse = formServClient.queryDetails(recordTemplateDO.getFormId());
if (formFacadeResponse.isSucceeded() && null != formFacadeResponse.getValue()) {
recordTemplateVO.setFormVO(formFacadeResponse.getValue());
}
}
return recordTemplateVO;
}).collect(Collectors.toList());
}
}
return recordTemplateVOS;
}
@Override
public PageSerializable<RecordTemplateOpLogVO> queryRecordTemplateOpLogList(RecordTemplateOpLogQueryRequest request) {
Page<RecordTemplateOpLogDO> recordTemplateOpLogDOS = csWorkOrderRecdTmplOpLogDAO.findPageByTemplateId(request.getRecordTemplateId(), request.getPage(), request.getSize());
List<RecordTemplateOpLogVO> recordTemplateOpLogVOS = new ArrayList<>();
if (!CollectionUtils.isEmpty(recordTemplateOpLogDOS)) {
recordTemplateOpLogVOS = recordTemplateOpLogDOS.stream().map(recordTemplateOpLogDO -> RecordTemplateOpLogVO.builder()
.opLogId(recordTemplateOpLogDO.getOpLogId())
.templateId(recordTemplateOpLogDO.getTemplateId())
.opUserId(recordTemplateOpLogDO.getOpUserId())
.opType(recordTemplateOpLogDO.getOpType())
.opSuggestion(recordTemplateOpLogDO.getOpSuggestion())
.opTime(recordTemplateOpLogDO.getOpTime())
.build()).collect(Collectors.toList());
}
PageSerializable<RecordTemplateOpLogVO> pageSerializable = PageSerializable.of(recordTemplateOpLogVOS);
pageSerializable.setTotal(recordTemplateOpLogDOS.getTotal());
return pageSerializable;
}
@Override
public void rejectPreAudit(CSWorkOrderRejectRequest req) {
CSWorkOrderDO workOrderDO = findWorkOrderOne(req.getWorkorderId());
if (workOrderDO == null) {
throw new CustomerServiceException(CSOrderSystemErrorCode.RecordNotFoundError, CSOrderBizErrorCode.NOT_FOUND, "该工单不存在!");
}
if (!CSWorkOrderStatus.Created.equals(workOrderDO.getStatus())) {
throw new CustomerServiceException(CSOrderSystemErrorCode.IllegalState, CSOrderBizErrorCode.NOT_SUPPORT, "工单当前状态不能驳回!");
}
CSWorkOrderConfigDO csWorkOrderConfigDO = csWorkOrderConfigDAO.queryValidByConfigId(workOrderDO.getWorkOrderConfigId());
if (csWorkOrderConfigDO == null) {
log.error("query workOrder config failed,workOrder config id is :{}", workOrderDO.getWorkOrderConfigId());
throw new CustomerServiceException(CSOrderSystemErrorCode.IllegalState, CSOrderBizErrorCode.NOT_SUPPORT, "工单类型查询失败!");
}
CSExceptionAssert.isTrue(!StringUtils.isEmpty(csWorkOrderConfigDO.getConfigType())
, CSOrderBizErrorCode.VALIDATION_ERROR
, "configType should not be empty, configType is " + WorkOrderConfigType.CertificationPreAudit);
if (!WorkOrderConfigType.CertificationPreAudit.name().equals(csWorkOrderConfigDO.getConfigType())) {
throw new CustomerServiceException(CSOrderSystemErrorCode.ValidationError, CSOrderBizErrorCode.NOT_SUPPORT, "只能驳回预审工单!");
}
workOrderDO.setStatus(CSWorkOrderStatus.Completed);
workOrderDO.setCompletedTime(new Date());
workOrderDO.setLastUpdatedBy(req.getPrincipalUserId());
workOrderDO.setLastUpdateDate(new Date());
workOrderDO.setCurrentDealUserId(req.getPrincipalUserId());
boolean updateRes = updateWorkOrder(workOrderDO, createdOpLogDO(workOrderDO.getWorkorderId(), workOrderDO.getStatus(), req.getPrincipalUserId(), req.getSuggestion()));
if (!updateRes) {
throw new CustomerServiceException(CSOrderSystemErrorCode.IllegalState, CSOrderBizErrorCode.SYSTEM_ERROR, "更新失败!");
}
CompletableFuture.runAsync(() -> doInstruction(workOrderDO.getWorkorderId()), commonExecutor);
}
@Override
public String complete(CSWorkOrderCompleteRequest request) {
CSExceptionAssert.isTrue(finalCSWorkOrderStatus.contains(request.getStatus())
, CSOrderBizErrorCode.VALIDATION_ERROR, "status should be final status.");
CSWorkOrderDO workOrderDO = findWorkOrderOne(request.getWorkorderId());
CSExceptionAssert.isTrue(workOrderDO != null
, CSOrderBizErrorCode.VALIDATION_ERROR
, "workOrder is not exist, WorkOrderId is: " + request.getWorkorderId());
if (finalCSWorkOrderStatus.contains(workOrderDO.getStatus())) {
return workOrderDO.getWorkorderId();
}
if (StringUtils.isNotBlank(workOrderDO.getReferenceId())
&&
needCheckWorkConfigIds.contains(workOrderDO.getWorkOrderConfigId())
&& preAuditNeedCheck(workOrderDO.getWorkorderId())
) {
FacadeResponse<AuditSnapshotCheckResult> res =
manualAuditSnapshotClient.auditSnapshotFieldCheck(workOrderDO.getReferenceId());
CSExceptionAssert.isTrue(res.isSucceeded()
, CSOrderBizErrorCode.SYSTEM_ERROR
, "call manualAuditSnapshotClient.auditSnapshotFieldCheck failed");
if (res.getValue() != null && Objects.equals(res.getValue().isSuccess(), false)) {
log.warn("auditSnapshotFieldCheck failed, workOrderId is: {}, referenceId is: {}, message is: {}"
, workOrderDO.getWorkorderId(), workOrderDO.getReferenceId(), res.getValue().getAbsentField());
String errorMsg = "";
if (!CollectionUtils.isEmpty(res.getValue().getAbsentField())) {
String tips = res.getValue().getAbsentField().stream().
map(ManualAuditSnapshotRequest.ManualAuditSnapshotUpdateEnum::getDescByType)
.collect(Collectors.joining(","));
errorMsg = "请先补充资料, 缺失的有: " + tips;
}
if (StringUtils.isNotEmpty(res.getValue().getErrCode())) {
errorMsg += ErrorInfoMap.getErrorInfo(res.getValue().getErrCode());
}
throw new CustomerServiceException(CSOrderSystemErrorCode.ValidationError, CSOrderBizErrorCode.NOT_SUPPORT, errorMsg);
}
}
//云雀发起的被动协同工单,存在created状态下还未分配就被动关闭的情况
if (Boolean.FALSE.equals(request.isSkylarkCallBack())) {
CSExceptionAssert.isTrue(CSWorkOrderStatus.Created != workOrderDO.getStatus()
, CSOrderBizErrorCode.VALIDATION_ERROR
, "worker order not be applied. status is: " + workOrderDO.getStatus());
}
String skylarkCollaborationId = workOrderDO.getSkylarkCollaborationId();
//是否有未完成的云雀协同工单
//云雀回调不检查协同单状态,默认是关闭的。云雀目前把协同单的状态修改和SPI调用放在了一个事务中,下面的查询拿不到status终态
if (!Objects.isNull(skylarkCollaborationId) && Boolean.FALSE.equals(request.isSkylarkCallBack())) {
CollaborationVO collaborationVO = skylarkManager.getCollaborationDetail(skylarkCollaborationId);
CSExceptionAssert.isTrue(Objects.nonNull(collaborationVO) && CollaborationStatus.COMPLETED.name().equals(collaborationVO.getStatus())
, CSOrderBizErrorCode.VALIDATION_ERROR
, "worker order has uncompleted skylark collaboration. status is: " + collaborationVO.getStatus());
}
// 如果是人工结案二线工单
if (!SystemConst.SYSTEM_USER_ID.equals(request.getOperatorUserId()) && workOrderDO.getOrderLevel() == OrderLevel.OL2
&& !WORK_ORDER_UPGRADE_LABEL_UL1.equals(workOrderDO.getUpgradeLabel())) {
BossUserInGroupReq bossUserInGroupReq = BossUserInGroupReq.builder()
.bossUserId(request.getOperatorUserId())
.groupIds(Sets.newHashSet(secondGroup))
.build();
FacadeResponse<Boolean> facadeResponse = bossUserGroupClient.bossUserInSpecifiedGroup(bossUserInGroupReq);
CSExceptionAssert.isTrue(facadeResponse.isSucceeded(), CSOrderBizErrorCode.SYSTEM_ERROR, "call bossUserGroupClient.bossUserInSpecifiedGroup failed");
CSExceptionAssert.isTrue(Boolean.TRUE.equals(facadeResponse.getValue())
, CSOrderBizErrorCode.VALIDATION_ERROR, "非二线人员,不能结案二线工单");
}
String suggestion = "结案工单";
if (org.springframework.util.StringUtils.hasText(request.getSuggestion())) {
suggestion = request.getSuggestion();
}
return workOrderClose(request.getWorkorderId(), request.getOperatorUserId(), request.getStatus(), suggestion);
}
@Override
public Boolean reopen(CSWorkOrderReopenRequest request) {
String workOrderId = request.getWorkOrderId();
String operatorUserId = request.getOperatorUserId();
CSExceptionAssert.isTrue(!Objects.isNull(workOrderId) || !Objects.isNull(operatorUserId)
, CSOrderBizErrorCode.VALIDATION_ERROR
, "客服工单ID或操作人为空");
CSWorkOrderDO csWorkOrderDO = csWorkOrderDAO.queryCSWorkOrderByWorkOrderId(workOrderId);
CSExceptionAssert.isTrue(!Objects.isNull(csWorkOrderDO),
CSOrderBizErrorCode.VALIDATION_ERROR,
"客服工单不存在");
//云雀上线前的历史工单不支持重开
CSExceptionAssert.isTrue(Boolean.TRUE.equals(csWorkOrderDO.getNewCollaboration()),
CSOrderBizErrorCode.VALIDATION_ERROR,
"历史工单不支持重开");
//预审工单不支持重开
CSExceptionAssert.isTrue(!isPreAuditWorkOrder(csWorkOrderDO),
CSOrderBizErrorCode.VALIDATION_ERROR,
"预审工单不支持重开");
//账号功能工单不支持重开
CSWorkOrderConfigDO csWorkOrderConfigDO = csWorkOrderConfigDAO.queryByWOConfigIdIgnoreStatus(csWorkOrderDO.getWorkOrderConfigId());
CSExceptionAssert.isTrue(!BusinessType.ACCOUNT_FUNCTION.equals(csWorkOrderConfigDO.getBusinessType()),
CSOrderBizErrorCode.VALIDATION_ERROR,
"账号功能工单不支持重开");
CSExceptionAssert.isTrue(CSWorkOrderStatus.Completed == csWorkOrderDO.getStatus(),
CSOrderBizErrorCode.VALIDATION_ERROR,
"工单状态非结案");
boolean needNotify = true;
//重开后工单状态区分工单级别,普通工单是处理中;升级工单是升级处理中
//不管工单是普通还是升级工单,路由给关闭前的工单处理人
CSWorkOrderStatus reopenStatus;
if (OrderLevel.OL2.equals(csWorkOrderDO.getOrderLevel())) {
reopenStatus = CSWorkOrderStatus.UpgradeProcessing;
csWorkOrderDO.setStatus(reopenStatus);
} else if ((OrderLevel.OL1.equals(csWorkOrderDO.getOrderLevel()) || Objects.isNull(csWorkOrderDO.getOrderLevel())) && !SystemConst.SYSTEM_USER_ID.equals(operatorUserId)) {
//一线客服工单被手动重开分配给当前操作人
reopenStatus = CSWorkOrderStatus.Processing;
csWorkOrderDO.setStatus(reopenStatus);
csWorkOrderDO.setPrincipalUserId(operatorUserId);
csWorkOrderDO.setCurrentDealUserId(operatorUserId);
needNotify = false;
} else {
reopenStatus = CSWorkOrderStatus.Processing;
csWorkOrderDO.setStatus(reopenStatus);
}
csWorkOrderDO.setCompletedTime(null);
//有重开权限的员工可以操作重开,不限普通工单、升级工单,落下工单重开的实际操作人
CSWorkOrderOpLogDO opLogDO = createdOpLogDO(workOrderId
, reopenStatus
, operatorUserId
, "工单重开");
boolean isOk = transactionUtil.executeMongo(() -> {
CSExceptionAssert.isTrue(csWorkOrderOpLogDAO.insert(opLogDO) != null
, CSOrderBizErrorCode.SYSTEM_ERROR
, "insert opLogDO failed.");
CSExceptionAssert.isTrue(csWorkOrderDAO.updateByIdSelective(csWorkOrderDO) != null
, CSOrderBizErrorCode.SYSTEM_ERROR
, "reopen workOrderDO failed.");
});
CSExceptionAssert.isTrue(isOk
, CSOrderBizErrorCode.SYSTEM_ERROR
, "reopen work order failed");
//发送通知
if (needNotify && !Strings.isNullOrEmpty(csWorkOrderDO.getPrincipalUserId())) {
//String content = String.format("工单编号:%s已被重开,请尽快处理!", workOrderId);
//messageManager.sendMessage(workOrderId, csWorkOrderDO.getPrincipalUserId(), content, bossAndDingding, MessageDomain.boss);
messageManager.sendReopenMessage(workOrderId, csWorkOrderDO.getPrincipalUserId(), WorkOrderOptType.REOPEN);
}
slaEscalationService.escalationReopenWorkOrderSla(csWorkOrderDO);
return true;
}
@Override
public PageSerializable<CSWorkOrderVO> pageList(CSWorkOrderPageListRequest request) {
Set<String> stringSet = null;
Set<String> excludeConfigIds = null;
if (!Strings.isNullOrEmpty(request.getProblemType())
|| !Strings.isNullOrEmpty(request.getWorkorderType())
|| request.getBusinessType() != null
|| request.getMainType() != null) {
stringSet = csWorkOrderConfigDAO.getConfigIds(request.getBusinessType()
, request.getWorkorderType()
, request.getProblemType()
, request.getCreateType()
, request.getMainType());
if (CollectionUtils.isEmpty(stringSet)) {
return null;
}
}
if (request.getExcludePreWorkOrder() != null && request.getExcludePreWorkOrder()) {
excludeConfigIds = preWorkOrderConfigIds;
}
if (request.getFilterSalesWorkOrder() != null && request.getFilterSalesWorkOrder()) {
Set<String> filterMarketingConfigIds = csWorkOrderConfigDAO.getConfigIdsByBusinessType(BusinessType.MARKETING);
if (CollectionUtils.isEmpty(stringSet)) {
stringSet = filterMarketingConfigIds;
}
}
Set<String> ids = new HashSet<>();
if (null != request.getCooperationDomain()) {
buildCoopCondition(request, ids);
}
if (StringUtils.isNotBlank(request.getSenderEmail())) {
List<String> csIds = csWorkOrderReceiveEmailRecordDAO.queryCsWorkOrderIdsBySender(request.getSenderEmail());
if (!CollectionUtils.isEmpty(csIds)) {
ids.addAll(csIds);
}
}
if (buildEmailCondition(request, ids)) return null;
if (StringUtils.isNotBlank(request.getWorkerOrderId()) && CollectionUtils.isEmpty(ids)) {
ids.add(request.getWorkerOrderId());
} else if (StringUtils.isNotBlank(request.getWorkerOrderId()) && !ids.contains(request.getWorkerOrderId())) {
return null;
}
Page<CSWorkOrderDO> CSWorkOrderDOS = new Page<>(); // NOSONAR
if (customerOrderSwitch) {
searchByWideTable(request, stringSet, ids, CSWorkOrderDOS, excludeConfigIds);
} else {
CSWorkOrderDOS = this.csWorkOrderDAO.findPage(MongoQueryFactory.create(request, stringSet, ids), request.getPage(), request.getSize());
}
List<CSWorkOrderVO> workOrderVOS = new LinkedList<>();
List<CSWorkOrderDO> collect = CSWorkOrderDOS;
if (!CollectionUtils.isEmpty(CSWorkOrderDOS)) {
//走优化后逻辑
Set<String> bossUserIds = collect.stream().map(CSWorkOrderDO::getUserId).collect(Collectors.toSet());
//查询全量user
// FacadeResponse<List<User>> allValidUsers = bossUserClient.listValidUser();
// FacadeResponse<List<User>> allValidUsers = bossUserClient.queryByBossUserIds(bossUserIds);
List<User> users = bossUserClient.queryByBossUserIds(bossUserIds);
//查ActionDO
Query query = new Query();
List<String> workOrderIds = collect.stream().map(CSWorkOrderDO::getWorkorderId).collect(Collectors.toList());
Criteria criteria = Criteria.where(ActionDO.SCENE_ID).in(workOrderIds).and("tagKey").is("preAudit");
query.addCriteria(criteria);
List<ActionDO> actionDOs = actionDAO.find(query);
//TODO 迁移变更:查CooperationWorkOrderDO 废弃
// List<CooperationWorkOrderDO> cooperationWorkOrderDOs = cooperationWorkOrderDAO.queryByCooperationOrderIds(workOrderIds);
for (CSWorkOrderDO workOrderDO : collect) {
// FacadeResponse<CSWorkOrderVO> facadeResponse1 = toWorkOrderVOListOpt(workOrderDO, allValidUsers.getValue(), actionDOs);
FacadeResponse<CSWorkOrderVO> facadeResponse1 = toWorkOrderVOListOpt(workOrderDO, users, actionDOs);
if (!facadeResponse1.isSucceeded()) {
CSExceptionAssert.fail(CSOrderBizErrorCode.SYSTEM_ERROR, facadeResponse1.getResponseMsg());
}
workOrderVOS.add(facadeResponse1.getValue());
}
//释放内存
if (!CollectionUtils.isEmpty(users)) {
users.clear();
}
if (!CollectionUtils.isEmpty(actionDOs)) {
actionDOs.clear();
}
// if (!CollectionUtils.isEmpty(cooperationWorkOrderDOs)) {
// cooperationWorkOrderDOs.clear();
// }
}
PageSerializable<CSWorkOrderVO> pageSerializable = new PageSerializable<>();
pageSerializable.setTotal(CSWorkOrderDOS.getTotal());
pageSerializable.setList(workOrderVOS);
return pageSerializable;
}
private void searchByWideTable(CSWorkOrderPageListRequest request, Set<String> stringSet, Set<String> ids, Page<CSWorkOrderDO> CSWorkOrderDOS, Set<String> excludeConfigIds) {
List<String> bossUserIdsFromOP = null;
if (SLAPageSource.OP.name().equalsIgnoreCase(request.getSlaPageSource())) {
bossUserIdsFromOP = slaOrganizerService.getBossUserIds(request.getOrganizer());
}
FacadeResponse<PageableResponse<String>> searchRes = csWorkOrderSearchClient
.searchCSWorkOrderPage(MongoQueryToDorisQueryConvert.convert(request, stringSet, ids, bossUserIdsFromOP, excludeConfigIds));
if (!searchRes.isSucceeded()) {
log.error("query from doris failed {}", searchRes.getResponseMsg());
return;
}
if (searchRes.getValue() == null) {
return;
}
PageableResponse<String> value = searchRes.getValue();
if (CollectionUtils.isEmpty(value.getData())) {
return;
}
List<CSWorkOrderDO> result;
if (SLAPageSource.SELF.name().equalsIgnoreCase(request.getSlaPageSource()) || SLAPageSource.OP.name().equalsIgnoreCase(request.getSlaPageSource())) {
result = csWorkOrderDAO.queryOrdersByWorkOrderIdsSortSlaTodoEndTime(Sets.newHashSet(value.getData()));
} else {
result = csWorkOrderDAO.queryOrdersByWorkOrderIdsSortCreateTimeDesc(Sets.newHashSet(value.getData()));
}
CSWorkOrderDOS.setTotal(value.getTotal());
CSWorkOrderDOS.addAll(result);
}
private boolean buildEmailCondition(CSWorkOrderPageListRequest request, Set<String> ids) {
if (StringUtils.isNotBlank(request.getReceiveEmail())) {
Set<String> tempIds = new HashSet<>();
List<CSWorkOrderCommRecordDO> commRecordsByEmailTO = csWorkOrderCommRecordDAO.getCommRecordsByEmailTO(request.getReceiveEmail());
if (!CollectionUtils.isEmpty(commRecordsByEmailTO)) {
List<String> collect = commRecordsByEmailTO.stream().map(CSWorkOrderCommRecordDO::getWorkorderId).collect(Collectors.toList());
tempIds.addAll(collect);
}
List<String> toIds = csWorkOrderReceiveEmailRecordDAO.queryCsWorkOrderIdsByTo(request.getReceiveEmail());
if (!CollectionUtils.isEmpty(toIds)) {
tempIds.addAll(toIds);
}
if (CollectionUtils.isEmpty(tempIds)) {
return true;
}
ids.addAll(tempIds);
}
return false;
}
private void buildCoopCondition(CSWorkOrderPageListRequest request, Set<String> ids) {
if (Objects.isNull(request.getCooperateWorkOrderCreateTimeBegin()) || Objects.isNull(request.getCooperateWorkOrderCreateTimeEnd())) {
throw new CustomerServiceException(CSOrderSystemErrorCode.BadRequest, CSOrderBizErrorCode.SYSTEM_ERROR, "请输入协同工单创建时间范围");
}
// List<CooperationWorkOrderDO> cooperationWorkOrderDOS = cooperationWorkOrderDAO.queryByCooperationDomainWithTimeRange(request.getCooperationDomain(),
// request.getCooperateWorkOrderCreateTimeBegin(), request.getCooperateWorkOrderCreateTimeEnd());
// if (!CollectionUtils.isEmpty(cooperationWorkOrderDOS)) {
// ids.addAll(cooperationWorkOrderDOS.stream().map(CooperationWorkOrderDO::getSourceOrderId).collect(Collectors.toSet()));
// }
// List<CoopWorkOrderDO> coopWorkOrderDOS = coopWorkOrderDAO.queryBySoAndCoDepartIdWithTimeRange(DepartmentConstant.CRM,
// request.getCooperationDomain().name(), request.getCooperateWorkOrderCreateTimeBegin(), request.getCooperateWorkOrderCreateTimeEnd());
// if (!CollectionUtils.isEmpty(coopWorkOrderDOS)) {
// ids.addAll(coopWorkOrderDOS.stream().map(CoopWorkOrderDO::getSoWorkOrderId).collect(Collectors.toSet()));
// }
// 兼容云雀的协同单
BizType bizType = COOPERATION_DOMAIN_BIZ_TYPE_MAP.get(request.getCooperationDomain());
if (Objects.nonNull(bizType)) {
List<String> collaborationIds = skylarkManager.queryCollaborationIds(BizType.CUSTOMER_SERVICE, bizType, request.getCooperateWorkOrderCreateTimeBegin(), request.getCooperateWorkOrderCreateTimeEnd(), coop_workoder_query_limit);
if (!CollectionUtils.isEmpty(collaborationIds)) {
List<CSWorkOrderDO> csWorkOrderDOS = csWorkOrderDAO.queryCSWorkOrderBySkylarkCollaborationIds(Sets.newHashSet(collaborationIds));
ids.addAll(csWorkOrderDOS.stream().map(CSWorkOrderDO::getWorkorderId).collect(Collectors.toSet()));
}
}
if (ids.size() > coop_workoder_query_limit) {
throw new CustomerServiceException(CSOrderSystemErrorCode.BadRequest, CSOrderBizErrorCode.SYSTEM_ERROR, "查询的工单数量超过限制,请缩短查询时间范围");
}
}
@Override
public CSWorkOrderVO queryOneWorkOrder(String workorderId) {
CSWorkOrderDO csWorkOrderDO = findWorkOrderOne(workorderId);
CSWorkOrderVO csWorkOrderVO = toWorkOrderVO(csWorkOrderDO);
csWorkOrderVO.setHistoryPreAuditWorkOrderVOList(getHistoryPreAuditWorkOrders(csWorkOrderDO));
// csWorkOrderVO.setPartnerBindVO(getPreAuditWorkOrderPartnerInfo(csWorkOrderDO));
// csWorkOrderVO.setBusinessBindVO(getExpeditedWorkOrderBusinessInfo(csWorkOrderDO));
return csWorkOrderVO;
}
@Override
public boolean allowedEditFirmInfo(String workorderId) {
if (StringUtils.isEmpty(workorderId)) {
return false;
}
CSWorkOrderDO csWorkOrderDO = findWorkOrderOne(workorderId);
if (Objects.isNull(csWorkOrderDO)) {
return false;
}
if (finalCSWorkOrderStatus.contains(csWorkOrderDO.getStatus())) {
return false;
}
return allowedEditFirmInfoConfigId.contains(csWorkOrderDO.getWorkOrderConfigId());
}
@Override
public CSWorkOrderVO queryWorkOrder(CSWorkOrderQueryRequest request) {
CSWorkOrderDO csWorkOrderDO = csWorkOrderDAO.queryCSWorkOrderByReferenceId(request.getReferenceId());
return toWorkOrderVO(csWorkOrderDO);
}
@Override
public List<CSWorkOrderVO> queryWorkOrderVOS(CSWorkOrdersQueryRequest request) {
Query query = new Query();
if (!Strings.isNullOrEmpty(request.getUserId())) {
query.addCriteria(Criteria.where(CSWorkOrderDO.USER_ID).is(request.getUserId()));
}
if (!Strings.isNullOrEmpty(request.getFirmId())) {
query.addCriteria(Criteria.where(CSWorkOrderDO.FIRM_ID).is(request.getFirmId()));
}
if (!Strings.isNullOrEmpty(request.getWorkOrderConfigId())) {
query.addCriteria(Criteria.where(CSWorkOrderDO.WORK_ORDER_CONFIG_ID).is(request.getWorkOrderConfigId()));
}
return csWorkOrderDAO.find(query).stream().map(this::toWorkOrderVO).collect(Collectors.toList());
}
@Override
public FacadeResponse<PageSerializable<CSWorkOrderVO>> bossAccountWorkOrderList(CSWorkOrderPageListRequest request) {
FacadeResponse facadeResponse = validate(request);
if (!facadeResponse.isSucceeded()) {
return facadeResponse;
}
Criteria criteria = new Criteria();
//工单所属领域为空,直接按照workOrderType和businessType查询工单配置
//工单所属领域不为空查询对应领域工单
//预审工单:workOrderType = 客户审核 and businessType = 客户成功
//客服工单:workOrderType != 客户审核 or businessType != 客户成功
Query configQuery = new Query();
buildSomePartQuery(request, configQuery);
Set<String> stringSet = null;
if (null != request.getWorkOrderDomain() || request.getBusinessType() != null || !StringUtils.isEmpty(request.getWorkorderType())) {
stringSet = csWorkOrderConfigDAO.find(configQuery).stream().map(CSWorkOrderConfigDO::getConfigId).collect(Collectors.toSet());
if (CollectionUtils.isEmpty(stringSet)) {
PageSerializable<CSWorkOrderVO> pageSerializable = new PageSerializable<>();
pageSerializable.setTotal(0);
pageSerializable.setList(new LinkedList<>());
return getFacadeResponseWithValue(pageSerializable);
}
}
//除销售工单外的所有工单配置id
Set<String> configIdsByBusinessType = csWorkOrderConfigDAO.getConfigIdsByBusinessType(BusinessType.MARKETING);
if (CollectionUtils.isEmpty(configIdsByBusinessType)) {
return getFacadeResponseWithValue(new PageSerializable<>());
}
if (!CollectionUtils.isEmpty(stringSet)) {
stringSet = stringSet.stream().filter(configIdsByBusinessType::contains).collect(Collectors.toSet());
} else {
//过滤销售工单的数据
stringSet = configIdsByBusinessType;
}
if (!CollectionUtils.isEmpty(stringSet)) {
criteria.and("workOrderConfigId").in(stringSet);
}
if (!Strings.isNullOrEmpty(request.getPrincipalUserId())) {
criteria.and("principalUserId").is(request.getPrincipalUserId());
}
Criteria criteria1;
Criteria criteria2;
if (!Strings.isNullOrEmpty(request.getFirmId()) && !Strings.isNullOrEmpty(request.getUserId())) {
criteria1 = Criteria.where("firmId").is(request.getFirmId());
criteria2 = Criteria.where("userId").is(request.getUserId());
criteria.andOperator(new Criteria().orOperator(criteria1, criteria2));
} else if (!Strings.isNullOrEmpty(request.getFirmId()) && Strings.isNullOrEmpty(request.getUserId())) {
criteria1 = Criteria.where("firmId").is(request.getFirmId());
criteria.andOperator(criteria1);
} else if (!Strings.isNullOrEmpty(request.getUserId()) && Strings.isNullOrEmpty(request.getFirmId())) {
criteria2 = Criteria.where("userId").is(request.getUserId());
criteria.andOperator(criteria2);
} else {
FacadeResponse<PageSerializable<CSWorkOrderVO>> response = new FacadeResponse<>();
response.fillWithUnSuccess(AttaResponseCode.ILLEGAL_ARGUMENT, "firmId or userId is not null");
return response;
}
if (request.getStatus() != null) {
criteria.and("status").is(request.getStatus().name());
}
if (request.getBeginCreatedTime() != null || request.getEndCreatedTime() != null) {
Criteria creationDateCriteria = criteria.and("creationDate");
if (request.getBeginCreatedTime() != null) {
creationDateCriteria.gte(request.getBeginCreatedTime());
}
if (request.getEndCreatedTime() != null) {
creationDateCriteria.lt(request.getEndCreatedTime());
}
}
Query query = new Query().addCriteria(criteria).with(Sort.by(Sort.Direction.DESC, CSWorkOrderDO.CREATION_DATE));
Page<CSWorkOrderDO> CSWorkOrderDOS = this.csWorkOrderDAO.findPage(query, request.getPage(), request.getSize());
List<CSWorkOrderVO> workOrderVOS = new LinkedList<>();
if (!CollectionUtils.isEmpty(CSWorkOrderDOS)) {
for (CSWorkOrderDO workOrderDO : CSWorkOrderDOS) {
FacadeResponse<CSWorkOrderVO> facadeResponse1 = toWorkOrderVOList(workOrderDO);
if (!facadeResponse1.isSucceeded()) {
return getFacadeResponseWithFailed(facadeResponse1.getResponseCode());
}
workOrderVOS.add(facadeResponse1.getValue());
}
}
PageSerializable<CSWorkOrderVO> pageSerializable = new PageSerializable<>();
pageSerializable.setTotal(CSWorkOrderDOS.getTotal());
pageSerializable.setList(workOrderVOS);
return getFacadeResponseWithValue(pageSerializable);
}
private CSWorkOrderDO findWorkOrderByReferenceId(String referenceId) {
Criteria criteria = new Criteria();
criteria.and("referenceId").is(referenceId);
return csWorkOrderDAO.findOne(new Query().addCriteria(criteria));
}
@Override
public FacadeResponse autoComplete(CSWorkOrderAutoCompleteRequest request) {
FacadeResponse<CSWorkOrderConfigDO> response = validateBaseCsWorkOrder(request);
if (!response.isSucceeded()) {
return response;
}
CSWorkOrderConfigDO csWorkOrderConfigDO = response.getValue();
CSWorkOrderDO exist = findWorkOrderByReferenceId(request.getReferenceId());
if (exist != null) {
return getFacadeResponseWithFailed(AttaResponseCode.VALIDATION_ERROR, "工单已存在");
}
String firmName = request.getFirmName();
if (Strings.isNullOrEmpty(firmName)) {
FacadeResponse<GetFirmNameInfoResponse> firmNameResponse = firmProfileClient.getFirmNameInfo(request.getFirmId());
if (firmNameResponse.isSucceeded() && firmNameResponse.getValue() != null) {
firmName = firmNameResponse.getValue().getFirmNameZh();
}
}
CSWorkOrderDO csWorkOrderDO = createdCSWorkOrderDO(request.getReferenceId(), csWorkOrderConfigDO.getConfigId(),
request.getMid(), request.getFirmId(), firmName, request.getUserId(), "system", request.getPhoneAreaCode(), request.getNewPhoneAreaCode());
csWorkOrderDO.setStatus(CSWorkOrderStatus.Completed);
csWorkOrderDO.setPhone(request.getPhone());
csWorkOrderDO.setVideoUrl(request.getVideoUrl());
csWorkOrderDO.setCompletedTime(new Date());
csWorkOrderDO.setMid(request.getMid());
csWorkOrderDO.setIdNumber(request.getIdNumber());
csWorkOrderDO.setDirectorName(request.getDirectorName());
if (csWorkOrderConfigDO.getBusinessType() == BusinessType.ACCOUNT_FUNCTION
&& WorkOrderType.ACCOUNT_SECURITY.getDesc().equals(csWorkOrderConfigDO.getWorkorderType())
&& ProblemType.CHANGE_PHONE_NUMBER_AUTO.getDesc().equals(csWorkOrderConfigDO.getProblemType())) {
if (request.getNewPhone() == null || (!phonePattern.matcher(request.getNewPhone()).matches() &&
!HKPhonePattern.matcher(request.getNewPhone()).matches())) {
return getFacadeResponseWithFailed(AttaResponseCode.ILLEGAL_ARGUMENT, "请输入正确的新手机号");
}
csWorkOrderDO.setNewPhone(request.getNewPhone());
}
CSWorkOrderCommRecordDO commRecordDO = createCommRecordDO(csWorkOrderDO.getWorkorderId()
, csWorkOrderDO.getPrincipalUserId()
, "人脸核身相似度:" + request.getCommRecord()
, null
, null);
//插入工单
boolean isOk = insertWO(csWorkOrderDO,
commRecordDO,
createdOpLogDO(csWorkOrderDO.getWorkorderId(), csWorkOrderDO.getStatus(), csWorkOrderDO.getPrincipalUserId(), "自动结案工单"));
if (!isOk) {
return getFacadeResponseWithFailed(AttaResponseCode.SYSTEM_ERROR);
}
return getFacadeResponseWithSuccess();
}
@Override
public FacadeResponse handleCustomerSubmitWorkOrder(CustomerSubmitWorkOrderRequest request) {
FacadeResponse<CSWorkOrderConfigDO> validateResponse = validateBaseCsWorkOrder(request);
if (!validateResponse.isSucceeded()) {
return validateResponse;
}
CSWorkOrderDO existReferenceId = findWorkOrderByReferenceId(request.getReferenceId());
if (existReferenceId != null) {
return getFacadeResponseWithFailed(AttaResponseCode.VALIDATION_ERROR, "工单已存在");
}
CSWorkOrderConfigDO csWorkOrderConfigDO = validateResponse.getValue();
CSWorkOrderDO csWorkOrderDO = createdCSWorkOrderDO(request.getReferenceId(), csWorkOrderConfigDO.getConfigId(),
request.getMid(), request.getFirmId(), request.getFirmName(), request.getUserId(), "system", request.getPhoneAreaCode(), request.getNewPhoneAreaCode());
csWorkOrderDO.setStatus(CSWorkOrderStatus.Checking);
csWorkOrderDO.setPhone(request.getPhone());
csWorkOrderDO.setIdNumber(request.getIdNumber());
csWorkOrderDO.setDirectorName(request.getDirectorName());
csWorkOrderDO.setSource(WorkOrderSource.USER);
if (csWorkOrderConfigDO.getBusinessType() == BusinessType.ACCOUNT_FUNCTION
&& WorkOrderType.ACCOUNT_SECURITY.getDesc().equals(csWorkOrderConfigDO.getWorkorderType())
&& ProblemType.CHANGE_PHONE_NUMBER.getDesc().equals(csWorkOrderConfigDO.getProblemType())) {
FacadeResponse phoneAvailable = checkPhoneAvailable(request.getPhoneAreaCode(), request.getPhone(), request.getNewPhoneAreaCode(), request.getNewPhone());
if (!phoneAvailable.isSucceeded()) {
return phoneAvailable;
}
csWorkOrderDO.setNewPhone(request.getNewPhone());
}
CSWorkOrderDO exist = checkSubsistingWorkOrder(csWorkOrderConfigDO.getConfigId(), request.getUserId());
if (exist != null) {
return getFacadeResponseWithFailed(AttaResponseCode.BIZ_ERROR, "已提交审核,无需重复提交。");
}
String key = "insertWorkOrderKey:" + request.getUserId() + csWorkOrderConfigDO.getConfigId();
FacadeResponse execute = redissonLock.execute(key, () -> {
//double check
CSWorkOrderDO exist2 = checkSubsistingWorkOrder(csWorkOrderConfigDO.getConfigId(), request.getUserId());
if (exist2 != null) {
return getFacadeResponseWithFailed(AttaResponseCode.BIZ_ERROR, "已提交审核,无需重复提交。");
}
CSWorkOrderCommRecordDO commRecordDO = createCommRecordDO(csWorkOrderDO.getWorkorderId()
, "system"
, request.getCommRecord()
, request.getAttachments()
, null);
boolean isOk = insertWO(csWorkOrderDO,
commRecordDO,
createdOpLogDO(csWorkOrderDO.getWorkorderId(), csWorkOrderDO.getStatus(), csWorkOrderDO.getPrincipalUserId(), "钉钉审核工单"));
if (!isOk) {
return getFacadeResponseWithFailed(AttaResponseCode.SYSTEM_ERROR);
}
return getFacadeResponseWithSuccess();
});
if (!execute.isSucceeded()) {
return execute;
}
sendApproval(csWorkOrderDO.getWorkorderId(), "customerWorkOrder", submitBossUserId, submitBossUserName);
return getFacadeResponseWithSuccess();
}
@Override
public FacadeResponse<Void> review(WorkOrderReviewRequest request) {
FacadeResponse validate = validate(request);
if (!validate.isSucceeded()) {
return validate;
}
CSWorkOrderDO csWorkOrderDO = findWorkOrderOne(request.getWorkorderId());
if (csWorkOrderDO == null) {
return getFacadeResponseWithFailed(AttaResponseCode.BIZ_ERROR, "工单不存在");
}
if (csWorkOrderDO.getStatus() == CSWorkOrderStatus.Completed) {
return getFacadeResponseWithFailed(AttaResponseCode.BIZ_ERROR, "工单已结案");
}
CSWorkOrderConfigDO csWorkOrderConfigDO = findConfigOne(request.getWorkorderTypeId());
FacadeResponse facadeResponse = checkCsWorkOrderConfigAvailable(csWorkOrderConfigDO);
if (!facadeResponse.isSucceeded()) {
return facadeResponse;
}
csWorkOrderDO.setCurrentDealUserId(request.getCurrentDealUserId());
return doHandleWorkOrderNotification(csWorkOrderDO, csWorkOrderConfigDO, request.getStatus());
}
@Override
public FacadeResponse<Void> submitReview(CSWorkOrderSubmitReviewRequest request) {
CSWorkOrderConfigDO csWorkOrderConfigDO = findConfigOne(request.getWorkorderTypeId());
if (csWorkOrderConfigDO == null) {
return getFacadeResponseWithFailed(AttaResponseCode.BIZ_ERROR, "工单配置不存在");
}
FacadeResponse facadeResponse = checkCsWorkOrderConfigAvailable(csWorkOrderConfigDO);
if (!facadeResponse.isSucceeded()) {
return facadeResponse;
}
CSWorkOrderDO csWorkOrderDO = WorkOrderConverter.convertFromSubmitReviewRequest(request);
csWorkOrderDO.setStatus(CSWorkOrderStatus.Checking);
csWorkOrderDO.setWorkorderId(getWorkOrderId());
csWorkOrderDO.setNewCollaboration(CsOrderConstants.newCollaboration);
WorkOrderConverter.setBasicFirmInfo(csWorkOrderDO, request.getUserId(), request.getFirmId(), firmClient, userClient);
WorkOrderConverter.setCSOrderDOFromOrderConfig(csWorkOrderDO, request.getWorkorderTypeId(), cSWorkOrderConfigService);
// 关联问卷
relateQuestionnaire(csWorkOrderDO.getWorkorderId(), request.getWorkorderTypeId(), request.getSceneConfigId());
//校验身份证
if (request.getIdNumber() != null) {
if (!IDUtils.isIDNumber(request.getIdNumber())) {
csWorkOrderDO.setIdType(IDType.passport.name());
} else {
csWorkOrderDO.setIdType(IDType.identity.name());
}
}
if (CHANGE_USER_MASTER_PHONE.equals(csWorkOrderConfigDO.getProblemType())) {
if (Strings.isNullOrEmpty(csWorkOrderDO.getUserId())) {
return getFacadeResponseWithFailed(AttaResponseCode.BIZ_ERROR, "非 XT 商户,修改手机号失败");
}
FacadeResponse phoneAvailable = checkPhoneAvailable(csWorkOrderDO.getPhoneAreaCode(), csWorkOrderDO.getPhone(), request.getNewPhoneAreaCode(), request.getNewPhone());
if (!phoneAvailable.isSucceeded()) {
return phoneAvailable;
}
}
//解绑x盾
if (UN_BIND_X.equals(csWorkOrderConfigDO.getProblemType())) {
if (Strings.isNullOrEmpty(request.getUserId())) {
return getFacadeResponseWithFailed(AttaResponseCode.BIZ_ERROR, "未绑定X盾");
}
FacadeResponse<Boolean> XShieldResponse = checkXshieldAvailable(csWorkOrderDO.getUserId());
if (!XShieldResponse.isSucceeded() || XShieldResponse.getValue() == null || !XShieldResponse.getValue()) {
return getFacadeResponseWithFailed(AttaResponseCode.BIZ_ERROR, "未绑定X盾");
}
}
CSWorkOrderDO exist = checkSubsistingWorkOrder(csWorkOrderConfigDO.getConfigId(), csWorkOrderDO.getUserId());
if (exist != null) {
return getFacadeResponseWithFailed(AttaResponseCode.BIZ_ERROR, "已提交审核,无需重复提交。");
}
String key = "insertWorkOrderKey:" + csWorkOrderDO.getUserId() + csWorkOrderConfigDO.getConfigId();
FacadeResponse execute = redissonLock.execute(key, () -> {
//double check
CSWorkOrderDO exist2 = checkSubsistingWorkOrder(csWorkOrderConfigDO.getConfigId(), csWorkOrderDO.getUserId());
if (exist2 != null) {
return getFacadeResponseWithFailed(AttaResponseCode.BIZ_ERROR, "已提交审核,无需重复提交。");
}
CSWorkOrderCommRecordDO commRecordDO = createCommRecordDO(csWorkOrderDO.getWorkorderId()
, request.getCurrentDealUserId()
, request.getCommRecord()
, request.getAttachments()
, request.getCallCenterIds());
boolean isOk = insertWO(csWorkOrderDO
, commRecordDO
, createdOpLogDO(csWorkOrderDO.getWorkorderId(), csWorkOrderDO.getStatus(), csWorkOrderDO.getPrincipalUserId(), "钉钉审核工单"));
if (!isOk) {
return getFacadeResponseWithFailed(AttaResponseCode.SYSTEM_ERROR);
}
return getFacadeResponseWithSuccess();
});
if (!execute.isSucceeded()) {
return execute;
}
//钉钉审核
sendApproval(csWorkOrderDO.getWorkorderId(), "customerWorkOrder", request.getCurrentDealUserId(), request.getCurrentDealUserName());
return getFacadeResponseWithSuccess();
}
@Override
public FacadeResponse<Void> doHandleWorkOrderNotification(CSWorkOrderDO csWorkOrderDO, CSWorkOrderConfigDO csWorkOrderConfigDO, CrmApprovalStatus crmApprovalStatus) {
if (csWorkOrderDO.getStatus() == CSWorkOrderStatus.Completed) {
log.warn("work order status is completed, work order id is {}", csWorkOrderDO.getWorkorderId());
return getFacadeResponseWithSuccess();
}
CSWorkOrderOpLogDO opLogDO = new CSWorkOrderOpLogDO();
opLogDO.setOpLogId(AttaIdUtils.getByProdCode(AttaIdUtils.ProdCode.CUSTOMER_SERVICE_WORKORDER_OP_LOG));
opLogDO.setOperatorUserId(csWorkOrderDO.getSource() == WorkOrderSource.BOSS ? csWorkOrderDO.getCurrentDealUserId() : "system");
opLogDO.setOpTime(new Date());
opLogDO.setStatus(CSWorkOrderStatus.Completed.name());
opLogDO.setSuggestion(crmApprovalStatus == CrmApprovalStatus.AGREED ? "审核通过" : "审核不通过");
opLogDO.setWorkorderId(csWorkOrderDO.getWorkorderId());
csWorkOrderDO.setCompletedTime(new Date());
csWorkOrderDO.setStatus(CSWorkOrderStatus.Completed);
try {
sendNotification(csWorkOrderDO, csWorkOrderConfigDO, crmApprovalStatus);
} catch (Exception e) {
log.error("send notification error,csWorkOrderDO workOrderId is {},{}", csWorkOrderDO.getWorkorderId(), e);
return getFacadeResponseWithFailed(AttaResponseCode.FAIL, "审核失败");
}
return mongoTransactionTemplate.execute(status -> {
if (csWorkOrderDAO.updateByIdSelective(csWorkOrderDO) == null) {
status.setRollbackOnly();
return getFacadeResponseWithFailed(AttaResponseCode.UNKNOWN_DATA_ACCESS_ERROR);
}
if (csWorkOrderOpLogDAO.insert(opLogDO) == null) {
status.setRollbackOnly();
return getFacadeResponseWithFailed(AttaResponseCode.UNKNOWN_DATA_ACCESS_ERROR);
}
return getFacadeResponseWithSuccess();
});
}
@Override
public boolean isPreAuditWorkOrder(String workOrderId) {
CSWorkOrderDO csWorkOrderDO = csWorkOrderDAO.queryCSWorkOrderByWorkOrderId(workOrderId);
if (csWorkOrderDO == null) {
log.warn("csWorkOrderDO not found workOrderId:{}", workOrderId);
return true;
}
return isPreAuditWorkOrder(csWorkOrderDO);
}
/**
* 是否预审工单(注意:不包含【理财业务预审】【大陆企业股东结汇预审】)
*
* @param workOrderDO
* @return
*/
@Override
public boolean isPreAuditWorkOrderV2(CSWorkOrderDO workOrderDO) {
CSExceptionAssert.isTrue(StringUtils.isNotBlank(workOrderDO.getWorkOrderConfigId())
, CSOrderBizErrorCode.VALIDATION_ERROR
, "workOrderConfigId is empty. workOrderId is: " + workOrderDO.getWorkorderId());
CSWorkOrderConfigDO configDO = csWorkOrderConfigDAO.queryByWOConfigIdIgnoreStatus(workOrderDO.getWorkOrderConfigId());
return configDO != null && (WorkOrderConfigType.CertificationPreAudit.name().equals(configDO.getConfigType())
|| WorkOrderConfigType.UpdateCertificationPreAudit.name().equals(configDO.getConfigType())
|| WorkOrderConfigType.CustomerAnnualPreAudit.name().equals(configDO.getConfigType()));
}
@Override
public void workOrderAutoCancelled() {
//获取当前日期N天前的客服工单,状态为"新建"
Date date = DateUtils.addDays(new Date(), -autoCancelledDays);
Criteria criteria = Criteria.where("creationDate").lt(date).and("status").is(CSWorkOrderStatus.Created);
Query query = new Query();
query.addCriteria(criteria);
int size = 500;
query.limit(size);
while (true) {
List<CSWorkOrderDO> workOrderDOList = csWorkOrderDAO.find(query);
if (CollectionUtils.isEmpty(workOrderDOList)) {
break;
}
workOrderDOList.forEach(w -> {
w.setStatus(CSWorkOrderStatus.Cancelled);
if (ExpediteType.ORDINARY_EXPEDITE.equals(w.getExpediteType())) {
cancelledExpediteWorkOrder(w);
} else {
this.updateWO(w, createdOpLogDO(w.getWorkorderId(), w.getStatus(), "system", "无人认领,撤销工单"));
}
});
}
}
@Override
public SpiServiceTicketOperationVO customerCancelWorkOrder(String userId, String serviceBizId, String reason, String language) {
//TODO 迁移变更:这里不再支持预审认证撤销操作
return SpiServiceTicketOperationVO.builder().globalId(serviceBizId).succeed(false).description("不支持的预审操作").build();
}
@Override
public FacadeResponse<Boolean> checkExistCSWorkOrder(CSWorkOrderBaseRequest request) {
FacadeResponse validateResponse = validate(request);
if (!validateResponse.isSucceeded()) {
return validateResponse;
}
FacadeResponse<Boolean> response = new FacadeResponse<>();
response.setSucceeded(true);
response.setValue(Boolean.TRUE);
CSWorkOrderConfigDO csWorkOrderConfigDO = csWorkOrderConfigDAO.findOne(MongoQueryFactory.create(request));
if (csWorkOrderConfigDO == null || csWorkOrderConfigDO.getConfigId() == null) {
response.setSucceeded(false);
response.setResponseCode(AttaResponseCode.VALIDATION_ERROR);
response.setResponseMsg("work config is not exist");
return response;
}
CSWorkOrderDO exist = checkSubsistingWorkOrder(csWorkOrderConfigDO.getConfigId(), request.getUserId());
if (exist == null) {
response.setValue(Boolean.FALSE);
}
return response;
}
@Override
public FacadeResponse<CSWorkorderConfigVO> queryConfigByWorkOrderId(String workorderId) {
FacadeResponse<CSWorkorderConfigVO> response = new FacadeResponse<>();
response.setSucceeded(true);
//查询工单
CSWorkOrderDO csWorkOrderDO = csWorkOrderDAO.findOne(new Query().addCriteria(Criteria.where("workorderId").is(workorderId)));
if (csWorkOrderDO == null || csWorkOrderDO.getWorkOrderConfigId() == null) {
log.error("find workOrder failed, workOrder id is {},or config id is null", workorderId);
response.setSucceeded(false);
return response;
}
CSWorkOrderConfigDO configDO = csWorkOrderConfigDAO.findOne(new Query().addCriteria(Criteria.where("configId").is(csWorkOrderDO.getWorkOrderConfigId())));
if (configDO == null) {
log.error("find WorkOrderConfig error ,config id is {}", csWorkOrderDO.getWorkOrderConfigId());
response.setSucceeded(false);
return response;
}
response.setValue(convertConfigDOToVo(configDO));
return response;
}
@Override
public CSWorkOrderVO queryByReferenceId(String referenceId) {
Assert.isTrue(StringUtils.isNotEmpty(referenceId), "referenceId should not be empty for queryByReferenceId");
CSWorkOrderDO csWorkOrderDO = csWorkOrderDAO.queryCSWorkOrderByReferenceId(referenceId);
return toWorkOrderVO(csWorkOrderDO);
}
@Override
public CSWorkOrderVO queryBySkylarkCollaborationId(String collaborationId) {
Assert.isTrue(StringUtils.isNotEmpty(collaborationId), "collaborationId should not be empty for queryBySkylarkCollaborationId");
CSWorkOrderDO csWorkOrderDO = csWorkOrderDAO.queryCSWorkOrderBySkylarkCollaborationId(collaborationId);
return WorkOrderConverter.toWorkOrderVO(csWorkOrderDO);
}
@Override
public boolean createChangePrincipalUserOrder(String customerId, String principalUserId) {
//TODO 迁移变更:无上游调用,先置空
return false;
}
@Override
public boolean changeWorkOrderPrincipalUser(String userId, String fromPrincipalUserId, String toPrincipalUserId) {
User principalUser = bossUserClient.queryByBossUserId(toPrincipalUserId);
if (principalUser == null) {
log.error("无法获取被转移人信息,工单转移失败:{}", toPrincipalUserId);
return false;
}
List<String> configIds = csWorkOrderConfigDAO.find(new Query().addCriteria(Criteria.where("businessType").is(BusinessType.CUSTOMER_SUCCESS.name()))).stream().map(CSWorkOrderConfigDO::getConfigId).collect(Collectors.toList());
if (CollectionUtils.isEmpty(configIds)) {
return true;
}
Criteria criteria = Criteria.where("userId").is(userId).and("workOrderConfigId").in(configIds);
if (StringUtils.isBlank(fromPrincipalUserId)) {
criteria.and("principalUserId").in(Sets.newHashSet(null, "")).and("status").is(CSWorkOrderStatus.Created);
} else {
criteria.and("principalUserId").is(fromPrincipalUserId).and("status").in(processCSWorkOrderStatus);
}
List<CSWorkOrderDO> workOrderDOList = csWorkOrderDAO.find(new Query().addCriteria(criteria));
if (CollectionUtils.isEmpty(workOrderDOList)) {
return true;
}
String suggestion = String.format("转移负责人至【%s】,分配理由:%s", principalUser.getNick(), "客户负责人转移,关联工单同步转移");
List<CSWorkOrderOpLogDO> opLogDOS = new LinkedList<>();
for (CSWorkOrderDO workOrderDO : workOrderDOList) {
if (StringUtils.isEmpty(workOrderDO.getBeforeUpgradePrincipalId())) {
workOrderDO.setStatus(CSWorkOrderStatus.Processing);
} else {
workOrderDO.setStatus(CSWorkOrderStatus.UpgradeProcessing);
}
workOrderDO.setCurrentDealUserId(toPrincipalUserId);
workOrderDO.setPrincipalUserId(toPrincipalUserId);
opLogDOS.add(createdOpLogDO(workOrderDO.getWorkorderId(), workOrderDO.getStatus(), workOrderDO.getCurrentDealUserId(), suggestion));
}
return updateWOS(workOrderDOList, opLogDOS).isSucceeded();
}
@Override
public boolean changeWorkOrderNonePrincipalUser(String userId, String fromPrincipalUserId) {
User principalUser = bossUserClient.queryByBossUserIdIgnoreStatus(fromPrincipalUserId);
if (principalUser == null) {
log.error("无法获取转移人信息,工单转移失败:{}", fromPrincipalUserId);
return false;
}
List<String> configIds = csWorkOrderConfigDAO.find(new Query().addCriteria(Criteria.where("businessType").is(BusinessType.CUSTOMER_SUCCESS.name()))).stream().map(CSWorkOrderConfigDO::getConfigId).collect(Collectors.toList());
if (CollectionUtils.isEmpty(configIds)) {
return true;
}
Criteria criteria = Criteria.where("userId").is(userId).and("workOrderConfigId").in(configIds);
criteria.and("principalUserId").is(fromPrincipalUserId).and("status").in(processCSWorkOrderStatus);
List<CSWorkOrderDO> workOrderDOList = csWorkOrderDAO.find(new Query().addCriteria(criteria));
if (CollectionUtils.isEmpty(workOrderDOList)) {
return true;
}
String suggestion;
List<CSWorkOrderOpLogDO> opLogDOS = new LinkedList<>();
for (CSWorkOrderDO workOrderDO : workOrderDOList) {
workOrderDO.setStatus(CSWorkOrderStatus.Closed);
workOrderDO.setCurrentDealUserId("");
workOrderDO.setPrincipalUserId("");
suggestion = String.format("从负责人【%s】转移至无负责人,分配理由:%s", principalUser.getNick(), "客户负责人转移,关联工单同步转移");
opLogDOS.add(createdOpLogDO(workOrderDO.getWorkorderId(), workOrderDO.getStatus(), "system", suggestion));
}
return updateWOS(workOrderDOList, opLogDOS).isSucceeded();
}
@Override
public void avgAssign(CSWorkOrderAssignRequest request) {
//TODO 迁移变更:营销域逻辑已废弃,先置空
}
@Override
public void weightAssign(CSWorkOrderWeightAssignRequest request) {
//TODO 迁移变更:营销域逻辑已废弃,先置空
}
@Override
public void directAssign(CSWorkOrderDirectAssignRequest request) {
//TODO 迁移变更:营销域逻辑已废弃,先置空
}
@Override
public void specificAssign(CSWorkOrderGroupAssignRequest request) {
//TODO 迁移变更:营销域逻辑已废弃,先置空
}
@Override
public void avgAssignForConfigId(CSWorkOrderAssignCommonRequest request) {
//TODO 迁移变更:营销域逻辑已废弃,先置空
}
@Override
public int avgAssignForWorkOrderIds(CSWorkOrderAssignReq request) {
//TODO 迁移变更:营销域逻辑已废弃,先置空
return 0;
}
@Override
public int avgAssignForReferenceIds(CSWorkOrderAssignByReferenceIdReq request) {
//TODO 迁移变更:营销域逻辑已废弃,先置空
return 0;
}
@Override
public int avgAssignForExecutorId(CSWorkOrderAssignByExecutorId request) {
//TODO 迁移变更:营销域逻辑已废弃,先置空
return 0;
}
@Override
public void closeCSWorkOrderToDate(CSWorkOrderAssignCommonRequest request) {
//TODO 迁移变更:营销域逻辑已废弃,先置空
}
@Override
public String autoCreate(CSWorkOrderAutoCreateRequest request) {
//TODO 迁移变更:营销域逻辑已废弃,先置空
return null;
}
@Override
public void batchWeightAssign(CSWorkOrderBatchWeightAssignRequest request) {
//TODO 迁移变更:营销域逻辑已废弃,先置空
}
@Override
public void batchSpecificAssign(CSWorkOrderGroupBatchAssignRequest request) {
//TODO 迁移变更:营销域逻辑已废弃,先置空
}
@Override
public void specificAssignForConfigId(CSWorkOrderAssignCommonRequest request) {
//TODO 迁移变更:营销域逻辑已废弃,先置空
}
@Override
public void specificAssignForReferenceIds(CSWorkOrderAssignByReferenceIdReq request) {
//TODO 迁移变更:营销域逻辑已废弃,先置空
}
@Override
public void specificAssignForExecutorId(CSWorkOrderAssignByExecutorId request) {
//TODO 迁移变更:营销域逻辑已废弃,先置空
}
@Override
public void preAuditSkip(PreAuditSkipRequest request) {
Criteria criteria = Criteria.where("workorderId").in(request.getWorkOrderIds());
List<CSWorkOrderDO> workOrderDOList = csWorkOrderDAO.find(new Query().addCriteria(criteria));
if (CollectionUtils.isEmpty(workOrderDOList)) {
return;
}
List<CSWorkOrderStatus> skipStatus = Arrays.asList(CSWorkOrderStatus.Created, CSWorkOrderStatus.Processing, CSWorkOrderStatus.UpgradeProcessing);
List<CSWorkOrderOpLogDO> opLogDOS = Lists.newArrayList();
List<ActionDO> actionDOS = Lists.newArrayList();
for (CSWorkOrderDO workOrder : workOrderDOList) {
if (!isPreAuditWorkOrder(workOrder)) {
throw new CustomerServiceException(CSOrderSystemErrorCode.ValidationError, CSOrderBizErrorCode.ILLEGAL_ARGUMENT, "只能跳过预审工单");
}
//大陆预审不让跳过
if (isMainLandFxPreAudit(workOrder)) {
throw new CustomerServiceException(CSOrderSystemErrorCode.ValidationError, CSOrderBizErrorCode.ILLEGAL_ARGUMENT, "大陆预审工单不能跳过");
}
if (!skipStatus.contains(workOrder.getStatus())) {
throw new CustomerServiceException(CSOrderSystemErrorCode.ValidationError, CSOrderBizErrorCode.ILLEGAL_ARGUMENT, "只能跳过新建、处理中的预审工单");
}
workOrder.setStatus(CSWorkOrderStatus.Completed);
workOrder.setCompletedTime(new Date());
workOrder.setCurrentDealUserId(request.getCurrentDealUserId());
opLogDOS.add(createdOpLogDO(workOrder.getWorkorderId(), workOrder.getStatus(), workOrder.getCurrentDealUserId(), "跳过预审工单"));
//预审核结果
Query query = new Query();
query.addCriteria(Criteria.where(ActionDO.SCENE_ID).is(workOrder.getWorkorderId()).and("tagKey").is("preAudit"));
ActionDO actionDO = actionDAO.findOne(query);
if (null == actionDO) {
throw new CustomerServiceException(CSOrderSystemErrorCode.ValidationError, CSOrderBizErrorCode.ILLEGAL_ARGUMENT, "未找到预审工单的action");
}
if (null == actionDO.getActionResults()) {
actionDO.setActionResults(Maps.newHashMap());
}
Map<String, Object> actionResults = actionDO.getActionResults();
actionResults.put(PRE_AUDIT_RESULT, "Skip");
actionResults.put("skipPreAudit", "yes");
actionDOS.add(actionDO);
}
Boolean isOk = mongoTransactionTemplate.execute(status -> {
try {
for (CSWorkOrderDO workOrderDO : workOrderDOList) {
if (csWorkOrderDAO.updateByIdSelective(workOrderDO) == null) {
throw new CustomerServiceException(CSOrderSystemErrorCode.UpdateError, CSOrderBizErrorCode.SYSTEM_ERROR, "update fail.");
}
if (null != workOrderDO.getExpediteType()) {
workOrderInstructionDAO.insertInstruction(workOrderDO.getWorkorderId(), WorkOrderInstructionType.ExpediteWorkOrder);
}
workOrderInstructionDAO.insertInstruction(workOrderDO.getWorkorderId(), WorkOrderInstructionType.CloseTag);
workOrderInstructionDAO.insertInstruction(workOrderDO.getWorkorderId(), WorkOrderInstructionType.PreAudit);
}
if (csWorkOrderOpLogDAO.batchInsert(opLogDOS).size() != opLogDOS.size()) {
throw new CustomerServiceException(CSOrderSystemErrorCode.UpdateError, CSOrderBizErrorCode.SYSTEM_ERROR, "insert op log fail.");
}
for (ActionDO actionDO : actionDOS) {
if (actionDAO.updateByIdSelective(actionDO) == null) {
throw new CustomerServiceException(CSOrderSystemErrorCode.UpdateError, CSOrderBizErrorCode.SYSTEM_ERROR, "update fail.");
}
}
} catch (Exception e) {
log.warn(e.getMessage(), e);
status.setRollbackOnly();
return Boolean.FALSE;
}
return Boolean.TRUE;
});
if (!Boolean.TRUE.equals(isOk)) {
throw new CustomerServiceException(CSOrderSystemErrorCode.ValidationError, CSOrderBizErrorCode.ILLEGAL_ARGUMENT, "跳过预审工单失败");
}
//批量跳过负责人,把原工单负责人加入到队列中
try {
workOrderDOList.forEach((workOrderDO) -> enterQueue(workOrderDO.getPrincipalUserId()));
} catch (Exception e) {
log.error("批量跳过负责人后,把用户移出自动分配队列异常", e);
}
CompletableFuture.runAsync(() -> workOrderDOList.forEach((workOrderDO) -> doInstruction(workOrderDO.getWorkorderId())), commonExecutor);
}
private boolean isMainLandFxPreAudit(CSWorkOrderDO workOrder) {
if (StringUtils.isEmpty(workOrder.getWorkOrderConfigId())) {
return false;
}
CSWorkOrderConfigDO configDO = csWorkOrderConfigDAO.queryByWOConfigIdIgnoreStatus(workOrder.getWorkOrderConfigId());
return WorkOrderConfigType.MainLandFxPreAudit.name().equals(configDO.getConfigType());
}
@Override
public void preAuditNotify(PreAuditNotifyRequest request) {
if (CollectionUtils.isEmpty(request.getWorkOrderIds())) {
return;
}
request.getWorkOrderIds().forEach(workOrderId -> {
CSWorkOrderDO csWorkOrderDO = csWorkOrderDAO.queryCSWorkOrderByWorkOrderId(workOrderId);
if (csWorkOrderDO != null) {
try {
workorderMessageProducer.sendPreAuditStatusEvent(csWorkOrderDO);
} catch (Exception e) {
log.error("send PreAudit failed. e:", e);
}
}
});
}
@Override
public void relateQuestionnaire(String workOrderId, String workOrderConfigId, String sceneConfigId) {
if (StringUtils.isAllBlank(workOrderConfigId, sceneConfigId) || StringUtils.isEmpty(workOrderId)) {
log.warn("workOrderId or workOrderConfigId should not be empty. workOrderId: {},workOrderConfigId: {}.", workOrderId, workOrderConfigId);
CSExceptionAssert.fail(CSOrderBizErrorCode.VALIDATION_ERROR, "");
}
QuestionnaireRelationQueryRequest relationQueryRequest = new QuestionnaireRelationQueryRequest();
relationQueryRequest.setBizId(StringUtils.isNotBlank(sceneConfigId) ? sceneConfigId : workOrderConfigId);
List<QuestionnaireRelationVO> relationVOS = questionnaireManager.queryQuestionnaireRelations(relationQueryRequest);
if (CollectionUtils.isEmpty(relationVOS)) {
return;
}
relationVOS.forEach(relationVO -> {
com.atta.infra.crm.form.api.model.request.QuestionnaireRelateRequest relateRequest = new com.atta.infra.crm.form.api.model.request.QuestionnaireRelateRequest();
relateRequest.setType(relationVO.getQuestionnaireType());
relateRequest.setDomain(QuestionnaireRelationDomain.CUSTOMER_SERCICE);
relateRequest.setScene(QuestionnaireRelationScene.CS_WORK_ORDER);
relateRequest.setFormId(relationVO.getFormId());
relateRequest.setFormVersion(relationVO.getFormVersion());
relateRequest.setBizId(workOrderId);
questionnaireManager.relateQuestionnaire(relateRequest);
});
}
@Override
public String queryPhoneByWorkOrderId(String workOrderId) {
CSExceptionAssert.isTrue(StringUtils.isNoneEmpty(workOrderId)
, CSOrderBizErrorCode.VALIDATION_ERROR
, "workOrderId should not be empty");
CSWorkOrderDO csWorkOrderDO = csWorkOrderDAO.queryCSWorkOrderByWorkOrderId(workOrderId);
CSExceptionAssert.isTrue(csWorkOrderDO != null
, CSOrderBizErrorCode.VALIDATION_ERROR
, "csWorkOrderDO is not exist.workOrderId is: " + workOrderId);
return csWorkOrderDO.getPhone();
}
@Override
public void autoClose() {
log.info("start to auto close workOrder ");
Integer count = 0;
Criteria criteria = Criteria.where(CSWorkOrderDO.WORK_ORDER_END_TIME).lt(new Date()).and(CSWorkOrderDO.STATUS).nin(CSWorkOrderStatus.finalCSWorkOrderStatus);
CloseableIterator<CSWorkOrderDO> iterator = csWorkOrderDAO.stream(new Query(criteria));
while (iterator.hasNext()) {
CSWorkOrderDO workOrderDO = iterator.next();
log.info("auto close customer service work order : {}", workOrderDO.getWorkorderId());
CSWorkOrderCompleteRequest completeRequest = new CSWorkOrderCompleteRequest();
completeRequest.setWorkorderId(workOrderDO.getWorkorderId());
completeRequest.setOperatorUserId(SystemConst.SYSTEM_USER_ID);
completeRequest.setStatus(CSWorkOrderStatus.Closed);
try {
workOrderClose(completeRequest.getWorkorderId(), completeRequest.getOperatorUserId(), completeRequest.getStatus(), "结案工单");
count++;
} catch (Exception e) {
log.error("auto close work order {} error:", workOrderDO.getWorkorderId(), e);
}
}
log.info("auto close work order end ,count:{}", count);
}
@Override
public String workOrderClose(String workOrderId, String operatorUserId, CSWorkOrderStatus status, String suggestion) {
CSWorkOrderDO workOrderDO = validateWorkOrderClose(workOrderId, status);
if (null == workOrderDO) {
return workOrderId;
}
CSWorkOrderStatus oldStatus = workOrderDO.getStatus();
ActionDO actionDO = actionDAO.getLastUpdateActionBySceneId(workOrderDO.getWorkorderId());
//是预审工单,且预审结果没选,不能提交工单
validatePreAudit(actionDO);
workOrderDO.setStatus(status);
// 设置关单类型
workOrderDO.setCloseType(SystemConst.SYSTEM_USER_ID.equalsIgnoreCase(operatorUserId)?
CSWorkOrderEmailCloseType.OTHER.getCode() : CSWorkOrderEmailCloseType.MANUAL_CLOSE.getCode());
workOrderDO.setCompletedTime(new Date());
workOrderDO.setCurrentDealUserId(operatorUserId);
if (CollectionUtils.isEmpty(workOrderDO.getHistoryDealUsers())) {
workOrderDO.setHistoryDealUsers(new HashSet<>());
}
workOrderDO.getHistoryDealUsers().add(operatorUserId);
CSWorkOrderOpLogDO opLogDO = createdOpLogDO(workOrderDO.getWorkorderId()
, workOrderDO.getStatus()
, operatorUserId
, suggestion);
boolean isGeneratedByTag = isGeneratedByTag(workOrderDO.getWorkOrderConfigId());
boolean isOk = transactionUtil.executeMongo(() -> {
CSExceptionAssert.isTrue(csWorkOrderOpLogDAO.insert(opLogDO) != null
, CSOrderBizErrorCode.SYSTEM_ERROR
, "insert opLogDO failed.");
CSExceptionAssert.isTrue(csWorkOrderDAO.updateByIdSelective(workOrderDO) != null
, CSOrderBizErrorCode.SYSTEM_ERROR
, "update workOrderDO failed.");
addWorkOrderInstructions(workOrderDO, actionDO, isGeneratedByTag);
});
CSExceptionAssert.isTrue(isOk
, CSOrderBizErrorCode.SYSTEM_ERROR
, "complete work order failed");
CompletableFuture.runAsync(() -> doInstruction(workOrderDO.getWorkorderId()), commonExecutor);
//TODO 迁移变更:预审驳回发送消息 废弃
// sendPreAuditNoPassMessage(actionDO, workOrderDO);
//发送工单结案消息
sendWorkOrderCompleteMessage(workOrderDO);
if (!Objects.isNull(workOrderDO.getSkylarkCollaborationId())) {
//云雀平台新协同工单
sendSkylarkCollaborationMessage(workOrderDO, workOrderDO.getSkylarkCollaborationId(), WorkOrderOptType.COMPLETE);
}
// else {
// sendCooperationMessageNew(workOrderDO, WorkOrderOptType.COMPLETE);
// }
//工单完成后给代办发送消息
sendToDoTaskMessage(workOrderDO);
//sla 上报
slaEscalationService.escalationCompleteWorkOrderSla(workOrderDO);
return workOrderDO.getWorkorderId();
}
private CSWorkOrderDO validateWorkOrderClose(String workOrderId, CSWorkOrderStatus status) {
CSExceptionAssert.isTrue(finalCSWorkOrderStatus.contains(status)
, CSOrderBizErrorCode.VALIDATION_ERROR, "status should be final status.");
CSWorkOrderDO workOrderDO = findWorkOrderOne(workOrderId);
CSExceptionAssert.isTrue(workOrderDO != null
, CSOrderBizErrorCode.VALIDATION_ERROR
, "workOrder is not exist, WorkOrderId is: " + workOrderId);
if (finalCSWorkOrderStatus.contains(workOrderDO.getStatus())) {
return null;
}
return workOrderDO;
}
/**
* 校验预审
*/
private void validatePreAudit(ActionDO actionDO) {
if (actionDO != null && (FIRST_AUDIT_TOW.equals(actionDO.getTagValue()) || UPDATE_AUDIT.equals(actionDO.getTagValue()))
&& (actionDO.getActionResults() == null || !Sets.newHashSet(PASS_RESULT, NO_PASS_RESULT).contains(String.valueOf(actionDO.getActionResults().get(PRE_AUDIT_RESULT))))
) {
CSExceptionAssert.fail(CSOrderBizErrorCode.VALIDATION_ERROR, "预审工单审核结果未保存");
}
}
/**
* 给代办发送消息
*/
private void sendToDoTaskMessage(CSWorkOrderDO workOrderDO) {
TodoTaskEvent todoTaskEvent = new TodoTaskEvent();
convertWorkOrderDO2TodoTaskEvent(workOrderDO, todoTaskEvent);
if (StringUtils.isNotEmpty(todoTaskEvent.getPrincipalUserId())) {
imqProvider.push(TodoTaskEvent.QUEUE_NAME, todoTaskEvent, QueueType.TOPIC);
}
}
@Override
public String close(CSWorkOrderCloseRequest request) {
try {
workOrderClose(request.getWorkOrderId(), request.getOperatorUserId(), CSWorkOrderStatus.Closed, request.getSuggestion());
} catch (Exception e) {
log.error("close work order {} fail: ", request.getWorkOrderId(), e);
}
return request.getWorkOrderId();
}
@Override
public void onCSWOOpen(CSWOOpenRequest request) {
//TODO czs 需要迁移吗?
}
@Override
public void onPreAuditWOOpen(CustomerTagChangeEvent event) {
ValidateUtil.assertValid(event);
String workOrderConfigId = findWorkOrderConfigId(event);
if (Strings.isNullOrEmpty(workOrderConfigId)) {
throw new CustomerServiceException(CSOrderSystemErrorCode.BadRequest, CSOrderBizErrorCode.SYSTEM_ERROR, "workOrderTypeId can not be null.");
}
if (Strings.isNullOrEmpty(event.getEventId())) {
log.error("pre audit evenId can't be empty!");
return;
}
CSWorkOrderDO csWorkOrderDO = csWorkOrderDAO.queryCSWorkOrderByReferenceId(event.getEventId());
if (csWorkOrderDO != null) {
return;
}
csWorkOrderDO = buildWorkOrderDO(event, workOrderConfigId);
// 关联问卷
relateQuestionnaire(csWorkOrderDO.getWorkorderId(), csWorkOrderDO.getWorkOrderConfigId(), csWorkOrderDO.getSceneConfigId());
ActionDO actionDO = buildActionDO(event, csWorkOrderDO.getWorkorderId());
List<CSWorkOrderOpLogDO> opLogDOS = new LinkedList<>();
CSWorkOrdersQueryRequest csWorkOrdersQueryRequest = new CSWorkOrdersQueryRequest();
csWorkOrdersQueryRequest.setUserId(event.getUserId());
csWorkOrdersQueryRequest.setWorkOrderConfigId(workOrderConfigId);
List<CSWorkOrderVO> csWorkOrderVOList = queryWorkOrderVOS(csWorkOrdersQueryRequest);
CSWorkOrderVO lastWorkOrderVO = csWorkOrderVOList.stream().filter(workOrderVO -> CSWorkOrderStatus.Completed.equals(workOrderVO.getStatus()))
.max(Comparator.comparing(CSWorkOrderVO::getCreatedTime)).orElse(null);
//上次预审结果是否通过
boolean isPassedInLastPreAudit = true;
ActionDO lastActionDO = null;
if (lastWorkOrderVO != null) {
lastActionDO = actionDAO.findOne(new Query(Criteria.where(ActionDO.SCENE_ID).is(lastWorkOrderVO.getWorkorderId())));
if (lastActionDO != null && !CollectionUtils.isEmpty(lastActionDO.getActionResults()) && PASS_RESULT.equals(lastActionDO.getActionResults().get(PRE_AUDIT_RESULT))) {
} else {
isPassedInLastPreAudit = false;
}
} else {
isPassedInLastPreAudit = false;
}
CSWorkOrderConfigDO configDO = csWorkOrderConfigDAO.findOne(new Query().addCriteria(Criteria.where("configId").is(workOrderConfigId)));
if (isPassedInLastPreAudit && null != configDO && (FIRST_AUDIT.equals(configDO.getProblemType()) || WEALTH_MANAGEMENT_AUDIT.equals(configDO.getProblemType()))) {
csWorkOrderDO.setPrincipalUserId("system");
csWorkOrderDO.setCurrentDealUserId("system");
csWorkOrderDO.setStatus(CSWorkOrderStatus.Completed);
csWorkOrderDO.setCompletedTime(new Date());
actionDO.setActionResults(lastActionDO.getActionResults());
opLogDOS.add(buildOpLogDO(csWorkOrderDO.getWorkorderId(), csWorkOrderDO.getStatus(), "system", "结案工单"));
} else {
// RelationshipVO principalVO = findPrincipalUserId(event.getDomain(), event.getUserId(), workOrderConfigId);
// csWorkOrderDO.setPrincipalUserId(principalVO == null ? null : principalVO.getPrincipalUserId());
csWorkOrderDO.setCurrentDealUserId(csWorkOrderDO.getPrincipalUserId());
if (Strings.isNullOrEmpty(csWorkOrderDO.getPrincipalUserId())) {
csWorkOrderDO.setStatus(CSWorkOrderStatus.Created);
} else {
csWorkOrderDO.setStatus(CSWorkOrderStatus.Processing);
}
//保留上次失败的审核结果、建议、备注
if (null != lastActionDO && !CollectionUtils.isEmpty(lastActionDO.getActionResults())) {
Map<String, Object> lastActionResults = lastActionDO.getActionResults();
Map<String, Object> lastAuditResults = new HashMap<>(4);
lastAuditResults.put(PRE_AUDIT_RESULT, lastActionResults.get(PRE_AUDIT_RESULT));
lastAuditResults.put("preAuditSuggestion", lastActionResults.get("preAuditSuggestion"));
lastAuditResults.put("preAuditRemark", lastActionResults.get("preAuditRemark"));
lastAuditResults.put("version", preWorkOrderFormVersion);
actionDO.setActionResults(lastAuditResults);
}
opLogDOS.add(buildOpLogDO(csWorkOrderDO.getWorkorderId(), csWorkOrderDO.getStatus(), "system", "创建工单"));
// if (!Strings.isNullOrEmpty(csWorkOrderDO.getPrincipalUserId())) {
// String principalUserName = principalVO == null ? "" : principalVO.getPrincipalUserName();
// opLogDOS.add(buildOpLogDO(csWorkOrderDO.getWorkorderId(), csWorkOrderDO.getStatus(), "system", "自动分配处理人【" + principalUserName + "】"));
// }
}
if (csWorkOrderDAO.insert(csWorkOrderDO) == null) {
log.warn("insert fail.event >>> {}", event);
throw new CustomerServiceException(CSOrderSystemErrorCode.InsertError, CSOrderBizErrorCode.SYSTEM_ERROR, "insert fail.");
}
if (actionDAO.insert(actionDO) == null) {
log.warn("insert fail.event >>> {}", event);
throw new CustomerServiceException(CSOrderSystemErrorCode.InsertError, CSOrderBizErrorCode.SYSTEM_ERROR, "insert fail.");
}
if (csWorkOrderOpLogDAO.batchInsert(opLogDOS).size() != opLogDOS.size()) {
log.warn("insert opLogs fail.event >>> {}", event);
throw new CustomerServiceException(CSOrderSystemErrorCode.InsertError, CSOrderBizErrorCode.SYSTEM_ERROR, "insert fail.");
}
workorderMessageProducer.sendPreAuditStatusEvent(csWorkOrderDO);
}
private String findWorkOrderConfigId(CustomerTagChangeEvent event) {
WorkOrderAndTagRelationVO relationVO = workOrderConfigAndTagRelationService.getTagAndOrderConfigRelationByTag(event.getDomain(), event.getKey(), event.getValue());
if (relationVO == null) {
return null;
} else {
return relationVO.getWorkOrderConfigId();
}
}
private CSWorkOrderDO buildWorkOrderDO(CustomerTagChangeEvent event, String workOrderTypeId) {
CSWorkOrderDO workOrderDO = new CSWorkOrderDO();
workOrderDO.setWorkorderId(AttaIdUtils.getByProdCode(AttaIdUtils.ProdCode.CUSTOMER_SERVICE_WORKORDER));
workOrderDO.setWorkOrderConfigId(workOrderTypeId);
workOrderDO.setLeadsId(event.getLeadsId());
workOrderDO.setNewCollaboration(true);
workOrderDO.setServiceBizId(event.getServiceBizId());
//设置leads数据
if (CrmDomain.leads.name().equals(event.getDomain())) {
throw new CustomerServiceException(CSOrderSystemErrorCode.InsertError, CSOrderBizErrorCode.SYSTEM_ERROR, "不支持leads场景");
}
if (event.isMainLand()) {
workOrderDO.setFirmId(event.getFirmId());
workOrderDO.setGrantorId(event.getGrantorId());
workOrderDO.setBeGrantorId(event.getBeGrantorId());
}
WorkOrderConverter.setBasicFirmInfo(workOrderDO, event.getUserId(), null, firmClient, userClient);
WorkOrderConverter.setCSOrderDOFromOrderConfig(workOrderDO, workOrderTypeId, cSWorkOrderConfigService);
workOrderDO.setReferenceId(event.getEventId());
return workOrderDO;
}
private ActionDO buildActionDO(CustomerTagChangeEvent event, String workOrderId) {
ActionDO actionDO = new ActionDO();
actionDO.setActionId(AttaIdUtils.getByProdCode(AttaIdUtils.ProdCode.MKT_ACTION));
actionDO.setTagEntityId(event.getUserId());
actionDO.setTagDomain(event.getDomain());
actionDO.setTagKey(event.getKey());
actionDO.setTagValue(event.getValue());
actionDO.setSceneId(workOrderId);
actionDO.setScene(ActionScene.CS_WORK_ORDER);
actionDO.setCreationDate(new Date());
actionDO.setLastUpdateDate(new Date());
return actionDO;
}
@Override
public void onAuditStatusChange(AuditStatusChangeEvent event) {
if (Strings.isNullOrEmpty(event.getEventId())) {
log.error("eventId can't be null!");
return;
}
if (event.getAuditType() == null || !BossConstants.AuditType.FirmOnboarding.equals(event.getAuditType())) {
log.warn("AuditType can't be " + (event.getAuditType() == null ? "null" : event.getAuditType().name()));
return;
}
if (event.getAuditStatus() == null) {
log.error("auditStatus can't be null!");
return;
} else {
if (!Sets.newHashSet(
BossConstants.AuditStatus.Completed
, BossConstants.AuditStatus.Cancelled
, BossConstants.AuditStatus.Rescinded
, BossConstants.AuditStatus.Stopped
, BossConstants.AuditStatus.Processing).contains(event.getAuditStatus())) {
log.warn("auditStatus can't be " + event.getAuditStatus().name());
return;
}
}
CSWorkOrderDO csWorkOrderDO = csWorkOrderDAO.queryCSWorkOrderByReferenceId(event.getEventId());
if (csWorkOrderDO == null) {
log.warn("CSWorkOrderDO can't be null!");
return;
}
//客服工单是否需要撤销
//撤销条件:
//1、风控工单不为被领取状态,并且预审工单不为结案和撤销状态
//2、风控工单为领取状态,并且预审工单为新建状态
boolean shouldBeCancelled = !BossConstants.AuditStatus.Processing.equals(event.getAuditStatus()) && csWorkOrderDO.getStatus() != CSWorkOrderStatus.Completed && csWorkOrderDO.getStatus() != CSWorkOrderStatus.Cancelled
|| BossConstants.AuditStatus.Processing.equals(event.getAuditStatus()) && CSWorkOrderStatus.Created.equals(csWorkOrderDO.getStatus());
if (shouldBeCancelled) {
csWorkOrderDO.setStatus(CSWorkOrderStatus.Cancelled);
CSWorkOrderOpLogDO csWorkOrderOpLogDO = buildOpLogDO(csWorkOrderDO.getWorkorderId(), csWorkOrderDO.getStatus(), "system", "首次认证预审撤销工单");
//需同步撤销的加急工单
List<CSWorkOrderDO> expediteWorkOrders = org.assertj.core.util.Lists.newArrayList();
if (ExpediteType.ORDINARY_EXPEDITE.equals(csWorkOrderDO.getExpediteType())) {
Criteria expediteConfigCriteria = Criteria.where("businessType").is(BusinessType.CUSTOMER_CONSULTATION)
.and("workorderType").is("其他")
.and("problemType").is("加急")
.and("status").is(CSWorkOrderConfigStatus.Enabled);
CSWorkOrderConfigDO csWorkOrderConfigDO = csWorkOrderConfigDAO.findOne(new Query().addCriteria(expediteConfigCriteria));
if (null == csWorkOrderConfigDO) {
throw new CustomerServiceException(CSOrderSystemErrorCode.UpdateError, CSOrderBizErrorCode.NOT_SUPPORT, "工单自动撤销失败, 未找到加急工单类型");
}
Criteria expediteWorkOrderCriteria = Criteria.where("workOrderConfigId").is(csWorkOrderConfigDO.getConfigId())
.and("relatedWorkOrderId").is(csWorkOrderDO.getWorkorderId())
.and("relatedWorkOrderDomain").is(WorkOrderDomain.CS_WORK_ORDER)
.and("status").nin(finalCSWorkOrderStatus);
expediteWorkOrders.addAll(csWorkOrderDAO.find(new Query().addCriteria(expediteWorkOrderCriteria)));
}
Boolean isOk = mongoTransactionTemplate.execute(status -> {
try {
if (csWorkOrderDAO.updateByIdSelective(csWorkOrderDO) == null) {
throw new CustomerServiceException(CSOrderSystemErrorCode.UpdateError, CSOrderBizErrorCode.SYSTEM_ERROR, "update fail.");
}
if (csWorkOrderOpLogDAO.insert(csWorkOrderOpLogDO) == null) {
throw new CustomerServiceException(CSOrderSystemErrorCode.InsertError, CSOrderBizErrorCode.SYSTEM_ERROR, "insert oplog fail.");
}
//撤销加急工单
if (!CollectionUtils.isEmpty(expediteWorkOrders)) {
for (CSWorkOrderDO expediteWorkOrder : expediteWorkOrders) {
expediteWorkOrder.setStatus(CSWorkOrderStatus.Cancelled);
CSWorkOrderOpLogDO expediteOpLogDO = buildOpLogDO(expediteWorkOrder.getWorkorderId(), expediteWorkOrder.getStatus(), "system", "同步撤销加急工单");
if (csWorkOrderDAO.updateByIdSelective(expediteWorkOrder) == null) {
throw new CustomerServiceException(CSOrderSystemErrorCode.UpdateError, CSOrderBizErrorCode.SYSTEM_ERROR, "update fail.");
}
if (csWorkOrderOpLogDAO.insert(expediteOpLogDO) == null) {
throw new CustomerServiceException(CSOrderSystemErrorCode.InsertError, CSOrderBizErrorCode.SYSTEM_ERROR, "insert oplog fail.");
}
}
}
workorderMessageProducer.closeCustomerTag(csWorkOrderDO);
} catch (Exception e) {
log.warn(e.getMessage(), e);
status.setRollbackOnly();
return Boolean.FALSE;
}
return Boolean.TRUE;
});
if (Boolean.FALSE.equals(isOk)) {
throw new CustomerServiceException(CSOrderSystemErrorCode.UpdateError, CSOrderBizErrorCode.NOT_SUPPORT, "update fail.");
}
}
workorderMessageProducer.sendPreAuditStatusEvent(csWorkOrderDO);
}
@Override
public void onExpediteWorkOrderComplete(ExpediteWorkOrderCompleteEvent event) {
if (Strings.isNullOrEmpty(event.getEventId())) {
log.warn("eventId can't be null!");
return;
}
if (null == event.getDomain()) {
log.warn("domain can't be null!");
return;
}
if (!WorkOrderDomain.CS_WORK_ORDER.equals(event.getDomain()) && !WorkOrderDomain.RISK_AUDIT_WORK_ORDER.equals(event.getDomain())) {
log.warn("only cs work order and risk audit work order can use this event");
return;
}
if (WorkOrderDomain.CS_WORK_ORDER.equals(event.getDomain())) {
CSWorkOrderDO csWorkOrderDO = csWorkOrderDAO.findOne(new Query().addCriteria(Criteria.where("workorderId").is(event.getEventId())));
if (null == csWorkOrderDO) {
log.warn("cs work order can't be null!");
return;
}
if (!isPreAuditWorkOrder(csWorkOrderDO)) {
log.warn("only pre audit cs work order can use this event");
return;
}
if (!CSWorkOrderStatus.Completed.equals(csWorkOrderDO.getStatus())) {
log.warn("only completed cs work order can use this event");
return;
}
}
if (WorkOrderDomain.RISK_AUDIT_WORK_ORDER.equals(event.getDomain())) {
AuditRequestVO auditRequestVO = riskWorkOrderClient.listAuditingByRequestId(event.getEventId());
if (null == auditRequestVO) {
log.warn("audit request can't be null!");
return;
}
if (!StringUtils.equals(BossConstants.AuditStatus.Completed.name(), auditRequestVO.getStatus().name())) {
log.warn("only completed risk audit work order can use this event");
return;
}
}
Criteria expediteCriteria = Criteria.where("businessType").is(BusinessType.CUSTOMER_CONSULTATION)
.and("workorderType").is("其他")
.and("problemType").is("加急")
.and("status").is(CSWorkOrderConfigStatus.Enabled);
CSWorkOrderConfigDO csWorkOrderConfigDO = csWorkOrderConfigDAO.findOne(new Query().addCriteria(expediteCriteria));
if (null == csWorkOrderConfigDO) {
log.warn("can not find expedite work order config!");
return;
}
Criteria criteria = Criteria.where("workOrderConfigId").is(csWorkOrderConfigDO.getConfigId())
.and("relatedWorkOrderId").is(event.getEventId())
.and("relatedWorkOrderDomain").is(event.getDomain())
.and("status").nin(finalCSWorkOrderStatus);
List<CSWorkOrderDO> csWorkOrderDOList = csWorkOrderDAO.find(new Query().addCriteria(criteria));
for (CSWorkOrderDO csWorkOrderDO : csWorkOrderDOList) {
csWorkOrderDO.setStatus(CSWorkOrderStatus.Closed);
CSWorkOrderOpLogDO csWorkOrderOpLogDO = buildOpLogDO(csWorkOrderDO.getWorkorderId(), csWorkOrderDO.getStatus(), "system", "加急工单同步关闭");
Boolean isOk = mongoTransactionTemplate.execute(status -> {
try {
if (csWorkOrderDAO.updateByIdSelective(csWorkOrderDO) == null) {
throw new AttaServiceException(SystemErrorCode.UpdateError, BizErrorCode.SystemError, "update fail.");
}
if (csWorkOrderOpLogDAO.insert(csWorkOrderOpLogDO) == null) {
throw new AttaServiceException(SystemErrorCode.InsertError, BizErrorCode.SystemError, "insert oplog fail.");
}
} catch (Exception e) {
log.warn(e.getMessage(), e);
status.setRollbackOnly();
return Boolean.FALSE;
}
return Boolean.TRUE;
});
if (!Boolean.TRUE.equals(isOk)) {
log.error("Close expedite work order fail.WorkOrderId:{}", csWorkOrderDO.getWorkorderId());
}
}
}
@Override
public FacadeResponse<CSWorkOrderVO> automaticAllocation(CSWorkOrderAutomaticAllocationRequest request) {
FacadeResponse facadeResponse = validate(request);
if (!facadeResponse.isSucceeded()) {
return getFacadeResponseWithFailed(AttaResponseCode.VALIDATION_ERROR);
}
CSWorkOrderDO workOrderDO = csWorkOrderDAO.queryCSWorkOrderByWorkOrderId(request.getWorkOrderId());
if (workOrderDO == null) {
return getFacadeResponseWithFailed(AttaResponseCode.VALIDATION_ERROR);
}
if (!CSWorkOrderStatus.Created.equals(workOrderDO.getStatus())) {
return getFacadeResponseWithFailed(AttaResponseCode.VALIDATION_ERROR);
}
if (!Strings.isNullOrEmpty(workOrderDO.getPrincipalUserId()) || !Strings.isNullOrEmpty(workOrderDO.getCurrentDealUserId())) {
return getFacadeResponseWithFailed(AttaResponseCode.VALIDATION_ERROR);
}
OrderAssignReq assignReq = OrderAssignReq.builder()
.workOrderId(workOrderDO.getWorkorderId())
.operatorUserId(SystemConst.SYSTEM_USER_ID)
.reason("系统分配")
.toPrincipalUserId(request.getUserId())
.build();
try {
transferPrincipal(assignReq);
} catch (Exception e) {
return getFacadeResponseWithFailed(AttaResponseCode.VALIDATION_ERROR);
}
return getFacadeResponseWithValue(toWorkOrderVO(workOrderDO));
}
@Override
public Boolean orderSuspend(CSWorkOrderAwakeRequest request) {
if (0 >= maxSuspendOrderCount) {
throw new CustomerServiceException(CSOrderSystemErrorCode.InsertError, CSOrderBizErrorCode.SYSTEM_ERROR, "不允许暂停工单");
}
Assert.isTrue(checkAwakeRequest(request), "work order suspend fail,request is error");
//校验当前用户名下暂停状态的工单是否达到三个
Query query = new Query();
query.addCriteria(Criteria.where("principalUserId").is(request.getUserId()));
query.addCriteria(Criteria.where(CSWorkOrderDO.STATUS).is(CSWorkOrderStatus.Suspend));
List<CSWorkOrderDO> workOrderDOS = csWorkOrderDAO.find(query);
if (!CollectionUtils.isEmpty(workOrderDOS) && workOrderDOS.size() >= maxSuspendOrderCount) {
throw new CustomerServiceException(CSOrderSystemErrorCode.InsertError, CSOrderBizErrorCode.SYSTEM_ERROR, "暂停工单失败,您名下已经存在" + maxSuspendOrderCount + "条暂停中的工单");
}
//更新工单状态为暂停
List<CSWorkOrderOpLogDO> opLogDOS = new LinkedList<>();
CSWorkOrderDO csWorkOrderDO = csWorkOrderDAO.findOne(new Query().addCriteria(Criteria.where("workorderId").is(request.getOrderId())));
if (null == csWorkOrderDO || null == csWorkOrderDO.getStatus() || !processCSWorkOrderStatus.contains(csWorkOrderDO.getStatus())) {
throw new CustomerServiceException(CSOrderSystemErrorCode.InsertError, CSOrderBizErrorCode.SYSTEM_ERROR, "can not find out work order by orderId or the order is not processing");
}
csWorkOrderDO.setStatus(CSWorkOrderStatus.Suspend);
List<CSWorkOrderDO> workOrders = new ArrayList<>();
workOrders.add(csWorkOrderDO);
opLogDOS.add(createdOpLogDO(csWorkOrderDO.getWorkorderId(), csWorkOrderDO.getStatus(), csWorkOrderDO.getCurrentDealUserId(), "暂停工单"));
FacadeResponse updateResponse = updateWOS(workOrders, opLogDOS);
return null != updateResponse && updateResponse.isSucceeded();
}
@Override
public Boolean orderAwake(CSWorkOrderAwakeRequest request) {
Assert.isTrue(checkAwakeRequest(request), "work order awake fail,request is error");
//当前工单是否是暂停中,更新工单状态为处理中
List<CSWorkOrderOpLogDO> opLogDOS = new LinkedList<>();
CSWorkOrderDO csWorkOrderDO = csWorkOrderDAO.findOne(new Query().addCriteria(Criteria.where("workorderId").is(request.getOrderId())));
if (null == csWorkOrderDO || null == csWorkOrderDO.getStatus() || !CSWorkOrderStatus.Suspend.equals(csWorkOrderDO.getStatus())) {
throw new CustomerServiceException(CSOrderSystemErrorCode.InsertError, CSOrderBizErrorCode.SYSTEM_ERROR, "can not find out work order by orderId or the order is not suspended");
}
// 说明是升级工单
if (!StringUtils.isEmpty(csWorkOrderDO.getBeforeUpgradePrincipalId())) {
csWorkOrderDO.setStatus(CSWorkOrderStatus.UpgradeProcessing);
} else {
csWorkOrderDO.setStatus(CSWorkOrderStatus.Processing);
}
List<CSWorkOrderDO> workOrders = new ArrayList<>();
workOrders.add(csWorkOrderDO);
opLogDOS.add(createdOpLogDO(csWorkOrderDO.getWorkorderId(), csWorkOrderDO.getStatus(), csWorkOrderDO.getCurrentDealUserId(), "唤醒工单"));
FacadeResponse updateResponse = updateWOS(workOrders, opLogDOS);
//唤醒工单后需要把当前工单负责人移出队列
removeUser(request.getUserId());
return null != updateResponse && updateResponse.isSucceeded();
}
private boolean checkAwakeRequest(CSWorkOrderAwakeRequest request) {
if (null == request) {
return false;
}
if (StringUtils.isEmpty(request.getOrderId())) {
return false;
}
if (StringUtils.isEmpty(request.getUserId())) {
return false;
}
return null != request.getDomain();
}
@Override
public String getSurveyQuestionnaireId() {
return questionnaireId;
}
@Override
public void upgradeWorkOrder(WorkOrderUpgradeReq workOrderUpgradeReq) {
CSWorkOrderDO csWorkOrderDO = csWorkOrderDAO.queryCSWorkOrderByWorkOrderId(workOrderUpgradeReq.getWorkOrderId());
CSExceptionAssert.isTrue(csWorkOrderDO != null, CSOrderBizErrorCode.VALIDATION_ERROR, "工单不存在");
if (finalCSWorkOrderStatus.contains(csWorkOrderDO.getStatus())) {
throw new CustomerServiceException(CSOrderSystemErrorCode.InternalError, CSOrderBizErrorCode.VALIDATION_ERROR, "工单已关闭,不允许升级");
}
CSExceptionAssert.isTrue(!StringUtils.isEmpty(csWorkOrderDO.getPrincipalUserId())
, CSOrderBizErrorCode.VALIDATION_ERROR
, "非处理中工单,不能升级");
if (StringUtils.isEmpty(primaryGroup)) {
log.error("primaryGroup is empty");
CSExceptionAssert.fail(CSOrderBizErrorCode.VALIDATION_ERROR, "非一线人员,不能升级工单");
}
if(!OrderLevel.OL2.equals(csWorkOrderDO.getOrderLevel())){
BossUserInGroupReq bossUserInGroupReq = BossUserInGroupReq.builder()
.bossUserId(workOrderUpgradeReq.getOperatorUserId())
.groupIds(Sets.newHashSet(primaryGroup))
.build();
FacadeResponse<Boolean> facadeResponse = bossUserGroupClient.bossUserInSpecifiedGroup(bossUserInGroupReq);
CSExceptionAssert.isTrue(facadeResponse.isSucceeded()
, CSOrderBizErrorCode.SYSTEM_ERROR, "系统内部错误,请重试");
CSExceptionAssert.isTrue(Boolean.TRUE.equals(facadeResponse.getValue())
, CSOrderBizErrorCode.SYSTEM_ERROR, "非一线人员,不能升级工单");
}
String beforeUpgradePrincipalId = csWorkOrderDO.getPrincipalUserId();
WorkOrderUpdateReq workOrderUpdateReq = WorkOrderUpdateReq.builder()
.workOrderId(csWorkOrderDO.getWorkorderId())
.principalUserId("")
.beforeUpdatePrincipalUserId(StringUtils.isBlank(csWorkOrderDO.getBeforeUpgradePrincipalId()) ? beforeUpgradePrincipalId : "")
.operatorUserId(workOrderUpgradeReq.getOperatorUserId())
.status(CSWorkOrderStatus.UpgradePending)
.orderLevel(OrderLevel.OL2)
.upgradeSource(workOrderUpgradeReq.getUpgradeSource())
.upgradeFlag(true)
.build();
List<DataPersistenceCommander> commanders = new ArrayList<>();
OpLogAddRequest request = OpLogAddRequest.builder()
.workOrderId(workOrderUpgradeReq.getWorkOrderId())
.suggestion("升级工单")
.status(workOrderUpdateReq.getStatus())
.operatorUserId(workOrderUpgradeReq.getOperatorUserId())
.build();
csWorkOrderLogService.insertOpLog(commanders, request);
upgradeOrBackWorkOrder(commanders, workOrderUpdateReq, true);
try {
transactionLazyExecutor.executeWithRequire(commanders);
} catch (Exception e) {
log.error("upgradeWorkOrder failed. e is:", e);
}
// 移除原来的升级自动分配
// CompletableFuture.runAsync(() -> {
// try {
// SecondGroupOrderAssignJob.assignOL2WorkOrder(csWorkOrderDO.getWorkorderId());
// } catch (Exception e) {
// log.error("assignOL2WorkOrder failed. e is: ", e);
// }
// });
//上报工单升级 sla
slaEscalationService.escalationUpgradeWorkOrderSla(csWorkOrderDO);
consultProgressPushService.upgradeWorkOrder(csWorkOrderDO);
}
@Override
public void backWorkOrder(WorkOrderBackReq req) {
CSWorkOrderDO csWorkOrderDO = csWorkOrderDAO.queryCSWorkOrderByWorkOrderId(req.getWorkOrderId());
CSExceptionAssert.isTrue(csWorkOrderDO != null
, CSOrderBizErrorCode.VALIDATION_ERROR, "工单不存在");
if (finalCSWorkOrderStatus.contains(csWorkOrderDO.getStatus())) {
throw new CustomerServiceException(CSOrderSystemErrorCode.InternalError
, CSOrderBizErrorCode.VALIDATION_ERROR, "工单已关闭,不允许退回");
}
if (csWorkOrderDO.getStatus() != CSWorkOrderStatus.UpgradeProcessing || StringUtils.isEmpty(csWorkOrderDO.getBeforeUpgradePrincipalId())) {
CSExceptionAssert.fail(CSOrderBizErrorCode.VALIDATION_ERROR
, "不是升级工单,不能退回");
}
CSExceptionAssert.isTrue(!StringUtils.isEmpty(csWorkOrderDO.getPrincipalUserId())
, CSOrderBizErrorCode.VALIDATION_ERROR
, "工单无负责人,不能退回");
if (!req.getOperatorUserId().equals(csWorkOrderDO.getPrincipalUserId())) {
CSExceptionAssert.fail(CSOrderBizErrorCode.VALIDATION_ERROR
, "非工单负责人,不能退回工单");
}
WorkOrderUpdateReq workOrderUpdateReq = WorkOrderUpdateReq.builder()
.workOrderId(csWorkOrderDO.getWorkorderId())
.beforeUpdatePrincipalUserId(handleUpdatePrincipalUserId(csWorkOrderDO))
.operatorUserId(req.getOperatorUserId())
.status(CSWorkOrderStatus.Processing)
.principalUserId(csWorkOrderDO.getBeforeUpgradePrincipalId())
.orderLevel(OrderLevel.OL1)
.build();
List<DataPersistenceCommander> commanders = new ArrayList<>();
OpLogAddRequest request = OpLogAddRequest.builder()
.workOrderId(req.getWorkOrderId())
.suggestion("工单退回")
.status(CSWorkOrderStatus.Processing)
.operatorUserId(req.getOperatorUserId())
.build();
csWorkOrderLogService.insertOpLog(commanders, request);
upgradeOrBackWorkOrder(commanders, workOrderUpdateReq, false);
try {
transactionLazyExecutor.executeWithRequire(commanders);
} catch (Exception e) {
log.error("upgradeWorkOrder failed. e is:", e);
return;
}
CompletableFuture.runAsync(() -> {
try {
notify(csWorkOrderDO.getBeforeUpgradePrincipalId(), csWorkOrderDO.getWorkorderId());
} catch (Exception e) {
log.error("notify failed. e is: ", e);
}
}, commonExecutor);
slaEscalationService.escalationBackWorkOrderSla(csWorkOrderDO, csWorkOrderDO.getBeforeUpgradePrincipalId(), req.getOperatorUserId());
}
private String handleUpdatePrincipalUserId(CSWorkOrderDO csWorkOrderDO) {
// 只有回退到最后一层级的时候才置空
if (CollectionUtils.isEmpty(csWorkOrderDO.getUpgradeLabelList()) || csWorkOrderDO.getUpgradeLabelList().size() == LABEL_LIST_SIZE_ONE) {
return "";
}
return csWorkOrderDO.getBeforeUpgradePrincipalId();
}
/**
* 查询客服意见反馈工单附件
*
* @param workOrderId 工单id
* @return voList 对于2022/03/11版本的客服意见反馈工单,listSize应当为1
* @throws CustomerServiceException case1:工单不存在 ;case2:通过formAnswer查询formAnswer不存在
*/
@Override
public List<CSWorkOrderFeedbackAttachmentVO> queryWorkOrderFeedbackAttachment(String workOrderId) {
//查询工单,获取businessInfo.bizId,bizId即crm_form_answer_whole.formAnswerId
CSWorkOrderDO csWorkOrderDO = csWorkOrderDAO.queryCSWorkOrderByWorkOrderId(workOrderId);
if (csWorkOrderDO == null) {
// log.error("csWorkOrder does not exist,workOrderId for query:{}", workOrderId);
// throw new MktServiceException(RecordNotFoundError, NOT_FOUND, "客服工单不存在");
return Lists.newArrayList();
}
List<BusinessInfoDTO> businessInfos = csWorkOrderDO.getBusinessInfos();
List<CSWorkOrderFeedbackAttachmentVO> attachmentsList = new ArrayList<>();
if (!CollectionUtils.isEmpty(businessInfos)) {
for (BusinessInfoDTO businessInfo : businessInfos) {
if (Objects.equals(businessInfo.getType(), BusinessInfoType.FeedbackWorkOrderAttachment)) {
FacadeResponse<FormAnswerVO> rsp = formServAnswerClient.getByFormAnswerId(businessInfo.getBizId());
if (rsp == null || !rsp.isSucceeded() || rsp.getValue() == null || CollectionUtils.isEmpty(rsp.getValue().getAnswers())) {
log.error("formAnswer does not exist,can not query attachments,workOrderId:{};formAnswerId:{}", workOrderId, businessInfo.getBizId());
throw new CustomerServiceException(CSOrderSystemErrorCode.RecordNotFoundError, CSOrderBizErrorCode.NOT_FOUND, "查询失败,附件不存在");
}
CSWorkOrderFeedbackAttachmentVO vo = toCSWorkOrderFeedbackAttachmentVO(rsp.getValue());
if (vo != null) {
attachmentsList.add(vo);
}
}
}
}
return attachmentsList;
}
@Override
public RecordTemplateVO queryRecordTemplateDetail(String recordTemplateId) {
RecordTemplateDO recordTemplateDO = csWorkOrderRecordTemplateDAO.findByTemplateId(recordTemplateId);
if (recordTemplateDO != null) {
RecordTemplateVO recordTemplateVO = WorkOrderConverter.toRecordTemplateVO(recordTemplateDO);
if (StringUtils.isNotEmpty(recordTemplateDO.getFormId())) {
FacadeResponse<FormVO> facadeResponse = formServClient.queryDetails(recordTemplateDO.getFormId());
if (facadeResponse.isSucceeded() && null != facadeResponse.getValue()) {
recordTemplateVO.setFormVO(facadeResponse.getValue());
}
}
return recordTemplateVO;
}
return null;
}
@Override
public List<ConsultingOrderVO> queryConsultingOrder(ConsultingOrderRequest request) {
return queryPageConsultingOrder(request).getList();
}
@Override
public AppointmentResultVO createAppointment(AppointmentCreateRequest request) {
if (StringUtils.isNotEmpty(request.getRemark())) {
CSExceptionAssert.isTrue(request.getRemark().length() <= remarkLength
, CSOrderBizErrorCode.VALIDATION_ERROR
, "留言不能超过 " + remarkLength + "字");
}
CSWorkOrderDO csWorkOrderDO = csWorkOrderDAO.queryCSWorkOrderByWorkOrderId(request.getWorkOrderId());
AppointmentResultVO resultVO = isAllowed(csWorkOrderDO);
if (!resultVO.getIsSuccess()) {
return resultVO;
}
List<DataPersistenceCommander> commanders = new ArrayList<>();
// 新增处理记录
String content = StringUtils.isEmpty(request.getRemark()) ? "客户预约回电。" : "客户预约回电,留言:" + request.getRemark();
ComRecordAddRequest addRequest = ComRecordAddRequest.builder()
.workOrderId(csWorkOrderDO.getWorkorderId())
.content(content)
.operatorUserId(request.getOperatorUserId())
.operatorType(request.getOperatorType())
.build();
String recordId = commRecordService.insertCommRecord(commanders, addRequest);
// 新增操作日志
OpLogAddRequest opLogAddRequest = OpLogAddRequest.builder()
.workOrderId(request.getWorkOrderId())
.commRecordId(recordId)
.operatorUserId(request.getOperatorUserId())
.status(csWorkOrderDO.getStatus())
.suggestion(content)
.operatorType(request.getOperatorType())
.build();
csWorkOrderLogService.insertOpLog(commanders, opLogAddRequest);
InstructionAddRequest instructionAddRequest = InstructionAddRequest.builder()
.associatedReferenceId(recordId)
.type(WorkOrderInstructionType.CustomerAppointment)
.referenceId(request.getWorkOrderId())
.build();
cSWorkOrderInstructionService.addInstructions(commanders, instructionAddRequest);
transactionLazyExecutor.executeCommanders(commanders);
CompletableFuture.runAsync(() -> {
try {
cSWorkOrderInstructionService.doUnSuccessStatusInstruction(request.getWorkOrderId());
} catch (Exception e) {
log.error("doUnSuccessStatusInstruction failed. e is: ", e);
}
}, commonExecutor);
resultVO.setIsSuccess(true);
//上报sla数据
slaEscalationService.escalationUserOpSla(csWorkOrderDO);
consultProgressPushService.userOpSubmitAppointment(csWorkOrderDO, request.getRemark());
return resultVO;
}
@Override
public List<CSWorkOrderResultVO> queryByFirmIdAndWorkOrderType(WorkOrderQueryRequest request) {
String configId = cSWorkOrderConfigService.getConfigIdByConfigType(request.getWorkOrderType());
Assert.isTrue(StringUtils.isNotEmpty(configId), "workOrderType: " + request.getWorkOrderType() + " is valid");
List<CSWorkOrderDO> workOrderDOS = csWorkOrderDAO.queryByFirmIdAndWorkOrderType(request.getFirmId(), configId);
if (CollectionUtils.isEmpty(workOrderDOS)) {
return new ArrayList<>();
}
return workOrderDOS.stream().map(this::resultConvert).collect(Collectors.toList());
}
@Override
public List<ConsultingTypeVO> getConsultingType() {
List<ConsultingTypeVO> consultingTypesVOS = new ArrayList<>();
if (consultingTypeMap == null) {
return consultingTypesVOS;
}
consultingTypeMap.forEach((key, value) -> {
ConsultingTypeVO consultingTypesVO = new ConsultingTypeVO();
consultingTypesVO.setConsultingType(key);
consultingTypesVO.setConsultingTypeDesc(value);
consultingTypesVOS.add(consultingTypesVO);
});
return consultingTypesVOS;
}
@Override
public CSWorkOrderVO queryOneWorkOrderByAssignId(String assignId) {
CSWorkOrderDO csWorkOrderDO = csWorkOrderDAO.findOne(new Query().addCriteria(Criteria.where(CSWorkOrderDO.ASSIGN_ID).is(assignId)));
return Optional.ofNullable(csWorkOrderDO).map(order -> {
CSWorkOrderVO csWorkOrderVO = toWorkOrderVO(order);
csWorkOrderVO.setHistoryPreAuditWorkOrderVOList(getHistoryPreAuditWorkOrders(order));
// csWorkOrderVO.setPartnerBindVO(getPreAuditWorkOrderPartnerInfo(order));
// csWorkOrderVO.setBusinessBindVO(getExpeditedWorkOrderBusinessInfo(order));
return csWorkOrderVO;
}).orElse(null);
}
private CSWorkOrderVO queryOneWorkOrderByCallCenterId(String callCenterId) {
CSWorkOrderDO csWorkOrderDO = csWorkOrderDAO.findOne(new Query().addCriteria(Criteria.where(CSWorkOrderDO.CALL_CENTER_ID).is(callCenterId)));
return Optional.ofNullable(csWorkOrderDO).map(order -> {
CSWorkOrderVO csWorkOrderVO = toWorkOrderVO(order);
csWorkOrderVO.setHistoryPreAuditWorkOrderVOList(getHistoryPreAuditWorkOrders(order));
// csWorkOrderVO.setPartnerBindVO(getPreAuditWorkOrderPartnerInfo(order));
// csWorkOrderVO.setBusinessBindVO(getExpeditedWorkOrderBusinessInfo(order));
return csWorkOrderVO;
}).orElse(null);
}
@Override
public CSWorkOrderVO queryLastOne(QueryLastWorkOrderRequest request) {
ConfigQueryByTypeRequest typeRequest = ConfigQueryByTypeRequest.builder()
.businessType(request.getBusinessType())
.workOrderType(request.getWorkorderType())
.problemType(request.getProblemType())
.build();
CSWorkorderConfigVO csWorkorderConfigVO = cSWorkOrderConfigService.getWorkOrderConfigVO(typeRequest);
if (null == csWorkorderConfigVO) {
throw new CustomerServiceException(CSOrderSystemErrorCode.ValidationError, CSOrderBizErrorCode.ILLEGAL_ARGUMENT, "can not find work order config by request");
}
Query query = new Query();
Criteria criteria = Criteria.where(CSWorkOrderDO.FIRM_ID).is(request.getFirmId())
.and(CSWorkOrderDO.WORK_ORDER_CONFIG_ID).is(csWorkorderConfigVO.getTypeId());
query.addCriteria(criteria);
query.with(Sort.by(Sort.Direction.DESC, CSWorkOrderDO.CREATION_DATE)).limit(1);
CSWorkOrderDO csWorkOrderDO = csWorkOrderDAO.findOne(query);
CSWorkOrderVO csWorkOrderVO = toWorkOrderVO(csWorkOrderDO);
if (Objects.isNull(csWorkOrderVO)) {
return null;
}
csWorkOrderVO.setHistoryPreAuditWorkOrderVOList(getHistoryPreAuditWorkOrders(csWorkOrderDO));
// csWorkOrderVO.setPartnerBindVO(getPreAuditWorkOrderPartnerInfo(csWorkOrderDO));
// csWorkOrderVO.setBusinessBindVO(getExpeditedWorkOrderBusinessInfo(csWorkOrderDO));
return csWorkOrderVO;
}
@Override
public void csWorkOrderRelateFirmInfo(String csWorkOrderId, String firmId) {
CSWorkOrderDO csWorkOrderDO = csWorkOrderDAO.queryCSWorkOrderByWorkOrderId(csWorkOrderId);
if (Objects.isNull(csWorkOrderDO)) {
throw new CustomerServiceException(CSOrderSystemErrorCode.BadRequest, CSOrderBizErrorCode.SYSTEM_ERROR,"工单不存在");
}
if (CSWorkOrderStatus.endStatusList().contains(csWorkOrderDO.getStatus())) {
throw new CustomerServiceException(CSOrderSystemErrorCode.BadRequest, CSOrderBizErrorCode.SYSTEM_ERROR, "工单当前状态不允许关联");
}
if (!csWorkOrderDO.isCanRelateFirmInfo()) {
throw new CustomerServiceException(CSOrderSystemErrorCode.BadRequest, CSOrderBizErrorCode.SYSTEM_ERROR, "该工单不支持关联企业信息");
}
WorkOrderConverter.setBasicFirmInfo(csWorkOrderDO, null, firmId, firmClient, userClient);
csWorkOrderDO.setCanRelateFirmInfo(false);
Assert.isTrue(csWorkOrderDAO.updateByIdSelective(csWorkOrderDO) != null, "工单关联企业信息失败");
}
@Override
public PageSerializable<CSWorkOrderVO> querySaleSessionWorkOrderPageList(CSSaleWorkOrderSessionRequest request) {
Page<CSWorkOrderDO> page = csWorkOrderDAO.querySaleSessionWorkOrderPageList(request.getBossUserId(), request.getMixId(), request.getMixName(), request.getMixIdAndName(),
request.getFromDate(), request.getPage(), request.getSize());
PageSerializable<CSWorkOrderVO> result = new PageSerializable<>();
result.setTotal(page.getTotal());
result.setList(Lists.newArrayList());
if (!CollectionUtils.isEmpty(page.getResult())) {
result.setList(page.getResult().stream().map(this::toWorkOrderVO).collect(Collectors.toList()));
}
return result;
}
@Override
public void workOrderBindSaleInfo(BindSaleInfoRequest request) {
CSWorkOrderDO csWorkOrderDO = csWorkOrderDAO.queryCSWorkOrderByWorkOrderId(request.getWorkOrderId());
Assert.notNull(csWorkOrderDO, "工单不存在");
if (StringUtils.isNotBlank(csWorkOrderDO.getSaleBossUserId())) {
return;
}
User user = bossUserClient.queryByBossUserId(request.getSaleBossUserId());
Assert.notNull(user, "销售不存在");
csWorkOrderDO.setSaleBossUserId(user.getBossUserId());
csWorkOrderDO.setSaleUserName(user.getUserName());
Assert.isTrue(csWorkOrderDAO.updateByIdSelective(csWorkOrderDO) != null, "工单绑定销售信息失败");
consultProgressPushService.sendSaleIdChange(csWorkOrderDO.getWorkorderId(), csWorkOrderDO.getSaleBossUserId());
}
@Override
public CSWorkOrderVO queryOneWorkOrderByAssignIdAndUseScene(String assignId, String useScene) {
switch (useScene) {
case "IM":
return queryOneWorkOrderByAssignId(assignId);
case "CALL_CENTER":
return queryOneWorkOrderByCallCenterId(assignId);
default:
return null;
}
}
@Override
public PageSerializable<ConsultingOrderVO> queryPageConsultingOrder(ConsultingOrderRequest request) {
List<CSWorkOrderDO> csWorkOrderDOS = csWorkOrderDAO.queryConsultingOrder(request, consultWorkOrderLimit, preDayLimit);
if (CollectionUtils.isEmpty(csWorkOrderDOS)) {
return new PageSerializable<>();
}
// 先按创建时间降序排
csWorkOrderDOS = csWorkOrderDOS.stream().sorted(Comparator.comparing(CSWorkOrderDO::getCreationDate).reversed()).collect(Collectors.toList());
List<CSWorkOrderDO> processingDOS = csWorkOrderDOS.stream()
.filter((csWorkOrderDO) -> processCSWorkOrderStatus.contains(csWorkOrderDO.getStatus()))
.collect(Collectors.toList());
List<CSWorkOrderDO> notProcessingDOS = csWorkOrderDOS.stream()
.filter((csWorkOrderDO) -> !processCSWorkOrderStatus.contains(csWorkOrderDO.getStatus()))
.collect(Collectors.toList());
List<CSWorkOrderDO> finalDOS = new ArrayList<>();
finalDOS.addAll(processingDOS);
finalDOS.addAll(notProcessingDOS);
int startIndex = (request.getPage() - 1) * request.getSize();
int endIndex = (request.getPage()) * request.getSize();
if (endIndex > finalDOS.size()) {
endIndex = finalDOS.size();
}
List<CSWorkOrderDO> allowedDOS = finalDOS.subList(startIndex, endIndex);
if (CollectionUtils.isEmpty(allowedDOS)) {
return new PageSerializable<>();
}
List<ConsultingOrderVO> allowedVOS = new ArrayList<>();
for (CSWorkOrderDO csWorkOrderDO : allowedDOS) {
ConsultingOrderVO orderVO = WorkOrderConverter.workOrderDO2ConsultingVO(csWorkOrderDO, consultingTypeMap);
AppointmentResultVO resultVO = isAllowed(csWorkOrderDO);
orderVO.setAllowedAppointment(resultVO.getIsSuccess());
if (StringUtils.isEmpty(csWorkOrderDO.getPrincipalUserId())) {
orderVO.setAllowedAppointment(false);
}
allowedVOS.add(orderVO);
}
PageSerializable<ConsultingOrderVO> result = new PageSerializable<>();
result.setList(allowedVOS);
result.setTotal(csWorkOrderDOS.size());
return result;
}
@Override
public Boolean existWorkOrderByAssIngId(String assignId) {
CSWorkOrderDO csWorkOrderDO = csWorkOrderDAO.findOne(new Query().addCriteria(Criteria.where(CSWorkOrderDO.ASSIGN_ID).is(assignId)));
return Objects.nonNull(csWorkOrderDO);
}
private void currentWorkOrderConfigIsUsable(String workorderTypeId, String operatorUserId) {
CSWorkorderConfigVO configVO = cSWorkOrderConfigService.getValidConfigVOByConfigId(workorderTypeId);
CSExceptionAssert.isTrue(configVO != null, CSOrderBizErrorCode.VALIDATION_ERROR, "当前工单类型不存在或不可用");
if (configVO.getCreateType() == CreateType.Auto && !SystemConst.SYSTEM_USER_ID.equals(operatorUserId)) {
CSExceptionAssert.fail(CSOrderBizErrorCode.VALIDATION_ERROR, "当前工单类型不可手动创建");
}
if (configVO.getBusinessType() == BusinessType.CUSTOMER_MANAGEMENT_SERVICE) {
CSExceptionAssert.fail(CSOrderBizErrorCode.VALIDATION_ERROR, "不支持创建" + BusinessType.CUSTOMER_MANAGEMENT_SERVICE.getDesc() + "类型工单");
}
}
private void checkWorkOrderTrackWay(CSWorkOrderCreateRequest request) {
if (Objects.isNull(request)) {
throw new CustomerServiceException(CSOrderSystemErrorCode.ValidationError, CSOrderBizErrorCode.ILLEGAL_ARGUMENT, "参数不能为空");
}
if (Objects.equals(WorkOrderTrackWay.EMAIL.name(), request.getWorkOrderTrackWay())) {
CSExceptionAssert.isTrue(Objects.nonNull(request.getCsWorkOrderEmailRequest())
, CSOrderBizErrorCode.VALIDATION_ERROR
, "邮件信息为空");
ValidateResult validate = ValidateUtil.validate(request.getCsWorkOrderEmailRequest());
if (!validate.isPassed()) {
throw new CustomerServiceException(CSOrderSystemErrorCode.ValidationError, CSOrderBizErrorCode.ILLEGAL_ARGUMENT, validate.getReason());
}
}
}
private String getWorkOrderId() {
return AttaIdUtils.getByProdCode(AttaIdUtils.ProdCode.CUSTOMER_SERVICE_WORKORDER);
}
private CSWorkOrderDO insertWorkOrder(WorkOrderAddRequest request) {
CSWorkOrderDO csWorkOrderDO = CSWorkOrderDO.builder()
.workorderId(getWorkOrderId())
.workOrderConfigId(request.getWorkOrderConfigId())
.currentDealUserId(request.getCurrentDealUserId())
.firmId(request.getFirmId())
.firmName(request.getFirmName())
.email(request.getEmail())
.source(request.getSource())
.userId(request.getUserId())
.feedbackTime(request.getFeedbackTime())
.generatedReason(request.getGeneratedReason())
.workorderEndTime(request.getWorkOrderEndTime())
.invitationCode(request.getInvitationCode())
.phone(request.getPhone())
.lastFollowedTime(request.getLastFollowedTime())
.principalUserId(request.getPrincipalUserId())
.referenceId(request.getReferenceId())
.orderLevel(request.getOrderLevel())
.vaAccount(request.getVaAccount())
.currency(request.getCurrency())
.amount(request.getAmount())
.serviceProvider(request.getServiceProvider())
.canRelateFirmInfo(false)
.newCollaboration(CsOrderConstants.newCollaboration)
.build();
if (StringUtils.isNotBlank(request.getPrincipalUserId())) {
csWorkOrderDO.setAllocateTime(new Date());
}
// 如果是人工新建的工单
if (!SystemConst.SYSTEM_USER_ID.equals(request.getCreateUserId())) {
csWorkOrderDO.setLastFollowedTime(new Date());
}
if (!CollectionUtils.isEmpty(request.getBusinessInfoVOList())) {
csWorkOrderDO.setBusinessInfos(request.getBusinessInfoVOList().stream()
.map(WorkOrderConverter::businessInfoVO2DO).collect(Collectors.toList()));
}
if (csWorkOrderDO.getHistoryDealUsers() == null || CollectionUtils.isEmpty(csWorkOrderDO.getHistoryDealUsers())) {
if (!StringUtils.isEmpty(request.getCurrentDealUserId())) {
csWorkOrderDO.setHistoryDealUsers(Sets.newHashSet(request.getCurrentDealUserId()));
}
} else {
csWorkOrderDO.getHistoryDealUsers().add(request.getCurrentDealUserId());
}
WorkOrderConverter.setCSOrderDOFromOrderConfig(csWorkOrderDO, request.getWorkOrderConfigId(), cSWorkOrderConfigService);
WorkOrderConverter.setBasicFirmInfo(csWorkOrderDO, request.getUserId(), request.getFirmId(), firmClient, userClient);
setOrderLevel(csWorkOrderDO, request.getPrincipalUserId());
csWorkOrderDO.setCreatedBy(request.getCreateUserId());
if (StringUtils.isEmpty(request.getPrincipalUserId()) || SystemConst.SYSTEM_USER_ID.equals(request.getPrincipalUserId())) {
csWorkOrderDO.setStatus(CSWorkOrderStatus.Created);
} else {
csWorkOrderDO.setStatus(CSWorkOrderStatus.Processing);
}
return csWorkOrderDO;
}
private CSWorkOrderDO insertWorkOrder(List<DataPersistenceCommander> commanders, WorkOrderAddRequest request) {
CSWorkOrderDO csWorkOrderDO = CSWorkOrderDO.builder()
.workorderId(getWorkOrderId())
.workOrderConfigId(request.getWorkOrderConfigId())
.sceneConfigId(request.getSceneConfigId())
.problemScene(request.getProblemScene())
.currentDealUserId(request.getCurrentDealUserId())
.firmId(request.getFirmId())
.firmName(request.getFirmName())
.email(request.getEmail())
.source(request.getSource())
.userId(request.getUserId())
.feedbackTime(request.getFeedbackTime())
.generatedReason(request.getGeneratedReason())
.workorderEndTime(request.getWorkOrderEndTime())
.invitationCode(request.getInvitationCode())
.phone(request.getPhone())
.lastFollowedTime(request.getLastFollowedTime())
.principalUserId(request.getPrincipalUserId())
.referenceId(request.getReferenceId())
.orderLevel(request.getOrderLevel())
.vaAccount(request.getVaAccount())
.currency(request.getCurrency())
.amount(request.getAmount())
.serviceProvider(request.getServiceProvider())
.canRelateFirmInfo(false)
.phoneAreaCode(request.getPhoneAreaCode())
.newPhoneAreaCode(request.getNewPhoneAreaCode())
.saleBossUserId(request.getSaleBossUserId())
.saleUserName(request.getSaleBossUserName())
.site(request.getSite())
.serviceObject(request.getServiceObject())
.callCenterId(request.getCallCenterId())
.newCollaboration(CsOrderConstants.newCollaboration)
.skylarkCollaborationId(request.getSkylarkCollaborationId())
.accountType(request.getAccountType())
.userAccountId(request.getUserAccountId())
.accountName(request.getAccountName())
.customerShowSwitch(StringUtils.isEmpty(request.getCustomerShowSwitch()) ? CsWoCustomerShowSwitchEnum.CLOSE.name() : request.getCustomerShowSwitch())
.receiptTradeId(request.getReceiptTradeId())
.majorClient(false)
.consultTopic(request.getConsultTopic())
.build();
if (StringUtils.isNotBlank(request.getPrincipalUserId())) {
csWorkOrderDO.setAllocateTime(new Date());
}
if (StringUtils.isNotEmpty(request.getAssignId())) {
csWorkOrderDO.setAssignId(request.getAssignId());
}
// 如果是人工新建的工单
if (!SystemConst.SYSTEM_USER_ID.equals(request.getCreateUserId())) {
csWorkOrderDO.setLastFollowedTime(new Date());
}
if (!CollectionUtils.isEmpty(request.getBusinessInfoVOList())) {
csWorkOrderDO.setBusinessInfos(request.getBusinessInfoVOList().stream()
.map(WorkOrderConverter::businessInfoVO2DO).collect(Collectors.toList()));
}
if (csWorkOrderDO.getHistoryDealUsers() == null || CollectionUtils.isEmpty(csWorkOrderDO.getHistoryDealUsers())) {
if (!StringUtils.isEmpty(request.getCurrentDealUserId())) {
csWorkOrderDO.setHistoryDealUsers(Sets.newHashSet(request.getCurrentDealUserId()));
}
} else {
csWorkOrderDO.getHistoryDealUsers().add(request.getCurrentDealUserId());
}
WorkOrderConverter.setCSOrderDOFromOrderConfig(csWorkOrderDO, request.getWorkOrderConfigId(), cSWorkOrderConfigService);
WorkOrderConverter.setBasicFirmInfo(csWorkOrderDO, request.getUserId(), request.getFirmId(), firmClient, userClient);
setOrderLevel(csWorkOrderDO, request.getPrincipalUserId());
csWorkOrderDO.setCreatedBy(request.getCreateUserId());
// 打标升级标签
allocateHandleService.setUpgradeLabelBySource(request, csWorkOrderDO);
if (StringUtils.isNotBlank(csWorkOrderDO.getUpgradeLabel()) && StringUtils.isEmpty(request.getPrincipalUserId())) {
csWorkOrderDO.setStatus(CSWorkOrderStatus.UpgradePending);
} else if (StringUtils.isEmpty(request.getPrincipalUserId()) || SystemConst.SYSTEM_USER_ID.equals(request.getPrincipalUserId())) {
csWorkOrderDO.setStatus(CSWorkOrderStatus.Created);
} else if (CSWorkOrderUpgradeSource.SENIOR_CREATE_UPGRADE.name().equals(request.getUpgradeSource())) {
csWorkOrderDO.setStatus(CSWorkOrderStatus.UpgradeProcessing);
} else {
csWorkOrderDO.setStatus(CSWorkOrderStatus.Processing);
}
commanders.add(() -> {
CSExceptionAssert.isTrue(csWorkOrderDAO.insert(csWorkOrderDO) != null
, CSOrderBizErrorCode.SYSTEM_ERROR
, "insert workOrderDO failed.");
});
return csWorkOrderDO;
}
private void setOrderLevel(CSWorkOrderDO csWorkOrderDO, String principalUserId) {
if (StringUtils.isEmpty(principalUserId)) {
return;
}
BossUserInGroupReq bossUserInSecondGroupReq = BossUserInGroupReq.builder()
.groupIds(Sets.newHashSet(csOrderConfig.secondGroup))
.bossUserId(principalUserId)
.build();
FacadeResponse<Boolean> secondGroupFacadeResponse = bossUserGroupClient.bossUserInSpecifiedGroup(bossUserInSecondGroupReq);
CSExceptionAssert.isTrue(secondGroupFacadeResponse.isSucceeded(), CSOrderBizErrorCode.SYSTEM_ERROR, "系统内部错误");
if (Boolean.TRUE.equals(secondGroupFacadeResponse.getValue())) {
csWorkOrderDO.setOrderLevel(OrderLevel.OL2);
return;
}
BossUserInGroupReq bossUserInPrimaryGroupReq = BossUserInGroupReq.builder()
.groupIds(Sets.newHashSet(csOrderConfig.primaryGroup))
.bossUserId(principalUserId)
.build();
FacadeResponse<Boolean> facadeResponse = bossUserGroupClient.bossUserInSpecifiedGroup(bossUserInPrimaryGroupReq);
CSExceptionAssert.isTrue(facadeResponse.isSucceeded(), CSOrderBizErrorCode.SYSTEM_ERROR, "系统内部错误");
if (Boolean.TRUE.equals(facadeResponse.getValue())) {
csWorkOrderDO.setOrderLevel(OrderLevel.OL1);
}
}
private OpLogAddRequest buildOpLogAddRequest(String workOrderId, CSWorkOrderStatus status, String operatorUserId, String suggestion) {
OpLogAddRequest opLogRequest = OpLogAddRequest.builder()
.workOrderId(workOrderId)
.operatorUserId(operatorUserId)
.status(status)
.suggestion(suggestion)
.build();
return opLogRequest;
}
private boolean sendWorkOrderEmail(CSWorkOrderEmailRequest request, String bizId, String workOrderConfigId) {
if (request == null) {
return false;
}
String emailAcctId = emailWorkOrderEmailAccountMap.get(request.getSender());
Assert.isTrue(StringUtils.isNotBlank(emailAcctId), "邮件账号不存在");
String content = buryingPointContent(request.getContent(), bizId);
EmailSendReq emailSendReq = EmailSendReq.builder()
.emailAcctId(emailAcctId)
.contentTemplate(DEFAULT_MESSAGE_TEMPLATE)
.separate(request.isSeparate())
.subject(request.getSubject())
.replyTo(Optional.ofNullable(request.getReplyTo()).map(String::trim).orElse(""))
.to(request.getTo())
.cc(request.getCc())
.bcc(request.getBcc())
.params(
ImmutableMap.of("content", content)
)
.sendRequestFrom(EmailSendRequestFrom.USER.name())
.attachments(Lists.newArrayList())
.build();
if (!CollectionUtils.isEmpty(request.getAttachmentRequests())) {
emailSendReq.setAttachments(request.getAttachmentRequests().stream().map(item -> {
EmailSendReq.Attachment attachment = new EmailSendReq.Attachment();
attachment.setDisposition(item.getDisposition());
attachment.setFilename(item.getFilename());
attachment.setStorageUrl(item.getStorageUrl());
attachment.setOriginFileId(item.getOriginFileId());
attachment.setOriginParentFileId(item.getOriginParentFileId());
return attachment;
}).collect(Collectors.toList()));
}
FacadeResponse<Void> response = emailSendClient.send(emailSendReq);
return response.isSucceeded();
}
private String buryingPointContent(String content, String bizId) {
content = String.format("<div id=\"csWorkOderBizId\" style=\"display: none\" data-csWorkOderBizId=\"%s\"></div>%s", bizId, content);
return "<!DOCTYPE html>\n" +
"<html>\n" +
"<head>\n" +
"</head>\n" +
"<body>\n" +
" <div id=\"content\">" +
content +
" </div>\n" +
"</body>\n" +
"</html>";
}
public void convertWorkOrderAddRequest2TodoTaskEvent(WorkOrderAddRequest workOrderAddRequest, TodoTaskEvent todoTaskEvent) {
todoTaskEvent.setPrincipalUserId(workOrderAddRequest.getPrincipalUserId());
todoTaskEvent.setReferenceDomain(TodoTaskReferenceDomain.WORK_ORDER);
todoTaskEvent.setReferenceType(workOrderAddRequest.getWorkOrderConfigId());
todoTaskEvent.setTodoTaskStatus(TodoTaskStatus.NEW);
todoTaskEvent.setFirmName(workOrderAddRequest.getFirmName());
todoTaskEvent.setFirmId(workOrderAddRequest.getFirmId());
todoTaskEvent.setContactName(workOrderAddRequest.getUserId());
todoTaskEvent.setStartTime(new Date());
}
public void createWorkOrderIntoEventCenter(String csWorkOrderId, WorkOrderSource source, String workOrderConfigId) {
CSWorkOrderDO csWorkOrderDO = csWorkOrderDAO.queryCSWorkOrderByWorkOrderId(csWorkOrderId);
if (csWorkOrderDO == null) {
return;
}
String userId = csWorkOrderDO.getUserId();
String firmId = csWorkOrderDO.getFirmId();
if (!openEventCenterEnabled || StringUtils.isBlank(workOrderConfigId) || (StringUtils.isBlank(userId) && StringUtils.isBlank(firmId))) {
return;
}
CSWorkorderConfigVO configVO = cSWorkOrderConfigService.getValidConfigVOByConfigId(workOrderConfigId);
if (configVO == null) {
return;
}
EventTarget target = null;
String targetId = "";
if (StringUtils.isNotBlank(firmId)) {
target = EventTarget.FIRM;
targetId = firmId;
}
if (StringUtils.isNotBlank(userId)) {
target = EventTarget.USER;
targetId = userId;
}
EventRecord eventRecord = EventRecord
.builder()
.target(target)
.targetId(targetId)
.event("create_csWorkOrder")
.bizId(csWorkOrderId)
.bizTime(new Date())
.eventId(csWorkOrderId)
.product("crm")
.withProperty("business_type", configVO.getBusinessType())
.withProperty("work_order_type", configVO.getWorkorderType())
.withProperty("problem_type", configVO.getProblemType())
.withProperty("work_order_config_id", workOrderConfigId)
.withProperty("work_order_id", csWorkOrderId)
.withProperty("service_order_create_time", new Date())
.withProperty("receipt_target", StringUtils.isNotBlank(csWorkOrderDO.getSaleBossUserId()) ? "sale" : "customer")
.build();
if (Objects.nonNull(source)) {
eventRecord.getPropertiesMap().put("service_order_channel", source);
}
eventProducer.asyncPost(eventRecord, (metadata, exception) -> {
if (exception != null) {
log.error(exception.getMessage());
}
});
}
private FacadeResponse<CSWorkOrderVO> toWorkOrderVOList(CSWorkOrderDO workOrderDO) {
if (workOrderDO == null) {
return null;
}
CSWorkOrderVO csWorkOrderVO = WorkOrderConverter.toWorkOrderVO(workOrderDO);
//TODO 迁移变更:有云雀协同单Id就是新协同UI展示---此处删除了五方协同灰度逻辑
csWorkOrderVO.setNewCollaboration(true);
if (StringUtils.isEmpty(csWorkOrderVO.getFirmId())) {
String userLoginMobile = getUserLoginMobile(csWorkOrderVO.getUserId());
if (null != userLoginMobile) {
csWorkOrderVO.setPhone(userLoginMobile);
}
}
converVideoUrl(csWorkOrderVO);
if (!Strings.isNullOrEmpty(workOrderDO.getPrincipalUserId())) {
User bossPrincipalUser = bossUserClient.queryByBossUserId(workOrderDO.getPrincipalUserId());
if (bossPrincipalUser != null) {
csWorkOrderVO.setPrincipalUserId(bossPrincipalUser.getBossUserId());
csWorkOrderVO.setPrincipalUserName(bossPrincipalUser.getUserName());
}
}
if (!Strings.isNullOrEmpty(workOrderDO.getCurrentDealUserId())) {
User bossCurrentDealUser = bossUserClient.queryByBossUserId(workOrderDO.getCurrentDealUserId());
if (bossCurrentDealUser != null) {
csWorkOrderVO.setCurrentDealUserId(bossCurrentDealUser.getBossUserId());
csWorkOrderVO.setCurrentDealUserName(bossCurrentDealUser.getUserName());
}
}
CSWorkOrderConfigDO workOrderTypeDO = findConfigOne(workOrderDO.getWorkOrderConfigId());
if (workOrderTypeDO != null) {
csWorkOrderVO.setWorkorderTypeVO(WorkOrderConverter.toWorkOrderTypeVO(workOrderTypeDO));
}
CSWorkOrderCommRecordQueryRequest request = new CSWorkOrderCommRecordQueryRequest();
request.setWorkorderId(workOrderDO.getWorkorderId());
request.setSize(1);
request.setPage(1);
Page<CSWorkOrderCommRecordDO> commRecordDOS = csWorkOrderCommRecordDAO.findPage(
new Query().addCriteria(Criteria.where("workorderId").is(request.getWorkorderId())).with(Sort.by(Sort.Direction.DESC, CSWorkOrderCommRecordDO.CREATION_DATE)),
request.getPage(),
request.getSize());
Set<String> bossUserIds = commRecordDOS.stream().map(CSWorkOrderCommRecordDO::getOperator).filter(operator -> !StringUtils.isEmpty(operator)).collect(Collectors.toSet());
List<User> users = bossUserClient.queryByBossUserIds(bossUserIds);
Map<String, String> userIdAndUserNameMap = new HashMap<>();
for (User user : users) {
userIdAndUserNameMap.put(user.getBossUserId(), user.getUserName());
}
List<CSWorkorderCommRecordVO> commRecordVOS = commRecordDOS
.stream().map(commRecordDO -> {
CSWorkorderCommRecordVO commRecordVO = WorkOrderConverter.toCommRecordVO(commRecordDO);
if (!StringUtils.isEmpty(commRecordDO.getOperator())) {
commRecordVO.setOperator(userIdAndUserNameMap.get(commRecordDO.getOperator()));
}
return commRecordVO;
})
.collect(Collectors.toList());
//预审核结果
ActionDO actionDO = actionDAO.findOneBySceneId(workOrderDO.getWorkorderId());
if (actionDO != null && !CollectionUtils.isEmpty(actionDO.getActionResults())) {
Object preAuditResult = actionDO.getActionResults().get(PRE_AUDIT_RESULT);
Object preAuditSuggestion = actionDO.getActionResults().get("preAuditSuggestion");
Object preAuditRemark = actionDO.getActionResults().get("preAuditRemark");
csWorkOrderVO.setPreAuditResult(null == preAuditResult ? null : String.valueOf(preAuditResult));
csWorkOrderVO.setPreAuditSuggestion(null == preAuditSuggestion ? null : String.valueOf(preAuditSuggestion));
csWorkOrderVO.setPreAuditRemark(null == preAuditRemark ? null : String.valueOf(preAuditRemark));
}
// 查询协同发起人
// 风控
// CooperationWorkOrderDO cooperationWorkOrderDO = cooperationWorkOrderDAO.queryByCooperationOrderId(workOrderDO.getWorkorderId());
// if (!ObjectUtils.isEmpty(cooperationWorkOrderDO)) {
// csWorkOrderVO.setCooSponsor(cooperationWorkOrderDO.getCreatorName());
// csWorkOrderVO.setSource(WorkOrderSource.RISK);
// } else {
// //
// CoopWorkOrderDO coopWorkOrderDO = coopWorkOrderDAO.queryByCoWorkOrderId(workOrderDO.getWorkorderId());
// if (!ObjectUtils.isEmpty(coopWorkOrderDO)) {
// csWorkOrderVO.setCooSponsor(coopWorkOrderDO.getSoCreatorName());
// if (Objects.equals(coopWorkOrderDO.getSoDepartmentId(), DepartmentConstant.CUSTOMER_ASSET)) {
// csWorkOrderVO.setSource(WorkOrderSource.CUSTOMER_ASSET);
// }
// }
// }
if (CollectionUtils.isEmpty(commRecordVOS) && !emailCsWorkOrderConfigIds.contains(workOrderDO.getWorkOrderConfigId())) {
return getFacadeResponseWithValue(csWorkOrderVO);
}
csWorkOrderVO.setCsWorkorderCommRecordVOS(commRecordVOS);
// if (!Objects.equals(workOrderDO.getWorkOrderConfigId(), emailCsWorkOrderConfigId)) {
// return getFacadeResponseWithValue(csWorkOrderVO);
// }
CSWorkOrderReceiveEmailRecordDO receiveEmailRecordDO = csWorkOrderReceiveEmailRecordDAO.
queryLastByWorkOrderId(workOrderDO.getWorkorderId());
if (Objects.isNull(receiveEmailRecordDO)) {
return getFacadeResponseWithValue(csWorkOrderVO);
}
csWorkOrderVO.setEmailType(receiveEmailRecordDO.getType());
if (CollectionUtils.isEmpty(commRecordVOS)) {
CSWorkorderCommRecordVO csWorkorderCommRecordVO = new CSWorkorderCommRecordVO();
csWorkorderCommRecordVO.setContent(receiveEmailRecordDO.getSubject());
csWorkorderCommRecordVO.setCreatedTime(receiveEmailRecordDO.getCreationDate());
commRecordVOS.add(csWorkorderCommRecordVO);
return getFacadeResponseWithValue(csWorkOrderVO);
}
CSWorkorderCommRecordVO csWorkorderCommRecordVO = commRecordVOS.get(0);
if (Objects.nonNull(receiveEmailRecordDO.getCreationDate()) &&
Objects.nonNull(csWorkorderCommRecordVO.getCreatedTime()) &&
receiveEmailRecordDO.getCreationDate().after(csWorkorderCommRecordVO.getCreatedTime())) {
csWorkorderCommRecordVO.setContent(receiveEmailRecordDO.getSubject());
csWorkorderCommRecordVO.setCreatedTime(receiveEmailRecordDO.getCreationDate());
}
return getFacadeResponseWithValue(csWorkOrderVO);
}
/**
* 获取用户登录手机号
*
* @param userId
* @return
*/
private String getUserLoginMobile(String userId) {
if (StringUtils.isBlank(userId)) {
return null;
}
FacadeResponse<UserAccountVO> response = userClient.queryUserAccountDetail(userId);
if (!response.isSucceeded() || null == response.getValue()) {
return null;
}
return response.getValue().getMobile();
}
private void converVideoUrl(CSWorkOrderVO workorderVO) {
if (workorderVO.getVideoUrl() != null) {
String url = workorderVO.getVideoUrl();
try {
InputStream fileFromOSS = fileStorageUtils.getFileFromOSS(url);
int len;
byte[] bytes = new byte[1024 * 8];
StringBuilder s = new StringBuilder();
while ((len = fileFromOSS.read(bytes)) != -1) {
s.append(new String(bytes, 0, len, StandardCharsets.UTF_8));
}
workorderVO.setVideoUrl(s.toString());
} catch (Exception e) {
log.error("get video base64 error ,url is {}, error info {}", url, e);
}
}
}
private CSWorkOrderConfigDO findConfigOne(String configId) {
return csWorkOrderConfigDAO.findOne(new Query().addCriteria(Criteria.where("configId").is(configId)));
}
private CSWorkOrderDO findWorkOrderOne(String workOrderId) {
return csWorkOrderDAO.queryCSWorkOrderByWorkOrderId(workOrderId);
}
private static <T> FacadeResponse<T> getFacadeResponseWithValue(T value) {
FacadeResponse<T> response = getFacadeResponseWithSuccess();
response.setValue(value);
return response;
}
private static <T> FacadeResponse<T> getFacadeResponseWithSuccess() {
FacadeResponse<T> response = new FacadeResponse<>();
response.fillWithSuccess();
return response;
}
private static <T> FacadeResponse<T> getFacadeResponseWithFailed(AttaResponseCode code) {
return getFacadeResponseWithFailed(code, null);
}
private static <T> FacadeResponse<T> getFacadeResponseWithFailed(AttaResponseCode code, String message) {
FacadeResponse<T> facadeResponse = new FacadeResponse<>();
facadeResponse.fillWithUnSuccess(code);
facadeResponse.setResponseMsg(message);
return facadeResponse;
}
private String transferPrincipal(OrderAssignReq request) {
request.validate();
List<DataPersistenceCommander> commanders = new ArrayList<>();
CSWorkOrderDO csWorkOrderDO = csWorkOrderDAO.queryCSWorkOrderByWorkOrderId(request.getWorkOrderId());
CSExceptionAssert.isTrue(csWorkOrderDO != null
, CSOrderBizErrorCode.VALIDATION_ERROR
, "csWorkOrderDO should not be empty. workOrderId is: " + request.getWorkOrderId());
if (finalCSWorkOrderStatus.contains(csWorkOrderDO.getStatus())) {
log.warn("csWorkOrderDO already completed. workOrderId is: {}", request.getWorkOrderId());
CSExceptionAssert.fail(CSOrderBizErrorCode.VALIDATION_ERROR, "工单已结案,不能转移负责人");
}
boolean statusIsChange = false;
if (csWorkOrderDO.getStatus() == CSWorkOrderStatus.Pending || csWorkOrderDO.getStatus() == CSWorkOrderStatus.Created) {
csWorkOrderDO.setStatus(CSWorkOrderStatus.Processing);
setOrderLevel(csWorkOrderDO, request.getToPrincipalUserId());
statusIsChange = true;
} else if (csWorkOrderDO.getStatus() == CSWorkOrderStatus.UpgradePending) {
csWorkOrderDO.setStatus(CSWorkOrderStatus.UpgradeProcessing);
statusIsChange = true;
}
csWorkOrderDO.setPrincipalUserId(request.getToPrincipalUserId());
csWorkOrderDO.setCurrentDealUserId(request.getOperatorUserId());
User user = bossUserClient.queryByBossUserId(request.getToPrincipalUserId());
String suggestion = StringUtils.isEmpty(request.getReason()) ? String.format("转移至负责人【%s】", user.getUserName()) : request.getReason();
OpLogAddRequest logAddRequest = OpLogAddRequest.builder()
.workOrderId(request.getWorkOrderId())
.status(csWorkOrderDO.getStatus())
.operatorUserId(request.getOperatorUserId())
.suggestion(suggestion)
.build();
csWorkOrderLogService.insertOpLog(commanders, logAddRequest);
commanders.add(() -> {
CSExceptionAssert.isTrue(csWorkOrderDAO.updateByIdSelective(csWorkOrderDO) != null
, CSOrderBizErrorCode.SYSTEM_ERROR, "更新失败");
});
try {
transactionLazyExecutor.executeWithRequire(commanders);
} catch (Exception e) {
log.error("transfer principal failed. e is: ", e);
CSExceptionAssert.fail(CSOrderBizErrorCode.SYSTEM_ERROR, "转移负责人失败");
}
//如果是协同工单需要发送消息
if (!Objects.isNull(csWorkOrderDO.getSkylarkCollaborationId())) {
//云雀平台新协同工单
//先通知工单变更处理人
skylarkManager.notifyChangePrincipal(csWorkOrderDO.getWorkorderId(), csWorkOrderDO.getSkylarkCollaborationId(), user.getBossUserId(), user.getUserName());
sendSkylarkCollaborationMessage(csWorkOrderDO, csWorkOrderDO.getSkylarkCollaborationId(), WorkOrderOptType.TRANSFER);
}
//转移负责人后把此时工单负责人移出队列
removeUser(request.getToPrincipalUserId());
slaEscalationService.escalationTransferPrincipalPrincipalWorkOrderSla(csWorkOrderDO, statusIsChange);
return csWorkOrderDO.getWorkorderId();
}
private String transferPrincipal(List<DataPersistenceCommander> commanders, OrderAssignReq request) {
request.validate();
CSWorkOrderDO csWorkOrderDO = csWorkOrderDAO.queryCSWorkOrderByWorkOrderId(request.getWorkOrderId());
CSExceptionAssert.isTrue(csWorkOrderDO != null
, CSOrderBizErrorCode.VALIDATION_ERROR
, "csWorkOrderDO should not be empty. workOrderId is: " + request.getWorkOrderId());
if (finalCSWorkOrderStatus.contains(csWorkOrderDO.getStatus())) {
log.warn("csWorkOrderDO already completed. workOrderId is: {}", request.getWorkOrderId());
CSExceptionAssert.fail(CSOrderBizErrorCode.VALIDATION_ERROR, "工单已结案,不能转移负责人");
}
boolean statusIsChange = false;
if (csWorkOrderDO.getStatus() == CSWorkOrderStatus.Pending || csWorkOrderDO.getStatus() == CSWorkOrderStatus.Created) {
csWorkOrderDO.setStatus(CSWorkOrderStatus.Processing);
statusIsChange = true;
setOrderLevel(csWorkOrderDO, request.getToPrincipalUserId());
} else if (csWorkOrderDO.getStatus() == CSWorkOrderStatus.UpgradePending) {
csWorkOrderDO.setStatus(CSWorkOrderStatus.UpgradeProcessing);
statusIsChange = true;
}
csWorkOrderDO.setPrincipalUserId(request.getToPrincipalUserId());
csWorkOrderDO.setAllocateTime(new Date());
csWorkOrderDO.setCurrentDealUserId(request.getOperatorUserId());
User user = bossUserClient.queryByBossUserId(request.getToPrincipalUserId());
String suggestion = StringUtils.isEmpty(request.getReason()) ? String.format("转移至负责人【%s】", user.getUserName()) : request.getReason();
OpLogAddRequest logAddRequest = OpLogAddRequest.builder()
.workOrderId(request.getWorkOrderId())
.status(csWorkOrderDO.getStatus())
.operatorUserId(request.getOperatorUserId())
.suggestion(suggestion)
.build();
csWorkOrderLogService.insertOpLog(commanders, logAddRequest);
// 记录分配负责人链路
allocateHandleService.recordAllocationChain(csWorkOrderDO);
final boolean finalStatusIsChange = statusIsChange;
commanders.add(() -> {
CSExceptionAssert.isTrue(csWorkOrderDAO.updateByIdSelective(csWorkOrderDO) != null
, CSOrderBizErrorCode.SYSTEM_ERROR, "更新失败");
slaEscalationService.escalationTransferPrincipalPrincipalWorkOrderSla(csWorkOrderDO, finalStatusIsChange);
});
TodoTaskEvent todoTaskEvent = new TodoTaskEvent();
convertWorkOrderDO2TodoTaskEvent(csWorkOrderDO, todoTaskEvent);
//转移负责人后给代办发送消息
if (StringUtils.isNotEmpty(todoTaskEvent.getPrincipalUserId())) {
imqProvider.push(TodoTaskEvent.QUEUE_NAME, todoTaskEvent, QueueType.TOPIC);
}
//如果是协同工单需要发送消息
//云雀平台新协同工单
if (!Objects.isNull(csWorkOrderDO.getSkylarkCollaborationId())) {
//先通知工单变更处理人
skylarkManager.notifyChangePrincipal(csWorkOrderDO.getWorkorderId(), csWorkOrderDO.getSkylarkCollaborationId(), user.getBossUserId(), user.getUserName());
sendSkylarkCollaborationMessage(csWorkOrderDO, csWorkOrderDO.getSkylarkCollaborationId(), WorkOrderOptType.TRANSFER);
}
// else {
// sendCooperationMessage(csWorkOrderDO);
// sendCooperationMessageNew(csWorkOrderDO, WorkOrderOptType.TRANSFER);
// }
//转移负责人后把此时工单负责人移出队列
removeUser(request.getToPrincipalUserId());
//插入同步云雀服务中心逻辑
// authenticationNodeProducer.sendPrincipalChangeEvent(csWorkOrderDO);
return csWorkOrderDO.getWorkorderId();
}
public void convertWorkOrderDO2TodoTaskEvent(CSWorkOrderDO csWorkOrderDO, TodoTaskEvent todoTaskEvent) {
todoTaskEvent.setPrincipalUserId(csWorkOrderDO.getPrincipalUserId());
todoTaskEvent.setReferenceDomain(TodoTaskReferenceDomain.WORK_ORDER);
todoTaskEvent.setReferenceType(csWorkOrderDO.getWorkOrderConfigId());
todoTaskEvent.setReferenceId(csWorkOrderDO.getWorkorderId());
todoTaskEvent.setActionId(csWorkOrderDO.getWorkorderId());
todoTaskEvent.setFirmId(csWorkOrderDO.getFirmId());
if (finalCSWorkOrderStatus.contains(csWorkOrderDO.getStatus())) {
todoTaskEvent.setTodoTaskStatus(TodoTaskStatus.FINISHED);
} else {
todoTaskEvent.setTodoTaskStatus(TodoTaskStatus.NEW);
}
todoTaskEvent.setFirmName(csWorkOrderDO.getFirmName());
todoTaskEvent.setContactName(csWorkOrderDO.getUserId());
todoTaskEvent.setStartTime(new Date());
}
/**
* 新的协同类型工单均通过云雀交互,由此方法发送工单通知
*
* @param csWorkOrderDO
* @param collaborationId
* @param workOrderOptType
*/
private void sendSkylarkCollaborationMessage(CSWorkOrderDO csWorkOrderDO, String collaborationId, String workOrderOptType) {
if (Objects.isNull(csWorkOrderDO) || Objects.isNull(collaborationId)) {
return;
}
CollaborationVO collaborationVO = skylarkManager.getCollaborationDetail(collaborationId);
BizType initiator = BizType.valueOf(collaborationVO.getFrom().getBizType());
Optional<CoopWorkOrderMessageHandle> choose = coopWorkOrderMessageHolder.chooseByBizType(initiator);
if (!choose.isPresent()) {
return;
}
CoopWorkOrderDO coopWorkOrderDO = new CoopWorkOrderDO();
coopWorkOrderDO.setSoWorkOrderId(collaborationVO.getFrom().getBizOrderId());
coopWorkOrderDO.setSoCreatorId(collaborationVO.getFrom().getOperator().getBossUserId());
choose.get().sendMessage(csWorkOrderDO, coopWorkOrderDO, workOrderOptType);
}
public void judgeAndSendAgent(String recordId, String currentUserId, String principalUserId, String csWorkOrderId) {
final int NORMAL_PRIORITY = 20;
if (StringUtils.isBlank(principalUserId)
|| StringUtils.isBlank(currentUserId)
|| Objects.equals(currentUserId, principalUserId)) {
return;
}
BossUserInGroupReq bossUserInGroupReq = BossUserInGroupReq.builder()
.bossUserId(principalUserId)
.groupIds(Sets.newHashSet(secondGroup))
.build();
FacadeResponse<Boolean> response = bossUserGroupClient.bossUserInSpecifiedGroup(bossUserInGroupReq);
//如果 当前负责人不是资深客服组的 不创建钉钉代办
if (!response.isSucceeded() || Objects.equals(response.getValue(), false)) {
return;
}
User currentUser = bossUserClient.queryByBossUserId(currentUserId);
User principalUser = bossUserClient.queryByBossUserId(principalUserId);
if (currentUser == null || principalUser == null) {
return;
}
if (StringUtils.isBlank(currentUser.getUnionId()) || StringUtils.isBlank(principalUser.getUnionId())) {
return;
}
DingTalkTodoCreateRequest request = new DingTalkTodoCreateRequest();
request.setSourceId(recordId);
request.setSubject(TODO_TITLE);
request.setCreatorId(currentUser.getUnionId());
request.setDescription(String.format(TODO_DESC, workOrderUrlPre, csWorkOrderId));
request.setDueTime(System.currentTimeMillis() + 2 * 60 * 60 * 1000);
request.setExecutorIds(Lists.newArrayList(principalUser.getUnionId()));
request.setParticipantIds(Lists.newArrayList(principalUser.getUnionId()));
request.setDetailUrl(null);
request.setIsOnlyShowExecutor(true);
request.setPriority(NORMAL_PRIORITY);
DingTalkTodoNotifyConfigs dingTalkTodoNotifyConfigs = new DingTalkTodoNotifyConfigs();
dingTalkTodoNotifyConfigs.setDingNotify(DING_NOTIFY_TYPE);
request.setNotifyConfigs(dingTalkTodoNotifyConfigs);
request.setAppName(APP_NAME);
request.setRequestId(UuidUtil.getId());
request.setRequestSource(REQUEST_SOURCE);
gwDingTalkTodoClient.createDingTalkTodo(request);
}
public void judgeSaleSessionWorkOrderAndSendAgent(String recordId, String bossUserId, String principalUserId, String csWorkOrderId, String content) {
final int NORMAL_PRIORITY = 20;
if (StringUtils.isBlank(principalUserId)) {
return;
}
User user = bossUserClient.queryByBossUserId(bossUserId);
if (user == null) {
return;
}
User principalUser = bossUserClient.queryByBossUserId(principalUserId);
if (principalUser == null) {
return;
}
DingTalkTodoCreateRequest request = new DingTalkTodoCreateRequest();
request.setSourceId(recordId);
request.setSubject(TODO_TITLE);
request.setCreatorId(user.getUnionId());
request.setDescription(String.format(SALE_SESSION_WORK_ORDER_TODO_DESC, user.getUserName(), content, csWorkOrderId));
request.setDueTime(System.currentTimeMillis() + 2 * 60 * 60 * 1000);
request.setExecutorIds(Lists.newArrayList(principalUser.getUnionId()));
request.setParticipantIds(Lists.newArrayList(principalUser.getUnionId()));
request.setDetailUrl(null);
request.setIsOnlyShowExecutor(true);
request.setPriority(NORMAL_PRIORITY);
DingTalkTodoNotifyConfigs dingTalkTodoNotifyConfigs = new DingTalkTodoNotifyConfigs();
dingTalkTodoNotifyConfigs.setDingNotify(DING_NOTIFY_TYPE);
request.setNotifyConfigs(dingTalkTodoNotifyConfigs);
request.setAppName(APP_NAME);
request.setRequestId(UuidUtil.getId());
request.setRequestSource(REQUEST_SOURCE);
gwDingTalkTodoClient.createDingTalkTodo(request);
}
public void insertRecordTemplateLog(List<DataPersistenceCommander> commanders, RecordTemplateDO recordTemplateDO, RecordTemplateCreateRequest request) {
RecordTemplateOpLogDO recordTemplateOpLogDO = RecordTemplateOpLogDO.builder()
.opLogId(AttaIdUtils.getByProdCode(AttaIdUtils.ProdCode.CUSTOMER_SERVICE_WORKORDER_RECORD_TEMPLATE_LOG))
.templateId(recordTemplateDO.getTemplateId())
.opTime(new Date())
.opType(RecordTemplateOpType.CREATE)
.opUserId(request.getOperatorUserId())
.opSuggestion(getOpSuggestion(recordTemplateDO, RecordTemplateOpType.CREATE)).build();
commanders.add(() -> {
CSExceptionAssert.isTrue(csWorkOrderRecdTmplOpLogDAO.insert(recordTemplateOpLogDO) != null
, CSOrderBizErrorCode.SYSTEM_ERROR
, "insert recordTemplateOpLogDO failed.");
});
}
public void updateRecordTemplateLog(List<DataPersistenceCommander> commanders, RecordTemplateDO recordTemplateDO, RecordTemplateEditRequest request) {
RecordTemplateOpLogDO recordTemplateOpLogDO = RecordTemplateOpLogDO.builder()
.opLogId(AttaIdUtils.getByProdCode(AttaIdUtils.ProdCode.CUSTOMER_SERVICE_WORKORDER_RECORD_TEMPLATE_LOG))
.templateId(recordTemplateDO.getTemplateId())
.opTime(new Date())
.opType(RecordTemplateOpType.UPDATE)
.opUserId(request.getOperatorUserId())
.opSuggestion(getOpSuggestion(recordTemplateDO, RecordTemplateOpType.UPDATE)).build();
commanders.add(() -> {
CSExceptionAssert.isTrue(csWorkOrderRecdTmplOpLogDAO.insert(recordTemplateOpLogDO) != null
, CSOrderBizErrorCode.SYSTEM_ERROR
, "update recordTemplateOpLogDO failed.");
});
}
public String getOpSuggestion(RecordTemplateDO recordTemplateDO, RecordTemplateOpType type) {
if (null == recordTemplateDO) {
return "";
}
String formName = "";
StringBuilder relatedGroupName = new StringBuilder();
String recordTemplateName = recordTemplateDO.getTemplateName();
String status = recordTemplateDO.getStatus().getDesc();
if (StringUtils.isNotEmpty(recordTemplateDO.getFormId())) {
FacadeResponse<FormVO> facadeResponse = formServClient.queryDetails(recordTemplateDO.getFormId());
if (facadeResponse.isSucceeded() && null != facadeResponse.getValue()) {
formName = facadeResponse.getValue().getFormName();
}
}
if (!CollectionUtils.isEmpty(recordTemplateDO.getRelatedGroupId())) {
for (String groupId : recordTemplateDO.getRelatedGroupId()) {
BossUserGroupQueryRequest bossUserGroupQueryRequest = new BossUserGroupQueryRequest();
bossUserGroupQueryRequest.setPage(1);
bossUserGroupQueryRequest.setSize(1);
bossUserGroupQueryRequest.setGroupId(groupId);
FacadeResponse<PageSerializable<BossUserGroupVO>> facadeResponse = bossUserClient.listGroups(bossUserGroupQueryRequest);
if (facadeResponse.isSucceeded() && !CollectionUtils.isEmpty(facadeResponse.getValue().getList())) {
relatedGroupName.append(facadeResponse.getValue().getList().get(0).getGroupName()).append(",");
}
}
if (relatedGroupName.length() > 0) {
relatedGroupName.deleteCharAt(relatedGroupName.length() - 1);
}
}
String suggestion = "";
if (type.getDesc().equals(RecordTemplateOpType.CREATE.getDesc())) {
String createSuggestionTemplate = "名称【templateName】;关联表单【relatedForm】;关联用户组【relatedGroup】;状态【status】";
suggestion = createSuggestionTemplate.replace("templateName", recordTemplateName)
.replace("relatedForm", formName)
.replace("relatedGroup", relatedGroupName)
.replace("status", status);
} else {
RecordTemplateDO recordTemplateDO1 = csWorkOrderRecordTemplateDAO.findByTemplateId(recordTemplateDO.getTemplateId());
String formNameSrc = "";
StringBuilder relatedGroupNameSrc = new StringBuilder();
String recordTemplateNameSrc = recordTemplateDO1.getTemplateName();
String statusSrc = recordTemplateDO1.getStatus().getDesc();
if (StringUtils.isNotEmpty(recordTemplateDO1.getFormId())) {
FacadeResponse<FormVO> facadeResponse = formServClient.queryDetails(recordTemplateDO1.getFormId());
if (facadeResponse.isSucceeded() && null != facadeResponse.getValue()) {
formNameSrc = facadeResponse.getValue().getFormName();
}
}
if (!CollectionUtils.isEmpty(recordTemplateDO1.getRelatedGroupId())) {
for (String groupId : recordTemplateDO1.getRelatedGroupId()) {
BossUserGroupQueryRequest bossUserGroupQueryRequest = new BossUserGroupQueryRequest();
bossUserGroupQueryRequest.setPage(1);
bossUserGroupQueryRequest.setSize(1);
bossUserGroupQueryRequest.setGroupId(groupId);
FacadeResponse<PageSerializable<BossUserGroupVO>> facadeResponse = bossUserClient.listGroups(bossUserGroupQueryRequest);
if (facadeResponse.isSucceeded() && !CollectionUtils.isEmpty(facadeResponse.getValue().getList())) {
relatedGroupNameSrc.append(facadeResponse.getValue().getList().get(0).getGroupName()).append(",");
}
}
if (relatedGroupNameSrc.length() > 0) {
relatedGroupNameSrc.deleteCharAt(relatedGroupNameSrc.length() - 1);
}
}
StringBuilder sb = new StringBuilder();
if (!recordTemplateName.equals(recordTemplateNameSrc)) {
sb.append("名称【").append(recordTemplateNameSrc).append("->").append(recordTemplateName).append(";】");
}
if (!formName.equals(formNameSrc)) {
sb.append("关联表单【").append(formNameSrc).append("->").append(formName).append(";】");
}
if (!relatedGroupName.toString().equals(relatedGroupNameSrc.toString())) {
sb.append("关联用户组【").append(relatedGroupNameSrc).append("->").append(relatedGroupName).append(";】");
}
if (!status.equals(statusSrc)) {
sb.append("状态【").append(statusSrc).append("->").append(status).append(";】");
}
suggestion = sb.toString();
}
return suggestion;
}
private CSWorkOrderOpLogDO createdOpLogDO(String workOrderId, CSWorkOrderStatus status, String operatorUserId, String suggestion) {
CSWorkOrderOpLogDO opLogDO = new CSWorkOrderOpLogDO();
opLogDO.setOpLogId(AttaIdUtils.getByProdCode(AttaIdUtils.ProdCode.CUSTOMER_SERVICE_WORKORDER_OP_LOG));
opLogDO.setOperatorUserId(operatorUserId);
if (StringUtils.isEmpty(operatorUserId)) {
opLogDO.setOperatorUserId("system");
}
opLogDO.setOpTime(new Date());
opLogDO.setStatus(status.name());
opLogDO.setSuggestion(suggestion);
opLogDO.setWorkorderId(workOrderId);
return opLogDO;
}
private boolean updateWorkOrder(CSWorkOrderDO workOrderDO, CSWorkOrderOpLogDO opLogDO) {
boolean isGeneratedByTag = isGeneratedByTag(workOrderDO.getWorkOrderConfigId());
Boolean result = mongoTransactionTemplate.execute(status -> {
try {
CSWorkOrderOpLogDO insertRes = csWorkOrderOpLogDAO.insert(opLogDO);
if (insertRes == null) {
status.setRollbackOnly();
return false;
}
CSWorkOrderDO updateRes = csWorkOrderDAO.updateByIdSelective(workOrderDO);
if (updateRes == null) {
status.setRollbackOnly();
return false;
}
ActionDO actionDO = actionDAO.find(new Query(Criteria.where("sceneId").is(updateRes.getWorkorderId())))
.stream().max(Comparator.comparing(ActionDO::getLastUpdateDate)).orElse(null);
if (actionDO == null) {
status.setRollbackOnly();
return false;
}
Map<String, Object> actionRes = new HashMap<>();
actionRes.put(PRE_AUDIT_RESULT, "NoPass");
actionRes.put("preAuditSuggestion", "BDM预审驳回");
actionRes.put("skipPreAudit", "no");
actionRes.put("specialPermit", "no");
actionDO.setActionResults(actionRes);
if (actionDAO.updateByIdSelective(actionDO) == null) {
log.warn("update action fail, actionId : {}", actionDO.getActionId());
throw new CustomerServiceException(CSOrderSystemErrorCode.UpdateError, CSOrderBizErrorCode.BUSINESS_DATA_NOT_EXISTS, "update action fail");
}
addWorkOrderInstructions(workOrderDO, actionDO, isGeneratedByTag);
} catch (Exception e) {
status.setRollbackOnly();
return false;
}
return true;
});
return result != null && result;
}
/**
* 判断该类型的工单是否为打标后生成
*/
private boolean isGeneratedByTag(String workOrderConfigId) {
CSExceptionAssert.isTrue(StringUtils.isNotEmpty(workOrderConfigId)
, CSOrderBizErrorCode.VALIDATION_ERROR, "workOrderConfigId should not be empty");
WorkOrderAndTagRelationVO relationVO = workOrderConfigAndTagRelationService.getTagAndOrderConfigRelationByConfigId(workOrderConfigId);
return relationVO != null;
}
public void addWorkOrderInstructions(CSWorkOrderDO csWorkOrderDO, ActionDO actionDO, boolean isGeneratedByTag) {
// if (actionDO != null && !CollectionUtils.isEmpty(actionDO.getActionResults()) && actionDO.getActionResults().containsValue(CsOrderConstants.LENGTHEN)) {
// workOrderInstructionDAO.insertInstruction(csWorkOrderDO.getWorkorderId(), WorkOrderInstructionType.ExtendTagValidTime);
// }
if (isGeneratedByTag) {
workOrderInstructionDAO.insertInstruction(csWorkOrderDO.getWorkorderId(), WorkOrderInstructionType.CloseTag);
}
if (actionDO != null && (FIRST_AUDIT_TOW.equals(actionDO.getTagValue()) || UPDATE_AUDIT.equals(actionDO.getTagValue()) ||
FIRM_SHAREHOLDER_AUDIT.equals(actionDO.getTagValue())
|| WEALTH_MANAGEMENT_AUDIT_PRE.equals(actionDO.getTagValue()) || CUSTOMER_ANNUAL_AUDIT.equals(actionDO.getTagValue()))) {
workOrderInstructionDAO.insertInstruction(csWorkOrderDO.getWorkorderId(), WorkOrderInstructionType.PreAudit);
}
if (isPreAuditWorkOrder(csWorkOrderDO) && null != csWorkOrderDO.getExpediteType()) {
workOrderInstructionDAO.insertInstruction(csWorkOrderDO.getWorkorderId(), WorkOrderInstructionType.ExpediteWorkOrder);
}
// add track record 根据工单类型判断
// CSWorkOrderConfigDO orderConfigDO = csWorkOrderConfigDAO.queryByWOConfigIdIgnoreStatus(csWorkOrderDO.getWorkOrderConfigId());
// String workOrderType = orderConfigDO.getWorkorderType();
// if (Sets.newHashSet(SellerWorkOrderEnum.CUSTOMER_FIRST_VISIT.getDesc(), SellerWorkOrderEnum.CUSTOMER_SECOND_VISIT.getDesc(),
// SellerWorkOrderEnum.CUSTOMER_THIRD_VISIT.getDesc()).contains(workOrderType)) {
// workOrderInstructionDAO.insertInstruction(csWorkOrderDO.getWorkorderId(), WorkOrderInstructionType.customerTrackRecord);
// }
}
/**
* 判断是否是预审工单
*
* @param workOrderDO
* @return
*/
private boolean isPreAuditWorkOrder(CSWorkOrderDO workOrderDO) {
CSExceptionAssert.isTrue(StringUtils.isNotBlank(workOrderDO.getWorkOrderConfigId())
, CSOrderBizErrorCode.VALIDATION_ERROR
, "workOrderConfigId is empty. workOrderId is: " + workOrderDO.getWorkorderId());
CSWorkOrderConfigDO configDO = csWorkOrderConfigDAO.queryByWOConfigIdIgnoreStatus(workOrderDO.getWorkOrderConfigId());
return WorkOrderConfigType.CertificationPreAudit.name().equals(configDO.getConfigType())
|| WorkOrderConfigType.UpdateCertificationPreAudit.name().equals(configDO.getConfigType())
|| WorkOrderConfigType.FinancePreAudit.name().equals(configDO.getConfigType())
|| WorkOrderConfigType.MainLandFxPreAudit.name().equals(configDO.getConfigType())
|| WorkOrderConfigType.CustomerAnnualPreAudit.name().equals(configDO.getConfigType());
}
private void doInstruction(String workOrderId) {
try {
cSWorkOrderInstructionService.doUnSuccessStatusInstruction(workOrderId);
} catch (Exception e) {
log.error("do process failed. e: ", e);
}
}
//获取预审结果
private String obtainPreAudit(String workOrderId) {
Set<String> preSet = Sets.newHashSet(FIRST_AUDIT_TOW, UPDATE_AUDIT);
ActionDO actionDO = actionDAO.getLastUpdateActionBySceneId(workOrderId);
return Optional.ofNullable(actionDO)
.filter(item -> (preSet.contains(actionDO.getTagValue()) && actionDO.getActionResults() != null))
.map(item -> String.valueOf(actionDO.getActionResults().get(PRE_AUDIT_RESULT)))
.orElse(null);
}
private boolean preAuditNeedCheck(String workOrderId) {
return Objects.equals(obtainPreAudit(workOrderId), PASS_RESULT);
}
private FacadeResponse<CSWorkOrderVO> toWorkOrderVOListOpt(CSWorkOrderDO workOrderDO, List<User> bossUsers, List<ActionDO> actionDOs) {
if (workOrderDO == null || CollectionUtils.isEmpty(bossUsers)) {
return null;
}
CSWorkOrderVO csWorkOrderVO = WorkOrderConverter.toWorkOrderVO(workOrderDO);
//有云雀协同单Id就是新协同UI展示
csWorkOrderVO.setNewCollaboration(true);
//TODO 迁移变更:检查工单是否存在老coop协同,存在老ui协同逻辑
// else if (existOldCoop(workOrderDO.getWorkorderId())) {
// csWorkOrderVO.setNewCollaboration(false);
// } else {
// csWorkOrderVO.setNewCollaboration(true);
// }
// //灰度开关
// if (grayscaleDataSwitch) {
// csWorkOrderVO.setNewCollaboration(false);
// }
if (StringUtils.isEmpty(csWorkOrderVO.getFirmId())) {
String userLoginMobile = getUserLoginMobile(csWorkOrderVO.getFirmId());
if (null != userLoginMobile) {
csWorkOrderVO.setPhone(userLoginMobile);
}
}
converVideoUrl(csWorkOrderVO);
if (!Strings.isNullOrEmpty(workOrderDO.getPrincipalUserId())) {
Optional<User> bossPrincipalUser = bossUsers.stream().filter(t -> t.getBossUserId().equals(workOrderDO.getPrincipalUserId())).findFirst();
if (bossPrincipalUser.isPresent()) {
csWorkOrderVO.setPrincipalUserId(bossPrincipalUser.get().getBossUserId());
csWorkOrderVO.setPrincipalUserName(bossPrincipalUser.get().getUserName());
}
}
if (!Strings.isNullOrEmpty(workOrderDO.getCurrentDealUserId())) {
Optional<User> bossCurrentDealUser = bossUsers.stream().filter(t -> t.getBossUserId().equals(workOrderDO.getCurrentDealUserId())).findFirst();
if (bossCurrentDealUser.isPresent()) {
csWorkOrderVO.setCurrentDealUserId(bossCurrentDealUser.get().getBossUserId());
csWorkOrderVO.setCurrentDealUserName(bossCurrentDealUser.get().getUserName());
}
}
CSWorkOrderConfigDO workOrderTypeDO = findConfigOne(workOrderDO.getWorkOrderConfigId());
if (workOrderTypeDO != null) {
csWorkOrderVO.setWorkorderTypeVO(WorkOrderConverter.toWorkOrderTypeVO(workOrderTypeDO));
}
CSWorkOrderCommRecordQueryRequest request = new CSWorkOrderCommRecordQueryRequest();
request.setWorkorderId(workOrderDO.getWorkorderId());
request.setSize(1);
request.setPage(1);
Page<CSWorkOrderCommRecordDO> commRecordDOS = csWorkOrderCommRecordDAO.findPage(
new Query().addCriteria(Criteria.where("workorderId").is(request.getWorkorderId())).with(Sort.by(Sort.Direction.DESC, CSWorkOrderCommRecordDO.CREATION_DATE)),
request.getPage(),
request.getSize());
Set<String> bossUserIds = commRecordDOS.stream().map(CSWorkOrderCommRecordDO::getOperator).filter(operator -> !StringUtils.isEmpty(operator)).collect(Collectors.toSet());
List<User> users = bossUsers.stream().filter(t -> bossUserIds.contains(t.getBossUserId())).collect(Collectors.toList());
Map<String, String> userIdAndUserNameMap = users.stream().collect(Collectors.toMap(User::getBossUserId, User::getUserName, (k, v) -> k));
List<CSWorkorderCommRecordVO> commRecordVOS = commRecordDOS
.stream().map(commRecordDO -> {
CSWorkorderCommRecordVO commRecordVO = WorkOrderConverter.toCommRecordVO(commRecordDO);
if (!StringUtils.isEmpty(commRecordDO.getOperator())) {
commRecordVO.setOperator(userIdAndUserNameMap.get(commRecordDO.getOperator()));
}
return commRecordVO;
})
.collect(Collectors.toList());
//预审核结果
Optional<ActionDO> actionDO = actionDOs.stream().filter(t -> t.getSceneId().equals(workOrderDO.getWorkorderId())).findFirst();
if (actionDO.isPresent() && !CollectionUtils.isEmpty(actionDO.get().getActionResults())) {
Object preAuditResult = actionDO.get().getActionResults().get(PRE_AUDIT_RESULT);
Object preAuditSuggestion = actionDO.get().getActionResults().get("preAuditSuggestion");
Object preAuditRemark = actionDO.get().getActionResults().get("preAuditRemark");
csWorkOrderVO.setPreAuditResult(null == preAuditResult ? null : String.valueOf(preAuditResult));
csWorkOrderVO.setPreAuditSuggestion(null == preAuditSuggestion ? null : String.valueOf(preAuditSuggestion));
csWorkOrderVO.setPreAuditRemark(null == preAuditRemark ? null : String.valueOf(preAuditRemark));
}
// 查询协同发起人
// 风控
// Optional<CooperationWorkOrderDO> cooperationWorkOrderDO = cooperationWorkOrderDOs.stream().filter(t -> t.getCooperationOrderId().equals(workOrderDO.getWorkorderId())).findFirst();
// if (cooperationWorkOrderDO.isPresent()) {
// csWorkOrderVO.setCooSponsor(cooperationWorkOrderDO.get().getCreatorName());
// csWorkOrderVO.setSource(WorkOrderSource.RISK);
// } else {
// //
// CoopWorkOrderDO coopWorkOrderDO = coopWorkOrderDAO.queryByCoWorkOrderId(workOrderDO.getWorkorderId());
// if (!ObjectUtils.isEmpty(coopWorkOrderDO)) {
// csWorkOrderVO.setCooSponsor(coopWorkOrderDO.getSoCreatorName());
// if (Objects.equals(coopWorkOrderDO.getSoDepartmentId(), DepartmentConstant.CUSTOMER_ASSET)) {
// csWorkOrderVO.setSource(WorkOrderSource.CUSTOMER_ASSET);
// }
// }
// }
if (CollectionUtils.isEmpty(commRecordVOS) && !emailCsWorkOrderConfigIds.contains(workOrderDO.getWorkOrderConfigId())) {
return getFacadeResponseWithValue(csWorkOrderVO);
}
csWorkOrderVO.setCsWorkorderCommRecordVOS(commRecordVOS);
CSWorkOrderReceiveEmailRecordDO receiveEmailRecordDO = csWorkOrderReceiveEmailRecordDAO.
queryLastByWorkOrderId(workOrderDO.getWorkorderId());
if (Objects.isNull(receiveEmailRecordDO)) {
return getFacadeResponseWithValue(csWorkOrderVO);
}
csWorkOrderVO.setEmailType(receiveEmailRecordDO.getType());
if (CollectionUtils.isEmpty(commRecordVOS)) {
CSWorkorderCommRecordVO csWorkorderCommRecordVO = new CSWorkorderCommRecordVO();
csWorkorderCommRecordVO.setContent(receiveEmailRecordDO.getSubject());
csWorkorderCommRecordVO.setCreatedTime(receiveEmailRecordDO.getCreationDate());
commRecordVOS.add(csWorkorderCommRecordVO);
return getFacadeResponseWithValue(csWorkOrderVO);
}
CSWorkorderCommRecordVO csWorkorderCommRecordVO = commRecordVOS.get(0);
if (Objects.nonNull(receiveEmailRecordDO.getCreationDate()) &&
Objects.nonNull(csWorkorderCommRecordVO.getCreatedTime()) &&
receiveEmailRecordDO.getCreationDate().after(csWorkorderCommRecordVO.getCreatedTime())) {
csWorkorderCommRecordVO.setContent(receiveEmailRecordDO.getSubject());
csWorkorderCommRecordVO.setCreatedTime(receiveEmailRecordDO.getCreationDate());
}
return getFacadeResponseWithValue(csWorkOrderVO);
}
private CSWorkOrderVO toWorkOrderVO(CSWorkOrderDO workOrderDO) {
if (workOrderDO == null) {
return null;
}
CSWorkOrderVO workOrderVO = WorkOrderConverter.toWorkOrderVO(workOrderDO);
//有云雀协同单Id就是新协同UI展示
workOrderVO.setNewCollaboration(true);
//TODO 迁移变更:检查工单是否存在老coop协同,存在老ui协同逻辑
// else if (existOldCoop(workOrderDO.getWorkorderId())) {
// workOrderVO.setNewCollaboration(false);
// } else {
// workOrderVO.setNewCollaboration(true);
// }
// //灰度开关
// if (grayscaleDataSwitch) {
// workOrderVO.setNewCollaboration(false);
// }
String userLoginMobile = getUserLoginMobile(workOrderVO.getUserId());
if (null != userLoginMobile) {
workOrderVO.setPhone(userLoginMobile);
}
converVideoUrl(workOrderVO);
if (Objects.equals(workOrderDO.getAccountType(), FundAccountTypeEnum.PERSONAL.name())
&& StringUtils.isNotBlank(workOrderDO.getUserAccountId())) {
FacadeResponse<FundAccountVO> accountRes = fundAccountClient.queryAccountByAccountId(workOrderDO.getUserAccountId());
if (accountRes.isSucceeded() && accountRes.getValue() != null) {
workOrderVO.setAccountEnglishName(accountRes.getValue().getAccountEnglishName());
}
}
if (!Strings.isNullOrEmpty(workOrderDO.getPrincipalUserId())) {
User bossPrincipalUser = bossUserClient.queryByBossUserId(workOrderDO.getPrincipalUserId());
if (bossPrincipalUser != null) {
workOrderVO.setPrincipalUserId(bossPrincipalUser.getBossUserId());
workOrderVO.setPrincipalUserName(bossPrincipalUser.getUserName());
}
}
if (!Strings.isNullOrEmpty(workOrderDO.getCurrentDealUserId())) {
User bossCurrentDealUser = bossUserClient.queryByBossUserId(workOrderDO.getCurrentDealUserId());
if (bossCurrentDealUser != null) {
workOrderVO.setCurrentDealUserId(bossCurrentDealUser.getBossUserId());
workOrderVO.setCurrentDealUserName(bossCurrentDealUser.getUserName());
}
}
//TODO 迁移变更:删除了opLogVOS和commRecordVOS的循环获取
// List<CSWorkorderOpLogVO> opLogVOS = csWorkOrderOpLogDAO
// .find(new Query().addCriteria(Criteria.where("workorderId").is(workOrderDO.getWorkorderId()))).stream().map(opLogDO -> {
// CSWorkorderOpLogVO opLogVO = WorkOrderConverter.toOpLogVO(opLogDO);
//
// if (SYSTEM.equals(opLogVO.getOperatorUserId())) {
// opLogVO.setOperatorUserName(SYSTEM);
// } else {
// User bossUser = bossUserClient.queryByBossUserId(opLogVO.getOperatorUserId());
// if (bossUser != null) {
// opLogVO.setOperatorUserName(bossUser.getUserName());
// }
// }
// return opLogVO;
// }).collect(Collectors.toList());
//
// workOrderVO.setWorkorderOpLogVOS(opLogVOS);
List<CSWorkorderCommRecordVO> commRecordVOS = commRecordService.getCommRecordsByWorkOrderId(workOrderVO.getWorkorderId());
workOrderVO.setCsWorkorderCommRecordVOS(commRecordVOS);
CSWorkOrderConfigDO workOrderTypeDO = findConfigOne(workOrderDO.getWorkOrderConfigId());
if (workOrderTypeDO != null) {
workOrderVO.setWorkorderTypeVO(WorkOrderConverter.toWorkOrderTypeVO(workOrderTypeDO));
}
try {
workOrderVO.setAttachmentVOList(attachmentFacade.getFileByReferenceId(workOrderDO.getWorkorderId()));
} catch (Exception e) {
log.error(e.getMessage());
}
CSWorkOrderConfigDO csWorkOrderConfigDO = csWorkOrderConfigDAO.queryByWOConfigIdIgnoreStatus(workOrderDO.getWorkOrderConfigId());
workOrderVO.setProblemType(Optional.ofNullable(csWorkOrderConfigDO).map(CSWorkOrderConfigDO::getProblemType).orElse(null));
//客服工作台
workOrderVO.setCurrTodoType(workOrderDO.getCurrTodoType());
workOrderVO.setCurrProcessType(workOrderDO.getCurrProcessType());
workOrderVO.setCurrProcessDeadline(workOrderDO.getCurrProcessDeadline());
workOrderVO.setCurrProcessDeadlinePre(workOrderDO.getCurrProcessDeadlinePre());
//咨询进度
workOrderVO.setCustomerShowSwitch(workOrderDO.getCustomerShowSwitch());
workOrderVO.setReceiptTradeId(workOrderDO.getReceiptTradeId());
//预约时间从跟进记录里获取
resetFeedbackTime(workOrderVO);
workOrderVO.setUpgradeSource(workOrderDO.getUpgradeSource());
return workOrderVO;
}
private void resetFeedbackTime(CSWorkOrderVO workOrderVO) {
workOrderVO.setFeedbackTime(cswoSlaEventService.getSlaFeedbackTime(workOrderVO.getWorkorderId()));
}
/**
* 获取预审工单对应相同客户的历史预审工单列表
*
* @param workOrderDO
* @return
*/
private List<CSWorkOrderVO> getHistoryPreAuditWorkOrders(CSWorkOrderDO workOrderDO) {
if (!isPreAuditWorkOrder(workOrderDO)) {
return null;
}
//获取同一客户的预审工单
//根据最后修改时间排序
List<CSWorkOrderDO> workOrderDOList = csWorkOrderDAO.find(new Query().addCriteria(Criteria.where("workOrderConfigId").in(getPreAuditConfigIds()).and("userId").is(workOrderDO.getUserId())))
.stream()
.sorted(Comparator.comparing(CSWorkOrderDO::getLastUpdateDate, Comparator.nullsLast(Date::compareTo)))
.collect(Collectors.toList());
// 判断是否为客户成功-客户审核类型的工单
if (customerAuditConfigId.contains(workOrderDO.getWorkOrderConfigId())) {
List<CSWorkOrderDO> operatingWorkOrderDOList = csWorkOrderDAO.find(new Query().addCriteria(Criteria.where(CSWorkOrderDO.WORK_ORDER_CONFIG_ID).in(preAuditConfigIds).and(CSWorkOrderDO.FIRM_ID).is(workOrderDO.getFirmId())))
.stream()
.sorted(Comparator.comparing(CSWorkOrderDO::getLastUpdateDate, Comparator.nullsLast(Date::compareTo)))
.collect(Collectors.toList());
if (!CollectionUtils.isEmpty(operatingWorkOrderDOList)) {
workOrderDOList.addAll(operatingWorkOrderDOList);
}
}
if (CollectionUtils.isEmpty(workOrderDOList)) {
return null;
}
List<CSWorkOrderVO> csWorkOrderVOList = Lists.newArrayList();
for (CSWorkOrderDO csWorkOrderDO : workOrderDOList) {
FacadeResponse<CSWorkOrderVO> response = toWorkOrderVOList(csWorkOrderDO);
if (response.isSucceeded()) {
csWorkOrderVOList.add(response.getValue());
}
}
return csWorkOrderVOList;
}
/**
* 查询预审工单配置id集合
*
* @return
*/
private Set<String> getPreAuditConfigIds() {
Query query = new Query();
query.addCriteria(Criteria.where(CSWorkOrderConfigDO.BUSINESS_TYPE).is(BusinessType.CUSTOMER_SUCCESS)
.and(CSWorkOrderConfigDO.WORK_ORDER_TYPE).is("客户审核")
.and(CSWorkOrderConfigDO.PROBLEM_TYPE).in("首次认证预审核", "更新认证预审核", "理财业务预审核", "客户年审预审核"));
List<CSWorkOrderConfigDO> configs = csWorkOrderConfigDAO.find(query);
return CollectionUtils.isEmpty(configs) ? Sets.newHashSet() : configs.stream().map(CSWorkOrderConfigDO::getConfigId).collect(Collectors.toSet());
}
private FacadeResponse validate(Object object) {
ValidateResult validateResult = ValidateUtil.validate(object);
if (!validateResult.isPassed()) {
return getFacadeResponseWithFailed(AttaResponseCode.VALIDATION_ERROR, validateResult.getField() + validateResult.getReason());
} else {
return getFacadeResponseWithSuccess();
}
}
private void buildSomePartQuery(CSWorkOrderPageListRequest request, Query configQuery) {
if (null != request.getWorkOrderDomain()) {
if (WorkOrderDomain.CS_WORK_ORDER.equals(request.getWorkOrderDomain())) {
Criteria configCriteria = new Criteria();
if (request.getBusinessType() == null) {
Criteria orCriteria1 = Criteria.where(CSWorkOrderConfigDO.BUSINESS_TYPE).ne(BusinessType.CUSTOMER_SUCCESS);
Criteria orCriteria2 = Criteria.where(CSWorkOrderConfigDO.WORK_ORDER_TYPE).ne("客户审核").and(CSWorkOrderConfigDO.BUSINESS_TYPE).is(BusinessType.CUSTOMER_SUCCESS);
configCriteria.orOperator(orCriteria1, orCriteria2);
} else if (request.getBusinessType() == BusinessType.CUSTOMER_SUCCESS) {
configCriteria = Criteria.where(CSWorkOrderConfigDO.BUSINESS_TYPE).is(BusinessType.CUSTOMER_SUCCESS)
.and(CSWorkOrderConfigDO.WORK_ORDER_TYPE).ne("客户审核");
} else {
configCriteria = Criteria.where(CSWorkOrderConfigDO.BUSINESS_TYPE).is(request.getBusinessType());
if (StringUtils.isNotBlank(request.getWorkorderType())) {
configQuery.addCriteria(Criteria.where(CSWorkOrderConfigDO.WORK_ORDER_TYPE).is(request.getWorkorderType()));
}
}
configQuery.addCriteria(configCriteria);
}
if (WorkOrderDomain.PRE_CS_WORK_ORDER.equals(request.getWorkOrderDomain())) {
configQuery.addCriteria(Criteria.where(CSWorkOrderConfigDO.BUSINESS_TYPE).is(BusinessType.CUSTOMER_SUCCESS));
configQuery.addCriteria(Criteria.where(CSWorkOrderConfigDO.WORK_ORDER_TYPE).is("客户审核"));
}
} else if (request.getBusinessType() != null || !StringUtils.isEmpty(request.getWorkorderType())) {
if (request.getBusinessType() != null) {
configQuery.addCriteria(Criteria.where("businessType").is(request.getBusinessType().name()));
}
if (!StringUtils.isEmpty(request.getWorkorderType())) {
configQuery.addCriteria(Criteria.where(CSWorkOrderConfigDO.WORK_ORDER_TYPE).is(request.getWorkorderType()));
}
}
}
private FacadeResponse<CSWorkOrderConfigDO> validateBaseCsWorkOrder(CSWorkOrderBaseRequest request) {
FacadeResponse validate = validate(request);
if (!validate.isSucceeded()) {
return validate;
}
CSWorkOrderConfigDO csWorkOrderConfigDO = csWorkOrderConfigDAO.findOne(MongoQueryFactory.create(request));
if (csWorkOrderConfigDO == null || csWorkOrderConfigDO.getConfigId() == null) {
return getFacadeResponseWithFailed(AttaResponseCode.WORK_ORDER_NOT_FUND, "未知工单配置");
}
FacadeResponse<CSWorkOrderConfigDO> success = new FacadeResponse<>();
success.setSucceeded(true);
success.setValue(csWorkOrderConfigDO);
return success;
}
private CSWorkOrderDO createdCSWorkOrderDO(String referenceId, String configId, String mid, String firmId, String firmName, String userId, String principalUserId, String phoneAreaCode, String newPhoneAreaCode) {
CSWorkOrderDO csWorkOrderDO = new CSWorkOrderDO();
csWorkOrderDO.setWorkorderId(getWorkOrderId());
csWorkOrderDO.setReferenceId(referenceId);
csWorkOrderDO.setWorkOrderConfigId(configId);
csWorkOrderDO.setMid(mid);
csWorkOrderDO.setFirmId(firmId);
csWorkOrderDO.setFirmName(firmName);
csWorkOrderDO.setUserId(userId);
csWorkOrderDO.setPrincipalUserId(principalUserId);
csWorkOrderDO.setNewCollaboration(CsOrderConstants.newCollaboration);
if (StringUtils.isNotEmpty(phoneAreaCode)) {
csWorkOrderDO.setPhoneAreaCode(phoneAreaCode);
}
if (StringUtils.isNotEmpty(newPhoneAreaCode)) {
csWorkOrderDO.setNewPhoneAreaCode(newPhoneAreaCode);
}
return csWorkOrderDO;
}
private CSWorkOrderCommRecordDO createCommRecordDO(String workOrderId
, String userId
, String content
, List<AttachmentVO> attachments
, Set<String> callCenterIds) {
if (Strings.isNullOrEmpty(content) && CollectionUtils.isEmpty(attachments)) {
return null;
}
CSWorkOrderCommRecordDO commRecordDo = new CSWorkOrderCommRecordDO();
commRecordDo.setRecordId(AttaIdUtils.getByProdCode(AttaIdUtils.ProdCode.CUSTOMER_SERVICE_WORKORDER_COMM_RECORD));
commRecordDo.setOperator(userId);
commRecordDo.setWorkorderId(workOrderId);
commRecordDo.setContent(content);
commRecordDo.setCallCenterIds(callCenterIds);
if (!CollectionUtils.isEmpty(attachments)) {
attachments.forEach(attachmentVO -> attachmentVO.setReferenceId(commRecordDo.getRecordId()));
try {
Assert.isTrue(attachmentFacade.submitAddedAttachment(attachments), "insert attachment failed.");
} catch (Exception e) {
log.error("insert attachment failed.e: ", e);
}
}
return commRecordDo;
}
private boolean insertWO(CSWorkOrderDO workOrderDO,
CSWorkOrderCommRecordDO commRecordDo,
CSWorkOrderOpLogDO opLogDO) {
boolean isOk = transactionUtil.executeMongo(() -> {
CSExceptionAssert.isTrue(csWorkOrderOpLogDAO.insert(opLogDO) != null
, CSOrderBizErrorCode.SYSTEM_ERROR
, "insert opLogDO failed.");
CSExceptionAssert.isTrue(csWorkOrderDAO.insert(workOrderDO) != null
, CSOrderBizErrorCode.SYSTEM_ERROR
, "insert workOrderDO failed.");
if (commRecordDo != null) {
CSExceptionAssert.isTrue(csWorkOrderCommRecordDAO.insert(commRecordDo) != null
, CSOrderBizErrorCode.SYSTEM_ERROR
, "insert commRecordDo failed.");
}
});
if (isOk) {
workorderMessageProducer.sendPreAuditStatusEvent(workOrderDO);
if (finalCSWorkOrderStatus.contains(workOrderDO.getStatus())) {
try {
workorderMessageProducer.closeCustomerTag(workOrderDO);
} catch (Exception e) {
log.error("close customer Tag failed. e: ", e);
}
}
}
return isOk;
}
@Autowired
private UserSecureInfoClient userSecureInfoClient;
@Autowired
private ApprovalClient approvalClient;
public FacadeResponse checkPhoneAvailable(String phoneAreaCode, String phone, String newPhoneAreaCode,String newPhone) {
if (phone == null) {
return getFacadeResponseWithFailed(AttaResponseCode.BIZ_ERROR, "该商户未绑定手机号, 修改手机号失败");
}
if(StringUtils.isEmpty(phoneAreaCode)){
phoneAreaCode = DEFAULT_PHONE_AREA_CODE;
}
if(StringUtils.isEmpty(newPhoneAreaCode)){
newPhoneAreaCode = DEFAULT_PHONE_AREA_CODE;
}
if (newPhone == null) {
return getFacadeResponseWithFailed(AttaResponseCode.BIZ_ERROR, "请输入正确的新手机号");
}
if (phoneAreaCode.equalsIgnoreCase(newPhoneAreaCode) && newPhone.equalsIgnoreCase(phone)) {
return getFacadeResponseWithFailed(AttaResponseCode.BIZ_ERROR, "请输入正确的新手机号");
}
//校验老手机号 是否在使用
PhoneNumberVO phoneNumberVO = new PhoneNumberVO();
phoneNumberVO.setDialingCode(phoneAreaCode);
phoneNumberVO.setNumber(phone);
FacadeResponse<UsernameInfo> oldUsernameInfo = userSecureInfoClient.loadUsernameInfo(phoneNumberVO);
if (!oldUsernameInfo.isSucceeded()) {
log.error("remote get userInfo by phone error,{}", oldUsernameInfo.getResponseMsg());
return getFacadeResponseWithFailed(AttaResponseCode.SYSTEM_ERROR);
}
if (oldUsernameInfo.getValue() == null) {
return getFacadeResponseWithFailed(AttaResponseCode.BIZ_ERROR, "该商户绑定手机号不存在");
}
//校验新手机号是否存在
PhoneNumberVO newPhoneNumberVO = new PhoneNumberVO();
newPhoneNumberVO.setDialingCode(newPhoneAreaCode);
newPhoneNumberVO.setNumber(newPhone);
FacadeResponse<UsernameInfo> loadUsernameInfo = userSecureInfoClient.loadUsernameInfo(newPhoneNumberVO);
if (!loadUsernameInfo.isSucceeded()) {
log.error("remote get userInfo by phone error,{}", loadUsernameInfo.getResponseMsg());
return getFacadeResponseWithFailed(AttaResponseCode.SYSTEM_ERROR);
}
if (loadUsernameInfo.getValue() != null) {
return getFacadeResponseWithFailed(AttaResponseCode.BIZ_ERROR, "该手机号已被占用");
}
return getFacadeResponseWithSuccess();
}
private CSWorkOrderDO checkSubsistingWorkOrder(String configId, String userId) {
Criteria criteria = new Criteria();
criteria.and("status").nin(Lists.newArrayList("Completed", "Cancelled"));
criteria.and("workOrderConfigId").is(configId);
criteria.and("userId").is(userId);
return csWorkOrderDAO.findOne(new Query().addCriteria(criteria));
}
private void sendApproval(String bizId, String bizType, String currentDealUserId, String currentDealUserName) {
ApprovalRequestCreateRequest approvalRequest = new ApprovalRequestCreateRequest();
approvalRequest.setBizId(bizId);
approvalRequest.setBizType(bizType);
approvalRequest.setCreatorUserId(currentDealUserId);
approvalRequest.setCreatorUserName(currentDealUserName);
CompletableFuture.runAsync(() -> {
try {
FacadeResponse approvalResponse = approvalClient.createApprovalRequest(approvalRequest);
if (!approvalResponse.isSucceeded()) {
log.error("Submit Ding Ding error ,bizId is {}, bizType is {}", bizId, bizType);
}
} catch (Exception e) {
log.error("createApprovalRequest failed. bizId is {}, bizType is {}, e is: ", bizId, bizType, e);
}
}, commonExecutor);
}
private FacadeResponse checkCsWorkOrderConfigAvailable(CSWorkOrderConfigDO csWorkOrderConfigDO) {
if (csWorkOrderConfigDO == null) {
return getFacadeResponseWithFailed(AttaResponseCode.ILLEGAL_ARGUMENT, "工单配置错误");
}
if (csWorkOrderConfigDO.getBusinessType() != BusinessType.ACCOUNT_FUNCTION) {
return getFacadeResponseWithFailed(AttaResponseCode.BIZ_ERROR, "暂不支持该业务类型");
}
if (!ACCOUNT_SECURITY.equals(csWorkOrderConfigDO.getWorkorderType())) {
return getFacadeResponseWithFailed(AttaResponseCode.BIZ_ERROR, "暂不支持该工单类型");
}
if (!CHANGE_USER_MASTER_PHONE.equals(csWorkOrderConfigDO.getProblemType()) && !UN_BIND_X.equals(csWorkOrderConfigDO.getProblemType())) {
return getFacadeResponseWithFailed(AttaResponseCode.BIZ_ERROR, "暂不支持该问题类型");
}
return getFacadeResponseWithSuccess();
}
private FacadeResponse<Boolean> checkXshieldAvailable(String userId) {
FacadeResponse<Boolean> response = userSecretClient.hasActiveSecret(userId, SecretType.OTP.name());
if (!response.isSucceeded()) {
log.error("remote get userInfo error,{}", response.getResponseMsg());
return getFacadeResponseWithFailed(AttaResponseCode.SYSTEM_ERROR);
}
return response;
}
@Autowired
private NotificationService notificationService;
public void sendNotification(CSWorkOrderDO csWorkOrderDO, CSWorkOrderConfigDO csWorkOrderConfigDO, CrmApprovalStatus approvalStatus) throws Exception {
NotificationEvent notificationEvent = new NotificationEvent();
notificationEvent.setEventId(csWorkOrderDO.getWorkorderId());
notificationEvent.setEventTopic("WorkOrderCheckResult");
notificationEvent.setTags(Lists.newArrayList("WorkOrderCheckAction"));
CSWorkOrderNotifyResultRequest request = new CSWorkOrderNotifyResultRequest();
request.setRequestId(csWorkOrderDO.getReferenceId());
request.setBusinessType(csWorkOrderConfigDO.getBusinessType());
request.setWorkOrderType(WorkOrderType.convertWorkOrderType(csWorkOrderConfigDO.getWorkorderType()));
request.setProblemType(ProblemType.convertProblemType(csWorkOrderConfigDO.getProblemType()));
request.setWorkOrderSource(csWorkOrderDO.getSource());
request.setStatus(approvalStatus);
request.setUserId(csWorkOrderDO.getUserId());
request.setPhone(csWorkOrderDO.getPhone());
request.setNewPhone(csWorkOrderDO.getNewPhone());
request.setPhoneAreaCode(csWorkOrderDO.getPhoneAreaCode());
request.setNewPhoneAreaCode(csWorkOrderDO.getNewPhoneAreaCode());
notificationEvent.setMessageBody(request);
notificationService.notify(notificationEvent);
}
/**
* 工单撤销
* 同步撤销加急工单
*/
private void cancelledExpediteWorkOrder(CSWorkOrderDO csWorkOrderDO) {
Criteria expediteConfigCriteria = Criteria.where("businessType").is(BusinessType.CUSTOMER_CONSULTATION)
.and("workorderType").is("其他")
.and("problemType").is("加急")
.and("status").is(CSWorkOrderConfigStatus.Enabled);
CSWorkOrderConfigDO csWorkOrderConfigDO = csWorkOrderConfigDAO.findOne(new Query().addCriteria(expediteConfigCriteria));
if (null == csWorkOrderConfigDO) {
log.error("工单自动撤销失败, 未找到加急工单类型");
return;
}
Criteria expediteWorkOrderCriteria = Criteria.where("workOrderConfigId").is(csWorkOrderConfigDO.getConfigId())
.and("relatedWorkOrderId").is(csWorkOrderDO.getWorkorderId())
.and("relatedWorkOrderDomain").is(WorkOrderDomain.CS_WORK_ORDER)
.and("status").nin(finalCSWorkOrderStatus);
List<CSWorkOrderDO> expediteWorkOrders = csWorkOrderDAO.find(new Query().addCriteria(expediteWorkOrderCriteria));
csWorkOrderDO.setStatus(CSWorkOrderStatus.Cancelled);
CSWorkOrderOpLogDO csWorkOrderOpLogDO = createdOpLogDO(csWorkOrderDO.getWorkorderId(), csWorkOrderDO.getStatus(), "system", "无人认领,撤销工单");
Boolean isOk = mongoTransactionTemplate.execute(status -> {
try {
if (csWorkOrderDAO.updateByIdSelective(csWorkOrderDO) == null) {
throw new CustomerServiceException(CSOrderSystemErrorCode.UpdateError, CSOrderBizErrorCode.SYSTEM_ERROR, "update fail.");
}
if (csWorkOrderOpLogDAO.insert(csWorkOrderOpLogDO) == null) {
throw new CustomerServiceException(CSOrderSystemErrorCode.InsertError, CSOrderBizErrorCode.SYSTEM_ERROR, "insert oplog fail.");
}
for (CSWorkOrderDO expediteWorkOrder : expediteWorkOrders) {
expediteWorkOrder.setStatus(CSWorkOrderStatus.Cancelled);
CSWorkOrderOpLogDO expediteOpLogDO = createdOpLogDO(expediteWorkOrder.getWorkorderId(), expediteWorkOrder.getStatus(), "system", "同步撤销加急工单");
if (csWorkOrderDAO.updateByIdSelective(expediteWorkOrder) == null) {
throw new CustomerServiceException(CSOrderSystemErrorCode.UpdateError, CSOrderBizErrorCode.SYSTEM_ERROR, "update fail.");
}
if (csWorkOrderOpLogDAO.insert(expediteOpLogDO) == null) {
throw new CustomerServiceException(CSOrderSystemErrorCode.InsertError, CSOrderBizErrorCode.SYSTEM_ERROR, "insert oplog fail.");
}
}
} catch (Exception e) {
log.warn(e.getMessage(), e);
status.setRollbackOnly();
return Boolean.FALSE;
}
return Boolean.TRUE;
});
if (!Boolean.TRUE.equals(isOk)) {
log.error("工单自动撤销失败, csWorkOrderDO: {}", csWorkOrderDO);
}
}
private FacadeResponse updateWO(CSWorkOrderDO workOrderDO,
CSWorkOrderOpLogDO opLogDO) {
FacadeResponse facadeResponse = mongoTransactionTemplate.execute(status -> {
if (csWorkOrderOpLogDAO.insert(opLogDO) == null) {
status.setRollbackOnly();
return getFacadeResponseWithFailed(AttaResponseCode.UNKNOWN_DATA_ACCESS_ERROR);
}
if (workOrderDO != null) {
if (csWorkOrderDAO.updateByIdSelective(workOrderDO) == null) {
status.setRollbackOnly();
return getFacadeResponseWithFailed(AttaResponseCode.UNKNOWN_DATA_ACCESS_ERROR);
}
}
return getFacadeResponseWithSuccess();
});
if (facadeResponse != null && facadeResponse.isSucceeded()) {
workorderMessageProducer.sendPreAuditStatusEvent(workOrderDO);
if (finalCSWorkOrderStatus.contains(workOrderDO.getStatus())) {
try {
workorderMessageProducer.closeCustomerTag(workOrderDO);
} catch (Exception e) {
log.error("close customer Tag failed. e: ", e);
}
}
}
return facadeResponse;
}
private static CSWorkorderConfigVO convertConfigDOToVo(CSWorkOrderConfigDO csWorkOrderConfigDO) {
CSWorkorderConfigVO vo = new CSWorkorderConfigVO();
vo.setCreatedTime(csWorkOrderConfigDO.getCreationDate());
vo.setProblemType(csWorkOrderConfigDO.getProblemType());
vo.setBusinessType(csWorkOrderConfigDO.getBusinessType());
vo.setWorkorderType(csWorkOrderConfigDO.getWorkorderType());
vo.setGroupId(csWorkOrderConfigDO.getGroupId());
vo.setStatus(csWorkOrderConfigDO.getStatus());
vo.setOpLog(csWorkOrderConfigDO.getOpLog());
vo.setExtra(csWorkOrderConfigDO.getExtra());
vo.setMainType(csWorkOrderConfigDO.getMainType());
return vo;
}
private FacadeResponse updateWOS(List<CSWorkOrderDO> workorderDOS, List<CSWorkOrderOpLogDO> opLogDOS) {
FacadeResponse facadeResponse = mongoTransactionTemplate.execute(status -> {
if (csWorkOrderOpLogDAO.batchInsert(opLogDOS).size() != opLogDOS.size()) {
status.setRollbackOnly();
return getFacadeResponseWithFailed(AttaResponseCode.UNKNOWN_DATA_ACCESS_ERROR);
}
for (CSWorkOrderDO workOrderDO : workorderDOS) {
if (csWorkOrderDAO.updateByIdSelective(workOrderDO) == null) {
status.setRollbackOnly();
return getFacadeResponseWithFailed(AttaResponseCode.UNKNOWN_DATA_ACCESS_ERROR);
}
}
return getFacadeResponseWithSuccess();
});
assert facadeResponse != null;
if (facadeResponse.isSucceeded()) {
workorderDOS.forEach(csWorkOrderDO -> workorderMessageProducer.sendPreAuditStatusEvent(csWorkOrderDO));
}
return facadeResponse;
}
//转移负责之后,把原工单负责人加入到自动分配用户队列中
private void enterQueue(String userId) {
try {
if (!StringUtils.isEmpty(userId) && !userId.equals(SystemConst.SYSTEM_USER_ID)) {
WorkOrderDistributionRequest request = new WorkOrderDistributionRequest();
request.setUserId(userId);
User user = bossUserClient.queryByBossUserId(userId);
request.setUserName(null != user ? user.getUserName() : "");
csWorkOrderAutomaticAllocationService.distribution(request);
}
} catch (Exception e) {
log.warn("【user queue】user enter queue :{} fail", userId);
}
}
//把用户从自动分配用户队列中移出
private void removeUser(String userId) {
try {
if (!StringUtils.isEmpty(userId)) {
csWorkOrderUserService.remove(userId);
}
} catch (Exception e) {
log.warn("【user queue】remove user :{} fail", userId);
}
}
private void sendWorkOrderCompleteMessage(CSWorkOrderDO csWorkOrderDO) {
//如果是技术工单需要发送通知
try {
if (!isItWorkOrder(csWorkOrderDO.getWorkOrderConfigId())) {
return;
}
//1,给创建人发送消息
messageManager.sendITCloseMessage(csWorkOrderDO.getWorkorderId(), csWorkOrderDO.getCreatedBy(), WorkOrderOptType.IT_CLOSE);
} catch (Exception e) {
log.error("【技术工单】发送消息失败", e);
}
}
private boolean isItWorkOrder(String workOrderConfigId) {
try {
CSWorkorderConfigVO configVO = cSWorkOrderConfigService.getValidConfigVOByConfigId(workOrderConfigId);
if (null == configVO) {
log.warn("根据工单类型ID:{},为查询到工单类型", workOrderConfigId);
return false;
}
if (null == workOrderConfig || CollectionUtils.isEmpty(workOrderConfig.getInfo()) || null == workOrderConfig.getInfo().get(WorkOrderConfig.ConfigKey.it)) {
log.warn("没有找到it工单配置");
return false;
}
WorkOrderConfig.configInfo configInfo = workOrderConfig.getInfo().get(WorkOrderConfig.ConfigKey.it);
if (configVO.getBusinessType().equals(configInfo.getBusinessType()) &&
(StringUtils.isEmpty(configInfo.getWorkOrderType()) || configVO.getWorkorderType().equals(configInfo.getWorkOrderType())) &&
(StringUtils.isEmpty(configInfo.getProblemType()) || configVO.getProblemType().equals(configInfo.getWorkOrderType()))) {
return true;
}
} catch (Exception e) {
log.warn("【技术工单】当前工单是否是it工单异常", e);
}
return false;
}
/**
* 构建操作日志
*
* @param workOrderId
* @param status
* @param operatorUserId
* @param suggestion
* @return
*/
private CSWorkOrderOpLogDO buildOpLogDO(String workOrderId
, CSWorkOrderStatus status
, String operatorUserId
, String suggestion) {
CSWorkOrderOpLogDO opLogDO = new CSWorkOrderOpLogDO();
opLogDO.setOpLogId(AttaIdUtils.getByProdCode(AttaIdUtils.ProdCode.CUSTOMER_SERVICE_WORKORDER_OP_LOG));
opLogDO.setOperatorUserId(operatorUserId);
opLogDO.setOpTime(new Date());
opLogDO.setStatus(status.name());
opLogDO.setSuggestion(suggestion);
opLogDO.setWorkorderId(workOrderId);
return opLogDO;
}
private void upgradeOrBackWorkOrder(List<DataPersistenceCommander> commanders, WorkOrderUpdateReq request, boolean showToCustomer) {
request.validate();
CSWorkOrderDO csWorkOrderDO = csWorkOrderDAO.queryCSWorkOrderByWorkOrderId(request.getWorkOrderId());
csWorkOrderDO.setCurrentDealUserId(request.getOperatorUserId());
csWorkOrderDO.setBeforeUpgradePrincipalId(request.getBeforeUpdatePrincipalUserId());
csWorkOrderDO.setPrincipalUserId(request.getPrincipalUserId());
csWorkOrderDO.setOrderLevel(request.getOrderLevel());
csWorkOrderDO.setStatus(request.getStatus());
if (request.isUpgradeFlag()) {
// 打标升级标签 舆情升级、普通升级、协同升级
allocateHandleService.setUpgradeLabelByUpgrade(request, csWorkOrderDO);
// 如果是协同升级,是否需要智能托管
if (CSWorkOrderUpgradeSource.COLLABORATION_UPGRADE.name().equals(csWorkOrderDO.getUpgradeSource())) {
hostingService.intelligentHostingStart(csWorkOrderDO);
}
} else {
// 回退逻辑 回退升级标签
allocateHandleService.backUpgradeLabel(request, csWorkOrderDO);
}
/* TODO 迁移变更:用户咨询类型的单子需要修改 showToCustomer字段 */
// String workOrderConfigId = csWorkOrderDO.getWorkOrderConfigId();
// if (StringUtils.isNotEmpty(workOrderConfigId)) {
// CSWorkOrderConfigDO configDO = csWorkOrderConfigDAO.queryValidByConfigId(workOrderConfigId);
// if (null != configDO && SHOW_TO_CUSTOMER.contains(configDO.getBusinessType())) {
// csWorkOrderDO.setShowToCustomer(showToCustomer);
// }
// }
commanders.add(() -> CSExceptionAssert.isTrue(csWorkOrderDAO.updateByIdSelective(csWorkOrderDO) != null
, CSOrderBizErrorCode.SYSTEM_ERROR, "更新失败"));
//云雀平台新协同工单通知工单变更处理人
if (!Strings.isNullOrEmpty(csWorkOrderDO.getSkylarkCollaborationId()) && !Strings.isNullOrEmpty(request.getPrincipalUserId())) {
User user = bossUserClient.queryByBossUserId(request.getPrincipalUserId());
skylarkManager.notifyChangePrincipal(csWorkOrderDO.getWorkorderId(), csWorkOrderDO.getSkylarkCollaborationId(),
user.getBossUserId(), user.getUserName());
}
}
/**
* 发送钉钉消息给指定用户
*
* @param bossUserId
* @param workOrderId
*/
private void notify(String bossUserId, String workOrderId) {
if (StringUtil.isEmpty(bossUserId)) {
return;
}
User user = bossUserClient.getByBossUserId(bossUserId);
if (null == user || StringUtil.isEmpty(user.getDingUserId())) {
return;
}
MessageRequestVO messageRequestVO = new MessageRequestVO();
messageRequestVO.setRequestId(UUID.randomUUID().toString());
messageRequestVO.setTemplateType(MessageTemplateType.JIRA_NOTIFY.name());
messageRequestVO.setTargetList(Lists.newArrayList(MessageTargetVO.builder("").dingUserId(user.getDingUserId()).build()));
HashMap<String, String> msgContext = Maps.newHashMap();
msgContext.put("message", "您的升级工单(" + workOrderId + ")已退回,请至BOSS后台查看处理");
messageRequestVO.setParamValueMap(msgContext);
ResponseEntity<Map<String, String>> resp = messageFacadeClient.sendMessage(messageRequestVO);
log.info("send ding message response is :{}", resp);
Assert.isTrue(resp != null && resp.getStatusCode() == HttpStatus.OK, "jira notify: notify failed");
}
private AppointmentResultVO isAllowed(CSWorkOrderDO csWorkOrderDO) {
AppointmentResultVO resultVO = new AppointmentResultVO();
resultVO.setIsSuccess(false);
// 工单不存在
if (csWorkOrderDO == null) {
resultVO.setReason(AppointmentResultVO.FailedReason.OrderNotExist);
return resultVO;
}
// 工单已结案
if (finalCSWorkOrderStatus.contains(csWorkOrderDO.getStatus())) {
resultVO.setReason(AppointmentResultVO.FailedReason.OrderCompleted);
return resultVO;
}
CSWorkorderCommRecordVO commRecordVO = commRecordService.getNewestStaffRecordsByWorkOrderId(csWorkOrderDO.getWorkorderId());
WorkOrderInstructionDO instructionDO = workOrderInstructionDAO.getLatestInstructionByReferenceId(csWorkOrderDO.getWorkorderId()
, WorkOrderInstructionType.CustomerAppointment);
if (Objects.nonNull(instructionDO) && Objects.equals(instructionDO.getStatus(), WorkOrderInstructionStatus.NEW)) {
resultVO.setReason(AppointmentResultVO.FailedReason.AppointmentNotExpired);
resultVO.setIsSuccess(false);
return resultVO;
}
// 查询最新的待办是否过期
QueryLatestTodoTaskRequest latestTaskRequest = new QueryLatestTodoTaskRequest();
latestTaskRequest.setBusinessId(csWorkOrderDO.getWorkorderId());
latestTaskRequest.setTodoTaskType(TodoTaskType.AppointmentCallBack.name());
TodoTaskVO todoTaskVO = todoTaskManager.queryLatestTodoTask(latestTaskRequest);
if (todoTaskVO != null && new Date().before(todoTaskVO.getEndTime())) { // 待办未过期的情况
// 在未过期的时间内
//1、没有新增沟通记录,不允许创建
//2、最新的沟通记录,创建时间在待办创建时间之前的。不允许创建
if (commRecordVO == null || commRecordVO.getCreatedTime().before(todoTaskVO.getCreationDate())) {
resultVO.setReason(AppointmentResultVO.FailedReason.AppointmentNotExpired);
resultVO.setIsSuccess(false);
return resultVO;
}
}
resultVO.setIsSuccess(true);
return resultVO;
}
/**
* 工单对象转换为工单结果对象
*/
private CSWorkOrderResultVO resultConvert(CSWorkOrderDO csWorkOrderDO) {
CSWorkOrderResultVO resultVO = new CSWorkOrderResultVO();
resultVO.setFirmId(csWorkOrderDO.getFirmId());
resultVO.setWorkOrderId(csWorkOrderDO.getWorkorderId());
resultVO.setCompletedTime(csWorkOrderDO.getCompletedTime());
resultVO.setStatus(csWorkOrderDO.getStatus().name());
ActionDO actionDO = actionDAO.getLastUpdateActionBySceneId(csWorkOrderDO.getWorkorderId());
if (null != actionDO && null != actionDO.getActionResults() && !actionDO.getActionResults().isEmpty()) {
resultVO.setAuditResult(null != actionDO.getActionResults().get(PRE_AUDIT_RESULT_KEY) ? actionDO.getActionResults().get(PRE_AUDIT_RESULT_KEY).toString() : "");
resultVO.setRejectReason(null != actionDO.getActionResults().get(PRE_AUDIT_SUGGESTION_KEY) ? actionDO.getActionResults().get(PRE_AUDIT_SUGGESTION_KEY).toString() : "");
}
return resultVO;
}
/**
* @param from formAnswer 附件存放于answers中 文本附件对应TEXT_INPUT 其他附件对应UPLOAD
* @return answers中为null的元素直接skip,UploadAnswer.valueList中为null的元素直接skip.to为空对象返回null
*/
private CSWorkOrderFeedbackAttachmentVO toCSWorkOrderFeedbackAttachmentVO(FormAnswerVO from) {
CSWorkOrderFeedbackAttachmentVO to = new CSWorkOrderFeedbackAttachmentVO();
List<AttachmentVO> attachmentList = new ArrayList<>();
for (FormAnswerVO.Answer answer : from.getAnswers()) {
if (Objects.isNull(answer)) {
continue;
}
//text_input存储文字反馈
if (QuestionTypeEnum.TEXT_INPUT.equals(answer.getQuestionType())) {
to.setContent((String) answer.getValue());
}
//upload中的valueList存储附件url
if (QuestionTypeEnum.UPLOAD.equals(answer.getQuestionType())) {
List<String> valueList = ((FormAnswerVO.UploadAnswer) answer).getValueList();
if (!CollectionUtils.isEmpty(valueList)) {
for (String value : valueList) {
if (value == null) {
continue;
}
AttachmentVO attachmentVO = new AttachmentVO();
attachmentVO.setUrl(value);
attachmentList.add(attachmentVO);
}
}
}
}
to.setAttachmentVOS(attachmentList);
return to.getContent() == null && CollectionUtils.isEmpty(to.getAttachmentVOS()) ? null : to;
}
@Override
public CSWorkOrderVO queryLastOneByAssignFirm(String assignId, String firmId) {
Query query = new Query();
Criteria criteria = Criteria.where(CSWorkOrderDO.FIRM_ID).is(firmId)
.and(CSWorkOrderDO.ASSIGN_ID).is(assignId);
query.addCriteria(criteria);
query.with(Sort.by(Sort.Direction.DESC, CSWorkOrderDO.CREATION_DATE)).limit(1);
CSWorkOrderDO csWorkOrderDO = csWorkOrderDAO.findOne(query);
CSWorkOrderVO csWorkOrderVO = toWorkOrderVO(csWorkOrderDO);
if (Objects.isNull(csWorkOrderVO)) {
return null;
}
csWorkOrderVO.setHistoryPreAuditWorkOrderVOList(getHistoryPreAuditWorkOrders(csWorkOrderDO));
return csWorkOrderVO;
}
private void pushHostingComplete(CSWorkOrderCommRecordSaveRequest request) {
HostingCompleteEvent event = new HostingCompleteEvent();
if (request.isOptBySale()) {
// 销售留言
event.setCompleteType(CSWorkOrderHostingCompleteType.SALE_LEAVE_MESSAGE.name());
} else if (CsWoButtonSource.EDIT_SUBMIT.name().equals(request.getButtonSource())) {
// 工单跟进
event.setRelateSession(!CollectionUtils.isEmpty(request.getSessionIds()) || !CollectionUtils.isEmpty(request.getCallCenterIds()));
event.setOptDate(new Date());
event.setCompleteType(CSWorkOrderHostingCompleteType.ADD_FOLLOW.name());
} else {
return;
}
event.setWorkorderId(request.getWorkorderId());
event.setCommRecord(request.getCommRecord());
csWorkOrderHostingEndProducer.send(event);
}
}
fuccc
霍金的微笑2026-09-14 11:23
相关推荐
潜心一志2 小时前
HALCON软件——数据结构秦哈哈2 小时前
【HelloAgents】学习笔记(一)wuyk5552 小时前
从零吃透 MQTT 通信|第 10 章 阿里云 / 腾讯云 MQTT 设备完整对接实战,三元组、签名、设备上云调试fanged3 小时前
English at Work小结(TODO)X-future4263 小时前
OpenClaw源码学习kaixin_啊啊3 小时前
中国研究生数学建模竞赛(华为杯)学习笔记——三维瀑布图绘图代码动词ing3 小时前
【学习笔记】数据结构(链表合并 双指针合并有序链表)风之清扬3 小时前
Agent学习之四-初识Agent CLI传奇开心果编程3 小时前
【xilem0.4基础语法学与练】第45课 xilem_core