feat:审批功能重构-安能添加行程和变更行程

This commit is contained in:
lulz1 2024-07-02 10:56:13 +08:00
parent 874bc75247
commit eaa76fbce3
50 changed files with 696 additions and 112 deletions

View File

@ -5,5 +5,6 @@ import lombok.Data;
@Data @Data
public class LegApprovalParam { public class LegApprovalParam {
private Long routeId; private Long routeId;
private String approvalReason;
private String extension; private String extension;
} }

View File

@ -9,6 +9,7 @@ import com.chint.domain.aggregates.order.OrderDetail;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
import org.springframework.data.annotation.Id; import org.springframework.data.annotation.Id;
import org.springframework.data.annotation.Transient;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.util.ArrayList; import java.util.ArrayList;
@ -44,11 +45,11 @@ public class LegRes {
private String destinationDescription; private String destinationDescription;
private List<String> supplierList; private List<String> supplierList;
private List<String> supplierNameList; private List<String> supplierNameList;
private Integer legStatus;
private String changeReason; private String changeReason;
private Integer legStatus;
private String legStatusName; private String legStatusName;
private Integer legApprovalStatus;
private String legApprovalStatusName;
private String currencyType; private String currencyType;
private List<LocationRes> otherLocationList; private List<LocationRes> otherLocationList;

View File

@ -2,6 +2,7 @@ package com.chint.application.dtos.response;
import com.chint.domain.aggregates.order.ApproveOrderNo; import com.chint.domain.aggregates.order.ApproveOrderNo;
import com.chint.domain.value_object.enums.RoutePermission;
import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
@ -11,6 +12,7 @@ import org.springframework.data.relational.core.mapping.Embedded;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.List; import java.util.List;
import java.util.Set;
@Data @Data
public class RouteOrderPageRes { public class RouteOrderPageRes {
@ -48,4 +50,5 @@ public class RouteOrderPageRes {
private String ifHaveCarLeg; private String ifHaveCarLeg;
@ApiModelProperty("是否能被确认结束, 0不能1能") @ApiModelProperty("是否能被确认结束, 0不能1能")
private String ifCanBeFinished; private String ifCanBeFinished;
private Set<RoutePermission> routePermissionSet;
} }

View File

@ -3,6 +3,7 @@ package com.chint.application.dtos.response;
import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.bean.BeanUtil;
import com.chint.domain.aggregates.order.ApproveOrderNo; import com.chint.domain.aggregates.order.ApproveOrderNo;
import com.chint.domain.aggregates.order.RouteOrder; import com.chint.domain.aggregates.order.RouteOrder;
import com.chint.domain.value_object.enums.RoutePermission;
import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
@ -13,6 +14,7 @@ import org.springframework.data.relational.core.mapping.Embedded;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.util.List; import java.util.List;
import java.util.Set;
import static com.chint.infrastructure.constant.RouteConstant.CAN_BE_FINISHED; import static com.chint.infrastructure.constant.RouteConstant.CAN_BE_FINISHED;
import static com.chint.infrastructure.constant.RouteConstant.CAN_NOT_BE_FINISHED; import static com.chint.infrastructure.constant.RouteConstant.CAN_NOT_BE_FINISHED;
@ -52,6 +54,7 @@ public class RouteOrderRes {
private List<OrderDetailRes> orderDetailRes; private List<OrderDetailRes> orderDetailRes;
@ApiModelProperty("是否能被确认结束, 0不能1能") @ApiModelProperty("是否能被确认结束, 0不能1能")
private String ifCanBeFinished; private String ifCanBeFinished;
private Set<RoutePermission> routePermissionSet;
public static RouteOrderRes copyFrom(RouteOrder routeOrder) { public static RouteOrderRes copyFrom(RouteOrder routeOrder) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");

View File

@ -1,13 +1,12 @@
package com.chint.application.in; package com.chint.application.in;
import com.chint.application.dtos.AddLegData; import com.chint.application.dtos.*;
import com.chint.application.dtos.DeleteLegData;
import com.chint.application.dtos.FinishOrderParam;
import com.chint.application.queryies.OrderQuery; import com.chint.application.queryies.OrderQuery;
import com.chint.application.services.OrderApplicationService; import com.chint.application.services.OrderApplicationService;
import com.chint.domain.aggregates.order.RouteOrder; import com.chint.domain.aggregates.order.RouteOrder;
import com.chint.domain.service.OrderDetailDomainService; import com.chint.domain.service.OrderDetailDomainService;
import com.chint.domain.service.OrderDomainService; import com.chint.domain.service.OrderDomainService;
import com.chint.domain.service.RouteApprovalDomainService;
import com.chint.domain.service.RouteRequestDomainService; import com.chint.domain.service.RouteRequestDomainService;
import com.chint.domain.value_object.OrderSaveData; import com.chint.domain.value_object.OrderSaveData;
import com.chint.domain.value_object.SyncLegData; import com.chint.domain.value_object.SyncLegData;
@ -42,6 +41,9 @@ public class OrderController {
@Autowired @Autowired
private RouteRequestDomainService routeRequestDomainService; private RouteRequestDomainService routeRequestDomainService;
@Autowired
private RouteApprovalDomainService routeApprovalDomainService;
@ApiOperation("保存行程规划单") @ApiOperation("保存行程规划单")
@PostMapping("/save") @PostMapping("/save")
@ -62,12 +64,11 @@ public class OrderController {
@ApiOperation("取消已同步的行程规划单") @ApiOperation("取消已同步的行程规划单")
@PostMapping("/sync/cancel") @PostMapping("/sync/cancel")
public Result<String> syncOrderCancel(@RequestBody SyncLegData syncLegData) { public Result<String> approvalLegChangeAndAdd(@RequestBody SyncLegData syncLegData) {
orderApplicationService.syncCancel(syncLegData); orderApplicationService.syncCancel(syncLegData);
return Result.Success(SUCCESS); return Result.Success(SUCCESS);
} }
@ApiOperation("批量同步行程规划单到供应商") @ApiOperation("批量同步行程规划单到供应商")
@PostMapping("/sync/batch") @PostMapping("/sync/batch")
public Result<String> syncOrderBatch(@RequestBody SyncLegData syncLegData) { public Result<String> syncOrderBatch(@RequestBody SyncLegData syncLegData) {
@ -96,7 +97,7 @@ public class OrderController {
return Result.Success(SUCCESS); return Result.Success(SUCCESS);
} }
@Transactional
@ApiOperation("修改行程节点") @ApiOperation("修改行程节点")
@PostMapping("/leg/change") @PostMapping("/leg/change")
public Result<String> changeLeg(@RequestBody AddLegData addLegData) { public Result<String> changeLeg(@RequestBody AddLegData addLegData) {
@ -105,7 +106,6 @@ public class OrderController {
} }
@ApiOperation("删除行程节点") @ApiOperation("删除行程节点")
@PostMapping("/leg/delete") @PostMapping("/leg/delete")
public Result<String> deleteLeg(@RequestBody DeleteLegData deleteLegData) { public Result<String> deleteLeg(@RequestBody DeleteLegData deleteLegData) {
@ -135,4 +135,11 @@ public class OrderController {
return Result.error(FAILURE); return Result.error(FAILURE);
} }
} }
@ApiOperation("行程规划单——行程变更新增批量提交审批")
@PostMapping("/approval/legs")
public Result<String> approvalLegChangeAndAdd(@RequestBody LegApprovalParam legApprovalParam) {
routeApprovalDomainService.approveRouteOfLegChangeAndAdd(legApprovalParam);
return Result.Success(SUCCESS);
}
} }

View File

@ -4,10 +4,12 @@ import com.chint.application.dtos.DeleteLegData;
import com.chint.application.dtos.LegApprovalParam; import com.chint.application.dtos.LegApprovalParam;
import com.chint.application.queryies.OrderQuery; import com.chint.application.queryies.OrderQuery;
import com.chint.application.services.OrderApplicationService; import com.chint.application.services.OrderApplicationService;
import com.chint.domain.aggregates.approval.ApprovalResultData;
import com.chint.domain.aggregates.order.RouteOrder; import com.chint.domain.aggregates.order.RouteOrder;
import com.chint.domain.repository.RouteRepository; import com.chint.domain.repository.RouteRepository;
import com.chint.domain.service.LegDomainService; import com.chint.domain.service.LegDomainService;
import com.chint.domain.service.OrderDomainService; import com.chint.domain.service.OrderDomainService;
import com.chint.domain.service.RouteApprovalDomainService;
import com.chint.domain.service.SystemDomainService; import com.chint.domain.service.SystemDomainService;
import com.chint.domain.value_object.ApproveCustomField; import com.chint.domain.value_object.ApproveCustomField;
import com.chint.domain.value_object.ApproveRouteData; import com.chint.domain.value_object.ApproveRouteData;
@ -44,6 +46,8 @@ public class OrderPublicController {
@Autowired @Autowired
private RouteRepository routeRepository; private RouteRepository routeRepository;
@Autowired
private RouteApprovalDomainService routeApprovalDomainService;
@ApiOperation("提交审批行程规划单") @ApiOperation("提交审批行程规划单")
@PostMapping("/approve") @PostMapping("/approve")
@ -54,12 +58,7 @@ public class OrderPublicController {
return Result.Success(SUCCESS); return Result.Success(SUCCESS);
} }
@ApiOperation("提交需要审批的行程节点")
@PostMapping("/approve/leg")
public Result<String> approveOrder(@RequestBody LegApprovalParam param) {
return Result.Success(SUCCESS);
}
@ApiOperation("审批拒绝行程规划单") @ApiOperation("审批拒绝行程规划单")
@ -105,4 +104,12 @@ public class OrderPublicController {
.toList(); .toList();
return Result.Success(SUCCESS, approveCustomFieldList); return Result.Success(SUCCESS, approveCustomFieldList);
} }
@ApiOperation("提交需要审批的行程节点")
@PostMapping("/approve/response")
public Result<String> approveOrder(@RequestBody ApprovalResultData data) {
routeApprovalDomainService.handlerApprovalResponse(data);
return Result.Success(SUCCESS);
}
} }

View File

@ -55,8 +55,8 @@ public class OrderOutController {
@Autowired @Autowired
private RouteRepository routeRepository; private RouteRepository routeRepository;
// @Autowired @Autowired
// private RouteApprovalDomainService routeApprovalDomainService; private RouteApprovalDomainService routeApprovalDomainService;
@ApiOperation("根据临时单号和系统编码查询订单") @ApiOperation("根据临时单号和系统编码查询订单")
@PostMapping("/query/billcode") @PostMapping("/query/billcode")
@ -90,7 +90,7 @@ public class OrderOutController {
routeOrder = routeOrderFromDB; routeOrder = routeOrderFromDB;
} }
if (routeOrder != null) { if (routeOrder != null) {
// routeApprovalDomainService.checkApprovalPermissions(routeOrder); routeApprovalDomainService.checkApprovalPermissions(routeOrder);
RouteOrderRes routeOrderRes = orderQuery.queryRouteRes(routeOrder); RouteOrderRes routeOrderRes = orderQuery.queryRouteRes(routeOrder);
return Result.Success(SUCCESS, routeOrderRes); return Result.Success(SUCCESS, routeOrderRes);
} else { } else {

View File

@ -18,6 +18,7 @@ import com.chint.domain.exceptions.NotFoundException;
import com.chint.domain.repository.*; import com.chint.domain.repository.*;
import com.chint.domain.service.LegDomainService; import com.chint.domain.service.LegDomainService;
import com.chint.domain.service.OrderDomainService; import com.chint.domain.service.OrderDomainService;
import com.chint.domain.service.RouteApprovalDomainService;
import com.chint.domain.service.amount_estimate.EstimateAdapter; import com.chint.domain.service.amount_estimate.EstimateAdapter;
import com.chint.domain.value_object.*; import com.chint.domain.value_object.*;
import com.chint.infrastructure.cache.RouteCacheService; import com.chint.infrastructure.cache.RouteCacheService;
@ -93,6 +94,9 @@ public class OrderQuery {
@Autowired @Autowired
private SupplierRepository supplierRepository; private SupplierRepository supplierRepository;
@Autowired
private RouteApprovalDomainService routeApprovalDomainService;
public RouteOrder queryByOrderId(OrderQueryData queryData) { public RouteOrder queryByOrderId(OrderQueryData queryData) {
return routeRepository.queryById(queryData.getRouteId()).reloadStatus(); return routeRepository.queryById(queryData.getRouteId()).reloadStatus();
} }
@ -154,6 +158,7 @@ public class OrderQuery {
); );
int total = routeOrders.size(); int total = routeOrders.size();
routeApprovalDomainService.checkApprovalPermissions(routeOrders);
List<RouteOrderPageRes> orders = routeOrders List<RouteOrderPageRes> orders = routeOrders
.stream() .stream()
.sorted(statusComparator.thenComparing(RouteOrder::getUpdateTime).reversed()) .sorted(statusComparator.thenComparing(RouteOrder::getUpdateTime).reversed())

View File

@ -17,4 +17,5 @@ public class ApprovalData {
private List<Leg> addLegList; private List<Leg> addLegList;
private List<Pair<Leg, Leg>> changeLegList; private List<Pair<Leg, Leg>> changeLegList;
private OrderDetail orderDetail; private OrderDetail orderDetail;
private String approvalRecordNo;
} }

View File

@ -4,7 +4,8 @@ import com.chint.domain.aggregates.approval.platform.ApprovalPlatform;
import com.chint.domain.aggregates.order.OrderDetail; import com.chint.domain.aggregates.order.OrderDetail;
import com.chint.domain.aggregates.order.RouteOrder; import com.chint.domain.aggregates.order.RouteOrder;
import static com.chint.domain.aggregates.approval.ApprovalProcess.ApprovalType.LEG_ADD; import static com.chint.domain.aggregates.approval.ApprovalType.LEG_ADD;
public class ApprovalLegAdd extends ApprovalProcess { public class ApprovalLegAdd extends ApprovalProcess {
@ -34,7 +35,13 @@ public class ApprovalLegAdd extends ApprovalProcess {
} }
@Override @Override
public void submitToBpm() { public ApprovalProcess doSubmitToBpm() {
bpmPlatform.submitLegAddApproval(approvalData); bpmPlatform.submitLegAddApproval(approvalData);
return this;
}
@Override
public void handlerApprovalResultBefore(ApprovalResultData data) {
} }
} }

View File

@ -1,18 +1,21 @@
package com.chint.domain.aggregates.approval; package com.chint.domain.aggregates.approval;
import com.chint.domain.aggregates.approval.platform.ApprovalPlatform; import com.chint.domain.aggregates.approval.platform.ApprovalPlatform;
import com.chint.domain.aggregates.base.BaseEvent;
import com.chint.domain.aggregates.order.Leg; import com.chint.domain.aggregates.order.Leg;
import com.chint.domain.aggregates.order.OrderDetail; import com.chint.domain.aggregates.order.LegApprovalEvent;
import com.chint.domain.aggregates.order.RouteOrder; import com.chint.domain.aggregates.order.RouteOrder;
import com.google.gson.Gson; import com.google.gson.Gson;
import org.springframework.data.util.Pair; import org.springframework.data.util.Pair;
import java.util.Comparator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static com.chint.domain.aggregates.approval.ApprovalProcess.ApprovalType.LEG_ADD_CHANGE_BATCH; import static com.chint.domain.aggregates.approval.ApprovalType.LEG_ADD_CHANGE_BATCH;
import static com.chint.infrastructure.constant.LegConstant.LEG_APPROVAL_STATUS_PREPARE; import static com.chint.infrastructure.constant.LegConstant.LEG_APPROVAL_STATUS_PREPARE;
import static com.chint.infrastructure.constant.LegConstant.LEG_APPROVAL_STATUS_SUBMIT;
public class ApprovalLegAddAndChangeBatch extends ApprovalProcess { public class ApprovalLegAddAndChangeBatch extends ApprovalProcess {
@ -55,7 +58,31 @@ public class ApprovalLegAddAndChangeBatch extends ApprovalProcess {
} }
@Override @Override
public void submitToBpm() { public ApprovalProcess doSubmitToBpm() {
bpmPlatform.submitLegAddOrChangeApproval(approvalData); bpmPlatform.submitLegAddOrChangeApproval(approvalData);
return this;
}
@Override
public void handlerApprovalResultBefore(ApprovalResultData data) {
String approvalRecordNo = data.getApprovalRecordNo();
RouteOrder routeOrder = data.getRouteOrder();
routeOrder.getLegItems().stream()
.filter(leg -> {
BaseEvent lastEvent = leg.getLastEvent();
return lastEvent.getEventType().equals(LEG_APPROVAL_STATUS_SUBMIT) &&
lastEvent.getExtension().equals(approvalRecordNo);
}).forEach(leg -> {
if (data.getApprovalStatus().equals(ApprovalRecord.successApprovalStatus())) {
leg.addEvent(LegApprovalEvent.success());
} else {
leg.addEvent(LegApprovalEvent.reject());//如果行程被驳回 那么就要回滚到审批前的状态
leg.getLegApprovalEventList()
.stream()
.filter(legApprovalEvent -> legApprovalEvent.getEventType().equals(LEG_APPROVAL_STATUS_PREPARE))
.max(Comparator.comparing(LegApprovalEvent::getHappenTime))
.ifPresent(it -> leg.restoreFromLegString(it.getExtension()));
}
});
} }
} }

View File

@ -4,8 +4,8 @@ package com.chint.domain.aggregates.approval;
import com.chint.domain.aggregates.approval.platform.ApprovalPlatform; import com.chint.domain.aggregates.approval.platform.ApprovalPlatform;
import com.chint.domain.aggregates.order.RouteOrder; import com.chint.domain.aggregates.order.RouteOrder;
import static com.chint.domain.aggregates.approval.ApprovalProcess.ApprovalType.LEG_ADD; import static com.chint.domain.aggregates.approval.ApprovalType.LEG_CHANGE;
import static com.chint.domain.aggregates.approval.ApprovalProcess.ApprovalType.LEG_CHANGE;
public class ApprovalLegChange extends ApprovalProcess{ public class ApprovalLegChange extends ApprovalProcess{
@ -30,7 +30,13 @@ public class ApprovalLegChange extends ApprovalProcess{
} }
@Override @Override
public void submitToBpm() { public ApprovalProcess doSubmitToBpm() {
bpmPlatform.submitLegChangeApproval(approvalData); bpmPlatform.submitLegChangeApproval(approvalData);
return this;
}
@Override
public void handlerApprovalResultBefore(ApprovalResultData data) {
} }
} }

View File

@ -3,7 +3,8 @@ package com.chint.domain.aggregates.approval;
import com.chint.domain.aggregates.approval.platform.ApprovalPlatform; import com.chint.domain.aggregates.approval.platform.ApprovalPlatform;
import com.chint.domain.aggregates.order.RouteOrder; import com.chint.domain.aggregates.order.RouteOrder;
import static com.chint.domain.aggregates.approval.ApprovalProcess.ApprovalType.LEG_CHANGE; import static com.chint.domain.aggregates.approval.ApprovalType.LEG_CHANGE;
public class ApprovalOrderChange extends ApprovalProcess{ public class ApprovalOrderChange extends ApprovalProcess{
@ -28,7 +29,13 @@ public class ApprovalOrderChange extends ApprovalProcess{
} }
@Override @Override
public void submitToBpm() { public ApprovalProcess doSubmitToBpm() {
bpmPlatform.submitOrderChangeApproval(approvalData); bpmPlatform.submitOrderChangeApproval(approvalData);
return this;
}
@Override
public void handlerApprovalResultBefore(ApprovalResultData data) {
} }
} }

View File

@ -3,7 +3,8 @@ package com.chint.domain.aggregates.approval;
import com.chint.domain.aggregates.approval.platform.ApprovalPlatform; import com.chint.domain.aggregates.approval.platform.ApprovalPlatform;
import com.chint.domain.aggregates.order.RouteOrder; import com.chint.domain.aggregates.order.RouteOrder;
import static com.chint.domain.aggregates.approval.ApprovalProcess.ApprovalType.ORDER_EXPENSE; import static com.chint.domain.aggregates.approval.ApprovalType.ORDER_EXPENSE;
public class ApprovalOrderExpense extends ApprovalProcess{ public class ApprovalOrderExpense extends ApprovalProcess{
@ -28,8 +29,14 @@ public class ApprovalOrderExpense extends ApprovalProcess{
} }
@Override @Override
public void submitToBpm() { public ApprovalProcess doSubmitToBpm() {
bpmPlatform.submitOrderExpenseApproval(approvalData); bpmPlatform.submitOrderExpenseApproval(approvalData);
return this;
}
@Override
public void handlerApprovalResultBefore(ApprovalResultData data) {
} }
} }

View File

@ -3,9 +3,10 @@ package com.chint.domain.aggregates.approval;
import com.chint.domain.aggregates.approval.platform.ApprovalPlatform; import com.chint.domain.aggregates.approval.platform.ApprovalPlatform;
import com.chint.domain.aggregates.order.RouteOrder; import com.chint.domain.aggregates.order.RouteOrder;
import static com.chint.domain.aggregates.approval.ApprovalProcess.ApprovalType.ORDER_REFUND; import static com.chint.domain.aggregates.approval.ApprovalType.ORDER_REFUND;
public class ApprovalOrderRefund extends ApprovalProcess{
public class ApprovalOrderRefund extends ApprovalProcess {
public ApprovalOrderRefund(ApprovalPlatform bpmPlatform) { public ApprovalOrderRefund(ApprovalPlatform bpmPlatform) {
super(bpmPlatform); super(bpmPlatform);
@ -28,8 +29,14 @@ public class ApprovalOrderRefund extends ApprovalProcess{
} }
@Override @Override
public void submitToBpm() { public ApprovalProcess doSubmitToBpm() {
bpmPlatform.submitOrderRefundApproval(approvalData); bpmPlatform.submitOrderRefundApproval(approvalData);
return this;
}
@Override
public void handlerApprovalResultBefore(ApprovalResultData data) {
} }
} }

View File

@ -1,11 +1,17 @@
package com.chint.domain.aggregates.approval; package com.chint.domain.aggregates.approval;
import com.chint.domain.aggregates.approval.platform.ApprovalPlatform; import com.chint.domain.aggregates.approval.platform.ApprovalPlatform;
import com.chint.domain.aggregates.order.Leg;
import com.chint.domain.aggregates.order.LegApprovalEvent;
import com.chint.domain.aggregates.order.OrderDetail; import com.chint.domain.aggregates.order.OrderDetail;
import com.chint.domain.aggregates.order.RouteOrder; import com.chint.domain.aggregates.order.RouteOrder;
import lombok.Data;
import java.util.function.Consumer;
// 定义抽象类 ApprovalProcess // 定义抽象类 ApprovalProcess
@Data
public abstract class ApprovalProcess { public abstract class ApprovalProcess {
protected ApprovalPlatform bpmPlatform; protected ApprovalPlatform bpmPlatform;
@ -20,9 +26,11 @@ public abstract class ApprovalProcess {
public ApprovalProcess approveData(RouteOrder routeOrder) { public ApprovalProcess approveData(RouteOrder routeOrder) {
approvalData = new ApprovalData(); approvalData = new ApprovalData();
approvalData.setRouteOrder(routeOrder);
return this; return this;
} }
public ApprovalProcess approveData(RouteOrder routeOrder, OrderDetail orderDetail) { public ApprovalProcess approveData(RouteOrder routeOrder, OrderDetail orderDetail) {
ApprovalData approvalData = new ApprovalData(); ApprovalData approvalData = new ApprovalData();
approvalData.setRouteOrder(routeOrder); approvalData.setRouteOrder(routeOrder);
@ -32,31 +40,66 @@ public abstract class ApprovalProcess {
} }
// 审批流程的抽象方法 // 审批流程的抽象方法
public abstract boolean approve(); public boolean approve() {
return false;
}
// 记录动作将审批记录保存到数据库
public ApprovalProcess record(Consumer<ApprovalRecord> consumer) {
RouteOrder routeOrder = approvalData.getRouteOrder();
if (routeOrder != null) {
ApprovalRecord approvalRecord = ApprovalRecord.of(routeOrder, this);
approvalData.setApprovalRecordNo(approvalRecord.getApprovalRecordNo());
consumer.accept(approvalRecord); // 使用传入的Consumer对象
return this;
} else {
return null;
}
}
// 退回流程的抽象方法 // 退回流程的抽象方法
public abstract void reject(); public void reject() {
}
// 退回流程的抽象方法
public void success() {
}
// 通用的通知方法 // 通用的通知方法
public void notifyUser(String message) { public void notifyUser(String message) {
// 发送通知的逻辑 // &#x53D1;&#x9001;&#x901A;&#x77E5;&#x7684;&#x903B;&#x8F91;
System.out.println("Notify user: " + message); System.out.println("Notify user: " + message);
} }
// 提交审批到BPM平台的抽象方法 // 提交审批到BPM平台的抽象方法
public abstract void submitToBpm(); public abstract ApprovalProcess doSubmitToBpm();
public ApprovalProcess beforeSubmitToBpm() {
//所有被提交审批的被加入审批事件
approvalData.getAddLegList().forEach(leg -> leg.addEvent(LegApprovalEvent.submit()));
approvalData.getChangeLegList().forEach(it -> {
Leg newLeg = it.getFirst();
newLeg.addEvent(LegApprovalEvent.submit());
});
return this;
}
public ApprovalProcess submitToBpm() {
return beforeSubmitToBpm().doSubmitToBpm();
}
public void handlerApprovalResult(ApprovalResultData data) {
handlerApprovalResultBefore(data);
this.bpmPlatform.receiveApprovalResult(data);
}
// 接收审批结果 // 接收审批结果
public void receiveApprovalResult(String resultData) { public abstract void handlerApprovalResultBefore(ApprovalResultData data);
bpmPlatform.receiveApprovalResult(resultData);
}
public enum ApprovalType {
LEG_ADD,
LEG_CHANGE,
ORDER_EXPENSE,
ORDER_CHANGE,
ORDER_REFUND,
LEG_ADD_CHANGE_BATCH
}
} }

View File

@ -1,21 +1,68 @@
package com.chint.domain.aggregates.approval; package com.chint.domain.aggregates.approval;
import com.chint.domain.aggregates.order.ApproveOrderNo;
import com.chint.domain.aggregates.order.RouteOrder;
import com.chint.infrastructure.util.OrderNo;
import lombok.Data; import lombok.Data;
import org.springframework.data.annotation.Id; import org.springframework.data.annotation.Id;
import org.springframework.data.relational.core.mapping.Table; import org.springframework.data.relational.core.mapping.Table;
import java.io.Serial; import java.io.Serial;
import java.io.Serializable; import java.io.Serializable;
import java.time.LocalDateTime;
@Data @Data
@Table("approval_record") @Table("approval_record")
public class ApprovalRecord implements Serializable { public class ApprovalRecord implements Serializable {
@Serial @Serial
private static final long serialVersionUID = 987769272351235112L; private static final long serialVersionUID = 987769272351235112L;
@Id @Id
private Long id; private Long id;
private Long routeId; private Long routeId;
private Long userId; private String employeeNo;
private String status; private String approvalRecordNo;
private String companyCode;
private String companyName;
private String sysCode;
private String approvalType;
private Integer approvalStatus;
private LocalDateTime approvalSubmitDate;
private LocalDateTime approvalResponseDate;
private String approvalPlatformMark;
private String approvalReason;
private String extension;
private String extensionSub;
public static ApprovalRecord of(RouteOrder routeOrder, ApprovalProcess approvalProcess) {
ApprovalRecord approvalRecord = new ApprovalRecord();
approvalRecord.routeId = routeOrder.getRouteId();
approvalRecord.employeeNo = routeOrder.getUserId();
approvalRecord.approvalRecordNo = OrderNo.generateApprovalNo();
ApproveOrderNo approveOrderNo = routeOrder.getApproveOrderNo();
approvalRecord.companyCode = approveOrderNo.getAccountCompany();
approvalRecord.companyName = approveOrderNo.getAccountCompanyName();
approvalRecord.sysCode = approveOrderNo.getSysCode();
approvalRecord.approvalType = approvalProcess.getApprovalType().name();
approvalRecord.approvalStatus = prepareApprovalStatus();
approvalRecord.approvalSubmitDate = LocalDateTime.now();
approvalRecord.approvalPlatformMark = approvalProcess.getBpmPlatform().getApprovalPlatformName();
return approvalRecord;
}
public ApprovalRecord reason(String approvalReason) {
this.approvalReason = approvalReason;
return this;
}
public static Integer prepareApprovalStatus() {
return 0;
}
public static Integer successApprovalStatus() {
return 1;
}
public static Integer rejectApprovalStatus() {
return -1;
}
} }

View File

@ -0,0 +1,12 @@
package com.chint.domain.aggregates.approval;
import com.chint.domain.aggregates.order.RouteOrder;
import lombok.Data;
@Data
public class ApprovalResultData {
private String approvalRecordNo;
private Integer approvalStatus;
private String extension;
private RouteOrder routeOrder;
}

View File

@ -1,6 +1,8 @@
package com.chint.domain.aggregates.approval; package com.chint.domain.aggregates.approval;
import com.chint.domain.aggregates.approval.platform.ApprovalPlatform; import com.chint.domain.aggregates.approval.platform.ApprovalPlatform;
import com.chint.domain.repository.ApprovalRecordRepository;
import com.chint.domain.repository.RouteRepository;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.event.ApplicationReadyEvent; import org.springframework.boot.context.event.ApplicationReadyEvent;
@ -12,11 +14,17 @@ import java.util.Map;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@Component @Component
public class ApprovalSubmit implements ApplicationListener<ApplicationReadyEvent> { public class ApprovalSubmit implements ApplicationListener<ApplicationReadyEvent> {
@Autowired @Autowired
private ApplicationContext applicationContext; private ApplicationContext applicationContext;
@Autowired
private ApprovalRecordRepository approvalRecordRepository;
@Autowired
private RouteRepository routeRepository;
@Override @Override
public void onApplicationEvent(@NotNull ApplicationReadyEvent event) { public void onApplicationEvent(@NotNull ApplicationReadyEvent event) {
@ -31,7 +39,7 @@ public class ApprovalSubmit implements ApplicationListener<ApplicationReadyEven
// 静态工厂方法根据类型和平台标识创建具体的 ApprovalProcess 实例 // 静态工厂方法根据类型和平台标识创建具体的 ApprovalProcess 实例
public static ApprovalProcess of(ApprovalProcess.ApprovalType type, String platformMark) { public static ApprovalProcess of(ApprovalType type, String platformMark) {
ApprovalPlatform bpmPlatform = approvalPlatformMap.get(platformMark); ApprovalPlatform bpmPlatform = approvalPlatformMap.get(platformMark);
if (bpmPlatform == null) { if (bpmPlatform == null) {
throw new IllegalArgumentException("Invalid platform mark: " + platformMark); throw new IllegalArgumentException("Invalid platform mark: " + platformMark);
@ -47,4 +55,16 @@ public class ApprovalSubmit implements ApplicationListener<ApplicationReadyEven
default -> throw new IllegalArgumentException("Invalid approval type: " + type); default -> throw new IllegalArgumentException("Invalid approval type: " + type);
}; };
} }
//用于处理审批结果
public void handleApprovalResult(ApprovalResultData data) {
approvalRecordRepository.findByApprovalRecordNo(data.getApprovalRecordNo())
.ifPresent(it -> {
data.setRouteOrder(routeRepository.queryById(it.getRouteId()));
ApprovalProcess approvalProcess = of(ApprovalType.valueOf(it.getApprovalType()), it.getApprovalPlatformMark());
approvalProcess.handlerApprovalResult(data);
approvalRecordRepository.save(it);
routeRepository.save(data.getRouteOrder());
});
}
} }

View File

@ -0,0 +1,10 @@
package com.chint.domain.aggregates.approval;
public enum ApprovalType {
LEG_ADD,
LEG_CHANGE,
ORDER_EXPENSE,
ORDER_CHANGE,
ORDER_REFUND,
LEG_ADD_CHANGE_BATCH
}

View File

@ -1,16 +1,13 @@
package com.chint.domain.aggregates.approval.platform; package com.chint.domain.aggregates.approval.platform;
import com.chint.domain.aggregates.approval.ApprovalData; import com.chint.domain.aggregates.approval.ApprovalData;
import com.chint.domain.aggregates.order.Leg; import com.chint.domain.aggregates.approval.ApprovalResultData;
import com.chint.domain.aggregates.order.OrderDetail;
import com.chint.domain.aggregates.order.RouteOrder;
public interface ApprovalPlatform { public interface ApprovalPlatform {
// 提交审批请求 // 提交审批请求
void submitApproval(ApprovalData approvalData); void submitApproval(ApprovalData approvalData);
// 接收审批结果
void receiveApprovalResult(String resultData);
String getApprovalPlatformName(); String getApprovalPlatformName();
@ -26,4 +23,13 @@ public interface ApprovalPlatform {
void submitOrderRefundApproval(ApprovalData approvalData); void submitOrderRefundApproval(ApprovalData approvalData);
void submitLegAddOrChangeApproval(ApprovalData approvalData); void submitLegAddOrChangeApproval(ApprovalData approvalData);
// 接收审批结果
void receiveApprovalResultCustom(ApprovalResultData resultData);
//这里引入模板模式对审批结果进行
default void receiveApprovalResult(ApprovalResultData resultData){
//这里所有的行程的审批结果进行
this.receiveApprovalResultCustom(resultData);
}
} }

View File

@ -2,6 +2,7 @@ package com.chint.domain.aggregates.approval.platform;
import com.chint.domain.aggregates.approval.ApprovalData; import com.chint.domain.aggregates.approval.ApprovalData;
import com.chint.domain.aggregates.approval.ApprovalResultData;
import com.chint.domain.aggregates.order.*; import com.chint.domain.aggregates.order.*;
import com.chint.domain.aggregates.supplier.Supplier; import com.chint.domain.aggregates.supplier.Supplier;
import com.chint.domain.repository.ApprovalPlatformInfoRepository; import com.chint.domain.repository.ApprovalPlatformInfoRepository;
@ -54,7 +55,7 @@ public class ApprovalPlatformAN implements ApprovalPlatform {
} }
@Override @Override
public void receiveApprovalResult(String resultData) { public void receiveApprovalResultCustom(ApprovalResultData resultData) {
} }
@ -103,6 +104,7 @@ public class ApprovalPlatformAN implements ApprovalPlatform {
private ApprovalScheduleParam createApprovalScheduleParam(ApprovalData approvalData) { private ApprovalScheduleParam createApprovalScheduleParam(ApprovalData approvalData) {
ApprovalScheduleParam approvalScheduleParam = new ApprovalScheduleParam(); ApprovalScheduleParam approvalScheduleParam = new ApprovalScheduleParam();
approvalScheduleParam.setApprovalRecordNo(approvalData.getApprovalRecordNo());
approvalScheduleParam.setSourceSystem(systemNum()); approvalScheduleParam.setSourceSystem(systemNum());
RouteOrder routeOrder = approvalData.getRouteOrder(); RouteOrder routeOrder = approvalData.getRouteOrder();
ApproveOrderNo approveOrderNo = routeOrder.getApproveOrderNo(); ApproveOrderNo approveOrderNo = routeOrder.getApproveOrderNo();
@ -279,7 +281,7 @@ public class ApprovalPlatformAN implements ApprovalPlatform {
} }
@Data @Data
private static class ApprovalScheduleParam { private static class ApprovalScheduleParam extends ApprovalRecordBase {
public String sourceSystem; public String sourceSystem;
public String sourceSystemNum; public String sourceSystemNum;
public String applicant; public String applicant;

View File

@ -0,0 +1,8 @@
package com.chint.domain.aggregates.approval.platform;
import lombok.Data;
@Data
public class ApprovalRecordBase {
private String approvalRecordNo;
}

View File

@ -0,0 +1,5 @@
package com.chint.domain.aggregates.approval.platform;
public interface ApprovalResultReceiver {
void receiveApprovalResult(String resultData, String platformMark);
}

View File

@ -3,6 +3,7 @@ package com.chint.domain.aggregates.base;
import com.chint.domain.aggregates.order.LegApprovalEvent; import com.chint.domain.aggregates.order.LegApprovalEvent;
import java.util.List; import java.util.List;
import java.util.Objects;
public interface EventManageable { public interface EventManageable {
@ -12,7 +13,10 @@ public interface EventManageable {
// 默认方法添加事件 // 默认方法添加事件
default void addEvent(BaseEvent event) { default void addEvent(BaseEvent event) {
List<BaseEvent> events = (List<BaseEvent>) getEvents(); List<BaseEvent> events = (List<BaseEvent>) getEvents();
events.add(event); BaseEvent lastEvent = getLastEvent();
if (!Objects.equals(lastEvent.getEventType(), event.getEventType())) {
events.add(event);
}
} }
// 默认方法获取最新的事件 // 默认方法获取最新的事件

View File

@ -0,0 +1,39 @@
package com.chint.domain.aggregates.base;
import lombok.Data;
import org.springframework.data.annotation.Id;
import org.springframework.data.relational.core.mapping.Table;
import java.io.Serial;
import java.io.Serializable;
import java.util.Arrays;
import java.util.List;
@Data
@Table("permission_config")
public class PermissionConfig implements Serializable {
@Serial
private static final long serialVersionUID = 1098772936113573530L;
@Id
private Long id;
private String permissionName;
private String permissionDescription;
private String permissionType;
private String permissionValue;
private String extension;
public List<String> permissions() {
if (permissionValue == null || permissionValue.isEmpty()) {
return List.of();
}
return Arrays.stream(permissionValue.split("&")).toList();
}
}

View File

@ -416,4 +416,23 @@ public class Leg implements Serializable, EventManageable {
// this.createTime = LocalDateTime.parse(this.createTime.toString(), dateTimeFormatter); // this.createTime = LocalDateTime.parse(this.createTime.toString(), dateTimeFormatter);
// return this; // return this;
// } // }
public String generateLegString() {
return DateTimeUtil.timeToStrCommon(startTime) + "|" +
DateTimeUtil.timeToStrCommon(endTime) + "|" +
originId + "|" + destinationId;
}
public void restoreFromLegString(String legString) {
String[] parts = legString.split("\\|");
if (parts.length == 4) {
this.startTime = DateTimeUtil.strToTime(parts[0]);
this.endTime = DateTimeUtil.strToTime(parts[1]);
this.originId = Long.parseLong(parts[2]);
this.destinationId = Long.parseLong(parts[3]);
} else {
throw new IllegalArgumentException("Invalid legString format.");
}
}
} }

View File

@ -1,7 +1,7 @@
package com.chint.domain.aggregates.order; package com.chint.domain.aggregates.order;
import com.chint.domain.aggregates.base.BaseEvent; import com.chint.domain.aggregates.base.BaseEvent;
import com.google.gson.Gson; import com.chint.infrastructure.util.Json;
import lombok.Data; import lombok.Data;
import org.springframework.data.annotation.Id; import org.springframework.data.annotation.Id;
import org.springframework.data.relational.core.mapping.Column; import org.springframework.data.relational.core.mapping.Column;
@ -41,10 +41,9 @@ public class LegApprovalEvent extends BaseEvent implements Serializable {
} }
public static LegApprovalEvent prepare(Leg oldLeg) { public static LegApprovalEvent prepare(Leg oldLeg) {
Gson gson = new Gson();
LegApprovalEvent event = new LegApprovalEvent(); LegApprovalEvent event = new LegApprovalEvent();
event.setEventType(LEG_APPROVAL_STATUS_PREPARE); event.setEventType(LEG_APPROVAL_STATUS_PREPARE);
event.extension(gson.toJson(oldLeg)); event.extension(oldLeg.generateLegString());
return event; return event;
} }

View File

@ -7,6 +7,7 @@ import com.chint.domain.service.LegDomainService;
import com.chint.domain.service.amount_estimate.EstimateAdapter; import com.chint.domain.service.amount_estimate.EstimateAdapter;
import com.chint.domain.service.supplier.SupplierConstantUtil; import com.chint.domain.service.supplier.SupplierConstantUtil;
import com.chint.domain.value_object.*; import com.chint.domain.value_object.*;
import com.chint.domain.value_object.enums.RoutePermission;
import com.chint.infrastructure.constant.LegConstant; import com.chint.infrastructure.constant.LegConstant;
import com.chint.infrastructure.constant.RouteConstant; import com.chint.infrastructure.constant.RouteConstant;
import com.chint.infrastructure.echo_framework.command.Command; import com.chint.infrastructure.echo_framework.command.Command;
@ -78,6 +79,8 @@ public class RouteOrder implements Serializable {
private String orderStatusName; private String orderStatusName;
@Transient @Transient
private String supplierCNName; private String supplierCNName;
@Transient
private Set<RoutePermission> routePermissionSet;
//共有的扩展字段 //共有的扩展字段
@MappedCollection(idColumn = "route_id") @MappedCollection(idColumn = "route_id")

View File

@ -26,16 +26,23 @@ public class SystemCode implements Serializable {
private List<CompanyInfo> companyInfos; private List<CompanyInfo> companyInfos;
@MappedCollection(idColumn = "system_code_id") @MappedCollection(idColumn = "system_code_id")
private SystemCodeUrl systemCodeUrl; private SystemCodeUrl systemCodeUrl;
@Transient @MappedCollection(idColumn = "system_code_id", keyColumn = "system_code_key")
// @MappedCollection(idColumn = "system_id", keyColumn = "system_key")
private List<SystemCodeExtensionField> systemCodeExtensionFieldList; private List<SystemCodeExtensionField> systemCodeExtensionFieldList;
public String getApprovalPlatformMark() { public String getApprovalPlatformMark() {
return getExtensionValue("ApprovalPlatformMark");
}
public String getApprovalType() {
return getExtensionValue("ApprovalType");
}
private String getExtensionValue(String fieldName) {
if (systemCodeExtensionFieldList == null || systemCodeExtensionFieldList.isEmpty()) { if (systemCodeExtensionFieldList == null || systemCodeExtensionFieldList.isEmpty()) {
return null; return "";
} }
return this.systemCodeExtensionFieldList.stream().filter(it -> it.getFieldName().equals("ApprovalPlatformMark")) return this.systemCodeExtensionFieldList.stream().filter(it -> it.getFieldName().equals(fieldName))
.map(SystemCodeExtensionField::getFieldValue) .map(SystemCodeExtensionField::getFieldValue)
.findFirst() .findFirst()
.orElse(""); .orElse("");

View File

@ -30,7 +30,5 @@ public class SystemCodeExtensionField implements Serializable {
public static SystemCodeExtensionField of(String fieldName, String fieldValue, String extension) { public static SystemCodeExtensionField of(String fieldName, String fieldValue, String extension) {
return new SystemCodeExtensionField(fieldName, fieldValue, extension); return new SystemCodeExtensionField(fieldName, fieldValue, extension);
} }
} }

View File

@ -0,0 +1,10 @@
package com.chint.domain.repository;
import com.chint.domain.aggregates.approval.ApprovalRecord;
import java.util.Optional;
public interface ApprovalRecordRepository {
ApprovalRecord save(ApprovalRecord record);
Optional<ApprovalRecord> findByApprovalRecordNo(String approvalRecordNo);
}

View File

@ -0,0 +1,13 @@
package com.chint.domain.repository;
import com.chint.domain.aggregates.base.PermissionConfig;
import java.util.List;
import java.util.Optional;
import java.util.Set;
public interface PermissionConfigRepository {
Optional<PermissionConfig> findByPermissionName(String permissionName);
List<PermissionConfig> findByPermissionNameIn(Set<String> approvalTypes);
}

View File

@ -3,6 +3,10 @@ package com.chint.domain.repository;
import com.chint.domain.aggregates.system.SystemCode; import com.chint.domain.aggregates.system.SystemCode;
import java.util.Collection;
import java.util.List;
import java.util.Set;
public interface SystemCodeRepository { public interface SystemCodeRepository {
SystemCode save(SystemCode systemCode); SystemCode save(SystemCode systemCode);
@ -11,4 +15,5 @@ public interface SystemCodeRepository {
SystemCode findById(Long id); SystemCode findById(Long id);
List<SystemCode> findBySysCodeIn(Set<String> sysCodes);
} }

View File

@ -228,7 +228,7 @@ public class LegDomainService {
List<Leg> filteredLegItems = legItems.stream() List<Leg> filteredLegItems = legItems.stream()
.filter(it -> !it.getLegType().equals(LEG_TYPE_OTHER) && it.legIsInternal()) .filter(it -> !it.getLegType().equals(LEG_TYPE_OTHER) && it.legIsInternal())
.peek(Leg::reloadStatus) .peek(Leg::reloadStatus)
.filter(it -> it.getLegApprovalStatus().equals(LEG_APPROVAL_STATUS_NOT)) .filter(it -> !it.getLegApprovalStatus().equals(LEG_APPROVAL_STATUS_SUBMIT))
.toList(); .toList();
// 根据供应商名称查找供应商并进行处理 // 根据供应商名称查找供应商并进行处理

View File

@ -1,17 +1,26 @@
package com.chint.domain.service; package com.chint.domain.service;
import com.chint.application.dtos.LegApprovalParam; import com.chint.application.dtos.LegApprovalParam;
import com.chint.domain.aggregates.approval.ApprovalResultData;
import com.chint.domain.aggregates.approval.ApprovalSubmit; import com.chint.domain.aggregates.approval.ApprovalSubmit;
import com.chint.domain.aggregates.base.PermissionConfig;
import com.chint.domain.aggregates.order.ApproveOrderNo; import com.chint.domain.aggregates.order.ApproveOrderNo;
import com.chint.domain.aggregates.order.RouteOrder; import com.chint.domain.aggregates.order.RouteOrder;
import com.chint.domain.aggregates.system.SystemCode;
import com.chint.domain.aggregates.system.SystemOrganization; import com.chint.domain.aggregates.system.SystemOrganization;
import com.chint.domain.repository.RouteRepository; import com.chint.domain.repository.*;
import com.chint.domain.repository.SystemCodeRepository; import com.chint.domain.value_object.enums.RoutePermission;
import com.chint.domain.repository.SystemOrganizationRepository;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import static com.chint.domain.aggregates.approval.ApprovalProcess.ApprovalType.LEG_ADD_CHANGE_BATCH; import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import static com.chint.domain.aggregates.approval.ApprovalType.LEG_ADD_CHANGE_BATCH;
@Service @Service
public class RouteApprovalDomainService { public class RouteApprovalDomainService {
@ -25,30 +34,119 @@ public class RouteApprovalDomainService {
@Autowired @Autowired
private SystemOrganizationRepository systemOrganizationRepository; private SystemOrganizationRepository systemOrganizationRepository;
@Autowired
private PermissionConfigRepository permissionConfigRepository;
public void legApprovalResponse(){ @Autowired
private ApprovalRecordRepository approvalRecordRepository;
private ApprovalSubmit approvalSubmit;
public void legApprovalResponse() {
} }
public void orderDetailResponse(){ public void orderDetailResponse() {
} }
public void handlerApprovalResponse(ApprovalResultData data) {
approvalSubmit.handleApprovalResult(data);
}
public void approveRouteOfLegChangeAndAdd(LegApprovalParam param) { public void approveRouteOfLegChangeAndAdd(LegApprovalParam param) {
RouteOrder routeOrder = routeRepository.queryById(param.getRouteId()); RouteOrder routeOrder = routeRepository.queryById(param.getRouteId());
String approvalPlatformMark = getApprovalPlatformMark(routeOrder); String approvalPlatformMark = getApprovalPlatformMark(routeOrder);
ApprovalSubmit.of(LEG_ADD_CHANGE_BATCH,approvalPlatformMark) ApprovalSubmit.of(LEG_ADD_CHANGE_BATCH, approvalPlatformMark)
.approveData(routeOrder) .approveData(routeOrder)
.record(record -> {
record.setApprovalReason(param.getApprovalReason());
approvalRecordRepository.save(record);
})
.submitToBpm(); .submitToBpm();
routeRepository.save(routeOrder);
}
public List<RouteOrder> checkApprovalPermissions(List<RouteOrder> routeOrderList) {
// 提取所有 approveOrderNo sysCode
Set<String> accountCompanyCodes = routeOrderList.stream()
.map(routeOrder -> routeOrder.getApproveOrderNo().getAccountCompany())
.collect(Collectors.toSet());
Set<String> sysCodes = routeOrderList.stream()
.map(routeOrder -> routeOrder.getApproveOrderNo().getSysCode())
.collect(Collectors.toSet());
// 批量查询 systemOrganizationRepository systemCodeRepository
Map<String, String> accountCompanyToApprovalType = systemOrganizationRepository.findByOrgCodeIn(accountCompanyCodes)
.stream()
.filter(it -> it.getApprovalType() != null && !it.getApprovalType().isEmpty())
.collect(Collectors.toMap(SystemOrganization::getOrgCode, SystemOrganization::getApprovalType));
Map<String, String> sysCodeToApprovalType = systemCodeRepository.findBySysCodeIn(sysCodes)
.stream()
.filter(it -> it.getApprovalType() != null && !it.getApprovalType().isEmpty())
.collect(Collectors.toMap(SystemCode::getSystemCode, SystemCode::getApprovalType));
// 获取所有审批类型
Set<String> approvalTypes = routeOrderList.stream()
.map(routeOrder -> {
ApproveOrderNo approveOrderNo = routeOrder.getApproveOrderNo();
String accountCompany = approveOrderNo.getAccountCompany();
return accountCompanyToApprovalType.getOrDefault(accountCompany, sysCodeToApprovalType.get(approveOrderNo.getSysCode()));
})
.collect(Collectors.toSet());
// 批量查询 permissionConfigRepository
Map<String, List<String>> approvalTypeToPermissions = permissionConfigRepository
.findByPermissionNameIn(approvalTypes)
.stream()
.collect(Collectors.toMap(PermissionConfig::getPermissionName, PermissionConfig::permissions));
// 将权限映射为枚举
Map<String, Set<RoutePermission>> approvalTypeToPermissionSet = approvalTypeToPermissions.entrySet().stream()
.collect(Collectors.toMap(Map.Entry::getKey, entry -> entry.getValue().stream()
.distinct()
.map(permission -> Enum.valueOf(RoutePermission.class, permission))
.collect(Collectors.toSet())));
// 更新每个 RouteOrder routePermissionSet
for (RouteOrder routeOrder : routeOrderList) {
ApproveOrderNo approveOrderNo = routeOrder.getApproveOrderNo();
String approvalType = accountCompanyToApprovalType.getOrDefault(approveOrderNo.getAccountCompany(),
sysCodeToApprovalType.get(approveOrderNo.getSysCode()));
Set<RoutePermission> routePermissionSet = approvalTypeToPermissionSet
.getOrDefault(approvalType, Collections.emptySet());
routeOrder.setRoutePermissionSet(routePermissionSet);
}
return routeOrderList;
}
public RouteOrder checkApprovalPermissions(RouteOrder routeOrder) {
ApproveOrderNo approveOrderNo = routeOrder.getApproveOrderNo();
String approvalType = systemOrganizationRepository.findByOrgCodeContainingOrOrgNameContaining(approveOrderNo.getAccountCompany(),
approveOrderNo.getAccountCompany()).map(SystemOrganization::getApprovalType).orElseGet(
() -> systemCodeRepository.findBySysCode(approveOrderNo.getSysCode()).getApprovalType());
routeOrder.setRoutePermissionSet(
permissionConfigRepository.findByPermissionName(approvalType)
.map(permissionConfig -> {
List<String> permissions = permissionConfig.permissions();
return permissions.stream()
.distinct()
.map(permission -> Enum.valueOf(RoutePermission.class, permission))
.collect(Collectors.toSet());
}).orElseGet(Set::of)
);
return routeOrder;
} }
private String getApprovalPlatformMark(RouteOrder routeOrder){ private String getApprovalPlatformMark(RouteOrder routeOrder) {
ApproveOrderNo approveOrderNo = routeOrder.getApproveOrderNo(); ApproveOrderNo approveOrderNo = routeOrder.getApproveOrderNo();
//先查寻公司是否有关联的BPM如果没有的话查询sysCode关联的BPM //先查寻公司是否有关联的BPM如果没有的话查询sysCode关联的BPM
return systemOrganizationRepository.findByOrgCodeContainingOrOrgNameContaining(approveOrderNo.getAccountCompany(), return systemOrganizationRepository.findByOrgCode(approveOrderNo.getAccountCompany())
approveOrderNo.getAccountCompany()).map(SystemOrganization::getApprovalPlatformMark).orElseGet( .map(SystemOrganization::getApprovalPlatformMark).orElseGet(
() -> systemCodeRepository.findBySysCode(approveOrderNo.getSysCode()).getApprovalPlatformMark() () -> systemCodeRepository.findBySysCode(approveOrderNo.getSysCode()).getApprovalPlatformMark()
); );
} }
} }

View File

@ -44,6 +44,8 @@ public interface SupplierOrderSync extends SupplierAdapter {
List<Leg> legList = routeRequest.getRouteRequestLegList() List<Leg> legList = routeRequest.getRouteRequestLegList()
.stream() .stream()
.map(RouteRequestLeg::getLeg) .map(RouteRequestLeg::getLeg)
.peek(Leg::reloadStatus)
.filter(it -> !it.getLegApprovalStatus().equals(LEG_APPROVAL_STATUS_SUBMIT))
.toList(); .toList();
// Legs can not be empty // Legs can not be empty

View File

@ -0,0 +1,5 @@
package com.chint.domain.value_object.enums;
public enum RoutePermission {
APPROVAL_BUTTON
}

View File

@ -0,0 +1,28 @@
package com.chint.infrastructure.repository;
import com.chint.domain.aggregates.approval.ApprovalRecord;
import com.chint.domain.repository.ApprovalRecordRepository;
import com.chint.infrastructure.repository.jdbc.JdbcApprovalRecordRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import java.util.Optional;
@Repository
public class ApprovalRecordRepositoryImpl implements ApprovalRecordRepository {
@Autowired
private JdbcApprovalRecordRepository jdbcApprovalRecordRepository;
@Override
public ApprovalRecord save(ApprovalRecord record) {
return jdbcApprovalRecordRepository.save(record);
}
@Override
public Optional<ApprovalRecord> findByApprovalRecordNo(String approvalRecordNo) {
return jdbcApprovalRecordRepository.findByApprovalRecordNo(approvalRecordNo).stream().findFirst();
}
}

View File

@ -0,0 +1,31 @@
package com.chint.infrastructure.repository;
import com.chint.domain.aggregates.base.PermissionConfig;
import com.chint.domain.repository.PermissionConfigRepository;
import com.chint.infrastructure.repository.jdbc.JdbcPermissionConfigRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Repository;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
@Repository
public class PermissionConfigRepositoryImpl implements PermissionConfigRepository {
@Autowired
private JdbcPermissionConfigRepository jdbcPermissionConfigRepository;
@Cacheable(value = "PermissionConfig", key = "#permissionName")
@Override
public Optional<PermissionConfig> findByPermissionName(String permissionName) {
return jdbcPermissionConfigRepository.findByPermissionName(permissionName).stream().findFirst();
}
@Override
public List<PermissionConfig> findByPermissionNameIn(Set<String> approvalTypes) {
return jdbcPermissionConfigRepository.findByPermissionNameIn(approvalTypes.stream().filter(Objects::nonNull).toList());
}
}

View File

@ -1,7 +1,9 @@
package com.chint.infrastructure.repository; package com.chint.infrastructure.repository;
import com.chint.application.dtos.system.RoleOrgParam; import com.chint.application.dtos.system.RoleOrgParam;
import com.chint.domain.aggregates.system.SystemOrganization;
import com.chint.domain.aggregates.user.Role; import com.chint.domain.aggregates.user.Role;
import com.chint.domain.aggregates.user.RoleOrganization;
import com.chint.domain.aggregates.user.RoleUser; import com.chint.domain.aggregates.user.RoleUser;
import com.chint.domain.aggregates.user.User; import com.chint.domain.aggregates.user.User;
import com.chint.domain.repository.RoleRepository; import com.chint.domain.repository.RoleRepository;
@ -103,6 +105,7 @@ public class RoleRepositoryImpl implements RoleRepository {
} }
user.setRoleOrgCodeList(orgCodeList); user.setRoleOrgCodeList(orgCodeList);
// List<String> orgCodeList = cacheRoleRepository // List<String> orgCodeList = cacheRoleRepository
// .roleOrgCodeList(userId, null); // .roleOrgCodeList(userId, null);
// List<SystemOrganizationVO> systemOrganizationVOList = cacheRoleRepository // List<SystemOrganizationVO> systemOrganizationVOList = cacheRoleRepository

View File

@ -8,6 +8,10 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable; import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
import java.util.List;
import java.util.Objects;
import java.util.Set;
@Repository @Repository
public class SystemCodeRepositoryImpl implements SystemCodeRepository { public class SystemCodeRepositoryImpl implements SystemCodeRepository {
@ -29,4 +33,9 @@ public class SystemCodeRepositoryImpl implements SystemCodeRepository {
public SystemCode findById(Long id) { public SystemCode findById(Long id) {
return jdbcSystemCodeRepository.findById(id).orElseThrow(() -> new NotFoundException("该产业公司不在实施范围内")); return jdbcSystemCodeRepository.findById(id).orElseThrow(() -> new NotFoundException("该产业公司不在实施范围内"));
} }
@Override
public List<SystemCode> findBySysCodeIn(Set<String> sysCodes) {
return jdbcSystemCodeRepository.findBySystemCodeIn(sysCodes.stream().filter(Objects::nonNull).toList());
}
} }

View File

@ -0,0 +1,12 @@
package com.chint.infrastructure.repository.jdbc;
import com.chint.domain.aggregates.approval.ApprovalRecord;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface JdbcApprovalRecordRepository extends CrudRepository<ApprovalRecord, Long> {
List<ApprovalRecord> findByApprovalRecordNo(String approvalRecordNo);
}

View File

@ -0,0 +1,15 @@
package com.chint.infrastructure.repository.jdbc;
import com.chint.domain.aggregates.base.PermissionConfig;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface JdbcPermissionConfigRepository extends CrudRepository<PermissionConfig, Long> {
List<PermissionConfig> findByPermissionName(String permissionName);
List<PermissionConfig> findByPermissionNameIn(List<String> permissionNames);
}

View File

@ -1,12 +1,15 @@
package com.chint.infrastructure.repository.jdbc; package com.chint.infrastructure.repository.jdbc;
import com.chint.domain.aggregates.order.RouteOrder;
import com.chint.domain.aggregates.system.SystemCode; import com.chint.domain.aggregates.system.SystemCode;
import org.springframework.data.repository.CrudRepository; import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
import java.util.List;
@Repository @Repository
public interface JdbcSystemCodeRepository extends CrudRepository<SystemCode, Long> { public interface JdbcSystemCodeRepository extends CrudRepository<SystemCode, Long> {
SystemCode findBySystemCode(String systemCode); SystemCode findBySystemCode(String systemCode);
List<SystemCode> findBySystemCodeIn(List<String> systemCodes);
} }

View File

@ -11,6 +11,7 @@ public class DateTimeUtil {
public final static DateTimeFormatter formatterDate = DateTimeFormatter.ofPattern("yyyy-MM-dd"); public final static DateTimeFormatter formatterDate = DateTimeFormatter.ofPattern("yyyy-MM-dd");
public final static DateTimeFormatter formatterDateYYYYMM = DateTimeFormatter.ofPattern("yyyyMM"); public final static DateTimeFormatter formatterDateYYYYMM = DateTimeFormatter.ofPattern("yyyyMM");
public final static DateTimeFormatter formatterDateYYYYMMDD = DateTimeFormatter.ofPattern("yyyyMMdd"); public final static DateTimeFormatter formatterDateYYYYMMDD = DateTimeFormatter.ofPattern("yyyyMMdd");
public final static DateTimeFormatter formatterMinSS = DateTimeFormatter.ofPattern("yyMMddHHmmss");
public static String timeFromInstant(Long instant) { public static String timeFromInstant(Long instant) {
LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(instant), ZoneId.systemDefault()); LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(instant), ZoneId.systemDefault());
@ -21,6 +22,9 @@ public class DateTimeUtil {
return formatter.format(time); return formatter.format(time);
} }
public static String timeToMinSS(LocalDateTime time) {
return formatterMinSS.format(time);
}
public static String timeToStr(LocalDateTime input) { public static String timeToStr(LocalDateTime input) {
return input.format(formatterDate); return input.format(formatterDate);
@ -79,6 +83,7 @@ public class DateTimeUtil {
LocalDate parse = LocalDate.parse(date, formatterDate); LocalDate parse = LocalDate.parse(date, formatterDate);
return LocalDateTime.of(parse, LocalTime.MIN); return LocalDateTime.of(parse, LocalTime.MIN);
} }
public static LocalDateTime endOfDay(String date) { public static LocalDateTime endOfDay(String date) {
LocalDate parse = LocalDate.parse(date, formatterDate); LocalDate parse = LocalDate.parse(date, formatterDate);
return LocalDateTime.of(parse, LocalTime.MAX); return LocalDateTime.of(parse, LocalTime.MAX);

View File

@ -5,10 +5,8 @@ import org.springframework.stereotype.Component;
@Component @Component
public class Json { public class Json {
private static final Gson gson = new Gson();
private final Gson gson = new Gson(); public static Gson gson() {
public Gson gson() {
return gson; return gson;
} }
} }

View File

@ -1,7 +1,6 @@
package com.chint.infrastructure.util; package com.chint.infrastructure.util;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Random; import java.util.Random;
public class OrderNo { public class OrderNo {
@ -10,15 +9,7 @@ public class OrderNo {
private static final String numbers = "0123456789"; private static final String numbers = "0123456789";
public static String generate() { public static String generate() {
// 获取当前时间 return "R" + generateNum();
LocalDateTime now = LocalDateTime.now();
// 格式化日期和时间部分
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyMMddHHmmss");
String datePart = now.format(formatter);
// 生成随机序列部分
int randomPart = new Random().nextInt(9000) + 1000; // 生成1000到9999之间的随机数
// 拼接最终的订单号
return "R" + datePart + randomPart;
} }
public static String generate(String sysCode, String billCode) { public static String generate(String sysCode, String billCode) {
@ -27,15 +18,19 @@ public class OrderNo {
} }
public static String generateLegNo() { public static String generateLegNo() {
// 获取当前时间 return "L" + generateNum();
LocalDateTime now = LocalDateTime.now(); }
public static String generateApprovalNo() {
return "A" + generateNum();
}
private static String generateNum() {
// 格式化日期和时间部分 // 格式化日期和时间部分
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyMMddHHmmss"); String datePart = DateTimeUtil.timeToMinSS(LocalDateTime.now());
String datePart = now.format(formatter);
// 生成随机序列部分 // 生成随机序列部分
int randomPart = new Random().nextInt(9000) + 1000; // 生成1000到9999之间的随机数 int randomPart = new Random().nextInt(9000) + 1000; // 生成1000到9999之间的随机数
// 拼接最终的订单号 return datePart + randomPart;
return "L" + datePart + randomPart;
} }
public static String generateRouteRequestNo(String routeOrderNo) { public static String generateRouteRequestNo(String routeOrderNo) {

View File

@ -821,7 +821,7 @@ public class LYTest {
@Test @Test
void searchTrain() { void searchTrain() {
TrainDetailResponse trainOrderDetail = lySearchRequest.getTrainOrderDetail("DT24062278179087557"); TrainDetailResponse trainOrderDetail = lySearchRequest.getTrainOrderDetail("DT24051673807741786");
Gson gson = new Gson(); Gson gson = new Gson();
String json = gson.toJson(trainOrderDetail); String json = gson.toJson(trainOrderDetail);
System.out.println(json); System.out.println(json);
@ -829,7 +829,7 @@ public class LYTest {
@Test @Test
void searchHotel() { void searchHotel() {
HotelDetailResponse hotelOrderDetail = lySearchRequest.getHotelOrderDetail("HO20240406120100189791"); HotelDetailResponse hotelOrderDetail = lySearchRequest.getHotelOrderDetail("HO20240321143500052669");
Gson gson = new Gson(); Gson gson = new Gson();
String json = gson.toJson(hotelOrderDetail); String json = gson.toJson(hotelOrderDetail);
System.out.println(json); System.out.println(json);

View File

@ -24,6 +24,7 @@ import com.chint.infrastructure.repository.CTripOrderDetailImpl;
import com.chint.infrastructure.util.DateTimeUtil; import com.chint.infrastructure.util.DateTimeUtil;
import com.chint.infrastructure.util.Digest; import com.chint.infrastructure.util.Digest;
import com.chint.infrastructure.util.PinyinUtil; import com.chint.infrastructure.util.PinyinUtil;
import com.chint.infrastructure.util.Result;
import com.chint.interfaces.rest.amap.dto.note.AmapNoteResponse; import com.chint.interfaces.rest.amap.dto.note.AmapNoteResponse;
import com.chint.interfaces.rest.base.PostRequest; import com.chint.interfaces.rest.base.PostRequest;
import com.chint.interfaces.rest.ctrip.CTripAirportRequest; import com.chint.interfaces.rest.ctrip.CTripAirportRequest;
@ -57,6 +58,7 @@ import org.springframework.boot.test.context.SpringBootTest;
import java.io.FileWriter; import java.io.FileWriter;
import java.io.IOException; import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.time.LocalDate; import java.time.LocalDate;
@ -322,16 +324,56 @@ class RouteApplicationTests {
@Test @Test
void loginSignProd() { void loginSignProd() {
String sfno = "080301001"; String sfno = "210506025";
String syscode = "FSSC"; String syscode = "ANFSSC";
String billcode = "CLSQ240620099999"; String billcode = "CLS24062700018";
String companycode = "正泰集团股份有限公司"; String companycode = "正泰安能数字能源(浙江)股份有限公司";
String timespan = "1708908662738"; String timespan = "1708908662738";
String key = "ZhengTaiRoute"; String key = "ZhengTaiRoute";
String s = Digest.md5(sfno + syscode + billcode + companycode + key + timespan); String s = Digest.md5(sfno + syscode + billcode + companycode + key + timespan);
System.out.println(s); System.out.println(s);
} }
@Test
void testPushBatch() throws UnsupportedEncodingException {
List<String> billcodeList = List.of("CLS24062500065",
"CLS24062400348",
"CLS24062500073",
"CLS24062500207");
List<String> sfnoList = List.of(
"220915110",
"220719073",
"230627119",
"220802056"
);
System.out.println(billcodeList.size());
System.out.println(sfnoList.size());
String sfno = "240227068";
String syscode = "ANFSSC";
String billcode = "CLS24062800068";
String companycode = "正泰安能数字能源(浙江)股份有限公司";
String timespan = "1708908662738";
String key = "ZhengTaiRoute";
for (int i = 0; i < billcodeList.size(); i++) {
billcode = billcodeList.get(i);
sfno = sfnoList.get(i);
String sign = Digest.md5(sfno + syscode + billcode + companycode + key + timespan);
String url = "https://trip.chint.com/api/public/login?sfno=" + sfno +
"&syscode=" + syscode +
"&billcode=" + billcode +
"&timespan=" + timespan +
"&sign=" + sign +
"&companycode=" + java.net.URLEncoder.encode(companycode, "UTF-8");
postRequest.get(url, Result.class);
}
}
// @Test // @Test
void queryUserInfo() { void queryUserInfo() {
User user2 = User.withEmployeeNo("180101001"); User user2 = User.withEmployeeNo("180101001");
@ -478,7 +520,6 @@ class RouteApplicationTests {
} }
CTripNoteResponse post = postRequest.post("https://trip.chint.com/api/public/CTrip/status", cTripStatusNotification, CTripNoteResponse.class); CTripNoteResponse post = postRequest.post("https://trip.chint.com/api/public/CTrip/status", cTripStatusNotification, CTripNoteResponse.class);
alreadyPost.add(cTripStatusNotification.getOrderId()); alreadyPost.add(cTripStatusNotification.getOrderId());
if (post.getErrorMessage() != null || !Objects.equals(post.getErrorCode(), "0")) { if (post.getErrorMessage() != null || !Objects.equals(post.getErrorCode(), "0")) {