diff --git a/base-server/pom.xml b/base-server/pom.xml index b2c88eee..d78949ca 100644 --- a/base-server/pom.xml +++ b/base-server/pom.xml @@ -82,6 +82,16 @@ + + org.apache.seata + seata-spring-boot-starter + + + com.alibaba + druid + + + diff --git a/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/base/vo/ElementPageReqVO.java b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/base/vo/ElementPageReqVO.java index 459d0190..c69b2d3a 100644 --- a/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/base/vo/ElementPageReqVO.java +++ b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/base/vo/ElementPageReqVO.java @@ -35,4 +35,6 @@ public class ElementPageReqVO extends PageParam { @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime[] createTime; + @Schema(description = "排序") + private Integer sort; } \ No newline at end of file diff --git a/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/base/vo/ElementRespVO.java b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/base/vo/ElementRespVO.java index 549daf73..dc5f6888 100644 --- a/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/base/vo/ElementRespVO.java +++ b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/base/vo/ElementRespVO.java @@ -44,4 +44,6 @@ public class ElementRespVO { @ExcelProperty("创建时间") private LocalDateTime createTime; + @Schema(description = "排序") + private Integer sort; } \ No newline at end of file diff --git a/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/base/vo/ElementSaveReqVO.java b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/base/vo/ElementSaveReqVO.java index 5d5c8e79..b632998e 100644 --- a/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/base/vo/ElementSaveReqVO.java +++ b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/base/vo/ElementSaveReqVO.java @@ -34,4 +34,7 @@ public class ElementSaveReqVO { @NotEmpty(message = "品位单位不能为空") private String gradeUnit; + @Schema(description = "排序") + private Integer sort; + } \ No newline at end of file diff --git a/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/dal/dataobject/base/ElementDO.java b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/dal/dataobject/base/ElementDO.java index 32ed81b1..357af721 100644 --- a/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/dal/dataobject/base/ElementDO.java +++ b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/dal/dataobject/base/ElementDO.java @@ -94,4 +94,7 @@ public class ElementDO extends BusinessBaseDO { @TableField("UPDATER_NAME") private String updaterName; + @TableField("SORT") + private Integer sort; + } \ No newline at end of file diff --git a/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/dal/mysql/base/ElementMapper.java b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/dal/mysql/base/ElementMapper.java index 83b90bbd..766d73cc 100644 --- a/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/dal/mysql/base/ElementMapper.java +++ b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/dal/mysql/base/ElementMapper.java @@ -26,13 +26,14 @@ public interface ElementMapper extends BaseMapperX { .likeIfPresent(ElementDO::getCoding, reqVO.getCoding()) .eqIfPresent(ElementDO::getGradeUnit, reqVO.getGradeUnit()) .betweenIfPresent(ElementDO::getCreateTime, reqVO.getCreateTime()) - .orderByDesc(ElementDO::getId)); + .orderByDesc(ElementDO::getSort)); } String selectMaxCode(); default List getElementNoPage() { return selectList(new LambdaQueryWrapperX() - .orderByDesc(ElementDO::getId)); + .eq(ElementDO::getIsEnable, 1) + .orderByDesc(ElementDO::getSort)); } } \ No newline at end of file diff --git a/zt-module-contract-order/zt-module-contract-order-api/src/main/java/com/zt/plat/module/contractorder/api/ContractApi.java b/zt-module-contract-order/zt-module-contract-order-api/src/main/java/com/zt/plat/module/contractorder/api/ContractApi.java index 217a20dd..55b7e767 100644 --- a/zt-module-contract-order/zt-module-contract-order-api/src/main/java/com/zt/plat/module/contractorder/api/ContractApi.java +++ b/zt-module-contract-order/zt-module-contract-order-api/src/main/java/com/zt/plat/module/contractorder/api/ContractApi.java @@ -9,6 +9,7 @@ import com.zt.plat.module.contractorder.api.dto.order.PurchaseOrderWithDetailsDT import com.zt.plat.module.contractorder.api.dto.order.SalesOrdDtlDTO; import com.zt.plat.module.contractorder.api.vo.contract.international.IntContract; import com.zt.plat.module.contractorder.api.vo.contract.international.IntContractPageReq; +import com.zt.plat.module.contractorder.api.vo.contract.international.IntPushContractReqVO; import com.zt.plat.module.contractorder.enums.ApiConstants; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; @@ -44,7 +45,7 @@ public interface ContractApi { @PostMapping(PREFIX + "/push") @Operation(summary = "国贸2.0系统推送合同") - CommonResult push(@Valid @RequestBody IntContract reqVO); + void push(@Valid @RequestBody IntPushContractReqVO pushReqVO); @GetMapping(PREFIX + "/logistics/list/page") @Operation(summary = "国贸2.0系统合同分页查询") diff --git a/zt-module-contract-order/zt-module-contract-order-api/src/main/java/com/zt/plat/module/contractorder/api/OrderApi.java b/zt-module-contract-order/zt-module-contract-order-api/src/main/java/com/zt/plat/module/contractorder/api/OrderApi.java new file mode 100644 index 00000000..56c300d0 --- /dev/null +++ b/zt-module-contract-order/zt-module-contract-order-api/src/main/java/com/zt/plat/module/contractorder/api/OrderApi.java @@ -0,0 +1,25 @@ +package com.zt.plat.module.contractorder.api; + +import com.zt.plat.framework.common.pojo.CommonResult; +import com.zt.plat.module.contractorder.api.dto.order.OrderDTO; +import com.zt.plat.module.contractorder.enums.ApiConstants; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; + +import java.util.List; + +@FeignClient(name = ApiConstants.NAME) +@Tag(name = "RPC 服务 - 订单") +public interface OrderApi { + String PREFIX = ApiConstants.PREFIX + "/order"; + @PostMapping(PREFIX + "/order-by-order-ids") + @Operation(summary = "通过订单id获取订单信息", description = "通过订单编号获取订单信息") + CommonResult> getOrderByOrderIds(@RequestBody List ids); + + @PostMapping(PREFIX + "/order-by-order-nos") + @Operation(summary = "通过订单号批量获取订单信息", description = "通过订单编号获取订单信息") + CommonResult> getOrderByOrderNos(@RequestBody List orderNoS); +} diff --git a/zt-module-contract-order/zt-module-contract-order-api/src/main/java/com/zt/plat/module/contractorder/api/dto/order/OrdDtlDTO.java b/zt-module-contract-order/zt-module-contract-order-api/src/main/java/com/zt/plat/module/contractorder/api/dto/order/OrdDtlDTO.java index 14735758..218ce62e 100644 --- a/zt-module-contract-order/zt-module-contract-order-api/src/main/java/com/zt/plat/module/contractorder/api/dto/order/OrdDtlDTO.java +++ b/zt-module-contract-order/zt-module-contract-order-api/src/main/java/com/zt/plat/module/contractorder/api/dto/order/OrdDtlDTO.java @@ -99,6 +99,11 @@ public class OrdDtlDTO { */ private String taxNum; + /** + * 税率 Y + */ + private BigDecimal taxRte; + // ========================== 采购订单特有属性(PrchOrdDtlDTO 独有)========================== /** * 含税单价;推送ERP(必须) @@ -271,10 +276,6 @@ public class OrdDtlDTO { */ private BigDecimal gross; - /** - * 税率 Y - */ - private BigDecimal taxRte; /** * 价格条件详情;推送ERP(必须):JSON diff --git a/zt-module-contract-order/zt-module-contract-order-api/src/main/java/com/zt/plat/module/contractorder/api/dto/order/OrderDTO.java b/zt-module-contract-order/zt-module-contract-order-api/src/main/java/com/zt/plat/module/contractorder/api/dto/order/OrderDTO.java new file mode 100644 index 00000000..3925ffb3 --- /dev/null +++ b/zt-module-contract-order/zt-module-contract-order-api/src/main/java/com/zt/plat/module/contractorder/api/dto/order/OrderDTO.java @@ -0,0 +1,291 @@ +package com.zt.plat.module.contractorder.api.dto.order; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import lombok.Data; + +import java.math.BigDecimal; +import java.time.LocalDateTime; +import java.util.List; + +@Data +public class OrderDTO { + + /** + * 主键 + */ + @TableId(type = IdType.ASSIGN_ID) + private Long id; + /** + * ERP订单号 + */ + @TableField("ORD_SAP_NUM") + private String orderSAPNumber; + /** + * 订单号 + */ + @TableField("SYS_ORD_NUM") + private String systemOrderNumber; + /** + * 公司名称 + */ + @TableField("CPN_NAME") + private String cpName; + /** + * 公司编码;推送ERP(必须) + */ + @TableField("CPN_NUM") + private String cpNum; + /** + * 客商编码;推送ERP(必须) + */ + @TableField("SPLR_NUM") + private String supplierNumber; + /** + * 客商名称 + */ + @TableField("SPLR_NAME") + private String supplierName; + /** + * 订单类型(字典:PRCH_ORD_TP);推送ERP(必须) + */ + @TableField("TP") + private String type; + /** + * 凭证日期;推送ERP(必须) + */ + @TableField("VCHR_DT") + private LocalDateTime voucherDate; + /** + * 采购组织编码;推送ERP(必须) + */ + @TableField("PRCH_ORGZ_CD") + private String purchaseOrganizationCustomsDeclaration; + /** + * 收货工厂名称 + */ + @TableField("RCV_FACT_NAME") + private String receiveFactoryName; + /** + * 收货工厂编码;推送ERP(必须) + */ + @TableField("RCV_FACT_NUM") + private String receiveFactoryNumber; + /** + * 收货库位名称 + */ + @TableField("RCV_WRH_NAME") + private String receiveWarehouseName; + /** + * 收货库位编码;推送ERP + */ + @TableField("RCV_WRH_NUM") + private String receiveWarehouseNumber; + /** + * 采购组编码(字典:PRCH_GRP_TP);推送ERP(必须) + */ + @TableField("PRCH_GRP") + private String purchaseGroup; + /** + * 货币码(字典:CUR);推送ERP(必须) + */ + @TableField("CUR_NUM") + private String currencyNumber; + /** + * 汇率;推送ERP + */ + @TableField("EXCH_RTE") + private BigDecimal exchangeRate; + /** + * 合同纸质合同号;推送ERP(必须) + */ + @TableField("PPR_CTRT_NUM") + private String paperContractNumber; + /** + * 小协议号;推送ERP + */ + @TableField("AGR_NUM") + private String agreementNumber; + /** + * 备注;推送ERP + */ + @TableField("RMK") + private String remark; + /** + * 代理方编码;推送ERP + */ + @TableField("AGT_NUM") + private String agentNumber; + /** + * 代理方名称 + */ + @TableField("AGT_NAME") + private String agentName; + /** + * 系统合同编号 + */ + @TableField("CTRT_NUM") + private String contractNumber; + /** + * 物料编码 + */ + @TableField("MTRL_NUM") + private String materialNumber; + /** + * 物料名称 + */ + @TableField("MTRL_NAME") + private String materialName; + /** + * 合同名称 + */ + @TableField("CTRT_NAME") + private String contractName; + /** + * 小户头号 + */ + @TableField("TNT_NUM") + private String tenantNumber; + /** + * ERP公司编号 + */ + @TableField("ERP_PRCH_CPN_NUM") + private String erpPurchaseCompanyNumber; + /** + * ERP公司名称 + */ + @TableField("ERP_PRCH_CPN_NAME") + private String erpPurchaseCompanyName; + /** + * ERP客商公司编码 + */ + @TableField("ERP_SALE_CPN_NUM") + private String erpSalesCompanyNumber; + /** + * ERP客商公司名称 + */ + @TableField("ERP_SALE_CPN_NAME") + private String erpSalesCompanyName; + /** + * 采购组织名称 + */ + @TableField("PRCH_ORGZ_NAME") + private String purchaseOrganizationName; + /** + * ERP状态(字典: ERP_REQ_STS) + */ + @TableField("ERP_STS") + private String erpStatus; + /** + * 请求ERP失败原因 + */ + @TableField("CAUS") + private String cause; + /** + * 订单状态(字典:PRCH_ORD_STS) + */ + @TableField("STS") + private String status; + /** + * 采购组名称 + */ + @TableField("PRCH_GRP_NAME") + private String purchaseGroupName; + + /** + * 流程实例编号 + */ + @TableField("PRCS_INSC_ID") + private String processInstanceId; + + /** + * 流程当前任务节点id + */ + @TableField("TSK_NDE_ID") + private String taskId; + + /** + * 审批意见 + */ + @TableField("RVW_ONN") + private String reviewOpinion; + + /** + * 是否需要审批 + */ + @TableField("IS_PUSH") + private int isPush; + + /** + * 计量单位 + */ + @TableField("UNT") + private String unt; + + /** + * 物料字典 + * + */ + @TableField("MTRL_TP") + private String mtrlTp; + + /** + * 订单分类 + * + */ + @TableField("SPLY_BSN_TP") + private String splyBsnTp; + /** + * 产品组编码 + * + */ + @TableField("PDT_GRP_CDG") + private String pdtGrpCdg; + /** + * 产品组名 + */ + @TableField("PDT_GRP_NAME") + private String pdtGrpName; + /** + * 分销聚道编码 + * + */ + @TableField("SALE_ACS_CDG") + private String saleAcsCdg; + /** + * 分销聚道名称 + * + */ + @TableField("SALE_ACS_NAME") + private String saleAcsName; + /** + * 销售组织编码 + * + */ + @TableField("SALE_ORGZ_CD") + private String saleOrgzCd; + /** + * 销售组织名称 + * + */ + @TableField("SALE_ORGZ_NAME") + private String saleOrgzName; + /** + * 付款方名称 + * + */ + @TableField("PYER_NAME") + private String payerName; + /** + * 付款方编码 + * + */ + @TableField("PYER_NUM") + private String payerNum; + + /** + * 订单明细 + */ + private List OrdDtlDTOS; +} diff --git a/zt-module-contract-order/zt-module-contract-order-api/src/main/java/com/zt/plat/module/contractorder/api/vo/contract/international/IntPushContractReqVO.java b/zt-module-contract-order/zt-module-contract-order-api/src/main/java/com/zt/plat/module/contractorder/api/vo/contract/international/IntPushContractReqVO.java new file mode 100644 index 00000000..4758570e --- /dev/null +++ b/zt-module-contract-order/zt-module-contract-order-api/src/main/java/com/zt/plat/module/contractorder/api/vo/contract/international/IntPushContractReqVO.java @@ -0,0 +1,24 @@ +package com.zt.plat.module.contractorder.api.vo.contract.international; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Schema(description = "国贸2.0系统推送合同 Request VO") +@Data +public class IntPushContractReqVO { + + @Schema(description = "接口请求号") + private String __requestId_; + @Schema(description = "接口类型") + private String __interfaceType__; + @Schema(description = "操作标志") + private String operateFlag; + @Schema(description = "发送时间 yyyyMMddHHmmss") + private String datetime; + @Schema(description = "单据号") + private String busiBillCode; + @Schema(description = "发送方系统") + private String system; + @Schema(description = "发送数据") + private IntContract data; +} diff --git a/zt-module-contract-order/zt-module-contract-order-api/src/main/java/com/zt/plat/module/contractorder/api/vo/contract/international/IntPushContractRespVO.java b/zt-module-contract-order/zt-module-contract-order-api/src/main/java/com/zt/plat/module/contractorder/api/vo/contract/international/IntPushContractRespVO.java new file mode 100644 index 00000000..c26f9bfc --- /dev/null +++ b/zt-module-contract-order/zt-module-contract-order-api/src/main/java/com/zt/plat/module/contractorder/api/vo/contract/international/IntPushContractRespVO.java @@ -0,0 +1,29 @@ +package com.zt.plat.module.contractorder.api.vo.contract.international; + +import cn.hutool.json.JSONObject; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Schema(description = "国贸2.0系统推送合同 Response VO") +@Data +public class IntPushContractRespVO { + + @Schema(description = "接口请求号") + private String __requestId_; + @Schema(description = "接口类型") + private String __interfaceType__; + @Schema(description = "单据号") + private String busiBillCode; + @Schema(description = "返回状态") + private Integer code; + @Schema(description = "返回信息") + private String message; + @Schema(description = "返回时间 yyyyMMddHHmmss") + private String datetime; + @Schema(description = "返回方系统") + private String system; + @Schema(description = "操作标志") + private String operateFlag; + @Schema(description = "返回数据") + private JSONObject data; +} diff --git a/zt-module-contract-order/zt-module-contract-order-server/src/main/java/com/zt/plat/module/contractorder/api/ContractApiImpl.java b/zt-module-contract-order/zt-module-contract-order-server/src/main/java/com/zt/plat/module/contractorder/api/ContractApiImpl.java index cd3efdb6..e4cc53b3 100644 --- a/zt-module-contract-order/zt-module-contract-order-server/src/main/java/com/zt/plat/module/contractorder/api/ContractApiImpl.java +++ b/zt-module-contract-order/zt-module-contract-order-server/src/main/java/com/zt/plat/module/contractorder/api/ContractApiImpl.java @@ -11,9 +11,7 @@ import com.zt.plat.module.contractorder.api.dto.contract.ContractRespDTO; import com.zt.plat.module.contractorder.api.dto.order.PrchOrdDtlDTO; import com.zt.plat.module.contractorder.api.dto.order.PurchaseOrderWithDetailsDTO; import com.zt.plat.module.contractorder.api.dto.order.SalesOrdDtlDTO; -import com.zt.plat.module.contractorder.api.vo.contract.international.IntContract; -import com.zt.plat.module.contractorder.api.vo.contract.international.IntContractPageReq; -import com.zt.plat.module.contractorder.api.vo.contract.international.Partner; +import com.zt.plat.module.contractorder.api.vo.contract.international.*; import com.zt.plat.module.contractorder.controller.admin.purchaseorder.vo.PurchaseOrderDetailsRespVO; import com.zt.plat.module.contractorder.dal.dataobject.contract.ContractMainDO; import com.zt.plat.module.contractorder.dal.dataobject.contract.ContractOtherFieldDO; @@ -33,10 +31,12 @@ import com.zt.plat.module.contractorder.dal.mysql.salesorder.SalesOrderMapper; import com.zt.plat.module.contractorder.enums.contract.DictEnum; import com.zt.plat.module.contractorder.service.contract.ContractService; import com.zt.plat.module.contractorder.service.purchaseorder.PurchaseOrderService; +import com.zt.plat.module.contractorder.util.ShareServiceUtil; import com.zt.plat.module.erp.controller.admin.erp.vo.ErpContractSaveReqVO; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.RequestBody; @@ -73,6 +73,8 @@ public class ContractApiImpl implements ContractApi { private ContractOtherFieldMapper contractOtherFieldMapper; @Resource private SystemRelativityMapper systemRelativityMapper; + @Autowired + private ShareServiceUtil shareServiceUtil; @Override public ContractRespDTO getContractByPaperNumber(String contractPaperNumber) { @@ -158,100 +160,106 @@ public class ContractApiImpl implements ContractApi { @Transactional @Override - public CommonResult push(@RequestBody IntContract reqVO) { + public void push(@RequestBody IntPushContractReqVO pushReqVO) { - // 合同主信息表映射 - ContractMainDO contractMainDO = internationalToMainDO(reqVO); + log.info("接受到国贸系统推送的合同数据:{}", new JSONObject(pushReqVO)); + try { + // 合同主信息表映射 + ContractMainDO contractMainDO = internationalToMainDO(pushReqVO.getData()); - // 逻辑处理 - // 操作标志 I 新增/更新;D 删除 - String operateFlag = reqVO.getOperateFlag(); - // 合同唯一键 - String externalId = reqVO.getContractId(); - // 系统合同ID - Long contractId = null; - // 查询系统关联合同 - SystemRelativityDO systemRelativityDO = systemRelativityMapper.selectOne("UP_ID", externalId); - if ("I".equals(operateFlag)) { - if (systemRelativityDO != null && systemRelativityDO.getDownId() != null) { // 修改合同 + // 逻辑处理 + // 操作标志 I 新增/更新;D 删除 + String operateFlag = pushReqVO.getData().getOperateFlag(); + // 合同唯一键 + String externalId = pushReqVO.getData().getContractId(); + // 系统合同ID + Long contractId = null; + // 查询系统关联合同 + SystemRelativityDO systemRelativityDO = systemRelativityMapper.selectOne("UP_ID", externalId); + if ("I".equals(operateFlag)) { + if (systemRelativityDO != null && systemRelativityDO.getDownId() != null) { // 修改合同 + contractId = systemRelativityDO.getDownId(); + contractMainDO.setId(contractId); + contractMainMapper.updateById(contractMainDO); + } else { // 新增合同 + contractMainMapper.insert(contractMainDO); + contractId = contractMainDO.getId(); + + // 生成关联数据 + SystemRelativityDO saveRelation = new SystemRelativityDO(); + saveRelation.setUpId(Long.parseLong(externalId)); + saveRelation.setDownId(contractId); + saveRelation.setWay(DictEnum.BSE_SYS_REL_WY_EXTERNAL.getCode()); + saveRelation.setStatus(DictEnum.BSE_SYS_REL_TP_CONTRACT.getCode()); + systemRelativityMapper.insert(saveRelation); + } + } else if ("D".equals(operateFlag)) { + if (systemRelativityDO == null || systemRelativityDO.getDownId() == null) throw exception(CONTRACT_NOT_EXISTS); contractId = systemRelativityDO.getDownId(); - contractMainDO.setId(contractId); - contractMainMapper.updateById(contractMainDO); - } else { // 新增合同 - contractMainMapper.insert(contractMainDO); - contractId = contractMainDO.getId(); - - // 生成关联数据 - SystemRelativityDO saveRelation = new SystemRelativityDO(); - saveRelation.setUpId(Long.parseLong(externalId)); - saveRelation.setDownId(contractId); - saveRelation.setWay(DictEnum.BSE_SYS_REL_WY_EXTERNAL.getCode()); - saveRelation.setStatus(DictEnum.BSE_SYS_REL_TP_CONTRACT.getCode()); - systemRelativityMapper.insert(saveRelation); + contractMainMapper.deleteById(contractId); + // 删除动态条款信息 + contractOtherFormMapper.delete("CTRT_MAIN_ID", contractId.toString()); + contractOtherFieldMapper.delete("CTRT_MAIN_ID", contractId.toString()); + pushResult(pushReqVO, 1, null); + } else { + throw exception(CONTRACT_UNKNOWN_OPERATE); } - } else if ("D".equals(operateFlag)) { - if (systemRelativityDO == null || systemRelativityDO.getDownId() == null) throw exception(CONTRACT_NOT_EXISTS); - contractId = systemRelativityDO.getDownId(); - contractMainMapper.deleteById(contractId); + + // 根据客商信息列表提交多个合同映射到erp + if (pushReqVO.getData().getPartnerList() == null || pushReqVO.getData().getPartnerList().isEmpty()) { + throw exception(CONTRACT_PARTNER_NOT_EXISTS); + } + + // 合同主信息-合同编号 + String contractPaperNumber = contractMainDO.getContractPaperNumber(); + // 合同主信息-合同名称 + String contractName = contractMainDO.getContractName(); + for (int i = 0; i < pushReqVO.getData().getPartnerList().size(); i++) { + Partner partner = pushReqVO.getData().getPartnerList().get(i); + + // 根据客商信息设置合同信息 + // 合同编号 + contractMainDO.setContractPaperNumber(contractPaperNumber + "_" + String.format("%03d", (i+1))); + pushReqVO.getData().getPartnerList().get(i) + .setErpContractPaperNumber(contractPaperNumber + "_" + String.format("%03d", (i+1))); + // 合同名称 + contractMainDO.setContractName(contractName + "_" + String.format("%03d", (i+1))); + // 境内/境外 -> 客商信息:境内/外 + contractMainDO.setIsDomestic(partner.getDomesticOrOverseas()); + // 乙方公司编号(销售方) -> 客商信息:供应商代码 + contractMainDO.setSalesCompanyNumber(partner.getPartnerCode()); + // ERP乙方公司编码 + contractMainDO.setErpSalesCompanyNumber(partner.getPartnerCode()); + // 乙方公司名称 -> 客商信息:供应商名称 + contractMainDO.setSalesCompanyName(partner.getPartnerName()); + // ERP乙方公司名称 + contractMainDO.setErpSalesCompanyName(partner.getPartnerName()); + + // 生成ERP合同映射表 + ErpContractSaveReqVO erpContractVO = contractService.getErpContract(contractMainDO); + + // 调用ERP模块 + JSONObject erpResult = contractService.sendToErp(erpContractVO); + log.info("合同提交ERP结果:{}", erpResult); + + // 调用ERP失败 + if (!erpResult.getBool("success")) { + throw exception(CONTRACT_SUBMIT_ERP_FAIL, erpResult.getStr("errMsg")); + } + } + // 删除动态条款信息 contractOtherFormMapper.delete("CTRT_MAIN_ID", contractId.toString()); contractOtherFieldMapper.delete("CTRT_MAIN_ID", contractId.toString()); - return success(true); - } else { - throw exception(CONTRACT_UNKNOWN_OPERATE); + + // 请求参数保存到动态条款 + saveIntContractFields(pushReqVO.getData(), contractId); + + pushResult(pushReqVO, 1, null); + } catch (Exception e) { + log.info("国贸系统推送合同异常:{}", e.getMessage(), e); + pushResult(pushReqVO, -1, e.getMessage()); } - - // 根据客商信息列表提交多个合同映射到erp - if (reqVO.getPartnerList() == null || reqVO.getPartnerList().isEmpty()) { - throw exception(CONTRACT_PARTNER_NOT_EXISTS); - } - - // 合同主信息-合同编号 - String contractPaperNumber = contractMainDO.getContractPaperNumber(); - // 合同主信息-合同名称 - String contractName = contractMainDO.getContractName(); - for (int i = 0; i < reqVO.getPartnerList().size(); i++) { - Partner partner = reqVO.getPartnerList().get(i); - - // 根据客商信息设置合同信息 - // 合同编号 - contractMainDO.setContractPaperNumber(contractPaperNumber + "_" + String.format("%03d", (i+1))); - reqVO.getPartnerList().get(i) - .setErpContractPaperNumber(contractPaperNumber + "_" + String.format("%03d", (i+1))); - // 合同名称 - contractMainDO.setContractName(contractName + "_" + String.format("%03d", (i+1))); - // 境内/境外 -> 客商信息:境内/外 - contractMainDO.setIsDomestic(partner.getDomesticOrOverseas()); - // 乙方公司编号(销售方) -> 客商信息:供应商代码 - contractMainDO.setSalesCompanyNumber(partner.getPartnerCode()); - // ERP乙方公司编码 - contractMainDO.setErpSalesCompanyNumber(partner.getPartnerCode()); - // 乙方公司名称 -> 客商信息:供应商名称 - contractMainDO.setSalesCompanyName(partner.getPartnerName()); - // ERP乙方公司名称 - contractMainDO.setErpSalesCompanyName(partner.getPartnerName()); - - // 生成ERP合同映射表 - ErpContractSaveReqVO erpContractVO = contractService.getErpContract(contractMainDO); - - // 调用ERP模块 - JSONObject erpResult = contractService.sendToErp(erpContractVO); - log.info("合同提交ERP结果:{}", erpResult); - - // 调用ERP失败 - if (!erpResult.getBool("success")) { - throw exception(CONTRACT_SUBMIT_ERP_FAIL, erpResult.getStr("errMsg")); - } - } - - // 删除动态条款信息 - contractOtherFormMapper.delete("CTRT_MAIN_ID", contractId.toString()); - contractOtherFieldMapper.delete("CTRT_MAIN_ID", contractId.toString()); - - // 请求参数保存到动态条款 - saveIntContractFields(reqVO, contractId); - - return success(true); } /** @@ -365,6 +373,32 @@ public class ContractApiImpl implements ContractApi { } } + private void pushResult(IntPushContractReqVO pushReqVO, Integer code, String msg) { + + // 返回数据 + IntPushContractRespVO body = new IntPushContractRespVO(); + body.set__requestId_(pushReqVO.get__requestId_()); + body.set__interfaceType__(pushReqVO.get__interfaceType__()); + body.setBusiBillCode(pushReqVO.getBusiBillCode()); + body.setCode(code); + body.setMessage(String.format("推送合同[%s]%s", pushReqVO.getData().getContractCode(), code >= 0 ? "成功" : "失败:" + msg)); + body.setDatetime(DateTimeFormatter.ofPattern("yyyyMMddHHmmss").format(LocalDateTime.now())); + body.setSystem("JYGK"); + body.setOperateFlag(pushReqVO.getOperateFlag()); + + // 回调参数 + JSONObject req = new JSONObject(); + req.set("messageKey", pushReqVO.getBusiBillCode()); + req.set("messageBody", body.toString()); + try { + log.info("国贸系统推送合同回调参数:{}",req); + String res = shareServiceUtil.callShareService("S_EPLAT_04", req.toString()); + log.info("国贸系统推送合同回调成功:{}",res); + } catch (Exception e) { + log.error("国贸系统推送合同回调失败:{}",e.getMessage(), e); + } + } + @Override public CommonResult> logisticsListPage(IntContractPageReq pageReq) { diff --git a/zt-module-contract-order/zt-module-contract-order-server/src/main/java/com/zt/plat/module/contractorder/api/OrderApiImpl.java b/zt-module-contract-order/zt-module-contract-order-server/src/main/java/com/zt/plat/module/contractorder/api/OrderApiImpl.java new file mode 100644 index 00000000..311a99d8 --- /dev/null +++ b/zt-module-contract-order/zt-module-contract-order-server/src/main/java/com/zt/plat/module/contractorder/api/OrderApiImpl.java @@ -0,0 +1,204 @@ +package com.zt.plat.module.contractorder.api; + +import cn.hutool.extra.spring.SpringUtil; +import com.zt.plat.framework.common.pojo.CommonResult; +import com.zt.plat.framework.common.util.object.BeanUtils; +import com.zt.plat.module.contractorder.api.dto.order.OrdDtlDTO; +import com.zt.plat.module.contractorder.api.dto.order.OrderDTO; +import com.zt.plat.module.contractorder.api.dto.order.PurchaseOrderWithDetailsDTO; +import com.zt.plat.module.contractorder.api.dto.order.SalesOrdDtlDTO; +import com.zt.plat.module.contractorder.dal.dataobject.purchaseorder.PrchOrdDtlDO; +import com.zt.plat.module.contractorder.dal.dataobject.purchaseorder.PurchaseOrderDO; +import com.zt.plat.module.contractorder.dal.dataobject.salesorder.SalesOrderDO; +import com.zt.plat.module.contractorder.dal.dataobject.salesorder.SalesOrderDetailDO; +import com.zt.plat.module.contractorder.dal.mysql.purchaseorder.PrchOrdDtlMapper; +import com.zt.plat.module.contractorder.dal.mysql.purchaseorder.PurchaseOrderMapper; +import com.zt.plat.module.contractorder.dal.mysql.salesorder.SalesOrderDetailMapper; +import com.zt.plat.module.contractorder.dal.mysql.salesorder.SalesOrderMapper; +import com.zt.plat.module.contractorder.service.purchaseorder.PurchaseOrderService; +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.RestController; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +import static com.zt.plat.framework.common.pojo.CommonResult.success; + +@RestController +@Validated +@Slf4j +public class OrderApiImpl implements OrderApi { + @Resource + private PurchaseOrderService purchaseOrderService; + + @Override + public CommonResult> getOrderByOrderIds(List ids) { + if (ids == null || ids.isEmpty()) { + throw new RuntimeException("订单id为空"); + } + List ordersByIds = purchaseOrderService.getOrdersByIds(ids.stream().map(String::valueOf).toList()); + List purchaseOrderIds = new ArrayList<>(); + List salesOrderIds = new ArrayList<>(); + List order = new ArrayList<>(); + if (ordersByIds.isEmpty()) { + return CommonResult.success(new ArrayList<>()); + } + ordersByIds.forEach(o -> { + if ("SALE".equals(o.getSplyBsnTp())) { + // 销售订单 + salesOrderIds.add(o.getId()); + } else { + // 非销售订单(采购订单) + purchaseOrderIds.add(o.getId()); + } + }); + if (!purchaseOrderIds.isEmpty()) { + order.addAll(getPoOrdByIds(purchaseOrderIds)); + } + if (!salesOrderIds.isEmpty()) { + order.addAll(getSalesOrdByIds(salesOrderIds)); + } + return success(order); + } + + @Override + public CommonResult> getOrderByOrderNos(List orderNoS) { + List orderByNos = purchaseOrderService.getOrderByNos(orderNoS); + if (orderByNos.isEmpty()) { + return success(new ArrayList<>()); + } + List order = new ArrayList<>(); + List purchaseOrderNoS = new ArrayList<>(); + List salesOrdNoS = new ArrayList<>(); + orderByNos.forEach(f -> { + if ("SALE".equals(f.getSplyBsnTp())) { + // 销售订单 + salesOrdNoS.add(f.getId()); + } else { + // 非销售订单(采购订单) + purchaseOrderNoS.add(f.getId()); + } + }); + if (!purchaseOrderNoS.isEmpty()) { + order.addAll(getPoOrdByIds(purchaseOrderNoS)); + } + if (!salesOrdNoS.isEmpty()) { + order.addAll(getSalesOrdByIds(salesOrdNoS)); + } + + return success(order); + } + + private List getOrderByIds(List ids) { + return SpringUtil.getBean(SalesOrderMapper.class).selectByIds(ids); // 采购订单与销售订单的 + } + + private List getPoOrdByIds(List ids) { + List purchaseOrderDOS = getOrderByIds(ids); + List orderDTOS = BeanUtils.toBean(purchaseOrderDOS, OrderDTO.class); + if (orderDTOS == null) { + return new ArrayList<>(); + } + PrchOrdDtlMapper prchOrdDtlMapper = SpringUtil.getBean(PrchOrdDtlMapper.class); + List orderIds = orderDTOS.stream().map(OrderDTO::getId).toList(); + List prchOrdDtlDOS = prchOrdDtlMapper.selectList(PrchOrdDtlDO::getOrdId, orderIds); + orderDTOS.forEach(o -> { + List ordDtlDTOS = new ArrayList<>(); + prchOrdDtlDOS.forEach(p -> { + + if (Objects.equals(o.getId(), p.getOrdId())) { + OrdDtlDTO ordDtlDTO = setOrderDtlDTO(o, p); + ordDtlDTOS.add(ordDtlDTO); + } + }); + o.setOrdDtlDTOS(ordDtlDTOS); + }); + return orderDTOS; + } + + private List getSalesOrdByIds(List ids) { + List salesOrderDOS = getOrderByIds(ids); + List orderDTOS = BeanUtils.toBean(salesOrderDOS, OrderDTO.class); + if (orderDTOS == null) { + return new ArrayList<>(); + } + SalesOrderDetailMapper salesOrderDetailMapper = SpringUtil.getBean(SalesOrderDetailMapper.class); + List orderIds = orderDTOS.stream().map(OrderDTO::getId).toList(); + List salesOrderDetailDOS = salesOrderDetailMapper.selectList(SalesOrderDetailDO::getOrderId, orderIds); + orderDTOS.forEach(o -> { + List salesOrdDtlDTOS = new ArrayList<>(); + salesOrderDetailDOS.forEach(s -> { + if (Objects.equals(o.getId(), s.getOrderId())) { + OrdDtlDTO ordDtlDTO = setOrderDtlDTO(o, s); + salesOrdDtlDTOS.add(ordDtlDTO); + } + }); + o.setOrdDtlDTOS(salesOrdDtlDTOS); + }); + return orderDTOS; + } + + private OrdDtlDTO setOrderDtlDTO(OrderDTO orderDTO, T t) { + OrdDtlDTO ordDtlDTO = new OrdDtlDTO(); + if (t instanceof PrchOrdDtlDO p) { + ordDtlDTO.setId(p.getId()); + ordDtlDTO.setOrderId(p.getOrdId()); + ordDtlDTO.setLineNum(p.getLineNum()); + ordDtlDTO.setMtrlName(p.getMtrlName()); + ordDtlDTO.setMtrlNum(p.getMtrlNum()); + ordDtlDTO.setFactoryName(p.getRcvFactNum()); + ordDtlDTO.setFactoryNum(p.getRcvFactNum()); + ordDtlDTO.setWarehouseName(p.getRcvWrhNum()); + ordDtlDTO.setWarehouseNum(p.getRcvWrhNum()); + ordDtlDTO.setUnit(p.getUnt()); + ordDtlDTO.setQuantity(p.getQty()); + ordDtlDTO.setProjectCategory(p.getPrjCtgr()); + ordDtlDTO.setAgreementNumber(p.getAgrNum()); + ordDtlDTO.setElementAbbreviation(p.getElemAbbr()); + ordDtlDTO.setElementName(p.getElemName()); + ordDtlDTO.setElementCode(p.getElemCdg()); + ordDtlDTO.setIsEnable(p.getIsEnb()); + ordDtlDTO.setTaxNum(p.getTaxNum()); + ordDtlDTO.setTaxRte(p.getTaxRte()); + //============================== + ordDtlDTO.setMtrlCpntNum(p.getMtrlCpntNum()); + ordDtlDTO.setMtrlCpntDsp(p.getMtrlCpntDsp()); + ordDtlDTO.setBgnDt(p.getBgnDt()); + ordDtlDTO.setDdlDt(p.getDdlDt()); + ordDtlDTO.setTrfFactName(p.getTrfFactName()); + ordDtlDTO.setTrfFactNum(p.getTrfFactNum()); + ordDtlDTO.setTrfWrhName(p.getTrfWrhName()); + ordDtlDTO.setTrfWrhNum(p.getTrfWrhNum()); + ordDtlDTO.setRmk(p.getRmk()); + + + } else if ( + t instanceof SalesOrdDtlDTO s + ) { + ordDtlDTO.setId(s.getId()); + ordDtlDTO.setOrderId(s.getOrderId()); + ordDtlDTO.setLineNum(s.getLineNumber()); + ordDtlDTO.setMtrlName(s.getMaterialName()); + ordDtlDTO.setMtrlNum(s.getMaterialNumber()); + ordDtlDTO.setFactoryName(s.getFactoryName()); + ordDtlDTO.setFactoryNum(s.getFactoryNumber()); + ordDtlDTO.setWarehouseName(s.getWarehouseName()); + ordDtlDTO.setWarehouseNum(s.getWarehouseNumber()); + ordDtlDTO.setUnit(s.getUnit()); + ordDtlDTO.setQuantity(s.getQuantity()); + ordDtlDTO.setProjectCategory(s.getProjectCategory()); + ordDtlDTO.setAgreementNumber(s.getAgreementNumber()); + ordDtlDTO.setElementAbbreviation(s.getElementAbbreviation()); + ordDtlDTO.setElementName(s.getElementName()); + ordDtlDTO.setElementCode(s.getElementNumber()); + ordDtlDTO.setIsEnable(s.getIsEnable()); + ordDtlDTO.setTaxNum(s.getTaxAcctasscat()); + //============================== + + } + return ordDtlDTO; + } +} diff --git a/zt-module-contract-order/zt-module-contract-order-server/src/main/java/com/zt/plat/module/contractorder/config/RestTemplateConfig.java b/zt-module-contract-order/zt-module-contract-order-server/src/main/java/com/zt/plat/module/contractorder/config/RestTemplateConfig.java new file mode 100644 index 00000000..b3827260 --- /dev/null +++ b/zt-module-contract-order/zt-module-contract-order-server/src/main/java/com/zt/plat/module/contractorder/config/RestTemplateConfig.java @@ -0,0 +1,34 @@ +package com.zt.plat.module.contractorder.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.client.ClientHttpRequestFactory; +import org.springframework.http.client.SimpleClientHttpRequestFactory; +import org.springframework.http.converter.StringHttpMessageConverter; +import org.springframework.web.client.RestTemplate; + +import java.nio.charset.Charset; + +/** + * RestTemplate配置类 + * @author ChenZhaoxue + * @date 2025/3/27 + */ +@Configuration +public class RestTemplateConfig { + + @Bean + public RestTemplate restTemplate(ClientHttpRequestFactory factory){ + RestTemplate restTemplate = new RestTemplate(factory); + restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(Charset.forName("UTF-8"))); + return restTemplate; + } + + @Bean + public ClientHttpRequestFactory simpleClientHttpRequestFactory(){ + SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory(); + factory.setConnectTimeout(10000);//单位为ms + factory.setReadTimeout(30000);//单位为ms + return factory; + } +} diff --git a/zt-module-contract-order/zt-module-contract-order-server/src/main/java/com/zt/plat/module/contractorder/controller/admin/contract/ContractController.java b/zt-module-contract-order/zt-module-contract-order-server/src/main/java/com/zt/plat/module/contractorder/controller/admin/contract/ContractController.java index 7373558e..4857d3c2 100644 --- a/zt-module-contract-order/zt-module-contract-order-server/src/main/java/com/zt/plat/module/contractorder/controller/admin/contract/ContractController.java +++ b/zt-module-contract-order/zt-module-contract-order-server/src/main/java/com/zt/plat/module/contractorder/controller/admin/contract/ContractController.java @@ -6,9 +6,11 @@ import com.zt.plat.framework.common.pojo.CommonResult; import com.zt.plat.framework.common.pojo.PageResult; import com.zt.plat.framework.common.util.object.BeanUtils; import com.zt.plat.module.contractorder.api.ContractApi; +import com.zt.plat.module.contractorder.api.dto.order.PurchaseOrderWithDetailsDTO; import com.zt.plat.module.contractorder.api.vo.contract.*; import com.zt.plat.module.contractorder.api.vo.contract.international.IntContract; import com.zt.plat.module.contractorder.api.vo.contract.international.IntContractPageReq; +import com.zt.plat.module.contractorder.api.vo.contract.international.IntPushContractReqVO; import com.zt.plat.module.contractorder.dal.dataobject.contract.ContractMainDO; import com.zt.plat.module.contractorder.service.contract.ContractService; import io.swagger.v3.oas.annotations.Operation; @@ -195,14 +197,21 @@ public class ContractController implements BusinessControllerMarker { @PostMapping("/push") @Operation(summary = "国贸2.0系统推送合同") @PreAuthorize("@ss.hasPermission('base:contract:create')") - CommonResult push(@Valid @RequestBody IntContract reqVO) { - return contractApi.push(reqVO); + public void push(@Valid @RequestBody IntPushContractReqVO pushReqVO) { + contractApi.push(pushReqVO); } @PostMapping("/logistics/list/page") @Operation(summary = "国贸2.0系统合同分页查询") @PreAuthorize("@ss.hasPermission('base:contract:query')") - CommonResult> logisticsListPage(IntContractPageReq pageReq) { + public CommonResult> logisticsListPage(IntContractPageReq pageReq) { return contractApi.logisticsListPage(pageReq); } + + @PostMapping("/order-by-order-no") + @Operation(summary = "通过订单编号获取订单信息", description = "通过订单编号获取订单信息") + @PreAuthorize("@ss.hasPermission('base:contract:query')") + public CommonResult> getOrderByOrderNo(@RequestBody List orderNoS){ + return contractApi.getOrderByOrderNo(orderNoS); + }; } diff --git a/zt-module-contract-order/zt-module-contract-order-server/src/main/java/com/zt/plat/module/contractorder/controller/admin/contractorder/ContractOrderController.java b/zt-module-contract-order/zt-module-contract-order-server/src/main/java/com/zt/plat/module/contractorder/controller/admin/contractorder/ContractOrderController.java index 62451506..d18a421e 100644 --- a/zt-module-contract-order/zt-module-contract-order-server/src/main/java/com/zt/plat/module/contractorder/controller/admin/contractorder/ContractOrderController.java +++ b/zt-module-contract-order/zt-module-contract-order-server/src/main/java/com/zt/plat/module/contractorder/controller/admin/contractorder/ContractOrderController.java @@ -1,13 +1,16 @@ package com.zt.plat.module.contractorder.controller.admin.contractorder; +import com.zt.plat.module.contractorder.api.dto.order.PurchaseOrderWithDetailsDTO; +import com.zt.plat.module.contractorder.service.contract.ContractService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import jakarta.annotation.Resource; +import org.springframework.web.bind.annotation.*; import com.zt.plat.framework.common.pojo.CommonResult; +import java.util.List; + import static com.zt.plat.framework.common.pojo.CommonResult.success; /** @@ -20,10 +23,12 @@ import static com.zt.plat.framework.common.pojo.CommonResult.success; @RequestMapping("/admin/contract-order/contract-order") public class ContractOrderController { + @Resource + private ContractService contractService; + @GetMapping("/hello") @Operation(summary = "Hello ContractOrder") public CommonResult hello() { return success("Hello, ContractOrder!"); } - } diff --git a/zt-module-contract-order/zt-module-contract-order-server/src/main/java/com/zt/plat/module/contractorder/dal/dataobject/purchaseorder/PrchOrdDtlDO.java b/zt-module-contract-order/zt-module-contract-order-server/src/main/java/com/zt/plat/module/contractorder/dal/dataobject/purchaseorder/PrchOrdDtlDO.java index fab9a2b8..ee0e10a3 100644 --- a/zt-module-contract-order/zt-module-contract-order-server/src/main/java/com/zt/plat/module/contractorder/dal/dataobject/purchaseorder/PrchOrdDtlDO.java +++ b/zt-module-contract-order/zt-module-contract-order-server/src/main/java/com/zt/plat/module/contractorder/dal/dataobject/purchaseorder/PrchOrdDtlDO.java @@ -274,6 +274,6 @@ public class PrchOrdDtlDO extends BusinessBaseDO { * 税率 */ @TableField("TAX_RTE") - private String taxRte; + private BigDecimal taxRte; } diff --git a/zt-module-contract-order/zt-module-contract-order-server/src/main/java/com/zt/plat/module/contractorder/util/RedisUtil.java b/zt-module-contract-order/zt-module-contract-order-server/src/main/java/com/zt/plat/module/contractorder/util/RedisUtil.java new file mode 100644 index 00000000..5b925b35 --- /dev/null +++ b/zt-module-contract-order/zt-module-contract-order-server/src/main/java/com/zt/plat/module/contractorder/util/RedisUtil.java @@ -0,0 +1,565 @@ +package com.zt.plat.module.contractorder.util; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.stereotype.Component; + +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.TimeUnit; + +/** + * redis 工具类 + * + */ +@Slf4j +@Component +public class RedisUtil { + + @Autowired + private RedisTemplate redisTemplate; + + /** + * 指定缓存失效时间 + * + * @param key 键 + * @param time 时间(秒) + * @return + */ + public boolean expire(String key, long time) { + try { + if (time > 0) { + redisTemplate.expire(key, time, TimeUnit.SECONDS); + } + return true; + } catch (Exception e) { + log.error(e.getMessage(), e); + return false; + } + } + + /** + * 根据key 获取过期时间 + * + * @param key 键 不能为null + * @return 时间(秒) 返回0代表为永久有效 + */ + public long getExpire(String key) { + return redisTemplate.getExpire(key, TimeUnit.SECONDS); + } + + /** + * 判断key是否存在 + * + * @param key 键 + * @return true 存在 false不存在 + */ + public boolean hasKey(String key) { + try { + return redisTemplate.hasKey(key); + } catch (Exception e) { + log.error(e.getMessage(), e); + return false; + } + } + + /** + * 删除缓存 + * + * @param key 可以传一个值 或多个 + */ + @SuppressWarnings("unchecked") + public void del(String key) { + redisTemplate.delete(key); + } + + // ============================String============================= + /** + * 普通缓存获取 + * + * @param key 键 + * @return 值 + */ + public Object get(String key) { + return key == null ? null : redisTemplate.opsForValue().get(key); + } + + /** + * 普通缓存放入 + * + * @param key 键 + * @param value 值 + * @return true成功 false失败 + */ + public boolean set(String key, Object value) { + try { + redisTemplate.opsForValue().set(key, value); + return true; + } catch (Exception e) { + log.error(e.getMessage(), e); + return false; + } + + } + + /** + * 普通缓存放入并设置时间 + * + * @param key 键 + * @param value 值 + * @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期 + * @return true成功 false 失败 + */ + public boolean set(String key, Object value, long time) { + try { + if (time > 0) { + redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS); + } else { + set(key, value); + } + return true; + } catch (Exception e) { + log.error(e.getMessage(), e); + return false; + } + } + + /** + * 递增 + * + * @param key 键 + * @param by 要增加几(大于0) + * @return + */ + public long incr(String key, long delta) { + if (delta < 0) { + throw new RuntimeException("递增因子必须大于0"); + } + return redisTemplate.opsForValue().increment(key, delta); + } + + /** + * 递减 + * + * @param key 键 + * @param by 要减少几(小于0) + * @return + */ + public long decr(String key, long delta) { + if (delta < 0) { + throw new RuntimeException("递减因子必须大于0"); + } + return redisTemplate.opsForValue().increment(key, -delta); + } + + // ================================Map================================= + /** + * HashGet + * + * @param key 键 不能为null + * @param item 项 不能为null + * @return 值 + */ + public Object hget(String key, String item) { + return redisTemplate.opsForHash().get(key, item); + } + + /** + * 获取hashKey对应的所有键值 + * + * @param key 键 + * @return 对应的多个键值 + */ + public Map hmget(String key) { + return redisTemplate.opsForHash().entries(key); + } + + /** + * HashSet + * + * @param key 键 + * @param map 对应多个键值 + * @return true 成功 false 失败 + */ + public boolean hmset(String key, Map map) { + try { + redisTemplate.opsForHash().putAll(key, map); + return true; + } catch (Exception e) { + log.error(e.getMessage(), e); + return false; + } + } + + /** + * HashSet 并设置时间 + * + * @param key 键 + * @param map 对应多个键值 + * @param time 时间(秒) + * @return true成功 false失败 + */ + public boolean hmset(String key, Map map, long time) { + try { + redisTemplate.opsForHash().putAll(key, map); + if (time > 0) { + expire(key, time); + } + return true; + } catch (Exception e) { + log.error(e.getMessage(), e); + return false; + } + } + + /** + * 向一张hash表中放入数据,如果不存在将创建 + * + * @param key 键 + * @param item 项 + * @param value 值 + * @return true 成功 false失败 + */ + public boolean hset(String key, String item, Object value) { + try { + redisTemplate.opsForHash().put(key, item, value); + return true; + } catch (Exception e) { + log.error(e.getMessage(), e); + return false; + } + } + + /** + * 向一张hash表中放入数据,如果不存在将创建 + * + * @param key 键 + * @param item 项 + * @param value 值 + * @param time 时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间 + * @return true 成功 false失败 + */ + public boolean hset(String key, String item, Object value, long time) { + try { + redisTemplate.opsForHash().put(key, item, value); + if (time > 0) { + expire(key, time); + } + return true; + } catch (Exception e) { + log.error(e.getMessage(), e); + return false; + } + } + + /** + * 删除hash表中的值 + * + * @param key 键 不能为null + * @param item 项 可以使多个 不能为null + */ + public void hdel(String key, Object... item) { + redisTemplate.opsForHash().delete(key, item); + } + + /** + * 判断hash表中是否有该项的值 + * + * @param key 键 不能为null + * @param item 项 不能为null + * @return true 存在 false不存在 + */ + public boolean hHasKey(String key, String item) { + return redisTemplate.opsForHash().hasKey(key, item); + } + + /** + * hash递增 如果不存在,就会创建一个 并把新增后的值返回 + * + * @param key 键 + * @param item 项 + * @param by 要增加几(大于0) + * @return + */ + public double hincr(String key, String item, double by) { + return redisTemplate.opsForHash().increment(key, item, by); + } + + /** + * hash递减 + * + * @param key 键 + * @param item 项 + * @param by 要减少记(小于0) + * @return + */ + public double hdecr(String key, String item, double by) { + return redisTemplate.opsForHash().increment(key, item, -by); + } + + // ============================set============================= + /** + * 根据key获取Set中的所有值 + * + * @param key 键 + * @return + */ + public Set sGet(String key) { + try { + return redisTemplate.opsForSet().members(key); + } catch (Exception e) { + log.error(e.getMessage(), e); + return null; + } + } + + /** + * 根据value从一个set中查询,是否存在 + * + * @param key 键 + * @param value 值 + * @return true 存在 false不存在 + */ + public boolean sHasKey(String key, Object value) { + try { + return redisTemplate.opsForSet().isMember(key, value); + } catch (Exception e) { + log.error(e.getMessage(), e); + return false; + } + } + + /** + * 将数据放入set缓存 + * + * @param key 键 + * @param values 值 可以是多个 + * @return 成功个数 + */ + public long sSet(String key, Object... values) { + try { + return redisTemplate.opsForSet().add(key, values); + } catch (Exception e) { + log.error(e.getMessage(), e); + return 0; + } + } + + /** + * 将set数据放入缓存 + * + * @param key 键 + * @param time 时间(秒) + * @param values 值 可以是多个 + * @return 成功个数 + */ + public long sSetAndTime(String key, long time, Object... values) { + try { + Long count = redisTemplate.opsForSet().add(key, values); + if (time > 0) { + expire(key, time); + } + return count; + } catch (Exception e) { + log.error(e.getMessage(), e); + return 0; + } + } + + /** + * 获取set缓存的长度 + * + * @param key 键 + * @return + */ + public long sGetSetSize(String key) { + try { + return redisTemplate.opsForSet().size(key); + } catch (Exception e) { + log.error(e.getMessage(), e); + return 0; + } + } + + /** + * 移除值为value的 + * + * @param key 键 + * @param values 值 可以是多个 + * @return 移除的个数 + */ + public long setRemove(String key, Object... values) { + try { + Long count = redisTemplate.opsForSet().remove(key, values); + return count; + } catch (Exception e) { + log.error(e.getMessage(), e); + return 0; + } + } + // ===============================list================================= + + /** + * 获取list缓存的内容 + * + * @param key 键 + * @param start 开始 + * @param end 结束 0 到 -1代表所有值 + * @return + */ + public List lGet(String key, long start, long end) { + try { + return redisTemplate.opsForList().range(key, start, end); + } catch (Exception e) { + log.error(e.getMessage(), e); + return null; + } + } + + /** + * 获取list缓存的长度 + * + * @param key 键 + * @return + */ + public long lGetListSize(String key) { + try { + return redisTemplate.opsForList().size(key); + } catch (Exception e) { + log.error(e.getMessage(), e); + return 0; + } + } + + /** + * 通过索引 获取list中的值 + * + * @param key 键 + * @param index 索引 index>=0时, 0 表头,1 第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素,依次类推 + * @return + */ + public Object lGetIndex(String key, long index) { + try { + return redisTemplate.opsForList().index(key, index); + } catch (Exception e) { + log.error(e.getMessage(), e); + return null; + } + } + + /** + * 将list放入缓存 + * + * @param key 键 + * @param value 值 + * @param time 时间(秒) + * @return + */ + public boolean lSet(String key, Object value) { + try { + redisTemplate.opsForList().rightPush(key, value); + return true; + } catch (Exception e) { + log.error(e.getMessage(), e); + return false; + } + } + + /** + * 将list放入缓存 + * + * @param key 键 + * @param value 值 + * @param time 时间(秒) + * @return + */ + public boolean lSet(String key, Object value, long time) { + try { + redisTemplate.opsForList().rightPush(key, value); + if (time > 0) { + expire(key, time); + } + return true; + } catch (Exception e) { + log.error(e.getMessage(), e); + return false; + } + } + + /** + * 将list放入缓存 + * + * @param key 键 + * @param value 值 + * @param time 时间(秒) + * @return + */ + public boolean lSet(String key, List value) { + try { + redisTemplate.opsForList().rightPushAll(key, value); + return true; + } catch (Exception e) { + log.error(e.getMessage(), e); + return false; + } + } + + /** + * 将list放入缓存 + * + * @param key 键 + * @param value 值 + * @param time 时间(秒) + * @return + */ + public boolean lSet(String key, List value, long time) { + try { + redisTemplate.opsForList().rightPushAll(key, value); + if (time > 0) { + expire(key, time); + } + return true; + } catch (Exception e) { + log.error(e.getMessage(), e); + return false; + } + } + + /** + * 根据索引修改list中的某条数据 + * + * @param key 键 + * @param index 索引 + * @param value 值 + * @return + */ + public boolean lUpdateIndex(String key, long index, Object value) { + try { + redisTemplate.opsForList().set(key, index, value); + return true; + } catch (Exception e) { + log.error(e.getMessage(), e); + return false; + } + } + + /** + * 移除N个值为value + * + * @param key 键 + * @param count 移除多少个 + * @param value 值 + * @return 移除的个数 + */ + public long lRemove(String key, long count, Object value) { + try { + Long remove = redisTemplate.opsForList().remove(key, count, value); + return remove; + } catch (Exception e) { + log.error(e.getMessage(), e); + return 0; + } + } +} diff --git a/zt-module-contract-order/zt-module-contract-order-server/src/main/java/com/zt/plat/module/contractorder/util/ShareServiceUtil.java b/zt-module-contract-order/zt-module-contract-order-server/src/main/java/com/zt/plat/module/contractorder/util/ShareServiceUtil.java new file mode 100644 index 00000000..4ee6cb02 --- /dev/null +++ b/zt-module-contract-order/zt-module-contract-order-server/src/main/java/com/zt/plat/module/contractorder/util/ShareServiceUtil.java @@ -0,0 +1,127 @@ +package com.zt.plat.module.contractorder.util; + +import cn.hutool.json.JSONObject; +import cn.hutool.json.JSONUtil; +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.*; +import org.springframework.stereotype.Component; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.web.client.RestTemplate; + +/** + * ePlat共享服务调用工具类 + */ +@Slf4j +@Configuration +@Component +public class ShareServiceUtil { + private static final String SHARE_TOKEN_KEY = "eplat:cache:shareToken"; + private static final String SHARE_REFRESH_TOKEN_KEY = "eplat:cache:shareRefreshToken"; + private static final int TOKEN_TIME_OUT = 5000; // token过期时间,默认7200秒,这里设置建议小一些,如7000秒 + + @Value("${eplat.share.urlPrex}") + private String urlPrex; + @Value("${eplat.share.clientId}") + private String clientId; + @Value("${eplat.share.clientSecret}") + private String clientSecret; + + + @Resource + private RestTemplate restTemplate; + @Resource + private RedisUtil redisUtil; + + + /** + * ePlat共享服务调用 + * @param serviceNo 服务号 + * @param request 请求json字符串 + * @return 调用结果 + */ + public String callShareService(String serviceNo, String request) { + String url = String.format("%s/service/%s", urlPrex, serviceNo); + log.info("ePlat共享服务调用url:[" + url + "],request:[" + request + "]"); + String token = generateToken(); + log.info("目标token:" + token); + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON_UTF8); + headers.add("Xplat-Token", token); + HttpEntity entity = new HttpEntity<>(request, headers); + ResponseEntity result = restTemplate.exchange(url, HttpMethod.POST, entity, String.class); + return result.getBody(); + } + + private String generateToken() { + // 先从redis中获取未过期token + String token = (String) redisUtil.get(SHARE_TOKEN_KEY); + if (token == null) { + synchronized (ShareServiceUtil.class) { + token = (String) redisUtil.get(SHARE_TOKEN_KEY); + if (token == null) { + try { + token = refreshToken(); + } catch (Exception e) { + log.warn("生成token出错,可能刷新token有问题,重新尝试下", e); + redisUtil.del(SHARE_REFRESH_TOKEN_KEY); + token = refreshToken(); + } + } + } + } + return token; + } + + private String refreshToken() { + // 先从redis中获取未过期的刷新token + String refreshToken = (String) redisUtil.get(SHARE_REFRESH_TOKEN_KEY); + if (refreshToken == null) { + // 重新创建token和刷新token + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); + // 构造form表单 + MultiValueMap paramsMap = new LinkedMultiValueMap<>(); + paramsMap.set("client_id", clientId); + paramsMap.set("client_secret", clientSecret); + paramsMap.set("grant_type", "client_credentials"); + paramsMap.set("scope", "read"); + String url = String.format("%s/eplat/oauth/token", urlPrex); + // 构造请求的实体。包含body和headers的内容 + HttpEntity> entity = new HttpEntity<>(paramsMap, headers); + log.info("获取token调用url:[" + url + "],request:[" + paramsMap + "]"); + ResponseEntity result = restTemplate.exchange(url, HttpMethod.POST, entity, String.class); + JSONObject json = JSONUtil.parseObj(result.getBody()); + String accessToken = json.getStr("access_token"); + refreshToken = json.getStr("refresh_token"); + // 缓存token、刷新token(刷新token过期时间为2倍token过期时间) + redisUtil.set(SHARE_TOKEN_KEY, accessToken, TOKEN_TIME_OUT); + redisUtil.set(SHARE_REFRESH_TOKEN_KEY, refreshToken, TOKEN_TIME_OUT * 2); + return accessToken; + } else { + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); + // 构造form表单 + MultiValueMap paramsMap = new LinkedMultiValueMap<>(); + paramsMap.set("client_id", clientId); + paramsMap.set("client_secret", clientSecret); + paramsMap.set("grant_type", "refresh_token"); + paramsMap.set("refresh_token", refreshToken); + String url = String.format("%s/eplat/oauth/token", urlPrex); + // 构造请求的实体。包含body和headers的内容 + HttpEntity> entity = new HttpEntity<>(paramsMap, headers); + log.info("刷新token调用url:[" + url + "],request:[" + paramsMap + "]"); + ResponseEntity result = restTemplate.exchange(url, HttpMethod.POST, entity, String.class); + JSONObject json = JSONUtil.parseObj(result.getBody()); + String accessToken = json.getStr("access_token"); + refreshToken = json.getStr("refresh_token"); + // 缓存token、刷新token(刷新token过期时间为2倍token过期时间) + redisUtil.set(SHARE_TOKEN_KEY, accessToken, TOKEN_TIME_OUT); + redisUtil.set(SHARE_REFRESH_TOKEN_KEY, refreshToken, TOKEN_TIME_OUT * 2); + return accessToken; + } + } +}