From 66bfe969e312645aa22911b6e9657d658c3d3e48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E4=B9=BE=E7=BF=94?= Date: Thu, 14 May 2026 19:20:36 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A4=96=E5=8D=8F=E8=AE=A2=E5=8D=95=E7=BB=93?= =?UTF-8?q?=E7=AE=97-=E5=BE=85=E7=A1=AE=E8=AE=A4=E3=80=81=E7=BB=93?= =?UTF-8?q?=E7=AE=97=E5=AE=A1=E6=A0=B8=E3=80=81=E7=BB=93=E7=AE=97=E5=AE=8C?= =?UTF-8?q?=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../OemSettlementApprovalDetailEntity.java | 98 +++++ .../entity/OemSettlementApprovalEntity.java | 191 ++++++++ .../oem/pojo/entity/OemStatementEntity.java | 4 +- .../pojo/request/SettlementApprovalQuery.java | 62 +++ .../request/SettlementApprovalRequest.java | 43 ++ .../SettlementConfirmRequestQuery.java | 2 + .../vo/OemSettlementApprovalDetailVO.java | 100 +++++ .../oem/pojo/vo/OemSettlementApprovalVO.java | 159 +++++++ .../feign/IErpOemSettlementClient.java | 32 ++ .../pojo/dto/OemProcessSettlementDTO.java | 171 ++++++++ .../OemSettlementApprovalController.java | 81 ++++ .../controller/OemStatementController.java | 28 +- .../OemSettlementApprovalDetailMapper.java | 13 + .../mapper/OemSettlementApprovalMapper.java | 28 ++ .../mapper/OemSettlementApprovalMapper.xml | 72 +++ .../desk/oem/mapper/OemStatementMapper.xml | 6 + .../IOemSettlementApprovalDetailService.java | 13 + .../IOemSettlementApprovalService.java | 55 +++ .../oem/service/IOemStatementService.java | 17 + ...emSettlementApprovalDetailServiceImpl.java | 18 + .../OemSettlementApprovalServiceImpl.java | 414 ++++++++++++++++++ .../service/impl/OemStatementServiceImpl.java | 385 +++++++++++++++- .../feign/ErpOemSettlementClientImpl.java | 29 ++ .../service/IErpOemSettlementService.java | 21 + .../impl/ErpOemSettlementServiceImpl.java | 126 ++++++ 25 files changed, 2158 insertions(+), 10 deletions(-) create mode 100644 blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/oem/pojo/entity/OemSettlementApprovalDetailEntity.java create mode 100644 blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/oem/pojo/entity/OemSettlementApprovalEntity.java create mode 100644 blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/oem/pojo/request/SettlementApprovalQuery.java create mode 100644 blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/oem/pojo/request/SettlementApprovalRequest.java create mode 100644 blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/oem/pojo/vo/OemSettlementApprovalDetailVO.java create mode 100644 blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/oem/pojo/vo/OemSettlementApprovalVO.java create mode 100644 blade-service-api/blade-erpdata-api/src/main/java/org/springblade/erpdata/feign/IErpOemSettlementClient.java create mode 100644 blade-service-api/blade-erpdata-api/src/main/java/org/springblade/erpdata/pojo/dto/OemProcessSettlementDTO.java create mode 100644 blade-service/blade-desk/src/main/java/org/springblade/desk/oem/controller/OemSettlementApprovalController.java create mode 100644 blade-service/blade-desk/src/main/java/org/springblade/desk/oem/mapper/OemSettlementApprovalDetailMapper.java create mode 100644 blade-service/blade-desk/src/main/java/org/springblade/desk/oem/mapper/OemSettlementApprovalMapper.java create mode 100644 blade-service/blade-desk/src/main/java/org/springblade/desk/oem/mapper/OemSettlementApprovalMapper.xml create mode 100644 blade-service/blade-desk/src/main/java/org/springblade/desk/oem/service/IOemSettlementApprovalDetailService.java create mode 100644 blade-service/blade-desk/src/main/java/org/springblade/desk/oem/service/IOemSettlementApprovalService.java create mode 100644 blade-service/blade-desk/src/main/java/org/springblade/desk/oem/service/impl/OemSettlementApprovalDetailServiceImpl.java create mode 100644 blade-service/blade-desk/src/main/java/org/springblade/desk/oem/service/impl/OemSettlementApprovalServiceImpl.java create mode 100644 blade-service/blade-erpdata/src/main/java/org/springblade/erpdata/feign/ErpOemSettlementClientImpl.java create mode 100644 blade-service/blade-erpdata/src/main/java/org/springblade/erpdata/service/IErpOemSettlementService.java create mode 100644 blade-service/blade-erpdata/src/main/java/org/springblade/erpdata/service/impl/ErpOemSettlementServiceImpl.java diff --git a/blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/oem/pojo/entity/OemSettlementApprovalDetailEntity.java b/blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/oem/pojo/entity/OemSettlementApprovalDetailEntity.java new file mode 100644 index 000000000..87e026f1e --- /dev/null +++ b/blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/oem/pojo/entity/OemSettlementApprovalDetailEntity.java @@ -0,0 +1,98 @@ +package org.springblade.desk.oem.pojo.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.springblade.core.mp.base.BaseEntity; + +import java.io.Serial; +import java.math.BigDecimal; + +/** + * 外协结算审批明细表 实体类 + * + * @author qyl + * @since 2026-05-12 + */ +@Data +@TableName("MES_OEM_SETTLE_APPROVAL_DTL") +@Schema(description = "OemSettlementApprovalDetail对象") +@EqualsAndHashCode(callSuper = true) +public class OemSettlementApprovalDetailEntity extends BaseEntity { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 审批主表ID + */ + @Schema(description = "审批主表ID") + private Long approvalId; + + /** + * 外协厂家ID + */ + @Schema(description = "外协厂家ID") + private Long ocId; + + /** + * 外协厂家编码 + */ + @Schema(description = "外协厂家编码") + private String ocCode; + + /** + * 外协厂家名称 + */ + @Schema(description = "外协厂家名称") + private String ocName; + + /** + * 标准工序代码(结算大类) + */ + @Schema(description = "标准工序代码(结算大类)") + private String standardProcessCode; + + /** + * 结算大类ID + */ + @Schema(description = "结算大类ID") + private Long statementCategoryId; + + /** + * 结算大类名称 + */ + @Schema(description = "结算大类名称") + private String statementCategory; + + /** + * 批数(分组结算数据数量) + */ + @Schema(description = "批数") + private Integer batchCount; + + /** + * 总面积(dm²)(分组结算数据总面积) + */ + @Schema(description = "总面积(dm²)") + private BigDecimal totalArea; + + /** + * 面积月占比(%) + */ + @Schema(description = "面积月占比(%)") + private BigDecimal areaMonthRatio; + + /** + * 月结算金额(元)(分组结算数据总金额) + */ + @Schema(description = "月结算金额(元)") + private BigDecimal monthAmount; + + /** + * 金额月占比(%) + */ + @Schema(description = "金额月占比(%)") + private BigDecimal amountMonthRatio; +} diff --git a/blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/oem/pojo/entity/OemSettlementApprovalEntity.java b/blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/oem/pojo/entity/OemSettlementApprovalEntity.java new file mode 100644 index 000000000..bebc0a8fa --- /dev/null +++ b/blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/oem/pojo/entity/OemSettlementApprovalEntity.java @@ -0,0 +1,191 @@ +package org.springblade.desk.oem.pojo.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import org.springblade.core.mp.base.BaseEntity; + +import java.io.Serial; +import java.math.BigDecimal; +import java.util.Date; + +/** + * 外协结算审批主表 实体类 + * + * @author qyl + * @since 2026-05-12 + */ +@Data +@TableName("MES_OEM_SETTLEMENT_APPROVAL") +@Schema(description = "OemSettlementApproval对象") +@EqualsAndHashCode(callSuper = true) +public class OemSettlementApprovalEntity extends BaseEntity { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 审批状态枚举 + */ + @Getter + @AllArgsConstructor + public enum ApprovalStatusEnum { + //(待校对、校对中、待审核、审核通过、不通过) + + /** + * 待审批 + */ + PENDING(1, "待校对"), + + /** + * 校对中 + */ + PROOFREADING(2, "校对中"), + + /** + * 审批通过 + */ + APPROVED(3, "审核通过"), + + /** + * 审批不通过 + */ + REJECTED(4, "不通过"), + + /** + * 待审核 + */ + WAITING_AUDIT(5, "待审核"); + + private final Integer code; + private final String name; + + /** + * 根据code获取枚举 + */ + public static ApprovalStatusEnum getByCode(Integer code) { + if (code == null) { + return null; + } + for (ApprovalStatusEnum status : values()) { + if (status.getCode().equals(code)) { + return status; + } + } + return null; + } + + /** + * 根据code获取名称 + */ + public static String getNameByCode(Integer code) { + ApprovalStatusEnum status = getByCode(code); + return status != null ? status.getName() : "未知"; + } + } + + /** + * 审批单号 + */ + @Schema(description = "审批单号") + private String approvalNo; + + /** + * 结算总批数 + */ + @Schema(description = "结算总批数") + private Integer totalCount; + + /** + * 结算总面积(dm²) + */ + @Schema(description = "结算总面积(dm²)") + private BigDecimal totalArea; + + /** + * 结算总金额(元) + */ + @Schema(description = "结算总金额(元)") + private BigDecimal totalAmount; + + /** + * 结算说明 + */ + @Schema(description = "结算说明") + private String settlementMemo; + + /** + * 审批状态:1-待校对,2-校对中,3-审核通过,4-不通过,5-待审核 + */ + @Schema(description = "审批状态:1-待校对,2-校对中,3-审核通过,4-不通过,5-待审核") + private Integer approvalStatus; + + /** + * 提交时间 + */ + @Schema(description = "提交时间") + private Date submitTime; + + /** + * 审批时间 + */ + @Schema(description = "审批时间") + private Date approvalTime; + + /** + * 审批人ID + */ + @Schema(description = "审批人ID") + private Long approvalUserId; + + /** + * 审批人姓名 + */ + @Schema(description = "审批人姓名") + private String approvalUserName; + + /** + * 审批意见 + */ + @Schema(description = "审批意见") + private String approvalMemo; + + /** + * 校对人1 ID + */ + @Schema(description = "校对人1 ID") + private Long proofreader1Id; + + /** + * 校对人1 姓名 + */ + @Schema(description = "校对人1 姓名") + private String proofreader1Name; + + /** + * 校对时间1 + */ + @Schema(description = "校对时间1") + private Date proofreadTime1; + + /** + * 校对人2 ID + */ + @Schema(description = "校对人2 ID") + private Long proofreader2Id; + + /** + * 校对人2 姓名 + */ + @Schema(description = "校对人2 姓名") + private String proofreader2Name; + + /** + * 校对时间2 + */ + @Schema(description = "校对时间2") + private Date proofreadTime2; +} diff --git a/blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/oem/pojo/entity/OemStatementEntity.java b/blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/oem/pojo/entity/OemStatementEntity.java index 087e16745..c0fd76ac1 100644 --- a/blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/oem/pojo/entity/OemStatementEntity.java +++ b/blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/oem/pojo/entity/OemStatementEntity.java @@ -129,7 +129,7 @@ public class OemStatementEntity extends BaseEntity { private Date approvalTime; @Schema(description = "推送时间") - private String pushTime; + private Date pushTime; @Schema(description = "结算单号") private String statementNo; @@ -221,6 +221,8 @@ public class OemStatementEntity extends BaseEntity { @Schema(description = "结算大类") private String statementCategory; + @Schema(description = "审批id") + private Long approvalId; @Schema(description = "流程卡号") private String cardNo; } diff --git a/blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/oem/pojo/request/SettlementApprovalQuery.java b/blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/oem/pojo/request/SettlementApprovalQuery.java new file mode 100644 index 000000000..143c844c6 --- /dev/null +++ b/blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/oem/pojo/request/SettlementApprovalQuery.java @@ -0,0 +1,62 @@ +package org.springblade.desk.oem.pojo.request; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; + +import java.time.LocalDate; + +/** + * 外协结算审批查询条件类 + * + * @author qyl + * @since 2026-05-12 + */ +@Data +@Schema(description = "外协结算审批查询条件") +public class SettlementApprovalQuery { + + /** + * 审批单号 + */ + @Schema(description = "审批单号") + private String approvalNo; + + /** + * 审批状态:1-待审批,2-审批中,3-审批通过,4-审批不通过 + */ + @Schema(description = "审批状态:1-待审批,2-审批中,3-审批通过,4-审批不通过") + private Integer approvalStatus; + + /** + * 提交时间开始 + */ + @DateTimeFormat(pattern = "yyyy-MM-dd") + @Schema(description = "提交时间开始") + private LocalDate submitTimeStart; + + /** + * 提交时间结束 + */ + @DateTimeFormat(pattern = "yyyy-MM-dd") + @Schema(description = "提交时间结束") + private LocalDate submitTimeEnd; + + /** + * 校对人1 ID + */ + @Schema(description = "校对人1 ID") + private Long proofreader1Id; + + /** + * 校对人2 ID + */ + @Schema(description = "校对人2 ID") + private Long proofreader2Id; + + /** + * 是否按厂家分组:true-按厂家,false-按厂家+结算大类(默认) + */ + @Schema(description = "是否按厂家分组:true-按厂家,false-按厂家+结算大类(默认)") + private Boolean groupByOc; +} diff --git a/blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/oem/pojo/request/SettlementApprovalRequest.java b/blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/oem/pojo/request/SettlementApprovalRequest.java new file mode 100644 index 000000000..7915bce66 --- /dev/null +++ b/blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/oem/pojo/request/SettlementApprovalRequest.java @@ -0,0 +1,43 @@ +package org.springblade.desk.oem.pojo.request; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; +import lombok.Data; + +/** + * 外协结算审批请求 + * + * @author qyl + * @since 2026-05-12 + */ +@Data +@Schema(description = "外协结算审批请求") +public class SettlementApprovalRequest { + + /** + * 审批ID + */ + @NotNull(message = "审批ID不能为空") + @Schema(description = "审批ID", required = true) + private Long approvalId; + + /** + * 审批类型:1-校对,2-审核 + */ + @NotNull(message = "审批类型不能为空") + @Schema(description = "审批类型:1-校对,2-审核", required = true) + private Integer approvalType; + + /** + * 审批结果:1-通过,2-不通过 + */ + @NotNull(message = "审批结果不能为空") + @Schema(description = "审批结果:1-通过,2-不通过", required = true) + private Integer approvalResult; + + /** + * 审批意见(不通过时必填) + */ + @Schema(description = "审批意见(不通过时必填)") + private String approvalMemo; +} diff --git a/blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/oem/pojo/request/SettlementConfirmRequestQuery.java b/blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/oem/pojo/request/SettlementConfirmRequestQuery.java index 1834b2489..4f6babf73 100644 --- a/blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/oem/pojo/request/SettlementConfirmRequestQuery.java +++ b/blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/oem/pojo/request/SettlementConfirmRequestQuery.java @@ -40,4 +40,6 @@ public class SettlementConfirmRequestQuery implements Serializable { */ @Schema(description = "异常原因(结算异常时必填),可选值:订单数据错误、无需结算") private String errorReason; + + String settlementMemo; } diff --git a/blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/oem/pojo/vo/OemSettlementApprovalDetailVO.java b/blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/oem/pojo/vo/OemSettlementApprovalDetailVO.java new file mode 100644 index 000000000..aff63ab62 --- /dev/null +++ b/blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/oem/pojo/vo/OemSettlementApprovalDetailVO.java @@ -0,0 +1,100 @@ +package org.springblade.desk.oem.pojo.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; +import java.math.BigDecimal; + +/** + * 外协结算审批明细 VO + * + * @author qyl + * @since 2026-05-12 + */ +@Data +@Schema(description = "外协结算审批明细VO") +public class OemSettlementApprovalDetailVO implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键ID + */ + @Schema(description = "主键ID") + private Long id; + + /** + * 审批主表ID + */ + @Schema(description = "审批主表ID") + private Long approvalId; + + /** + * 外协厂家ID + */ + @Schema(description = "外协厂家ID") + private Long ocId; + + /** + * 外协厂家编码 + */ + @Schema(description = "外协厂家编码") + private String ocCode; + + /** + * 外协厂家名称 + */ + @Schema(description = "外协厂家名称") + private String ocName; + + /** + * 标准工序代码 + */ + @Schema(description = "标准工序代码") + private String standardProcessCode; + + /** + * 结算大类ID + */ + @Schema(description = "结算大类ID") + private Long statementCategoryId; + + /** + * 结算大类名称 + */ + @Schema(description = "结算大类名称") + private String statementCategory; + + /** + * 批数 + */ + @Schema(description = "批数") + private Integer batchCount; + + /** + * 总面积(dm²) + */ + @Schema(description = "总面积(dm²)") + private BigDecimal totalArea; + + /** + * 面积月占比(%) + */ + @Schema(description = "面积月占比(%)") + private BigDecimal areaMonthRatio; + + /** + * 月结算金额(元) + */ + @Schema(description = "月结算金额(元)") + private BigDecimal monthAmount; + + /** + * 金额月占比(%) + */ + @Schema(description = "金额月占比(%)") + private BigDecimal amountMonthRatio; +} diff --git a/blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/oem/pojo/vo/OemSettlementApprovalVO.java b/blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/oem/pojo/vo/OemSettlementApprovalVO.java new file mode 100644 index 000000000..242ee7a29 --- /dev/null +++ b/blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/oem/pojo/vo/OemSettlementApprovalVO.java @@ -0,0 +1,159 @@ +package org.springblade.desk.oem.pojo.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.springblade.core.mp.base.BaseEntity; + +import java.io.Serial; +import java.math.BigDecimal; +import java.util.Date; + +/** + * 外协结算审批主表 VO + * + * @author qyl + * @since 2026-05-12 + */ +@Data +@Schema(description = "外协结算审批主表VO") +@EqualsAndHashCode(callSuper = true) +public class OemSettlementApprovalVO extends BaseEntity { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 审批单号 + */ + @Schema(description = "审批单号") + private String approvalNo; + + /** + * 结算总批数 + */ + @Schema(description = "结算总批数") + private Integer totalCount; + + /** + * 结算总面积(dm²) + */ + @Schema(description = "结算总面积(dm²)") + private BigDecimal totalArea; + + /** + * 结算总金额(元) + */ + @Schema(description = "结算总金额(元)") + private BigDecimal totalAmount; + + /** + * 结算说明 + */ + @Schema(description = "结算说明") + private String settlementMemo; + + /** + * 审批状态:1-待审批,2-审批中,3-审批通过,4-审批不通过 + */ + @Schema(description = "审批状态:1-待审批,2-审批中,3-审批通过,4-审批不通过") + private Integer approvalStatus; + + /** + * 审批状态名称 + */ + @Schema(description = "审批状态名称") + private String approvalStatusName; + + /** + * 提交时间 + */ + @Schema(description = "提交时间") + private Date submitTime; + + /** + * 提交日期字符串 + */ + @Schema(description = "提交日期") + private String submitDate; + + /** + * 审批时间 + */ + @Schema(description = "审批时间") + private Date approvalTime; + + /** + * 审批日期字符串 + */ + @Schema(description = "审批日期") + private String approvalDate; + + /** + * 审批人ID + */ + @Schema(description = "审批人ID") + private Long approvalUserId; + + /** + * 审批人姓名 + */ + @Schema(description = "审批人姓名") + private String approvalUserName; + + /** + * 审批意见 + */ + @Schema(description = "审批意见") + private String approvalMemo; + + /** + * 校对人1 ID + */ + @Schema(description = "校对人1 ID") + private Long proofreader1Id; + + /** + * 校对人1 姓名 + */ + @Schema(description = "校对人1 姓名") + private String proofreader1Name; + + /** + * 校对时间1 + */ + @Schema(description = "校对时间1") + private Date proofreadTime1; + + /** + * 校对时间1字符串 + */ + @Schema(description = "校对时间1") + private String proofreadTime1Str; + + /** + * 校对人2 ID + */ + @Schema(description = "校对人2 ID") + private Long proofreader2Id; + + /** + * 校对人2 姓名 + */ + @Schema(description = "校对人2 姓名") + private String proofreader2Name; + + /** + * 校对时间2 + */ + @Schema(description = "校对时间2") + private Date proofreadTime2; + + /** + * 校对时间2字符串 + */ + @Schema(description = "校对时间2") + private String proofreadTime2Str; + + private String createUserName; +} diff --git a/blade-service-api/blade-erpdata-api/src/main/java/org/springblade/erpdata/feign/IErpOemSettlementClient.java b/blade-service-api/blade-erpdata-api/src/main/java/org/springblade/erpdata/feign/IErpOemSettlementClient.java new file mode 100644 index 000000000..342c0b24a --- /dev/null +++ b/blade-service-api/blade-erpdata-api/src/main/java/org/springblade/erpdata/feign/IErpOemSettlementClient.java @@ -0,0 +1,32 @@ +package org.springblade.erpdata.feign; + +import org.springblade.common.constant.LauncherConstant; +import org.springblade.core.launch.constant.AppConstant; +import org.springblade.core.tool.api.R; +import org.springblade.erpdata.pojo.dto.OemProcessSettlementDTO; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; + +/** + * ERP外协结算 Feign接口类 + * + * @author qyl + * @since 2026-05-13 + */ +@FeignClient(value = LauncherConstant.APPLICATION_ERP_DATA_NAME, + fallback = IErpPartoplinkFirseqClientFallback.class) +public interface IErpOemSettlementClient { + + String API_PREFIX = "/feign/client/erpOemSettlement"; + String PUSH_SINGLE = API_PREFIX + "/pushSingle"; + + /** + * 推送单条外协结算数据到ERP + * + * @param dto 结算数据 + * @return 结果 + */ + @PostMapping(PUSH_SINGLE) + R pushSingleToErp(@RequestBody OemProcessSettlementDTO dto); +} diff --git a/blade-service-api/blade-erpdata-api/src/main/java/org/springblade/erpdata/pojo/dto/OemProcessSettlementDTO.java b/blade-service-api/blade-erpdata-api/src/main/java/org/springblade/erpdata/pojo/dto/OemProcessSettlementDTO.java new file mode 100644 index 000000000..8e5dbb441 --- /dev/null +++ b/blade-service-api/blade-erpdata-api/src/main/java/org/springblade/erpdata/pojo/dto/OemProcessSettlementDTO.java @@ -0,0 +1,171 @@ +package org.springblade.erpdata.pojo.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Date; + +/** + * 外协工序结算单 DTO + * + * @author qyl + * @since 2026-05-13 + */ +@Data +@Schema(description = "外协工序结算单DTO") +public class OemProcessSettlementDTO implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * ID(mes_card_no) + */ + @Schema(description = "ID") + private String id; + + /** + * 车间订单号(wo_code_run) + */ + @Schema(description = "车间订单号") + private String sono; + + /** + * 零件号(part_code) + */ + @Schema(description = "零件号") + private String prtno; + + /** + * 批次号(batch_no) + */ + @Schema(description = "批次号") + private String splcode; + + /** + * 生产标识(prod_ident) + */ + @Schema(description = "生产标识") + private String prtlotno; + + /** + * 计划部门(plan_deptcode) + */ + @Schema(description = "计划部门") + private String plndept; + + /** + * 使用部门(use_deptcode) + */ + @Schema(description = "使用部门") + private String usedept; + + /** + * 完成日期(put_store_time) + */ + @Schema(description = "完成日期") + private Date soenddat; + + /** + * 厂家代码(oc_code) + */ + @Schema(description = "厂家代码") + private String splycode; + + /** + * 厂家名称(oc_name) + */ + @Schema(description = "厂家名称") + private String splyname; + + /** + * 合格数量(inventory_qty) + */ + @Schema(description = "合格数量") + private BigDecimal sorecqty; + + /** + * 单价 + */ + @Schema(description = "单价") + private BigDecimal price; + + /** + * 单位面积(po_are) + */ + @Schema(description = "单位面积") + private BigDecimal unitarea; + + /** + * 总面积 + */ + @Schema(description = "总面积") + private BigDecimal sumarea; + + /** + * 结算金额 + */ + @Schema(description = "结算金额") + private BigDecimal clearfund; + + /** + * 工序名称(pps_name) + */ + @Schema(description = "工序名称") + private String seqdesc; + + /** + * 报价单号 + */ + @Schema(description = "报价单号") + private String priceno; + + /** + * 色标个数 + */ + @Schema(description = "色标个数") + private String sbnumber; + + /** + * 色带个数 + */ + @Schema(description = "色带个数") + private String sdnumber; + + /** + * 箭头个数 + */ + @Schema(description = "箭头个数") + private String jtnumber; + + /** + * 计量单位 + */ + @Schema(description = "计量单位") + private String prtum; + + /** + * 计划单号(4车间) + */ + @Schema(description = "计划单号") + private String planno; + + /** + * 镀种描述 + */ + @Schema(description = "镀种描述") + private String kdofplatdesc; + + /** + * 镀层厚度 + */ + @Schema(description = "镀层厚度") + private String kdofplatheight; + + /** + * 零件名称 + */ + @Schema(description = "零件名称") + private String prtdesc; +} diff --git a/blade-service/blade-desk/src/main/java/org/springblade/desk/oem/controller/OemSettlementApprovalController.java b/blade-service/blade-desk/src/main/java/org/springblade/desk/oem/controller/OemSettlementApprovalController.java new file mode 100644 index 000000000..34360bef9 --- /dev/null +++ b/blade-service/blade-desk/src/main/java/org/springblade/desk/oem/controller/OemSettlementApprovalController.java @@ -0,0 +1,81 @@ +package org.springblade.desk.oem.controller; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.Valid; +import lombok.AllArgsConstructor; +import org.springblade.core.boot.ctrl.BladeController; +import org.springblade.core.mp.support.Condition; +import org.springblade.core.mp.support.Query; +import org.springblade.core.tool.api.R; +import org.springblade.desk.oem.pojo.request.SettlementApprovalQuery; +import org.springblade.desk.oem.pojo.request.SettlementApprovalRequest; +import org.springblade.desk.oem.pojo.request.StatementQuery; +import org.springblade.desk.oem.pojo.vo.OemSettlementApprovalDetailVO; +import org.springblade.desk.oem.pojo.vo.OemSettlementApprovalVO; +import org.springblade.desk.oem.service.IOemSettlementApprovalService; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +/** + * 外协结算审批 控制器 + * + * @author qyl + * @since 2026-05-12 + */ +@RestController +@AllArgsConstructor +@RequestMapping("/oemSettlementApproval") +@Tag(name = "外协结算审批", description = "外协结算审批接口") +public class OemSettlementApprovalController extends BladeController { + + private final IOemSettlementApprovalService oemSettlementApprovalService; + + /** + * 审批列表分页查询 + */ + @GetMapping("/page") + @ApiOperationSupport(order = 1) + @Operation(summary = "审批列表", description = "分页查询外协结算审批列表") + public R> page(SettlementApprovalQuery queryEntity, Query query) { + IPage page = Condition.getPage(query); + return R.data(oemSettlementApprovalService.selectApprovalPage(page, queryEntity)); + } + + /** + * 审批详情 + */ + @GetMapping("/detail") + @ApiOperationSupport(order = 2) + @Operation(summary = "审批详情", description = "根据ID查询审批详情") + public R detail(@RequestParam Long id) { + return R.data(oemSettlementApprovalService.getApprovalDetail(id)); + } + + /** + * 审批明细列表 + */ + @GetMapping("/detailList") + @ApiOperationSupport(order = 3) + @Operation(summary = "审批明细列表", description = "查询审批明细,支持按厂家或厂家+结算大类分组") + public R> detailList(@RequestParam Long approvalId, + @RequestParam(required = false, defaultValue = "false") Boolean groupByOc) { + // groupByOc: true-按厂家,false-按厂家+结算大类(默认) + return R.data(oemSettlementApprovalService.getApprovalDetailList(approvalId, groupByOc)); + } + + /** + * 提交审批(校对/审核) + */ + @PostMapping("/submit") + @ApiOperationSupport(order = 4) + @Operation(summary = "提交审批", description = "校对员或审核员提交审批结果") + public R submit(@Valid @RequestBody SettlementApprovalRequest request) { + return oemSettlementApprovalService.submitApproval(request); + } + + +} diff --git a/blade-service/blade-desk/src/main/java/org/springblade/desk/oem/controller/OemStatementController.java b/blade-service/blade-desk/src/main/java/org/springblade/desk/oem/controller/OemStatementController.java index 80ddaa860..4785485e8 100644 --- a/blade-service/blade-desk/src/main/java/org/springblade/desk/oem/controller/OemStatementController.java +++ b/blade-service/blade-desk/src/main/java/org/springblade/desk/oem/controller/OemStatementController.java @@ -159,11 +159,10 @@ public class OemStatementController extends BladeController { /** * 外协结算无需结算 */ - @PostMapping("/noSettlement") + @GetMapping("/noSettlement") @ApiOperationSupport(order = 12) @Operation(summary = "外协结算无需结算", description = "") public R noSettlement(StatementQuery mesOemStatement, Query query) { - mesOemStatement.setRosStatusList("1"); //设置不分页 query.setCurrent(1); query.setSize(Integer.MAX_VALUE); @@ -283,5 +282,30 @@ public class OemStatementController extends BladeController { return mesOemStatementService.settlementConfirm(request); } + /** + * 发起审批 + * 将所有待审核状态的结算数据提交审批 + */ + @PostMapping("/submitApproval") + @ApiOperationSupport(order = 18) + @Operation(summary = "发起审批", description = "将所有待审核状态的结算数据提交审批,更新为审批中状态") + @ApiLog("外协结算 发起审批") + public R submitApproval( @RequestBody SettlementConfirmRequestQuery request) { + String settlementMemo = request.getSettlementMemo(); + return mesOemStatementService.submitApproval(settlementMemo); + } + + /** + * 推送ERP + * 将所有待推送状态的结算数据推送到ERP + */ + @PostMapping("/pushToErp") + @ApiOperationSupport(order = 19) + @Operation(summary = "推送ERP", description = "将所有待推送状态的结算数据推送到ERP,更新为结算完成状态") + @ApiLog("外协结算 推送ERP") + public R pushToErp() { + return mesOemStatementService.pushToErp(); + } + } diff --git a/blade-service/blade-desk/src/main/java/org/springblade/desk/oem/mapper/OemSettlementApprovalDetailMapper.java b/blade-service/blade-desk/src/main/java/org/springblade/desk/oem/mapper/OemSettlementApprovalDetailMapper.java new file mode 100644 index 000000000..a196eb8e7 --- /dev/null +++ b/blade-service/blade-desk/src/main/java/org/springblade/desk/oem/mapper/OemSettlementApprovalDetailMapper.java @@ -0,0 +1,13 @@ +package org.springblade.desk.oem.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.springblade.desk.oem.pojo.entity.OemSettlementApprovalDetailEntity; + +/** + * 外协结算审批明细表 Mapper 接口 + * + * @author qyl + * @since 2026-05-12 + */ +public interface OemSettlementApprovalDetailMapper extends BaseMapper { +} diff --git a/blade-service/blade-desk/src/main/java/org/springblade/desk/oem/mapper/OemSettlementApprovalMapper.java b/blade-service/blade-desk/src/main/java/org/springblade/desk/oem/mapper/OemSettlementApprovalMapper.java new file mode 100644 index 000000000..5736fae8c --- /dev/null +++ b/blade-service/blade-desk/src/main/java/org/springblade/desk/oem/mapper/OemSettlementApprovalMapper.java @@ -0,0 +1,28 @@ +package org.springblade.desk.oem.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import org.apache.ibatis.annotations.Param; +import org.springblade.desk.oem.pojo.entity.OemSettlementApprovalEntity; +import org.springblade.desk.oem.pojo.request.SettlementApprovalQuery; +import org.springblade.desk.oem.pojo.vo.OemSettlementApprovalVO; + +import java.util.List; + +/** + * 外协结算审批主表 Mapper 接口 + * + * @author qyl + * @since 2026-05-12 + */ +public interface OemSettlementApprovalMapper extends BaseMapper { + + /** + * 自定义分页查询 + * + * @param page 分页参数 + * @param query 查询条件 + * @return List + */ + List selectApprovalPage(IPage page, @Param("query") SettlementApprovalQuery query); +} diff --git a/blade-service/blade-desk/src/main/java/org/springblade/desk/oem/mapper/OemSettlementApprovalMapper.xml b/blade-service/blade-desk/src/main/java/org/springblade/desk/oem/mapper/OemSettlementApprovalMapper.xml new file mode 100644 index 000000000..9abf9e7be --- /dev/null +++ b/blade-service/blade-desk/src/main/java/org/springblade/desk/oem/mapper/OemSettlementApprovalMapper.xml @@ -0,0 +1,72 @@ + + + + + + + + diff --git a/blade-service/blade-desk/src/main/java/org/springblade/desk/oem/mapper/OemStatementMapper.xml b/blade-service/blade-desk/src/main/java/org/springblade/desk/oem/mapper/OemStatementMapper.xml index 431670f6c..268da6e1f 100644 --- a/blade-service/blade-desk/src/main/java/org/springblade/desk/oem/mapper/OemStatementMapper.xml +++ b/blade-service/blade-desk/src/main/java/org/springblade/desk/oem/mapper/OemStatementMapper.xml @@ -247,6 +247,12 @@ #{status} + + AND MEMO IN + + #{memo} + + AND PUT_STORE_TIME >= #{query.postPlatingStorageTimeStart} diff --git a/blade-service/blade-desk/src/main/java/org/springblade/desk/oem/service/IOemSettlementApprovalDetailService.java b/blade-service/blade-desk/src/main/java/org/springblade/desk/oem/service/IOemSettlementApprovalDetailService.java new file mode 100644 index 000000000..e47861fab --- /dev/null +++ b/blade-service/blade-desk/src/main/java/org/springblade/desk/oem/service/IOemSettlementApprovalDetailService.java @@ -0,0 +1,13 @@ +package org.springblade.desk.oem.service; + +import org.springblade.core.mp.base.BaseService; +import org.springblade.desk.oem.pojo.entity.OemSettlementApprovalDetailEntity; + +/** + * 外协结算审批明细表 服务类 + * + * @author qyl + * @since 2026-05-12 + */ +public interface IOemSettlementApprovalDetailService extends BaseService { +} diff --git a/blade-service/blade-desk/src/main/java/org/springblade/desk/oem/service/IOemSettlementApprovalService.java b/blade-service/blade-desk/src/main/java/org/springblade/desk/oem/service/IOemSettlementApprovalService.java new file mode 100644 index 000000000..df5a9d898 --- /dev/null +++ b/blade-service/blade-desk/src/main/java/org/springblade/desk/oem/service/IOemSettlementApprovalService.java @@ -0,0 +1,55 @@ +package org.springblade.desk.oem.service; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import org.springblade.core.mp.base.BaseService; +import org.springblade.core.tool.api.R; +import org.springblade.desk.oem.pojo.entity.OemSettlementApprovalEntity; +import org.springblade.desk.oem.pojo.request.SettlementApprovalQuery; +import org.springblade.desk.oem.pojo.request.SettlementApprovalRequest; +import org.springblade.desk.oem.pojo.vo.OemSettlementApprovalDetailVO; +import org.springblade.desk.oem.pojo.vo.OemSettlementApprovalVO; + +import java.util.List; + +/** + * 外协结算审批主表 服务类 + * + * @author qyl + * @since 2026-05-12 + */ +public interface IOemSettlementApprovalService extends BaseService { + + /** + * 自定义分页查询 + * + * @param page 分页参数 + * @param query 查询条件 + * @return IPage + */ + IPage selectApprovalPage(IPage page, SettlementApprovalQuery query); + + /** + * 根据ID查询审批详情 + * + * @param id 审批ID + * @return OemSettlementApprovalVO + */ + OemSettlementApprovalVO getApprovalDetail(Long id); + + /** + * 查询审批明细列表 + * + * @param approvalId 审批ID + * @param groupByOc 是否按厂家分组:true-按厂家,false-按厂家+结算大类(默认) + * @return List + */ + List getApprovalDetailList(Long approvalId, Boolean groupByOc); + + /** + * 提交审批(校对/审核) + * + * @param request 审批请求 + * @return R + */ + R submitApproval(SettlementApprovalRequest request); +} diff --git a/blade-service/blade-desk/src/main/java/org/springblade/desk/oem/service/IOemStatementService.java b/blade-service/blade-desk/src/main/java/org/springblade/desk/oem/service/IOemStatementService.java index f779f3e72..574fc310b 100644 --- a/blade-service/blade-desk/src/main/java/org/springblade/desk/oem/service/IOemStatementService.java +++ b/blade-service/blade-desk/src/main/java/org/springblade/desk/oem/service/IOemStatementService.java @@ -135,6 +135,23 @@ public interface IOemStatementService extends BaseService { */ R settlementConfirm(SettlementConfirmRequestQuery request); + /** + * 发起审批 + * 将所有待审核状态的结算数据提交审批,更新为审批中状态 + * + * @param settlementMemo 结算说明 + * @return + */ + R submitApproval(String settlementMemo); + + /** + * 推送ERP + * 将所有待推送状态的结算数据推送到ERP,更新为结算完成状态 + * + * @return + */ + R pushToErp(); + /** * 生成旧MES结算数据 * diff --git a/blade-service/blade-desk/src/main/java/org/springblade/desk/oem/service/impl/OemSettlementApprovalDetailServiceImpl.java b/blade-service/blade-desk/src/main/java/org/springblade/desk/oem/service/impl/OemSettlementApprovalDetailServiceImpl.java new file mode 100644 index 000000000..c53411b41 --- /dev/null +++ b/blade-service/blade-desk/src/main/java/org/springblade/desk/oem/service/impl/OemSettlementApprovalDetailServiceImpl.java @@ -0,0 +1,18 @@ +package org.springblade.desk.oem.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springblade.core.mp.base.BaseServiceImpl; +import org.springblade.desk.oem.mapper.OemSettlementApprovalDetailMapper; +import org.springblade.desk.oem.pojo.entity.OemSettlementApprovalDetailEntity; +import org.springblade.desk.oem.service.IOemSettlementApprovalDetailService; +import org.springframework.stereotype.Service; + +/** + * 外协结算审批明细表 服务实现类 + * + * @author qyl + * @since 2026-05-12 + */ +@Service +public class OemSettlementApprovalDetailServiceImpl extends BaseServiceImpl implements IOemSettlementApprovalDetailService { +} diff --git a/blade-service/blade-desk/src/main/java/org/springblade/desk/oem/service/impl/OemSettlementApprovalServiceImpl.java b/blade-service/blade-desk/src/main/java/org/springblade/desk/oem/service/impl/OemSettlementApprovalServiceImpl.java new file mode 100644 index 000000000..695d08f35 --- /dev/null +++ b/blade-service/blade-desk/src/main/java/org/springblade/desk/oem/service/impl/OemSettlementApprovalServiceImpl.java @@ -0,0 +1,414 @@ +package org.springblade.desk.oem.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; +import org.springblade.common.cache.CacheNames; +import org.springblade.core.mp.base.BaseServiceImpl; +import org.springblade.core.secure.utils.AuthUtil; +import org.springblade.core.tool.api.R; +import org.springblade.desk.common.feign.IMesNotifyMessageClient; +import org.springblade.desk.common.pojo.entity.MesNotifyMessageEntity; +import org.springblade.desk.oem.mapper.OemSettlementApprovalMapper; +import org.springblade.desk.oem.pojo.entity.OemSettlementApprovalDetailEntity; +import org.springblade.desk.oem.pojo.entity.OemSettlementApprovalEntity; +import org.springblade.desk.oem.pojo.entity.OemStatementEntity; +import org.springblade.desk.oem.pojo.request.SettlementApprovalQuery; +import org.springblade.desk.oem.pojo.request.SettlementApprovalRequest; +import org.springblade.desk.oem.pojo.vo.OemSettlementApprovalDetailVO; +import org.springblade.desk.oem.pojo.vo.OemSettlementApprovalVO; +import org.springblade.desk.oem.service.IOemSettlementApprovalDetailService; +import org.springblade.desk.oem.service.IOemSettlementApprovalService; +import org.springblade.desk.oem.service.IOemStatementService; +import org.springframework.beans.BeanUtils; +import org.springframework.context.annotation.Lazy; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.math.BigDecimal; +import java.util.*; +import java.util.stream.Collectors; + +/** + * 外协结算审批主表 服务实现类 + * + * @author qyl + * @since 2026-05-12 + */ +@Slf4j +@Service +public class OemSettlementApprovalServiceImpl extends BaseServiceImpl implements IOemSettlementApprovalService { + + @Resource + private IOemSettlementApprovalDetailService oemSettlementApprovalDetailService; + + @Resource + private IOemStatementService oemStatementService; + + @Resource + private IMesNotifyMessageClient mesNotifyMessageClient; + + @Override + public IPage selectApprovalPage(IPage page, SettlementApprovalQuery query) { + return page.setRecords(baseMapper.selectApprovalPage(page, query)); + } + + @Override + public OemSettlementApprovalVO getApprovalDetail(Long id) { + OemSettlementApprovalEntity entity = this.getById(id); + if (entity == null) { + return null; + } + OemSettlementApprovalVO vo = new OemSettlementApprovalVO(); + BeanUtils.copyProperties(entity, vo); + + // 设置审批状态名称 + if (entity.getApprovalStatus() != null) { + vo.setApprovalStatusName(OemSettlementApprovalEntity.ApprovalStatusEnum.getNameByCode(entity.getApprovalStatus())); + } + + return vo; + } + + @Override + public List getApprovalDetailList(Long approvalId, Boolean groupByOc) { + // 查询该审批的所有明细 + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(OemSettlementApprovalDetailEntity::getApprovalId, approvalId); + queryWrapper.eq(OemSettlementApprovalDetailEntity::getIsDeleted, 0); + List detailList = oemSettlementApprovalDetailService.list(queryWrapper); + + if (detailList == null || detailList.isEmpty()) { + return new ArrayList<>(); + } + + // 默认按厂家+结算大类分组(groupByOc=false),如果groupByOc=true则按厂家分组 + if (Boolean.TRUE.equals(groupByOc)) { + // 按厂家分组 + return groupByOc(detailList); + } else { + // 按厂家+结算大类分组(原始数据) + return convertToVOList(detailList); + } + } + + /** + * 按厂家分组合并数据 + */ + private List groupByOc(List detailList) { + // 按厂家ID分组 + Map> groupedMap = detailList.stream() + .collect(Collectors.groupingBy(OemSettlementApprovalDetailEntity::getOcId)); + + List result = new ArrayList<>(); + + for (Map.Entry> entry : groupedMap.entrySet()) { + List groupDetails = entry.getValue(); + if (groupDetails.isEmpty()) { + continue; + } + + OemSettlementApprovalDetailEntity first = groupDetails.get(0); + + // 合并统计数据 + int totalBatchCount = groupDetails.stream() + .mapToInt(d -> d.getBatchCount() != null ? d.getBatchCount() : 0) + .sum(); + + BigDecimal totalArea = groupDetails.stream() + .map(d -> d.getTotalArea() != null ? d.getTotalArea() : BigDecimal.ZERO) + .reduce(BigDecimal.ZERO, BigDecimal::add); + + BigDecimal totalAmount = groupDetails.stream() + .map(d -> d.getMonthAmount() != null ? d.getMonthAmount() : BigDecimal.ZERO) + .reduce(BigDecimal.ZERO, BigDecimal::add); + + + OemSettlementApprovalDetailVO vo = new OemSettlementApprovalDetailVO(); + vo.setOcId(first.getOcId()); + vo.setOcCode(first.getOcCode()); + vo.setOcName(first.getOcName()); + vo.setBatchCount(totalBatchCount); + vo.setTotalArea(totalArea); + vo.setMonthAmount(totalAmount); + + result.add(vo); + } + + return result; + } + + + private List convertToVOList(List detailList) { + List voList = new ArrayList<>(); + for (OemSettlementApprovalDetailEntity entity : detailList) { + OemSettlementApprovalDetailVO vo = new OemSettlementApprovalDetailVO(); + BeanUtils.copyProperties(entity, vo); + voList.add(vo); + } + return voList; + } + + @Override + @Transactional + public R submitApproval(SettlementApprovalRequest request) { + // 1. 参数校验 + if (request.getApprovalId() == null) { + throw new RuntimeException("审批ID不能为空"); + } + if (request.getApprovalType() == null || (request.getApprovalType() != 1 && request.getApprovalType() != 2)) { + throw new RuntimeException("审批类型错误,1-校对,2-审核"); + } + if (request.getApprovalResult() == null || (request.getApprovalResult() != 1 && request.getApprovalResult() != 2)) { + throw new RuntimeException("审批结果错误,1-通过,2-不通过"); + } + //if (request.getApprovalResult() == 2 && (request.getApprovalMemo() == null || request.getApprovalMemo().trim().isEmpty())) { + // throw new RuntimeException("审批不通过时,必须填写审批意见"); + //} + + // 2. 查询审批记录 + OemSettlementApprovalEntity approval = this.getById(request.getApprovalId()); + if (approval == null) { + throw new RuntimeException("审批记录不存在"); + } + + // 获取当前用户信息 + // TODO: 2026/5/14 是否校验用户角色 + Long currentUserId = AuthUtil.getUserId(); + String currentUserName = AuthUtil.getUserName(); + + // 4. 根据审批类型处理 + if (request.getApprovalType() == 1) { + // 校对流程 + return handleProofreading(approval, request, currentUserId, currentUserName); + } else { + // 审核流程 + return handleAudit(approval, request, currentUserId, currentUserName); + } + } + + /** + * 处理校对流程 + */ + private R handleProofreading(OemSettlementApprovalEntity approval, SettlementApprovalRequest request, + Long currentUserId, String currentUserName) { + Integer approvalStatus = approval.getApprovalStatus(); + + // 校验:只有【待审批】或【校对中】状态可以进行校对 + if (approvalStatus != 1 && approvalStatus != 2) { + throw new RuntimeException("当前审批状态不允许校对,当前状态:" + getApprovalStatusName(approvalStatus)); + } + + // 校验:一个校对员只可以校对一次 + if (currentUserId.equals(approval.getProofreader1Id()) || currentUserId.equals(approval.getProofreader2Id())) { + throw new RuntimeException("您已经校对过此审批,不能重复校对"); + } + + // 更新校对信息 + Date now = new Date(); + if (approval.getProofreader1Id() == null) { + // 第一次校对 + approval.setProofreader1Id(currentUserId); + approval.setProofreader1Name(currentUserName); + approval.setProofreadTime1(now); + + // 校对人1通过后更新为【校对中】 + if (request.getApprovalResult() == 1) { + approval.setApprovalStatus(OemSettlementApprovalEntity.ApprovalStatusEnum.PROOFREADING.getCode()); + } else { + // 校对不通过 + return handleApprovalReject(approval, request.getApprovalMemo()); + } + } else if (approval.getProofreader2Id() == null) { + // 第二次校对 + approval.setProofreader2Id(currentUserId); + approval.setProofreader2Name(currentUserName); + approval.setProofreadTime2(now); + + // 校对人2通过后更新为【待审核】 + if (request.getApprovalResult() == 1) { + // 5-待审核 + approval.setApprovalStatus(OemSettlementApprovalEntity.ApprovalStatusEnum.WAITING_AUDIT.getCode()); + // 送消息通知 + sendNotificationToAuditLeader(approval); + } else { + // 校对不通过 + return handleApprovalReject(approval, request.getApprovalMemo()); + } + } else { + return R.fail("已完成两次校对,无法再次校对"); + } + + // 保存审批记录 + this.updateById(approval); + + return R.success(); + } + + /** + * 处理审核流程 + */ + private R handleAudit(OemSettlementApprovalEntity approval, SettlementApprovalRequest request, + Long currentUserId, String currentUserName) { + Integer approvalStatus = approval.getApprovalStatus(); + + // 校验:只有【待审核】状态可以进行审核 + if (!Objects.equals(approvalStatus, OemSettlementApprovalEntity.ApprovalStatusEnum.WAITING_AUDIT.getCode())) { + throw new RuntimeException("当前审批状态不允许审核,当前状态:" + getApprovalStatusName(approvalStatus)); + } + + // 校验:是否已完成两次校对 + if (approval.getProofreader1Id() == null || approval.getProofreader2Id() == null) { + throw new RuntimeException("尚未完成两次校对,无法进行审核"); + } + + Date now = new Date(); + + if (request.getApprovalResult() == 1) { + // 审核通过 + approval.setApprovalStatus(3); // 3-审批通过 + approval.setApprovalUserId(currentUserId); + approval.setApprovalUserName(currentUserName); + approval.setApprovalTime(now); + approval.setApprovalMemo(request.getApprovalMemo()); + + // 更新审批记录 + this.updateById(approval); + + // 更新所有关联结算单的状态为【待推送】 + updateStatementsStatus(approval.getId(), OemStatementEntity.PENDING_PUSH_SETTLEMENT, null); + + return R.success(); + } else { + // 审核不通过 + return handleApprovalReject(approval, request.getApprovalMemo()); + } + } + + /** + * 处理审批不通过 + */ + private R handleApprovalReject(OemSettlementApprovalEntity approval, String memo) { + Date now = new Date(); + + // 更新审批状态为【不通过】 + approval.setApprovalStatus(OemSettlementApprovalEntity.ApprovalStatusEnum.REJECTED.getCode()); + approval.setApprovalTime(now); + approval.setApprovalMemo(memo); + this.updateById(approval); + + // 更新所有关联结算单的状态为【结算异常】 + updateStatementsStatus(approval.getId(), OemStatementEntity.ERR_SETTLEMENT, "MES结算审核不通过"); + + return R.success("审批已拒绝"); + } + + /** + * 更新结算单状态 + * + * @param approvalId 审批ID + * @param newStatus 新状态 + * @param abnormalReason 异常原因(可选) + */ + private void updateStatementsStatus(Long approvalId, Integer newStatus, String abnormalReason) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(OemStatementEntity::getApprovalId, approvalId); + List statements = oemStatementService.list(queryWrapper); + + if (statements == null || statements.isEmpty()) { + throw new RuntimeException("未找到审批ID=" + approvalId + "关联的结算单"); + } + + List updateList = new ArrayList<>(); + for (OemStatementEntity statement : statements) { + OemStatementEntity entity = new OemStatementEntity(); + entity.setId(statement.getId()); + entity.setRosStatus(newStatus); + if (abnormalReason != null) { + entity.setMemo(abnormalReason); + } + entity.setUpdateTime(new Date()); + entity.setApprovalTime(new Date()); + updateList.add(entity); + } + + oemStatementService.updateBatchById(updateList); + } + + /** + * 发送通知给外协结算审核领导 + */ + private void sendNotificationToAuditLeader(OemSettlementApprovalEntity approval) { + try { + Long auditLeaderRoleId = 2054852195869057026L; + String roleName = "外协结算审核领导"; + + // 构建通知消息 + String title = String.format("外协结算审批提醒 - %s", + approval.getApprovalNo()); + + String content = String.format( + "外协结算审批详情:\n" + + "- 审批单号:%s\n" + + "- 结算总批数:%d\n" + + "- 结算总面积:%.2f dm²\n" + + "- 结算总金额:%.2f 元\n" + + "- 提交时间:%s\n" + + "- 状态:已完成两次校对,等待审核", + approval.getApprovalNo(), + approval.getTotalCount() != null ? approval.getTotalCount() : 0, + approval.getTotalArea() != null ? approval.getTotalArea() : BigDecimal.ZERO, + approval.getTotalAmount() != null ? approval.getTotalAmount() : BigDecimal.ZERO, + approval.getSubmitTime() + ); + + // 创建通知消息实体 + MesNotifyMessageEntity notifyMessage = MesNotifyMessageEntity.builder() + .title(title) + .content(content) + .receiveRoleId(auditLeaderRoleId) + .receiveRoleName(roleName) + .receiveUserId(AuthUtil.getUserId()) + .build(); + // 通知失败不影响主流程 + // 调用Feign客户端保存通知消息 + R result = mesNotifyMessageClient.save(notifyMessage); + + if (result != null && result.isSuccess()) { + log.info("成功发送外协结算审批提醒,审批单号: {}, 校对人: {}", + approval.getApprovalNo(), AuthUtil.getUserName()); + } else { + log.error("发送外协结算审批提醒失败,审批单号: {}, 错误信息: {}", + approval.getApprovalNo(), result != null ? result.getMsg() : "返回结果为空"); + } + + } catch (Exception e) { + log.error("发送外协结算审批提醒时发生异常,审批单号: {}", approval.getApprovalNo(), e); + } + } + + /** + * 获取审批状态名称 + */ + private String getApprovalStatusName(Integer status) { + if (status == null) { + return "未知"; + } + switch (status) { + case 1: + return "待审批"; + case 2: + return "校对中"; + case 3: + return "审批通过"; + case 4: + return "审批不通过"; + case 5: + return "待审核"; + default: + return "未知"; + } + } +} diff --git a/blade-service/blade-desk/src/main/java/org/springblade/desk/oem/service/impl/OemStatementServiceImpl.java b/blade-service/blade-desk/src/main/java/org/springblade/desk/oem/service/impl/OemStatementServiceImpl.java index fff1e7311..f49ee929c 100644 --- a/blade-service/blade-desk/src/main/java/org/springblade/desk/oem/service/impl/OemStatementServiceImpl.java +++ b/blade-service/blade-desk/src/main/java/org/springblade/desk/oem/service/impl/OemStatementServiceImpl.java @@ -16,13 +16,14 @@ import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; import org.springblade.core.mp.base.BaseServiceImpl; import org.springblade.core.mp.support.Query; +import org.springblade.core.secure.utils.AuthUtil; import org.springblade.core.tool.api.R; import org.springblade.core.tool.utils.Func; +import org.springblade.desk.common.feign.IMesNotifyMessageClient; +import org.springblade.desk.common.pojo.entity.MesNotifyMessageEntity; import org.springblade.desk.oem.mapper.OemStatementMapper; import org.springblade.desk.oem.mapper.PlatingTypeRulesMapper; -import org.springblade.desk.oem.pojo.entity.OemStandardProcessEntity; -import org.springblade.desk.oem.pojo.entity.OemStatementEntity; -import org.springblade.desk.oem.pojo.entity.PlatingTypeRulesEntity; +import org.springblade.desk.oem.pojo.entity.*; import org.springblade.desk.oem.pojo.excel.OemStatementExcel; import org.springblade.desk.oem.pojo.request.OemSettleAccountsApproval; import org.springblade.desk.oem.pojo.request.PriceSheetQuery; @@ -30,17 +31,20 @@ import org.springblade.desk.oem.pojo.request.SettlementConfirmRequestQuery; import org.springblade.desk.oem.pojo.request.StatementQuery; import org.springblade.desk.oem.pojo.vo.PriceSheetVO; import org.springblade.desk.oem.pojo.vo.StatementVO; -import org.springblade.desk.oem.service.IOemStandardProcessService; -import org.springblade.desk.oem.service.IOemStatementService; -import org.springblade.desk.oem.service.IOemStatementTaskLogService; +import org.springblade.desk.oem.service.*; import org.springblade.desk.util.PriceMatcher; import org.springblade.erpdata.feign.IErpDataOemClient; +import org.springblade.erpdata.feign.IErpOemSettlementClient; +import org.springblade.erpdata.pojo.dto.OemProcessSettlementDTO; import org.springblade.system.feign.IDictClient; import org.springblade.system.pojo.entity.Dict; import org.springframework.beans.BeanUtils; +import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import java.math.BigDecimal; +import java.math.RoundingMode; import java.text.SimpleDateFormat; import java.time.LocalDate; import java.time.ZoneId; @@ -75,6 +79,22 @@ public class OemStatementServiceImpl extends BaseServiceImpl wrapper = Wrappers.lambdaUpdate(); -// wrapper.set(OemStatementEntity::getTotalPrice, entity.getTotalPrice()).set(OemStatementEntity::getUnitPrice, entity.getUnitPrice()).set(OemStatementEntity::getQuotation, entity.getQuotation()).set(OemStatementEntity::getApprovalStatus, entity.getApprovalStatus()).set(OemStatementEntity::getRosStatus, entity.getRosStatus()).set(OemStatementEntity::getMemo, entity.getMemo()).set(OemStatementEntity::getUpdateTime, entity.getUpdateTime()).eq(OemStatementEntity::getId, entity.getId()); + wrapper.set(OemStatementEntity::getTotalPrice, entity.getTotalPrice()) + .set(OemStatementEntity::getUnitPrice, entity.getUnitPrice()) + .set(OemStatementEntity::getQuotation, entity.getQuotation()) + .set(OemStatementEntity::getRosStatus, entity.getRosStatus()) + .set(OemStatementEntity::getMemo, entity.getMemo()) + .set(OemStatementEntity::getUpdateTime, entity.getUpdateTime()) + .eq(OemStatementEntity::getId, entity.getId()); baseMapper.update(null, wrapper); } @@ -2281,6 +2307,351 @@ public class OemStatementServiceImpl extends BaseServiceImpl queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(OemStatementEntity::getRosStatus, OemStatementEntity.AWAITING_APPROVAL_SETTLEMENT); + List statements = this.list(queryWrapper); + + if (CollectionUtils.isEmpty(statements)) { + return R.success("没有需要提交审批的待审核数据"); + } + + // 计算汇总数据 + int totalCount = statements.size(); + BigDecimal totalArea = statements.stream() + .map(s -> s.getTotalArea() != null ? s.getTotalArea() : BigDecimal.ZERO) + .reduce(BigDecimal.ZERO, BigDecimal::add); + BigDecimal totalAmount = statements.stream() + .map(s -> s.getTotalPrice() != null ? s.getTotalPrice() : BigDecimal.ZERO) + .reduce(BigDecimal.ZERO, BigDecimal::add); + + + // 审批主表记录 + OemSettlementApprovalEntity approval = new OemSettlementApprovalEntity(); + approval.setApprovalNo(generateApprovalNo()); + approval.setTotalCount(totalCount); + approval.setTotalArea(totalArea); + approval.setTotalAmount(totalAmount); + approval.setSettlementMemo(settlementMemo); // 结算说明 + approval.setApprovalStatus(OemSettlementApprovalEntity.ApprovalStatusEnum.PENDING.getCode()); // 1-待审批 + approval.setSubmitTime(new Date()); + approval.setIsDeleted(0); + + oemSettlementApprovalService.save(approval); + + // 审批明细(按厂家和标准工序代码分组) + generateApprovalDetails(approval.getId(), statements); + + // 状态为【审批中】 + List updateList = new ArrayList<>(); + for (OemStatementEntity statement : statements) { + OemStatementEntity entity = new OemStatementEntity(); + entity.setId(statement.getId()); + entity.setApprovalId(approval.getId()); + entity.setRosStatus(OemStatementEntity.PENDING_APPROVAL_SETTLEMENT); + entity.setUpdateTime(new Date()); + updateList.add(entity); + } + + if (!CollectionUtils.isEmpty(updateList)) { + this.updateBatchById(updateList); + } + + // 发送消息通知给“外协结算校对员”角色的用户 + sendNotificationToProofreaders(approval); + + return R.success(); + } + + /** + * 生成审批明细记录 + * 按厂家代码和结算大类分组统计 + */ + private void generateApprovalDetails(Long approvalId, List statements) { + // 1. 按厂家ID和结算大类ID分组 + Map> groupedMap = statements.stream() + .filter(s -> s.getOcId() != null && s.getStatementCategoryId() != null) + .collect(Collectors.groupingBy(s -> s.getOcId() + "_" + s.getStatementCategoryId())); + + if (groupedMap.isEmpty()) { + throw new RuntimeException("没有符合条件的结算单生成分组明细,缺少外协厂家或结算大类数据"); + } + + // 2. 计算每个结算大类的总面积和总金额(不按厂家汇总)用于计算 + Map categoryAreaMap = new HashMap<>(); + Map categoryAmountMap = new HashMap<>(); + + for (OemStatementEntity statement : statements) { + if (statement.getStatementCategoryId() == null) { + continue; + } + Long categoryId = statement.getStatementCategoryId(); + BigDecimal area = statement.getTotalArea() != null ? statement.getTotalArea() : BigDecimal.ZERO; + BigDecimal amount = statement.getTotalPrice() != null ? statement.getTotalPrice() : BigDecimal.ZERO; + + categoryAreaMap.merge(categoryId, area, BigDecimal::add); + categoryAmountMap.merge(categoryId, amount, BigDecimal::add); + } + + // 3. 生成分组明细 + List detailList = new ArrayList<>(); + + for (Map.Entry> entry : groupedMap.entrySet()) { + List groupStatements = entry.getValue(); + if (CollectionUtils.isEmpty(groupStatements)) { + continue; + } + + OemStatementEntity firstStatement = groupStatements.get(0); + Long categoryId = firstStatement.getStatementCategoryId(); + String categoryName = firstStatement.getStatementCategory(); + + // 计算分组的统计数据 + int batchCount = groupStatements.size(); + BigDecimal groupTotalArea = groupStatements.stream() + .map(s -> s.getTotalArea() != null ? s.getTotalArea() : BigDecimal.ZERO) + .reduce(BigDecimal.ZERO, BigDecimal::add); + BigDecimal groupTotalAmount = groupStatements.stream() + .map(s -> s.getTotalPrice() != null ? s.getTotalPrice() : BigDecimal.ZERO) + .reduce(BigDecimal.ZERO, BigDecimal::add); + + // 计算占比(按结算大类汇总,不按厂家) + BigDecimal totalAreaByCategory = categoryAreaMap.getOrDefault(categoryId, BigDecimal.ZERO); + BigDecimal totalAmountByCategory = categoryAmountMap.getOrDefault(categoryId, BigDecimal.ZERO); + + BigDecimal areaRatio = BigDecimal.ZERO; + BigDecimal amountRatio = BigDecimal.ZERO; + + if (totalAreaByCategory.compareTo(BigDecimal.ZERO) > 0) { + areaRatio = groupTotalArea.divide(totalAreaByCategory, 4, RoundingMode.HALF_UP) + .multiply(new BigDecimal("100")); + } + + if (totalAmountByCategory.compareTo(BigDecimal.ZERO) > 0) { + amountRatio = groupTotalAmount.divide(totalAmountByCategory, 4, RoundingMode.HALF_UP) + .multiply(new BigDecimal("100")); + } + + // 创建明细记录 + OemSettlementApprovalDetailEntity detail = new OemSettlementApprovalDetailEntity(); + detail.setApprovalId(approvalId); + detail.setOcId(firstStatement.getOcId()); + detail.setOcCode(firstStatement.getOcCode()); + detail.setOcName(firstStatement.getOcName()); + detail.setStandardProcessCode(firstStatement.getStandardProcessCode()); + detail.setStatementCategoryId(categoryId); + detail.setStatementCategory(categoryName); + detail.setBatchCount(batchCount); + detail.setTotalArea(groupTotalArea); + detail.setAreaMonthRatio(areaRatio); + detail.setMonthAmount(groupTotalAmount); + detail.setAmountMonthRatio(amountRatio); + detail.setIsDeleted(0); + + detailList.add(detail); + } + + // 批量保存明细 + if (!CollectionUtils.isEmpty(detailList)) { + oemSettlementApprovalDetailService.saveBatch(detailList); + } + + } + + /** + * 生成审批单号 + * 格式:WXJS + 6位年月日(yyMMdd) + 4位随机数 + * 示例:WXJS2608109321 + */ + private String generateApprovalNo() { + SimpleDateFormat sdf = new SimpleDateFormat("yyMMdd"); + String dateStr = sdf.format(new Date()); + int random = (int) (Math.random() * 9000) + 1000; + return "WXJS" + dateStr + random; + } + + /** + * 发送消息通知给外协结算校对员 + */ + private void sendNotificationToProofreaders(OemSettlementApprovalEntity approval) { + try { + Long proofreaderRoleId = 2054845722912940033L; + String roleName = "外协结算校对员"; + + // 构建通知消息 + String title = String.format("外协结算审批提醒 - %s", + approval.getApprovalNo()); + + String content = String.format( + "外协结算审批详情:\n" + + "- 审批单号:%s\n" + + "- 结算总批数:%d\n" + + "- 结算总面积:%.2f dm²\n" + + "- 结算总金额:%.2f 元\n" + + "- 提交时间:%s\n" + + "- 状态:待校对,请进行校对", + approval.getApprovalNo(), + approval.getTotalCount() != null ? approval.getTotalCount() : 0, + approval.getTotalArea() != null ? approval.getTotalArea() : BigDecimal.ZERO, + approval.getTotalAmount() != null ? approval.getTotalAmount() : BigDecimal.ZERO, + approval.getSubmitTime() + ); + + // 创建通知消息实体 + MesNotifyMessageEntity notifyMessage = MesNotifyMessageEntity.builder() + .title(title) + .content(content) + .receiveRoleId(proofreaderRoleId) + .receiveRoleName(roleName) + .receiveUserId(AuthUtil.getUserId()) + .build(); + + // 调用Feign客户端保存通知消息 + R result = mesNotifyMessageClient.save(notifyMessage); + // 通知失败不影响主流程 + if (result != null && result.isSuccess()) { + log.info("成功发送外协结算校对提醒,审批单号: {}, 提交人: {}", approval.getApprovalNo(), AuthUtil.getUserName()); + } else { + log.error("发送外协结算校对提醒失败,审批单号: {}, 错误信息: {}", approval.getApprovalNo(), result != null ? result.getMsg() : "返回结果为空"); + } + + } catch (Exception e) { + log.error("发送外协结算校对提醒时发生异常,审批单号: {}", approval.getApprovalNo(), e); + } + } + + @Override + @Transactional(rollbackFor = Exception.class) + public R pushToErp() { + // 查询所有【待推送】状态的结算数据 + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(OemStatementEntity::getRosStatus, OemStatementEntity.PENDING_PUSH_SETTLEMENT); + List statements = this.list(queryWrapper); + + if (CollectionUtils.isEmpty(statements)) { + return R.success("没有需要推送到ERP的待推送数据"); + } + + int totalCount = statements.size(); + int successCount = 0; + int failCount = 0; + List errorMessages = new ArrayList<>(); + + log.info("开始推送 {} 条外协结算数据到ERP", totalCount); + + for (OemStatementEntity statement : statements) { + try { + // 转换为DTO + OemProcessSettlementDTO dto = convertToSettlementDTO(statement); + + // 调用Feign接口推送到ERP + R result = erpOemSettlementClient.pushSingleToErp(dto); + + if (result != null && result.isSuccess()) { + // 推送成功,更新状态为【结算完成】 + OemStatementEntity updateEntity = new OemStatementEntity(); + updateEntity.setId(statement.getId()); + updateEntity.setRosStatus(OemStatementEntity.OK_SETTLEMENT); + updateEntity.setUpdateTime(new Date()); + updateEntity.setPushTime(new Date()); + this.updateById(updateEntity); + + successCount++; + log.info("推送成功,ID: {}, 车间订单号: {}", statement.getId(), statement.getWoCode()); + } else { + failCount++; + String errorMsg = String.format("ID:%s, 错误:%s", statement.getId(), + result != null ? result.getMsg() : "未知错误"); + errorMessages.add(errorMsg); + log.error("推送失败,{}", errorMsg); + } + } catch (Exception e) { + failCount++; + String errorMsg = String.format("ID:%s, 异常:%s", statement.getId(), e.getMessage()); + errorMessages.add(errorMsg); + log.error("推送异常,{}", errorMsg, e); + } + } + + // 构建返回结果 + Map resultMap = new HashMap<>(); + resultMap.put("total", totalCount); + resultMap.put("success", successCount); + resultMap.put("fail", failCount); + + if (failCount > 0) { + resultMap.put("errors", errorMessages); + return R.data(resultMap, String.format("推送完成:成功%d条,失败%d条", successCount, failCount)); + } else { + return R.data(resultMap, String.format("全部推送成功,共%d条", successCount)); + } + } + + /** + * 将结算单实体转换为推送ERP的DTO + */ + private OemProcessSettlementDTO convertToSettlementDTO(OemStatementEntity entity) { + OemProcessSettlementDTO dto = new OemProcessSettlementDTO(); + + // ID(mes_card_no)- 使用ID字段 + dto.setId(entity.getId() != null ? String.valueOf(entity.getId()) : ""); + // 车间订单号(wo_code_run) + dto.setSono(entity.getWoCode()); + // 零件号(part_code) + dto.setPrtno(entity.getPartCode()); + // 批次号(batch_no) + dto.setSplcode(entity.getBatchNo()); + // 生产标识(prod_ident) + dto.setPrtlotno(entity.getProductIdent()); + // 计划部门(plan_deptcode) + dto.setPlndept(entity.getPlanDeptcode()); + // 使用部门(use_deptcode) + dto.setUsedept(entity.getUseDeptCode()); + // 完成日期(put_store_time) + if (entity.getPutStoreTime() != null) { + dto.setSoenddat(entity.getPutStoreTime()); + } + // 厂家代码(oc_code) + dto.setSplycode(entity.getOcCode()); + // 厂家名称(oc_name) + dto.setSplyname(entity.getOcName()); + // 合格数量(inventory_qty)- 使用makeQty + dto.setSorecqty(entity.getMakeQty()); + // 单价 - 使用unitPrice + dto.setPrice(entity.getUnitPrice()); + // 单位面积(po_are)- 使用ypArea + dto.setUnitarea(entity.getYpArea()); + // 总面积 + dto.setSumarea(entity.getTotalArea()); + // 结算金额 + dto.setClearfund(entity.getTotalPrice()); + // 工序名称(pps_name)- 使用psName + dto.setSeqdesc(entity.getPsName()); + // 报价单号 + dto.setPriceno(entity.getQuotation()); + // 色标个数 + dto.setSbnumber(entity.getTsbNum() != null ? entity.getTsbNum() : "0"); + // 色带个数 + dto.setSdnumber(entity.getTsdNum() != null ? entity.getTsdNum() : "0"); + // 箭头个数 + dto.setJtnumber(entity.getTjtNum() != null ? entity.getTjtNum() : "0"); + // 计量单位 + dto.setPrtum(entity.getUnit()); + // 计划单号(4车间)- 使用ypCode + dto.setPlanno(entity.getYpCode()); + // 镀种描述 - 使用plate + dto.setKdofplatdesc(entity.getPlate()); + // 镀层厚度 + dto.setKdofplatheight(entity.getRosThickness() != null ? String.valueOf(entity.getRosThickness()) : ""); + // 零件名称 + dto.setPrtdesc(entity.getPartName()); + + return dto; + } + @Override public R generateSettlementByMjMes() { diff --git a/blade-service/blade-erpdata/src/main/java/org/springblade/erpdata/feign/ErpOemSettlementClientImpl.java b/blade-service/blade-erpdata/src/main/java/org/springblade/erpdata/feign/ErpOemSettlementClientImpl.java new file mode 100644 index 000000000..0339f5402 --- /dev/null +++ b/blade-service/blade-erpdata/src/main/java/org/springblade/erpdata/feign/ErpOemSettlementClientImpl.java @@ -0,0 +1,29 @@ +package org.springblade.erpdata.feign; + +import io.swagger.v3.oas.annotations.Hidden; +import lombok.AllArgsConstructor; +import org.springblade.core.tenant.annotation.NonDS; +import org.springblade.core.tool.api.R; +import org.springblade.erpdata.pojo.dto.OemProcessSettlementDTO; +import org.springblade.erpdata.service.IErpOemSettlementService; +import org.springframework.web.bind.annotation.RestController; + +/** + * ERP外协结算 Feign实现类 + * + * @author qyl + * @since 2026-05-13 + */ +@NonDS +@Hidden +@RestController +@AllArgsConstructor +public class ErpOemSettlementClientImpl implements IErpOemSettlementClient { + + private final IErpOemSettlementService erpOemSettlementService; + + @Override + public R pushSingleToErp(OemProcessSettlementDTO dto) { + return erpOemSettlementService.pushSingleToErp(dto); + } +} diff --git a/blade-service/blade-erpdata/src/main/java/org/springblade/erpdata/service/IErpOemSettlementService.java b/blade-service/blade-erpdata/src/main/java/org/springblade/erpdata/service/IErpOemSettlementService.java new file mode 100644 index 000000000..0c1f4ab0f --- /dev/null +++ b/blade-service/blade-erpdata/src/main/java/org/springblade/erpdata/service/IErpOemSettlementService.java @@ -0,0 +1,21 @@ +package org.springblade.erpdata.service; + +import org.springblade.core.tool.api.R; +import org.springblade.erpdata.pojo.dto.OemProcessSettlementDTO; + +/** + * ERP外协结算数据服务接口 + * + * @author qyl + * @since 2026-05-13 + */ +public interface IErpOemSettlementService { + + /** + * 推送单条外协结算数据到ERP + * + * @param dto 结算数据 + * @return 结果 + */ + R pushSingleToErp(OemProcessSettlementDTO dto); +} diff --git a/blade-service/blade-erpdata/src/main/java/org/springblade/erpdata/service/impl/ErpOemSettlementServiceImpl.java b/blade-service/blade-erpdata/src/main/java/org/springblade/erpdata/service/impl/ErpOemSettlementServiceImpl.java new file mode 100644 index 000000000..b6872b76c --- /dev/null +++ b/blade-service/blade-erpdata/src/main/java/org/springblade/erpdata/service/impl/ErpOemSettlementServiceImpl.java @@ -0,0 +1,126 @@ +package org.springblade.erpdata.service.impl; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springblade.core.tenant.annotation.NonDS; +import org.springblade.core.tool.api.R; +import org.springblade.erpdata.pojo.dto.OemProcessSettlementDTO; +import org.springblade.erpdata.service.IErpOemSettlementService; +import org.springframework.jdbc.core.SqlOutParameter; +import org.springframework.jdbc.core.SqlParameter; +import org.springframework.jdbc.core.simple.SimpleJdbcCall; +import org.springframework.stereotype.Service; + +import jakarta.annotation.Resource; +import java.sql.Types; +import java.util.HashMap; +import java.util.Map; + +/** + * ERP外协结算数据服务实现类 + * + * @author qyl + * @since 2026-05-13 + */ +@NonDS +@Slf4j +@Service +@RequiredArgsConstructor +public class ErpOemSettlementServiceImpl implements IErpOemSettlementService { + + @Resource + private final org.springframework.jdbc.core.JdbcTemplate jdbcTemplate; + + @Override + public R pushSingleToErp(OemProcessSettlementDTO dto) { + try { + log.info("开始推送外协结算数据到ERP,ID: {}, 车间订单号: {}", dto.getId(), dto.getSono()); + + // 1. 配置 SimpleJdbcCall + SimpleJdbcCall jdbcCall = new SimpleJdbcCall(jdbcTemplate) + // 指定存储过程名称 + .withProcedureName("pro_rbwxgxclesrbill") + // 【关键】关闭元数据自动获取 + .withoutProcedureColumnMetaDataAccess() + // 2. 显式声明所有参数 (顺序建议与存储过程定义一致) + .declareParameters( + // --- 输入参数 (IN) --- + new SqlParameter("v_id", Types.VARCHAR), + new SqlParameter("v_sono", Types.VARCHAR), + new SqlParameter("v_prtno", Types.VARCHAR), + new SqlParameter("v_splcode", Types.VARCHAR), + new SqlParameter("v_prtlotno", Types.VARCHAR), + new SqlParameter("v_plndept", Types.VARCHAR), + new SqlParameter("v_usedept", Types.VARCHAR), + new SqlParameter("v_soenddat", Types.DATE), + new SqlParameter("v_splycode", Types.VARCHAR), + new SqlParameter("v_splyname", Types.VARCHAR), + new SqlParameter("v_sorecqty", Types.NUMERIC), + new SqlParameter("v_price", Types.NUMERIC), + new SqlParameter("v_unitarea", Types.NUMERIC), + new SqlParameter("v_sumarea", Types.NUMERIC), + new SqlParameter("v_clearfund", Types.NUMERIC), + new SqlParameter("v_seqdesc", Types.VARCHAR), + new SqlParameter("v_priceno", Types.VARCHAR), + new SqlParameter("v_sbnumber", Types.VARCHAR), + new SqlParameter("v_sdnumber", Types.VARCHAR), + new SqlParameter("v_jtnumber", Types.VARCHAR), + new SqlParameter("v_prtum", Types.VARCHAR), + new SqlParameter("v_planno", Types.VARCHAR), + new SqlParameter("v_kdofplatdesc", Types.VARCHAR), + new SqlParameter("v_kdofplatheight", Types.VARCHAR), + new SqlParameter("v_prtdesc", Types.VARCHAR), + // --- 输出参数 (OUT) --- + new SqlOutParameter("v_excnote", Types.VARCHAR), + new SqlOutParameter("v_excflag", Types.VARCHAR) + ); + + // 3. 封装输入参数 Map + Map inParams = new HashMap<>(); + inParams.put("v_id", dto.getId()); + inParams.put("v_sono", dto.getSono()); + inParams.put("v_prtno", dto.getPrtno()); + inParams.put("v_splcode", dto.getSplcode()); + inParams.put("v_prtlotno", dto.getPrtlotno()); + inParams.put("v_plndept", dto.getPlndept()); + inParams.put("v_usedept", dto.getUsedept()); + inParams.put("v_soenddat", dto.getSoenddat()); + inParams.put("v_splycode", dto.getSplycode()); + inParams.put("v_splyname", dto.getSplyname()); + inParams.put("v_sorecqty", dto.getSorecqty()); + inParams.put("v_price", dto.getPrice()); + inParams.put("v_unitarea", dto.getUnitarea()); + inParams.put("v_sumarea", dto.getSumarea()); + inParams.put("v_clearfund", dto.getClearfund()); + inParams.put("v_seqdesc", dto.getSeqdesc()); + inParams.put("v_priceno", dto.getPriceno()); + inParams.put("v_sbnumber", dto.getSbnumber()); + inParams.put("v_sdnumber", dto.getSdnumber()); + inParams.put("v_jtnumber", dto.getJtnumber()); + inParams.put("v_prtum", dto.getPrtum()); + inParams.put("v_planno", dto.getPlanno()); + inParams.put("v_kdofplatdesc", dto.getKdofplatdesc()); + inParams.put("v_kdofplatheight", dto.getKdofplatheight()); + inParams.put("v_prtdesc", dto.getPrtdesc()); + + // 4. 执行存储过程 + Map resultMap = jdbcCall.execute(inParams); + + // 5. 获取输出参数 (安全处理:避免 null.toString() 导致空指针异常 NPE) + String excflag = (String) resultMap.get("v_excflag"); + String excnote = (String) resultMap.get("v_excnote"); + + if ("1".equals(excflag)) { + log.info("推送外协结算数据到ERP成功,ID: {}, 结果: {}", dto.getId(), excnote); + return R.success("推送成功:" + excnote); + } else { + log.error("推送外协结算数据到ERP失败,ID: {}, 错误: {}", dto.getId(), excnote); + return R.fail("推送失败:" + excnote); + } + + } catch (Exception e) { + log.error("推送外协结算数据到ERP异常,ID: {}", dto.getId(), e); + return R.fail("推送异常:" + e.getMessage()); + } + } +}