外协订单结算-待确认、结算审核、结算完成

liweidong
张乾翔 2 weeks ago
parent 9dc103d1c9
commit 66bfe969e3
  1. 98
      blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/oem/pojo/entity/OemSettlementApprovalDetailEntity.java
  2. 191
      blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/oem/pojo/entity/OemSettlementApprovalEntity.java
  3. 4
      blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/oem/pojo/entity/OemStatementEntity.java
  4. 62
      blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/oem/pojo/request/SettlementApprovalQuery.java
  5. 43
      blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/oem/pojo/request/SettlementApprovalRequest.java
  6. 2
      blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/oem/pojo/request/SettlementConfirmRequestQuery.java
  7. 100
      blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/oem/pojo/vo/OemSettlementApprovalDetailVO.java
  8. 159
      blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/oem/pojo/vo/OemSettlementApprovalVO.java
  9. 32
      blade-service-api/blade-erpdata-api/src/main/java/org/springblade/erpdata/feign/IErpOemSettlementClient.java
  10. 171
      blade-service-api/blade-erpdata-api/src/main/java/org/springblade/erpdata/pojo/dto/OemProcessSettlementDTO.java
  11. 81
      blade-service/blade-desk/src/main/java/org/springblade/desk/oem/controller/OemSettlementApprovalController.java
  12. 28
      blade-service/blade-desk/src/main/java/org/springblade/desk/oem/controller/OemStatementController.java
  13. 13
      blade-service/blade-desk/src/main/java/org/springblade/desk/oem/mapper/OemSettlementApprovalDetailMapper.java
  14. 28
      blade-service/blade-desk/src/main/java/org/springblade/desk/oem/mapper/OemSettlementApprovalMapper.java
  15. 72
      blade-service/blade-desk/src/main/java/org/springblade/desk/oem/mapper/OemSettlementApprovalMapper.xml
  16. 6
      blade-service/blade-desk/src/main/java/org/springblade/desk/oem/mapper/OemStatementMapper.xml
  17. 13
      blade-service/blade-desk/src/main/java/org/springblade/desk/oem/service/IOemSettlementApprovalDetailService.java
  18. 55
      blade-service/blade-desk/src/main/java/org/springblade/desk/oem/service/IOemSettlementApprovalService.java
  19. 17
      blade-service/blade-desk/src/main/java/org/springblade/desk/oem/service/IOemStatementService.java
  20. 18
      blade-service/blade-desk/src/main/java/org/springblade/desk/oem/service/impl/OemSettlementApprovalDetailServiceImpl.java
  21. 414
      blade-service/blade-desk/src/main/java/org/springblade/desk/oem/service/impl/OemSettlementApprovalServiceImpl.java
  22. 385
      blade-service/blade-desk/src/main/java/org/springblade/desk/oem/service/impl/OemStatementServiceImpl.java
  23. 29
      blade-service/blade-erpdata/src/main/java/org/springblade/erpdata/feign/ErpOemSettlementClientImpl.java
  24. 21
      blade-service/blade-erpdata/src/main/java/org/springblade/erpdata/service/IErpOemSettlementService.java
  25. 126
      blade-service/blade-erpdata/src/main/java/org/springblade/erpdata/service/impl/ErpOemSettlementServiceImpl.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;
}

@ -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;
}

@ -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;
}

@ -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;
}

@ -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;
}

@ -40,4 +40,6 @@ public class SettlementConfirmRequestQuery implements Serializable {
*/
@Schema(description = "异常原因(结算异常时必填),可选值:订单数据错误、无需结算")
private String errorReason;
String settlementMemo;
}

@ -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;
}

@ -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;
}

@ -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);
}

@ -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;
/**
* IDmes_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;
}

@ -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<IPage<OemSettlementApprovalVO>> page(SettlementApprovalQuery queryEntity, Query query) {
IPage<OemSettlementApprovalVO> page = Condition.getPage(query);
return R.data(oemSettlementApprovalService.selectApprovalPage(page, queryEntity));
}
/**
* 审批详情
*/
@GetMapping("/detail")
@ApiOperationSupport(order = 2)
@Operation(summary = "审批详情", description = "根据ID查询审批详情")
public R<OemSettlementApprovalVO> detail(@RequestParam Long id) {
return R.data(oemSettlementApprovalService.getApprovalDetail(id));
}
/**
* 审批明细列表
*/
@GetMapping("/detailList")
@ApiOperationSupport(order = 3)
@Operation(summary = "审批明细列表", description = "查询审批明细,支持按厂家或厂家+结算大类分组")
public R<List<OemSettlementApprovalDetailVO>> 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);
}
}

@ -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();
}
}

@ -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<OemSettlementApprovalDetailEntity> {
}

@ -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<OemSettlementApprovalEntity> {
/**
* 自定义分页查询
*
* @param page 分页参数
* @param query 查询条件
* @return List<OemSettlementApprovalVO>
*/
List<OemSettlementApprovalVO> selectApprovalPage(IPage page, @Param("query") SettlementApprovalQuery query);
}

@ -0,0 +1,72 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.springblade.desk.oem.mapper.OemSettlementApprovalMapper">
<!-- 自定义分页查询 -->
<select id="selectApprovalPage" resultType="org.springblade.desk.oem.pojo.vo.OemSettlementApprovalVO">
SELECT
a.ID,
a.TENANT_ID,
a.CREATE_USER,
a.CREATE_TIME,
a.CREATE_DEPT,
a.UPDATE_USER,
a.UPDATE_TIME,
a.STATUS,
a.IS_DELETED,
a.APPROVAL_NO,
a.TOTAL_COUNT,
a.TOTAL_AREA,
a.TOTAL_AMOUNT,
a.SETTLEMENT_MEMO,
a.APPROVAL_STATUS,
CASE a.APPROVAL_STATUS
WHEN 1 THEN '待审批'
WHEN 2 THEN '审批中'
WHEN 3 THEN '审批通过'
WHEN 4 THEN '审批不通过'
ELSE '未知'
END AS APPROVAL_STATUS_NAME,
a.SUBMIT_TIME,
to_char(a.SUBMIT_TIME, 'yyyy-MM-dd') as SUBMIT_DATE,
a.APPROVAL_TIME,
to_char(a.APPROVAL_TIME, 'yyyy-MM-dd') as APPROVAL_DATE,
a.APPROVAL_USER_ID,
a.APPROVAL_MEMO,
a.PROOFREADER1_ID,
a.PROOFREADER1_NAME,
a.PROOFREAD_TIME1,
to_char(a.PROOFREAD_TIME1, 'yyyy-MM-dd HH24:mi:ss') as PROOFREAD_TIME1_STR,
a.PROOFREADER2_ID,
a.PROOFREADER2_NAME,
a.PROOFREAD_TIME2,
to_char(a.PROOFREAD_TIME2, 'yyyy-MM-dd HH24:mi:ss') as PROOFREAD_TIME2_STR,
u.NAME AS CREATE_USER_NAME,
a.APPROVAL_USER_NAME
FROM MES_OEM_SETTLEMENT_APPROVAL a
LEFT JOIN BLADE_USER u ON a.CREATE_USER = u.ID
<where>
a.IS_DELETED = 0
<if test="query.approvalNo != null and query.approvalNo != ''">
AND a.APPROVAL_NO LIKE CONCAT('%', CONCAT(#{query.approvalNo}, '%'))
</if>
<if test="query.approvalStatus != null">
AND a.APPROVAL_STATUS = #{query.approvalStatus}
</if>
<if test="query.submitTimeStart != null">
AND a.SUBMIT_TIME &gt;= #{query.submitTimeStart}
</if>
<if test="query.submitTimeEnd != null">
AND a.SUBMIT_TIME &lt; #{query.submitTimeEnd} + 1
</if>
<if test="query.proofreader1Id != null">
AND a.PROOFREADER1_ID = #{query.proofreader1Id}
</if>
<if test="query.proofreader2Id != null">
AND a.PROOFREADER2_ID = #{query.proofreader2Id}
</if>
</where>
ORDER BY a.SUBMIT_TIME DESC
</select>
</mapper>

@ -247,6 +247,12 @@
#{status}
</foreach>
</if>
<if test="query.memo != null and query.memo != ''">
AND MEMO IN
<foreach collection="query.memo.split(';')" item="memo" open="(" separator="," close=")" index="index">
#{memo}
</foreach>
</if>
<if test="query.postPlatingStorageTimeStart != null">
AND PUT_STORE_TIME &gt;= #{query.postPlatingStorageTimeStart}
</if>

@ -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<OemSettlementApprovalDetailEntity> {
}

@ -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<OemSettlementApprovalEntity> {
/**
* 自定义分页查询
*
* @param page 分页参数
* @param query 查询条件
* @return IPage<OemSettlementApprovalVO>
*/
IPage<OemSettlementApprovalVO> selectApprovalPage(IPage<OemSettlementApprovalVO> page, SettlementApprovalQuery query);
/**
* 根据ID查询审批详情
*
* @param id 审批ID
* @return OemSettlementApprovalVO
*/
OemSettlementApprovalVO getApprovalDetail(Long id);
/**
* 查询审批明细列表
*
* @param approvalId 审批ID
* @param groupByOc 是否按厂家分组true-按厂家false-按厂家+结算大类默认
* @return List<OemSettlementApprovalDetailVO>
*/
List<OemSettlementApprovalDetailVO> getApprovalDetailList(Long approvalId, Boolean groupByOc);
/**
* 提交审批校对/审核
*
* @param request 审批请求
* @return R
*/
R submitApproval(SettlementApprovalRequest request);
}

@ -135,6 +135,23 @@ public interface IOemStatementService extends BaseService<OemStatementEntity> {
*/
R settlementConfirm(SettlementConfirmRequestQuery request);
/**
* 发起审批
* 将所有待审核状态的结算数据提交审批更新为审批中状态
*
* @param settlementMemo 结算说明
* @return
*/
R submitApproval(String settlementMemo);
/**
* 推送ERP
* 将所有待推送状态的结算数据推送到ERP更新为结算完成状态
*
* @return
*/
R pushToErp();
/**
* 生成旧MES结算数据
*

@ -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<OemSettlementApprovalDetailMapper, OemSettlementApprovalDetailEntity> implements IOemSettlementApprovalDetailService {
}

@ -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<OemSettlementApprovalMapper, OemSettlementApprovalEntity> implements IOemSettlementApprovalService {
@Resource
private IOemSettlementApprovalDetailService oemSettlementApprovalDetailService;
@Resource
private IOemStatementService oemStatementService;
@Resource
private IMesNotifyMessageClient mesNotifyMessageClient;
@Override
public IPage<OemSettlementApprovalVO> selectApprovalPage(IPage<OemSettlementApprovalVO> 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<OemSettlementApprovalDetailVO> getApprovalDetailList(Long approvalId, Boolean groupByOc) {
// 查询该审批的所有明细
LambdaQueryWrapper<OemSettlementApprovalDetailEntity> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(OemSettlementApprovalDetailEntity::getApprovalId, approvalId);
queryWrapper.eq(OemSettlementApprovalDetailEntity::getIsDeleted, 0);
List<OemSettlementApprovalDetailEntity> 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<OemSettlementApprovalDetailVO> groupByOc(List<OemSettlementApprovalDetailEntity> detailList) {
// 按厂家ID分组
Map<Long, List<OemSettlementApprovalDetailEntity>> groupedMap = detailList.stream()
.collect(Collectors.groupingBy(OemSettlementApprovalDetailEntity::getOcId));
List<OemSettlementApprovalDetailVO> result = new ArrayList<>();
for (Map.Entry<Long, List<OemSettlementApprovalDetailEntity>> entry : groupedMap.entrySet()) {
List<OemSettlementApprovalDetailEntity> 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<OemSettlementApprovalDetailVO> convertToVOList(List<OemSettlementApprovalDetailEntity> detailList) {
List<OemSettlementApprovalDetailVO> 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<OemStatementEntity> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(OemStatementEntity::getApprovalId, approvalId);
List<OemStatementEntity> statements = oemStatementService.list(queryWrapper);
if (statements == null || statements.isEmpty()) {
throw new RuntimeException("未找到审批ID=" + approvalId + "关联的结算单");
}
List<OemStatementEntity> 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 "未知";
}
}
}

@ -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<OemStatementMapper,
@Resource
private IOemStatementTaskLogService oemStatementTaskLogService;
@Lazy
@Resource
private IOemSettlementApprovalService oemSettlementApprovalService;
@Resource
private IOemSettlementApprovalDetailService oemSettlementApprovalDetailService;
@Resource
private IOemProcessService oemProcessService;
@Resource
private IMesNotifyMessageClient mesNotifyMessageClient;
@Resource
private IErpOemSettlementClient erpOemSettlementClient;
public static final String DEPT_CODE_REWORK = "3400";
public static final String MANUAL_AUTO = "0";
public static final String MANUAL_HAND = "1";
@ -609,7 +629,13 @@ public class OemStatementServiceImpl extends BaseServiceImpl<OemStatementMapper,
} else {
// 更新,使用UpdateWrapper确保null值被更新
LambdaUpdateWrapper<OemStatementEntity> 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<OemStatementMapper,
return R.success();
}
@Override
@Transactional
public R submitApproval(String settlementMemo) {
// 【待审核】数据
LambdaQueryWrapper<OemStatementEntity> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(OemStatementEntity::getRosStatus, OemStatementEntity.AWAITING_APPROVAL_SETTLEMENT);
List<OemStatementEntity> 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<OemStatementEntity> 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<OemStatementEntity> statements) {
// 1. 按厂家ID和结算大类ID分组
Map<String, List<OemStatementEntity>> 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<Long, BigDecimal> categoryAreaMap = new HashMap<>();
Map<Long, BigDecimal> 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<OemSettlementApprovalDetailEntity> detailList = new ArrayList<>();
for (Map.Entry<String, List<OemStatementEntity>> entry : groupedMap.entrySet()) {
List<OemStatementEntity> 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<OemStatementEntity> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(OemStatementEntity::getRosStatus, OemStatementEntity.PENDING_PUSH_SETTLEMENT);
List<OemStatementEntity> statements = this.list(queryWrapper);
if (CollectionUtils.isEmpty(statements)) {
return R.success("没有需要推送到ERP的待推送数据");
}
int totalCount = statements.size();
int successCount = 0;
int failCount = 0;
List<String> 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<String, Object> 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() {

@ -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);
}
}

@ -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);
}

@ -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<String, Object> 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<String, Object> 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());
}
}
}
Loading…
Cancel
Save