feat:智能柜错误处理

This commit is contained in:
dzc committed 2025-04-17 15:48:29 +08:00
1 parent 796985f3c6
commit 2ecc2e78ce
8 files changed
+208 -55

No files matched your search

+4
View File
@@ -133,6 +133,10 @@ CREATE TABLE hard_door_flow
sku_driving_dto varchar(512) DEFAULT NULL COMMENT 'sku识别主动获取参数',
sku_driving_vo varchar(512) DEFAULT NULL COMMENT 'sku识别主动获取结果',
sku_driving_time datetime DEFAULT NULL COMMENT 'sku识别主动获取时间',
# 流程相关
flow_status varchar(32) DEFAULT NULL COMMENT '流程状态',
error varchar(512) DEFAULT NULL COMMENT '流程错误信息',
error_desc varchar(64) DEFAULT NULL COMMENT '流程错误描述(展示)',
# 其他字段
create_by varchar(64) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '创建人',
create_time datetime DEFAULT NULL COMMENT '创建时间',
@@ -11,7 +11,7 @@ import java.util.Arrays;
*/
@AllArgsConstructor
@Getter
public enum HardDoorFlowEnum {
public enum HardDoorFlowBizEnum {
PAY_OPEN("10", "购买开门"),
REPERTORY_OPEN("20", "上架开门"),
ACCESS_OPEN("20", "检修开门"),
@@ -19,7 +19,7 @@ public enum HardDoorFlowEnum {
private final String type;
private final String description;
public static HardDoorFlowEnum valueOfByType(String type) {
public static HardDoorFlowBizEnum valueOfByType(String type) {
if (ObjectUtil.isEmpty(type)) return null;
return Arrays.stream(values()).filter(v -> ObjectUtil.equals(type, v.getType())).findFirst().get();
}
@@ -0,0 +1,39 @@
package com.bsd.pjcloud.hard.api.constant.flow;
import cn.hutool.core.util.ObjectUtil;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.Arrays;
/**
* 智能柜流程
*/
@AllArgsConstructor
@Getter
public enum HardDoorFlowEnum {
FLOW_AUTH("10", "用户授权", "20"),
FLOW_APPLY_OPEN("20", "智能柜申请开门", "30"),
FLOW_CALLBACK_OPEN("30", "智能柜开门响应", "40"),
FLOW_CALLBACK_VIDEO("40", "智能柜视频回调", "50"),
FLOW_SUBMIT_RECOGNITION("50", "旷世提交识别", "60"),
FLOW_CALLBACK_RECOGNITION("60", "旷世识别响应", "70"),
FLOW_PAY_ORDER("60", "订单结算", null),
;
private final String type;
private final String description;
private final String nextType;
public static HardDoorFlowEnum valueOfByType(String type) {
if (ObjectUtil.isEmpty(type)) return null;
return Arrays.stream(values()).filter(v -> ObjectUtil.equals(type, v.getType())).findFirst().get();
}
public static HardDoorFlowEnum getNextType(HardDoorFlowEnum type) {
if (ObjectUtil.isEmpty(type)) return null;
String nextType = Arrays.stream(values()).filter(v -> ObjectUtil.equals(type, v.getType())).findFirst().get().getNextType();
if (ObjectUtil.isEmpty(nextType)) return null;
return valueOfByType(nextType);
}
}
@@ -1,6 +1,6 @@
package com.bsd.pjcloud.hard.api.dto;
import com.bsd.pjcloud.hard.api.constant.HardDoorFlowEnum;
import com.bsd.pjcloud.hard.api.constant.HardDoorFlowBizEnum;
import com.bsd.pjcloud.hard.api.constant.HardDoorOpenTypeEnum;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
@@ -28,7 +28,7 @@ public class HardDoorFlowOpenDto {
/**
* 流程类型
*/
private HardDoorFlowEnum flowType;
private HardDoorFlowBizEnum flowType;
/**
* 开门操作类型
@@ -176,6 +176,24 @@ public class HardDoorFlowEntity extends Model<HardDoorFlowEntity> {
@Schema(description = "sku识别主动获取时间")
private LocalDateTime skuDrivingTime;
/**
* 流程状态
*/
@Schema(description = "流程状态")
private String flowStatus;
/**
* 流程错误信息
*/
@Schema(description = "流程错误信息")
private String error;
/**
* 流程错误描述(展示)
*/
@Schema(description = "流程错误描述(展示)")
private String errorDesc;
/**
* 创建人
*/
@@ -10,7 +10,7 @@ import com.bsd.pjcloud.common.log.annotation.SysLog;
import com.bsd.pjcloud.common.security.annotation.Inner;
import com.bsd.pjcloud.common.security.service.PjcloudUser;
import com.bsd.pjcloud.common.security.util.SecurityUtils;
import com.bsd.pjcloud.hard.api.constant.HardDoorFlowEnum;
import com.bsd.pjcloud.hard.api.constant.HardDoorFlowBizEnum;
import com.bsd.pjcloud.hard.api.constant.HardDoorOpenTypeEnum;
import com.bsd.pjcloud.hard.api.dto.HardDoorFlowDto;
import com.bsd.pjcloud.hard.api.dto.HardDoorFlowOpenDto;
@@ -96,7 +96,7 @@ public class HardDoorFlowController {
@PostMapping("/open-access")
public R openAccess(@Validated @RequestBody HardDoorFlowOpenDto dto) {
PjcloudUser user = SecurityUtils.getUser();
dto.setFlowType(HardDoorFlowEnum.ACCESS_OPEN);
dto.setFlowType(HardDoorFlowBizEnum.ACCESS_OPEN);
dto.setOpenType(HardDoorOpenTypeEnum.MAINTENANCE_UNLOCK);
dto.setUserId(user.getId());
hardDoorFlowService.openDoorAccess(dto);
@@ -107,7 +107,7 @@ public class HardDoorFlowController {
@PostMapping("/close-access")
public R closeAccess(@Validated @RequestBody HardDoorFlowOpenDto dto) {
PjcloudUser user = SecurityUtils.getUser();
dto.setFlowType(HardDoorFlowEnum.ACCESS_OPEN);
dto.setFlowType(HardDoorFlowBizEnum.ACCESS_OPEN);
dto.setOpenType(HardDoorOpenTypeEnum.MAINTENANCE_LOCK);
dto.setUserId(user.getId());
hardDoorFlowService.closeAccess(dto);
@@ -11,7 +11,7 @@ import com.bsd.pjcloud.common.core.util.CollectionUtils;
import com.bsd.pjcloud.common.core.util.R;
import com.bsd.pjcloud.common.data.datascope.DataScope;
import com.bsd.pjcloud.hard.api.constant.HardAuthTypeEnum;
import com.bsd.pjcloud.hard.api.constant.HardDoorFlowEnum;
import com.bsd.pjcloud.hard.api.constant.HardDoorFlowBizEnum;
import com.bsd.pjcloud.hard.api.constant.HardDoorOpenTypeEnum;
import com.bsd.pjcloud.hard.api.dto.HardAuthAppDto;
import com.bsd.pjcloud.hard.api.dto.HardAuthDto;
@@ -106,7 +106,7 @@ public class HardAuthServiceImpl extends ServiceImpl<HardAuthMapper, HardAuthEnt
HardDoorFlowOpenDto openDoorDto = new HardDoorFlowOpenDto();
openDoorDto.setHardDoorId(hardDoorDetail.getId());
openDoorDto.setCabinetNo(authEntity.getCabinetNo());
openDoorDto.setFlowType(HardDoorFlowEnum.PAY_OPEN);
openDoorDto.setFlowType(HardDoorFlowBizEnum.PAY_OPEN);
openDoorDto.setOpenType(HardDoorOpenTypeEnum.RECORD_VIDEO);
openDoorDto.setUserId(dto.getUserId());
openDoorDto.setAuthId(dto.getAuthId());
@@ -15,8 +15,8 @@ import com.bsd.pjcloud.common.core.constant.enums.YesNoEnum;
import com.bsd.pjcloud.common.core.util.CollectionUtils;
import com.bsd.pjcloud.common.core.util.R;
import com.bsd.pjcloud.common.data.datascope.DataScope;
import com.bsd.pjcloud.hard.api.constant.HardDoorFlowEnum;
import com.bsd.pjcloud.hard.api.constant.HardDoorOpenTypeEnum;
import com.bsd.pjcloud.hard.api.constant.HardDoorFlowBizEnum;
import com.bsd.pjcloud.hard.api.constant.flow.HardDoorFlowEnum;
import com.bsd.pjcloud.hard.api.dto.HardDoorFlowDto;
import com.bsd.pjcloud.hard.api.dto.HardDoorFlowOpenDto;
import com.bsd.pjcloud.hard.api.dto.manager.HardManagerDto;
@@ -26,7 +26,6 @@ import com.bsd.pjcloud.hard.api.entity.manager.HardDoorManagerEntity;
import com.bsd.pjcloud.hard.api.entity.manager.HardManagerEntity;
import com.bsd.pjcloud.hard.api.entity.order.HardOrderEntity;
import com.bsd.pjcloud.hard.api.utils.HardUtil;
import com.bsd.pjcloud.hard.api.vo.HardAuthVo;
import com.bsd.pjcloud.hard.api.vo.HardDoorFlowVo;
import com.bsd.pjcloud.hard.api.vo.manager.HardDoorManagerVo;
import com.bsd.pjcloud.hard.api.vo.spu.HardSpuJoinVo;
@@ -100,11 +99,12 @@ public class HardDoorFlowServiceImpl extends ServiceImpl<HardDoorFlowMapper, Har
*/
@Transactional(rollbackFor = Exception.class)
public void openDoor(HardDoorFlowOpenDto dto, HardDoorManagerVo hardDoorVo) {
HardDoorFlowEntity saveObj = HardDoorFlowEntity.builder().userId(dto.getUserId()).bizType(dto.getFlowType().getType()).isOpen(YesNoEnum.NO.getCode()).build();
HardDoorFlowEntity saveObj = HardDoorFlowEntity.builder().flowStatus(HardDoorFlowEnum.FLOW_AUTH.getType()).userId(dto.getUserId()).bizType(dto.getFlowType().getType()).isOpen(YesNoEnum.NO.getCode()).build();
baseMapper.insert(saveObj);
HardDoorManagerEntity hardDoorStatus = hardDoorManagerService.refresh(hardDoorVo.getDeviceCode());
// 校验设备和货柜编号
hardDoorStatus = hardDoorManagerService.checkDeviceAndCabinet(dto.getHardDoorId(), dto.getCabinetNo());
HardDoorFlowEntity updateObj = HardDoorFlowEntity.builder().id(saveObj.getId()).flowStatus(saveObj.getFlowStatus()).hardId(hardDoorStatus.getHardId()).hardDoorId(dto.getHardDoorId()).cabinetNo(dto.getCabinetNo()).build();
// 请求开门
DoorOpenDto openDto = BeanUtil.toBean(dto, DoorOpenDto.class);
openDto.setDeviceCode(hardDoorVo.getDeviceCode());
@@ -112,19 +112,15 @@ public class HardDoorFlowServiceImpl extends ServiceImpl<HardDoorFlowMapper, Har
openDto.setOutOpenNo(String.valueOf(saveObj.getId()));
openDto.setEventType(Integer.valueOf(dto.getOpenType().getType()));
DoorOpenVo openVo = thirdDoorApiService.open(openDto).getData();
if (ObjectUtil.isEmpty(openVo) || !openVo.isSuccess()) throw new RuntimeException(openVo.getMessage());
HardDoorFlowEntity updateObj = HardDoorFlowEntity.builder()
.id(saveObj.getId())
.hardId(hardDoorStatus.getHardId())
.hardDoorId(dto.getHardDoorId())
.cabinetNo(dto.getCabinetNo())
.requestOpenDto(JSONUtil.toJsonStr(openDto))
.requestOpenVo(JSONUtil.toJsonStr(openVo))
.requestOpenTime(LocalDateTime.now()).build();
if (ObjectUtil.isNotEmpty(dto.getAuthId())) updateObj.setAuthId(dto.getAuthId());
// 是否开门成功
updateObj.setIsOpen(YesNoEnum.YES.getCode());
baseMapper.updateById(updateObj);
if (ObjectUtil.isEmpty(openVo) || !openVo.isSuccess()) {
String errorMsg = "智能柜申请开门错误," + openVo.getMessage();
flowStatusControl(updateObj, openDto, openVo, errorMsg);
throw new RuntimeException(errorMsg);
}
if (ObjectUtil.isNotEmpty(dto.getAuthId())) {
updateObj.setAuthId(dto.getAuthId());
}
flowStatusControl(updateObj, openDto, openVo, null);
}
@@ -199,26 +195,15 @@ public class HardDoorFlowServiceImpl extends ServiceImpl<HardDoorFlowMapper, Har
log.info("|{}|disposeLocakCallback 意外的错误,流程不存在dto|{}|", TAG, JSONUtil.toJsonStr(dto));
return;
}
// 维修开锁不处理
List<String> maintenanceList = HardDoorOpenTypeEnum.getMaintenanceListCodes();
if (maintenanceList.contains(String.valueOf(dto.getEventType()))) {
hardDoorManagerService.refresh(dto.getDeviceCode());
return;
}
boolean isOpenDoor = ObjectUtil.equals(dto.getType(), "OPEN");
HardDoorFlowEntity updateObj = HardDoorFlowEntity.builder()
.id(flowDetail.getId())
.isOpen(isOpenDoor ? YesNoEnum.YES.getCode() : YesNoEnum.NO.getCode())
.openCallbackTime(LocalDateTime.now())
.openCallbackVo(JSONUtil.toJsonStr(dto))
.build();
HardDoorFlowEntity updateObj = HardDoorFlowEntity.builder().id(flowDetail.getId()).flowStatus(flowDetail.getFlowStatus()).isOpen(isOpenDoor ? YesNoEnum.YES.getCode() : YesNoEnum.NO.getCode()).build();
// 如果是购买的话
if (ObjectUtil.equals(flowDetail.getBizType(), HardDoorFlowEnum.PAY_OPEN.getType())) {
if (ObjectUtil.equals(flowDetail.getBizType(), HardDoorFlowBizEnum.PAY_OPEN.getType())) {
// 创建订单
Long orderId = hardOrderService.createHardDoorOrder(flowDetail.getUserId(), flowDetail.getHardId());
updateObj.setOrderId(orderId);
}
baseMapper.updateById(updateObj);
flowStatusControl(updateObj, null, dto, null);
}
/**
@@ -284,6 +269,8 @@ public class HardDoorFlowServiceImpl extends ServiceImpl<HardDoorFlowMapper, Har
// 更新流程
HardDoorFlowEntity vodeoUpdateObj = HardDoorFlowEntity.builder().id(flowDetail.getId()).videoCallbackVo(JSONUtil.toJsonStr(dto)).videoCallbackTime(LocalDateTime.now()).build();
baseMapper.updateById(vodeoUpdateObj);
// 更新流程
getSelf().flowStatusControl(flowDetail, null, dto, null);
// 提交识别
KsRecognitionDto ksRecognitionDto = new KsRecognitionDto();
ksRecognitionDto.setRecog_id(String.valueOf(flowDetail.getId()));
@@ -296,12 +283,13 @@ public class HardDoorFlowServiceImpl extends ServiceImpl<HardDoorFlowMapper, Har
ksRecognitionDto.setSub_mch_id(String.valueOf(flowDetail.getOrderId()));
KsRecognitionVo ksRecognitionVo = thirdKsService.recognition(ksRecognitionDto).getData();
if (ObjectUtil.isEmpty(ksRecognitionVo) || !ksRecognitionVo.isSuccess()) {
log.info("|{}|disposeVideoCallback 提交识别错误dto|{}|vo|{}|", TAG, JSONUtil.toJsonStr(ksRecognitionDto), JSONUtil.toJsonStr(ksRecognitionVo));
String errorMsg = String.format("|%s|disposeVideoCallback 提交识别错误dto|%s|vo|%s|", TAG, JSONUtil.toJsonStr(ksRecognitionDto), JSONUtil.toJsonStr(ksRecognitionVo));
log.error(errorMsg);
getSelf().flowStatusControl(flowDetail, ksRecognitionDto, ksRecognitionVo, errorMsg);
return;
}
// 更新流程
HardDoorFlowEntity ksSubmitUpdateObj = HardDoorFlowEntity.builder().id(flowDetail.getId()).skuSubmitDto(JSONUtil.toJsonStr(ksRecognitionDto)).skuSubmitVo(JSONUtil.toJsonStr(ksRecognitionVo)).skuSubmitRecogId(ksRecognitionVo.getKs_recog_id()).skuSubmitTime(LocalDateTime.now()).build();
baseMapper.updateById(ksSubmitUpdateObj);
getSelf().flowStatusControl(flowDetail, ksRecognitionDto, ksRecognitionVo, null);
}
/**
@@ -329,24 +317,128 @@ public class HardDoorFlowServiceImpl extends ServiceImpl<HardDoorFlowMapper, Har
log.error("|{}|disposeRecognitionCallback 该流程识别已经回调dto|{}|", TAG, JSONUtil.toJsonStr(dto));
return;
}
HardDoorFlowEntity updateObj = HardDoorFlowEntity.builder().id(flowDetail.getId()).skuCallbackVo(JSONUtil.toJsonStr(dto)).skuCallbackTime(LocalDateTime.now()).build();
baseMapper.updateById(updateObj);
// 查询订单
HardOrderEntity orderDetail = hardOrderService.getById(flowDetail.getOrderId());
if (ObjectUtil.isEmpty(orderDetail)) {
log.error("|{}|disposeRecognitionCallback 意外的错误,订单不存在dto|{}|", TAG, JSONUtil.toJsonStr(dto));
String ksFlowCode = dto.getState().getCode();
String ksRecognitionCode = dto.getResult().getStatus().getCode();
if (ObjectUtil.notEqual(ksFlowCode, "2") || ObjectUtil.notEqual(ksRecognitionCode, "2")) {
String ksErrorMsg = String.format("商品识别响应错误:ksFlowCode:%s;ksRecognitionCode:%s;", ksFlowCode, ksRecognitionCode);
log.error(ksErrorMsg);
getSelf().flowStatusControl(flowDetail, null, dto, ksErrorMsg);
return;
}
KsRecognitionCallbackDto.Result result = dto.getResult();
List<KsRecognitionCallbackDto.ResultSku> resultSkuList = result.getResult();
if (ObjectUtil.isNotEmpty(resultSkuList)) {
Long orderId = hardOrderService.payHardDoorOrder(orderDetail, resultSkuList);
if (ObjectUtil.isNotEmpty(orderId)) {
// 完成授权流程
HardAuthEntity updateAuthObj = HardAuthEntity.builder().id(authDetail.getId()).isDone(YesNoEnum.YES.getCode()).isDoneTime(LocalDateTime.now()).build();
hardAuthMapper.updateById(updateAuthObj);
if (ObjectUtil.isEmpty(resultSkuList)) {
String ksErrorMsg = "商品识别响应错误,识别的商品列表为空";
log.error(ksErrorMsg);
getSelf().flowStatusControl(flowDetail, null, dto, ksErrorMsg);
return;
}
getSelf().flowStatusControl(flowDetail, null, dto, null);
// 查询订单
HardOrderEntity orderDetail = hardOrderService.getById(flowDetail.getOrderId());
if (ObjectUtil.isEmpty(orderDetail)) {
String ksErrorMsg = String.format("订单结算错误,订单不存在orderId%s", flowDetail.getOrderId());
log.error(ksErrorMsg);
getSelf().flowStatusControl(flowDetail, null, dto, ksErrorMsg);
return;
}
try {
hardOrderService.payHardDoorOrder(orderDetail, resultSkuList);
// 完成授权流程
HardAuthEntity updateAuthObj = HardAuthEntity.builder().id(authDetail.getId()).isDone(YesNoEnum.YES.getCode()).isDoneTime(LocalDateTime.now()).build();
hardAuthMapper.updateById(updateAuthObj);
} catch (Exception e) {
e.printStackTrace();
String ksErrorMsg = String.format("订单结算错误,订单支付失败error%s;", e.getMessage());
log.error(ksErrorMsg);
getSelf().flowStatusControl(flowDetail, null, dto, ksErrorMsg);
}
}
/**
* 流程状态控制(发起流程需要手动)
*/
@Transactional(rollbackFor = Exception.class)
public void flowStatusControl(HardDoorFlowEntity flow, Object dto, Object vo, String error) {
if (ObjectUtil.isAllNotEmpty(flow.getId(), flow.getFlowStatus())) {
log.error("|{}|flowStatusControl 意外的错误,流程id或者flowstatus为空", TAG);
return;
}
HardDoorFlowEnum flowStatus = HardDoorFlowEnum.valueOfByType(flow.getFlowStatus());
HardDoorFlowEnum nextType = HardDoorFlowEnum.getNextType(flowStatus);
if (ObjectUtil.isEmpty(nextType)) {
log.error("|{}|flowStatusControl 意外的错误,流程状态控制错误该流程已结束", TAG);
return;
}
HardDoorFlowEntity updateObj = new HardDoorFlowEntity();
updateObj.setId(flow.getId());
updateObj.setError(error);
updateObj.setFlowStatus(nextType.getType());
switch (nextType) {
// 智能柜申请开门
case FLOW_APPLY_OPEN -> {
updateObj.setRequestOpenDto(JSONUtil.toJsonStr(dto));
updateObj.setRequestOpenVo(JSONUtil.toJsonStr(vo));
updateObj.setRequestOpenTime(LocalDateTime.now());
if (ObjectUtil.isNotEmpty(flow.getHardId())) {
updateObj.setHardId(flow.getHardId());
}
if (ObjectUtil.isNotEmpty(flow.getHardDoorId())) {
updateObj.setHardDoorId(flow.getHardDoorId());
}
if (ObjectUtil.isNotEmpty(flow.getCabinetNo())) {
updateObj.setCabinetNo(flow.getCabinetNo());
}
if (ObjectUtil.isNotEmpty(error)) {
updateObj.setErrorDesc("智能柜申请开门错误");
}
break;
}
// 智能柜开门响应
case FLOW_CALLBACK_OPEN -> {
updateObj.setOpenCallbackVo(JSONUtil.toJsonStr(vo));
updateObj.setOpenCallbackTime(LocalDateTime.now());
if (ObjectUtil.isNotEmpty(flow.getIsOpen())) {
updateObj.setIsOpen(flow.getIsOpen());
}
if (ObjectUtil.isNotEmpty(flow.getOrderId())) {
updateObj.setOrderId(flow.getOrderId());
}
if (ObjectUtil.isNotEmpty(error)) {
updateObj.setErrorDesc("智能柜开门响应错误");
}
break;
}
// 智能柜视频回调
case FLOW_CALLBACK_VIDEO -> {
updateObj.setVideoCallbackVo(JSONUtil.toJsonStr(vo));
updateObj.setVideoCallbackTime(LocalDateTime.now());
if (ObjectUtil.isNotEmpty(error)) {
updateObj.setErrorDesc("智能柜视频回调错误");
}
break;
}
// 商品提交识别提交
case FLOW_SUBMIT_RECOGNITION -> {
updateObj.setSkuSubmitDto(JSONUtil.toJsonStr(dto));
updateObj.setSkuSubmitVo(JSONUtil.toJsonStr(vo));
updateObj.setSkuSubmitTime(LocalDateTime.now());
if (ObjectUtil.isNotEmpty(error)) {
updateObj.setErrorDesc("商品提交识别提交错误");
}
break;
}
// 商品识别响应
case FLOW_CALLBACK_RECOGNITION -> {
updateObj.setSkuCallbackVo(JSONUtil.toJsonStr(vo));
updateObj.setSkuCallbackTime(LocalDateTime.now());
if (ObjectUtil.isNotEmpty(error)) {
updateObj.setErrorDesc("商品识别响应错误");
}
break;
}
}
baseMapper.updateById(updateObj);
}
private void disposeList(List<HardDoorFlowVo> list, HardDoorFlowDto dto) {