From fb9fca375c78c5b79acf6db990357816f86100fb Mon Sep 17 00:00:00 2001
From: shiyunteng <shiyunteng@example.com>
Date: 星期三, 13 五月 2026 15:39:31 +0800
Subject: [PATCH] feat:合同、出库、资金明细、发票

---
 platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/dto/OutBoundAddDTO.java                                     |   27 
 platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/entity/Contract.java                                        |   44 +
 platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/controller/ContractBillingController.java                   |   61 +
 platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/utils/ContractNumberGenerator.java                          |   40 +
 platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/service/ContractPaymentScheduleProcessService.java          |   13 
 platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/dto/ContractPaymentScheduleAddDTO.java                      |   20 
 platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/controller/ContractPaymentScheduleProcessController.java    |  129 ++++
 platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/service/impl/ContractPaymentScheduleProcessServiceImpl.java |  181 +++++
 platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/service/HistoryOverdueService.java                          |    4 
 platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/controller/ContractController.java                          |   43 +
 platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/controller/OutBoundController.java                          |   11 
 platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/vo/ContractPaymentScheduleVo.java                           |   47 +
 platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/dto/ContractSubjectMatterAddDTO.java                        |   30 
 platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/service/impl/ContractServiceImpl.java                       |  297 +++++++++
 platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/service/impl/PaymentConfirmServiceImpl.java                 |  138 ++++
 platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/entity/ContractPaymentScheduleProcess.java                  |   59 +
 platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/entity/ContractSubjectMatter.java                           |   49 
 platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/service/OutBoundService.java                                |    7 
 platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/dto/PaymentConfirmAddDTO.java                               |   27 
 platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/vo/ScheduleProcessVo.java                                   |   24 
 platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/service/impl/OutBoundServiceImpl.java                       |  247 +++++++
 platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/dto/ContractAddDTO.java                                     |   78 ++
 platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/entity/ContractPaymentSchedule.java                         |   41 
 platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/vo/ContractDetailVo.java                                    |   76 ++
 platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/entity/CurrentOverdue.java                                  |   11 
 platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/controller/CurrentOverdueController.java                    |    2 
 platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/entity/HistoryOverdue.java                                  |    8 
 platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/dto/ContractPaymentScheduleProcessAddDTO.java               |   22 
 platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/dto/ContractUpdateDTO.java                                  |   10 
 platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/dto/OutSubjectMatterAddDTO.java                             |   26 
 platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/service/ContractService.java                                |   13 
 platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/mapper/ContractPaymentScheduleProcessMapper.java            |   11 
 platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/entity/PaymentConfirm.java                                  |   12 
 platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/controller/HistoryOverdueController.java                    |    2 
 platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/controller/PaymentConfirmController.java                    |   10 
 platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/service/PaymentConfirmService.java                          |    7 
 platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/service/CurrentOverdueService.java                          |    4 
 platformx-business-finance-biz/src/main/resources/mapper/ContractPaymentScheduleProcessMapper.xml                                        |   22 
 38 files changed, 1,769 insertions(+), 84 deletions(-)

diff --git a/platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/dto/ContractAddDTO.java b/platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/dto/ContractAddDTO.java
new file mode 100644
index 0000000..7a1110b
--- /dev/null
+++ b/platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/dto/ContractAddDTO.java
@@ -0,0 +1,78 @@
+package com.by4cloud.platformx.business.dto;
+
+import com.by4cloud.platformx.business.entity.ContractPaymentSchedule;
+import com.by4cloud.platformx.business.entity.ContractSubjectMatter;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.persistence.Column;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+@Data
+public class ContractAddDTO {
+
+	@Schema(description = "鍚堝悓鍚嶇О")
+	private String contractName;
+
+	@Schema(description = "鐢叉柟id")
+	@JsonProperty("partyAId")
+	private Long partyAId;
+
+	@Schema(description = "鐢叉柟鍚嶇О")
+	@JsonProperty("partyA")
+	private String partyA;
+
+	@Schema(description = "涔欐柟id")
+	private Long partyBId;
+
+	@Schema(description = "涔欐柟鍚嶇О")
+	private String partyB;
+
+	@Schema(description = "鍚堝悓閲戦")
+	private BigDecimal amount;
+
+	@Schema(description = "甯佺锛圕NY/USD绛夛級")
+	private String currency;
+
+	@Schema(description = "鍚堝悓绫诲瀷锛�0-鐢熸垚寮� 1-澶囨寮忥級")
+	private Integer contractType;
+
+	@Schema(description = "渚涘簲灞炴�� 0-鎴愬搧 1-澶囦欢 2-澶т慨 3-鍏朵粬")
+	private Integer supplyAttribute;
+
+	@Schema(description = "鍚堝悓鐘舵�侊紙0-鑽夌 1-宸茬敓鏁� 2-宸茬粓姝� 3-宸茶繃鏈燂級")
+	private Integer contractStatus;
+
+	@Schema(description = "鍚堝悓鏈嶅姟灞炴�э紙0-浜у搧閿�鍞� 1-鏃犲舰鏈嶅姟锛�")
+	private Integer contractAttribute;
+
+	@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm")
+	@JsonFormat(pattern = "yyyy-MM-dd HH:mm")
+	@Schema(description = "绛剧讲鏃ユ湡")
+	private String signDate;
+
+	@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm")
+	@JsonFormat(pattern = "yyyy-MM-dd HH:mm")
+	@Schema(description = "鐢熸晥鏃ユ湡")
+	private String effectiveDate;
+
+	@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm")
+	@JsonFormat(pattern = "yyyy-MM-dd HH:mm")
+	@Schema(description = "鍒版湡鏃ユ湡")
+	private String expirationDate;
+
+	@Schema(description = "鍚堝悓闄勪欢URL")
+	private String attachmentUrl;
+
+	@Schema(description = "澶囨敞")
+	private String remark;
+
+	private List<ContractPaymentScheduleAddDTO> contractPaymentSchedule;
+
+	private List<ContractSubjectMatterAddDTO> contractSubjectMatter;
+
+}
diff --git a/platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/dto/ContractPaymentScheduleAddDTO.java b/platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/dto/ContractPaymentScheduleAddDTO.java
new file mode 100644
index 0000000..3f857bf
--- /dev/null
+++ b/platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/dto/ContractPaymentScheduleAddDTO.java
@@ -0,0 +1,20 @@
+package com.by4cloud.platformx.business.dto;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+@Data
+public class ContractPaymentScheduleAddDTO {
+
+	@Schema(description = "鏀舵闃舵鍚嶇О锛堟樉鎬ц绱狅紝濡傦細鍚堝悓绛捐棰勪粯銆佸彂璐у墠浠樻銆佽揣鍒扮鏀朵粯娆俱�佽皟璇曞畬鎴愪粯娆俱�佽川淇濋噾锛�")
+	private String stageName;
+
+	@Schema(description = "鏀舵姣斾緥锛�%锛屽30琛ㄧず30%锛夛紙鏄炬�ц绱狅級")
+	private BigDecimal paymentRatio;
+
+	@Schema(description = "绾﹀畾澶╂暟锛堝悎鍚岀璁㈠悗X澶╁唴浠樻/璐у埌鍚嶺澶╁唴浠樻绛夛級")
+	private Integer agreedDays;
+
+}
diff --git a/platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/dto/ContractPaymentScheduleProcessAddDTO.java b/platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/dto/ContractPaymentScheduleProcessAddDTO.java
new file mode 100644
index 0000000..e64d931
--- /dev/null
+++ b/platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/dto/ContractPaymentScheduleProcessAddDTO.java
@@ -0,0 +1,22 @@
+package com.by4cloud.platformx.business.dto;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.persistence.Column;
+import lombok.Data;
+
+import java.util.Date;
+
+@Data
+public class ContractPaymentScheduleProcessAddDTO {
+
+	@Schema(description = "闃舵ID")
+	@Column(columnDefinition = "bigint comment '闃舵ID'")
+	private Long scheduleId;
+
+	@Schema(description = "灞ョ害鏃堕棿")
+	@JsonFormat(pattern = "yyyy-MM-dd")
+	@Column(columnDefinition = "date comment '灞ョ害鏃堕棿'")
+	private Date processDate;
+
+}
diff --git a/platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/dto/ContractSubjectMatterAddDTO.java b/platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/dto/ContractSubjectMatterAddDTO.java
new file mode 100644
index 0000000..d5755a1
--- /dev/null
+++ b/platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/dto/ContractSubjectMatterAddDTO.java
@@ -0,0 +1,30 @@
+package com.by4cloud.platformx.business.dto;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.persistence.Column;
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+@Data
+public class ContractSubjectMatterAddDTO {
+
+	@Column(columnDefinition = "VARCHAR(200) comment '鏍囩殑鐗╁悕绉�'")
+	private String materialName;
+
+	@Schema(description = "鏍囩殑鐗╃紪鐮侊紙鍐呴儴鍞竴缂栫爜锛�")
+	private String materialCode;
+
+	@Schema(description = "鏍囩殑鐗╃紪鐮侊紙鍐呴儴鍞竴鍚嶇О锛�")
+	private String materialInternalName;
+
+	@Schema(description = "鏍囩殑鐗╄鏍�/鍨嬪彿")
+	private String specification;
+
+	@Schema(description = "鏁伴噺")
+	private BigDecimal quantity;
+
+	@Schema(description = "鍗曚环")
+	private BigDecimal unitPrice;
+
+}
diff --git a/platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/dto/ContractUpdateDTO.java b/platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/dto/ContractUpdateDTO.java
new file mode 100644
index 0000000..6645ced
--- /dev/null
+++ b/platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/dto/ContractUpdateDTO.java
@@ -0,0 +1,10 @@
+package com.by4cloud.platformx.business.dto;
+
+import lombok.Data;
+
+@Data
+public class ContractUpdateDTO extends ContractAddDTO{
+
+	private Long id;
+
+}
diff --git a/platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/dto/OutBoundAddDTO.java b/platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/dto/OutBoundAddDTO.java
new file mode 100644
index 0000000..5dd6f5d
--- /dev/null
+++ b/platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/dto/OutBoundAddDTO.java
@@ -0,0 +1,27 @@
+package com.by4cloud.platformx.business.dto;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.persistence.Column;
+import lombok.Data;
+
+import java.util.Date;
+import java.util.List;
+
+@Data
+public class OutBoundAddDTO {
+
+	@Schema(description = "瀹㈠晢鍚嶇О")
+	private String busGuestName;
+
+	@Schema(description = "瀹㈠晢ID")
+	private Long busGuestId;
+
+	@Schema(description = "鍑哄簱鏃堕棿")
+	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+	private Date outBoundTime;
+
+	@Schema(description = "鍑哄簱鏍囩殑鐗�")
+	private List<OutSubjectMatterAddDTO> subjectMatterList;
+
+}
diff --git a/platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/dto/OutSubjectMatterAddDTO.java b/platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/dto/OutSubjectMatterAddDTO.java
new file mode 100644
index 0000000..baeb967
--- /dev/null
+++ b/platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/dto/OutSubjectMatterAddDTO.java
@@ -0,0 +1,26 @@
+package com.by4cloud.platformx.business.dto;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+@Data
+public class OutSubjectMatterAddDTO {
+
+	@Schema(description = "鏍囩殑鐗╁悕绉�")
+	private String subjectMatterName;
+
+	@Schema(description = "鏍囩殑鐗╃紪鐮�")
+	private String subjectMatterCode;
+
+	@Schema(description = "鍑哄簱鏁伴噺")
+	private BigDecimal outBoundNum;
+
+	@Schema(description = "鍗曟嵁鍚嶇О")
+	private String outBoundAttNames;
+
+	@Schema(description = "鍗曟嵁璺緞")
+	private String outBoundAttPaths;
+
+}
diff --git a/platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/dto/PaymentConfirmAddDTO.java b/platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/dto/PaymentConfirmAddDTO.java
new file mode 100644
index 0000000..6589e0b
--- /dev/null
+++ b/platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/dto/PaymentConfirmAddDTO.java
@@ -0,0 +1,27 @@
+package com.by4cloud.platformx.business.dto;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+@Data
+public class PaymentConfirmAddDTO {
+
+	private String contractNo;
+
+	private String busGuestId;
+
+	private String busGuestName;
+
+	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+	private Date confirmTime;
+
+	/**
+	 * 杞叆 1 杞嚭 2
+	 */
+	private String inOrOut;
+
+	private BigDecimal transationAmount;
+}
diff --git a/platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/entity/Contract.java b/platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/entity/Contract.java
index 5647387..761d6ac 100644
--- a/platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/entity/Contract.java
+++ b/platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/entity/Contract.java
@@ -13,6 +13,8 @@
 import lombok.ToString;
 import org.springframework.format.annotation.DateTimeFormat;
 
+import java.math.BigDecimal;
+import java.util.Date;
 import java.util.List;
 
 /**
@@ -53,8 +55,8 @@
     private String partyB;
 
     @Schema(description = "鍚堝悓閲戦")
-    @Column(columnDefinition = "double comment '鍚堝悓閲戦'")
-    private Double amount;
+    @Column(columnDefinition = "decimal(10,2) comment '鍚堝悓閲戦'")
+    private BigDecimal amount;
 
     @Schema(description = "甯佺锛圕NY/USD绛夛級")
     @Column(columnDefinition = "VARCHAR(10) default 'CNY' comment '甯佺'")
@@ -79,20 +81,24 @@
     @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm")
     @JsonFormat(pattern = "yyyy-MM-dd HH:mm")
     @Schema(description = "绛剧讲鏃ユ湡")
-    @Column(columnDefinition = "VARCHAR(64) comment '绛剧讲鏃ユ湡'")
-    private String signDate;
+    @Column(columnDefinition = "date comment '绛剧讲鏃ユ湡'")
+    private Date signDate;
 
     @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm")
     @JsonFormat(pattern = "yyyy-MM-dd HH:mm")
     @Schema(description = "鐢熸晥鏃ユ湡")
-    @Column(columnDefinition = "VARCHAR(64) comment '鐢熸晥鏃ユ湡'")
-    private String effectiveDate;
+    @Column(columnDefinition = "date comment '鐢熸晥鏃ユ湡'")
+    private Date effectiveDate;
+
+	@Schema(description = "浜や粯鍛ㄦ湡")
+	@Column(columnDefinition = "int default 0 comment '浜や粯鍛ㄦ湡'")
+	private Integer deliveryCycle;
 
     @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm")
     @JsonFormat(pattern = "yyyy-MM-dd HH:mm")
     @Schema(description = "鍒版湡鏃ユ湡")
-    @Column(columnDefinition = "VARCHAR(64) comment '鍒版湡鏃ユ湡'")
-    private String expirationDate;
+    @Column(columnDefinition = "date comment '鍒版湡鏃ユ湡'")
+    private Date expirationDate;
 
     @Schema(description = "鍚堝悓闄勪欢URL")
     @Column(columnDefinition = "VARCHAR(500) comment '鍚堝悓闄勪欢URL'")
@@ -111,7 +117,27 @@
     @JsonFormat(pattern = "yyyy-MM-dd HH:mm")
     @Schema(description = "瀹℃壒鏃堕棿")
     @Column(columnDefinition = "datetime comment '瀹℃壒鏃堕棿'")
-    private String approveTime;
+    private Date approveTime;
+
+	@Schema(description = "鍒拌揣鑺傜偣ID")
+	@Column(columnDefinition = "bigint comment '鍒拌揣鑺傜偣ID'")
+	private Long arrivalScheduleId;
+
+	@Schema(description = "楠屾敹鑺傜偣ID")
+	@Column(columnDefinition = "bigint comment '楠屾敹鑺傜偣ID'")
+	private Long acceptScheduleId;
+
+	@Schema(description = "erp鎺ㄩ�佹爣璇�")
+	@Column(columnDefinition = "char comment 'erp鎺ㄩ�佹爣璇� 0 鏈帹 1 宸叉帹'")
+	private String erpPushFlag;
+
+	@Schema(description = "寮�绁ㄧ姸鎬�")
+	@Column(columnDefinition = "char comment '寮�绁ㄧ姸鎬� 0 涓嶈兘寮�绁� 1 閮ㄥ垎鍙紑 2 寰呭紑 3 宸插紑'")
+	private String billingStatus;
+
+	@Schema(description = "宸插紑绁ㄩ噾棰�")
+	@Column(columnDefinition = "decimal(10,2) comment '宸插紑绁ㄩ噾棰�'")
+	private BigDecimal billingAmout;
 
     /**
      * 涓存椂瀛楁 - 鐢ㄤ簬鎺ユ敹瀹℃壒浜哄悕绉扮瓑鍏宠仈鏌ヨ缁撴灉
diff --git a/platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/entity/ContractPaymentSchedule.java b/platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/entity/ContractPaymentSchedule.java
index 614592d..2f80b76 100644
--- a/platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/entity/ContractPaymentSchedule.java
+++ b/platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/entity/ContractPaymentSchedule.java
@@ -13,6 +13,9 @@
 import lombok.ToString;
 import org.springframework.format.annotation.DateTimeFormat;
 
+import java.math.BigDecimal;
+import java.util.Date;
+
 /**
  * 鍚堝悓鏀舵璁″垝/灞ョ害鑺傜偣瀹炰綋绫�
  * 缁熶竴绠$悊鍚堝悓鐨勬敹娆鹃樁娈点�佸饱绾﹁妭鐐广�佹敹娆炬瘮渚嬪強灞ョ害鏃堕棿鑺傜偣
@@ -70,16 +73,16 @@
     // ==================== 鏀舵姣斾緥/閲戦 ====================
 
     @Schema(description = "鏀舵姣斾緥锛�%锛屽30琛ㄧず30%锛夛紙鏄炬�ц绱狅級")
-    @Column(columnDefinition = "double comment '鏀舵姣斾緥锛�%锛�'")
-    private Double paymentRatio;
+    @Column(columnDefinition = "decimal(10,2) comment '鏀舵姣斾緥锛�%锛�'")
+    private BigDecimal paymentRatio;
 
     @Schema(description = "璁″垝鏀舵閲戦锛堟牴鎹悎鍚屾�婚噾棰�*姣斾緥鑷姩璁$畻锛�")
-    @Column(columnDefinition = "double comment '璁″垝鏀舵閲戦'")
-    private Double plannedAmount;
+    @Column(columnDefinition = "decimal(10,2) comment '璁″垝鏀舵閲戦'")
+    private BigDecimal plannedAmount;
 
     @Schema(description = "瀹為檯鏀舵閲戦")
-    @Column(columnDefinition = "double default 0.00 comment '瀹為檯鏀舵閲戦'")
-    private Double actualAmount;
+    @Column(columnDefinition = "decimal(10,2) comment '瀹為檯鏀舵閲戦'")
+    private BigDecimal actualAmount;
 
     // ==================== 鏃跺簭鎺у埗 ====================
 
@@ -87,17 +90,29 @@
     @Column(columnDefinition = "int not null comment '闃舵椤哄簭'")
     private Integer stageOrder;
 
-    @Schema(description = "璁″垝鏀舵鏃ユ湡锛堝熀浜庡悎鍚岀璁㈡棩鏈�+绾﹀畾澶╂暟璁$畻锛�")
-    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm")
-    @JsonFormat(pattern = "yyyy-MM-dd HH:mm")
-    @Column(columnDefinition = "VARCHAR(64) comment '璁″垝鏀舵鏃ユ湡'")
-    private String plannedPaymentDate;
+//    @Schema(description = "璁″垝鏀舵鏃ユ湡锛堝熀浜庡悎鍚岀璁㈡棩鏈�+绾﹀畾澶╂暟璁$畻锛�")
+//    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm")
+//    @JsonFormat(pattern = "yyyy-MM-dd HH:mm")
+//    @Column(columnDefinition = "date comment '璁″垝鏀舵鏃ユ湡'")
+//    private Date plannedPaymentDate;
+
+	@Schema(description = "鏀舵鏃ユ湡")
+	@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+	@Column(columnDefinition = "datetime comment '鏀舵鏃ユ湡'")
+	private Date paymentDate;
 
     @Schema(description = "鏀舵闃舵鐢熸晥鏃ユ湡锛堥殣鎬ц绱� - 灞ョ害鏃堕棿璧风偣锛屽嵆璇ヨ妭鐐瑰疄闄呰揪鎴愮殑鏃ユ湡锛�")
     @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm")
     @JsonFormat(pattern = "yyyy-MM-dd HH:mm")
-    @Column(columnDefinition = "VARCHAR(64) comment '鏀舵闃舵鐢熸晥鏃ユ湡锛堝饱绾﹁妭鐐瑰疄闄呰揪鎴愭棩鏈燂級'")
-    private String effectiveDate;
+    @Column(columnDefinition = "date comment '鏀舵闃舵鐢熸晥鏃ユ湡锛堝饱绾﹁妭鐐瑰疄闄呰揪鎴愭棩鏈燂級'")
+    private Date effectiveDate;
+
+	@Schema(description = "鏀舵闃舵鎴鏃ユ湡")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm")
+    @Column(columnDefinition = "date comment '鏀舵闃舵鎴鏃ユ湡'")
+    private Date effectiveEndDate;
 
     @Schema(description = "绾﹀畾澶╂暟锛堝悎鍚岀璁㈠悗X澶╁唴浠樻/璐у埌鍚嶺澶╁唴浠樻绛夛級")
     @Column(columnDefinition = "int default 0 comment '绾﹀畾澶╂暟'")
diff --git a/platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/entity/ContractPaymentScheduleProcess.java b/platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/entity/ContractPaymentScheduleProcess.java
new file mode 100644
index 0000000..e80321b
--- /dev/null
+++ b/platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/entity/ContractPaymentScheduleProcess.java
@@ -0,0 +1,59 @@
+package com.by4cloud.platformx.business.entity;
+
+import com.by4cloud.platformx.common.data.mybatis.BaseModel;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.persistence.Column;
+import jakarta.persistence.Entity;
+import jakarta.persistence.Table;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.util.Date;
+
+/**
+ * 鍚堝悓鏀舵璁″垝/灞ョ害鑺傜偣瀹炰綋绫�
+ * 缁熶竴绠$悊鍚堝悓鐨勬敹娆鹃樁娈点�佸饱绾﹁妭鐐广�佹敹娆炬瘮渚嬪強灞ョ害鏃堕棿鑺傜偣
+ *
+ * @author xfei
+ * @date 2024-01-15
+ */
+@Data
+@Entity
+@Table(name = "contract_payment_schedule_process")
+@ToString(callSuper = true)
+@EqualsAndHashCode(callSuper = true)
+public class ContractPaymentScheduleProcess extends BaseModel<ContractPaymentScheduleProcess> {
+
+    @Schema(description = "鍏宠仈鍚堝悓ID")
+    @Column(columnDefinition = "bigint not null comment '鍏宠仈鍚堝悓ID'")
+    private Long contractId;
+
+    @Schema(description = "鍚堝悓鍚嶇О")
+    @Column(columnDefinition = "VARCHAR(64) comment '鍚堝悓鍚嶇О'")
+    private String contractName;
+
+    @Schema(description = "闃舵ID")
+    @Column(columnDefinition = "bigint comment '闃舵ID'")
+    private Long scheduleId;
+
+    @Schema(description = "闃舵鍚嶇О")
+    @Column(columnDefinition = "VARCHAR(64) comment '闃舵鍚嶇О'")
+    private String scheduleName;
+
+    @Schema(description = "灞ョ害鏃堕棿")
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @Column(columnDefinition = "date comment '灞ョ害鏃堕棿'")
+    private Date processDate;
+
+	@Schema(description = "灞ョ害鍗曟嵁鍚嶇О")
+	@Column(columnDefinition="text comment '灞ョ害鍗曟嵁鍚嶇О'")
+	private String outBoundAttNames;
+
+	@Schema(description = "灞ョ害鍗曟嵁璺緞")
+	@Column(columnDefinition="text comment '灞ョ害鍗曟嵁璺緞'")
+	private String outBoundAttPaths;
+}
\ No newline at end of file
diff --git a/platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/entity/ContractSubjectMatter.java b/platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/entity/ContractSubjectMatter.java
index 314f6d9..cede782 100644
--- a/platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/entity/ContractSubjectMatter.java
+++ b/platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/entity/ContractSubjectMatter.java
@@ -13,6 +13,8 @@
 import lombok.ToString;
 import org.springframework.format.annotation.DateTimeFormat;
 
+import java.math.BigDecimal;
+
 /**
  * 鍚堝悓鏍囩殑鐗╂槑缁嗗疄浣撶被
  * @author xfei
@@ -66,32 +68,32 @@
     private Integer category;
 
     @Schema(description = "鏁伴噺")
-    @Column(columnDefinition = "double comment '鏁伴噺'")
-    private Double quantity;
+    @Column(columnDefinition = "decimal(10,2) comment '鏁伴噺'")
+    private BigDecimal quantity;
 
     @Schema(description = "璁¢噺鍗曚綅锛堜釜/鍙�/鍚�/椤�/濂楃瓑锛�")
     @Column(columnDefinition = "VARCHAR(20) comment '璁¢噺鍗曚綅'")
     private String unit;
 
     @Schema(description = "鍗曚环")
-    @Column(columnDefinition = "double comment '鍗曚环'")
-    private Double unitPrice;
+    @Column(columnDefinition = "decimal(10,2) comment '鍗曚环'")
+    private BigDecimal unitPrice;
 
     @Schema(description = "绋庣巼锛堢櫨鍒嗘瘮锛屽13琛ㄧず13%锛�")
-    @Column(columnDefinition = "double default 0.00 comment '绋庣巼'")
-    private Double taxRate;
+    @Column(columnDefinition = "decimal(10,2) comment '绋庣巼'")
+    private BigDecimal taxRate;
 
     @Schema(description = "绋庨")
-    @Column(columnDefinition = "double default 0.00 comment '绋庨'")
-    private Double taxAmount;
+    @Column(columnDefinition = "decimal(10,2) comment '绋庨'")
+    private BigDecimal taxAmount;
 
     @Schema(description = "鍚◣鎬讳环")
-    @Column(columnDefinition = "double comment '鍚◣鎬讳环'")
-    private Double totalAmount;
+    @Column(columnDefinition = "decimal(10,2) comment '鍚◣鎬讳环'")
+    private BigDecimal totalAmount;
 
     @Schema(description = "涓嶅惈绋庢�讳环")
-    @Column(columnDefinition = "double comment '涓嶅惈绋庢�讳环'")
-    private Double totalAmountExcludingTax;
+    @Column(columnDefinition = "decimal(10,2) comment '涓嶅惈绋庢�讳环'")
+    private BigDecimal totalAmountExcludingTax;
 
     @Schema(description = "浜よ揣/浜や粯鍦扮偣")
     @Column(columnDefinition = "VARCHAR(500) comment '浜よ揣/浜や粯鍦扮偣'")
@@ -109,7 +111,7 @@
     @Column(columnDefinition = "VARCHAR(64) comment '瀹為檯浜や粯鏃ユ湡'")
     private String actualDeliveryDate;
 
-    @Schema(description = "浜や粯鐘舵�侊紙0-鏈氦浠� 1-閮ㄥ垎浜や粯 2-宸蹭氦浠� 3-閫炬湡锛�")
+    @Schema(description = "浜や粯鐘舵�侊紙0-鏈氦浠� 1-閮ㄥ垎浜や粯 2-宸蹭氦浠橈級")
     @Column(columnDefinition = "tinyint(2) default 0 comment '浜や粯鐘舵��'")
     private Integer deliveryStatus;
 
@@ -139,12 +141,19 @@
     @Column(columnDefinition = "VARCHAR(64) comment '楠屾敹鏃堕棿'")
     private String acceptTime;
 
+    @Schema(description = "宸蹭氦浠樻暟閲�")
+	@Column(columnDefinition = "decimal(10,2) comment '宸蹭氦浠樻暟閲�'")
+	private BigDecimal deliveredQuantity;
 
-    /**
-     * 涓存椂瀛楁 - 宸蹭氦浠樻暟閲忥紙鐢ㄤ簬浜や粯杩涘害缁熻锛�
-     */
-    @Transient
-    @TableField(exist = false)
-    @Schema(description = "宸蹭氦浠樻暟閲忥紙涓存椂瀛楁锛�")
-    private Double deliveredQuantity;
+	@Schema(description = "鏈氦浠樻暟閲�")
+	@Column(columnDefinition = "decimal(10,2) comment '鏈氦浠樻暟閲�'")
+	private BigDecimal remainingQuantity;
+
+	@Schema(description = "鎶樻墸鐜�")
+	@Column(columnDefinition = "decimal(10,2) comment '鎶樻墸鐜�'")
+	private BigDecimal discountRate;
+
+	@Schema(description = "鏈�杩戜竴娆′氦浠樻暟閲�")
+	@Column(columnDefinition = "decimal(10,2) comment '鏈�杩戜竴娆′氦浠樻暟閲�'")
+	private BigDecimal lastDeliveredQuantity;
 }
\ No newline at end of file
diff --git a/platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/entity/CurrentOverdue.java b/platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/entity/CurrentOverdue.java
index 05237fe..90c8689 100644
--- a/platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/entity/CurrentOverdue.java
+++ b/platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/entity/CurrentOverdue.java
@@ -41,7 +41,15 @@
 	@Column(columnDefinition="decimal(10,2) comment '搴旀敹閲戦  /鍏� 涓や綅灏忔暟'")
 	private BigDecimal receivableAmount;
 
-	@Schema(description = "鍚堝悓鍒版湡鏃堕棿")
+	@Schema(description = "闃舵ID")
+	@Column(columnDefinition = "bigint comment '闃舵ID'")
+	private Long scheduleId;
+
+	@Schema(description = "闃舵鍚嶇О")
+	@Column(columnDefinition = "VARCHAR(64) comment '闃舵鍚嶇О'")
+	private String scheduleName;
+
+	@Schema(description = "閫炬湡鏃堕棿")
 	@Column(columnDefinition="datetime comment '鍚堝悓鍒版湡鏃堕棿'")
 	@JsonFormat(pattern = "yyyy-MM-dd")
 	private Date contractExpirTime;
@@ -49,5 +57,4 @@
 	@Schema(description = "閫炬湡鏃堕暱")
 	@Column(columnDefinition="decimal(10,0) comment '閫炬湡鏃堕暱  /澶�'")
 	private BigDecimal overdueDuration;
-
 }
diff --git a/platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/entity/HistoryOverdue.java b/platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/entity/HistoryOverdue.java
index 062ad24..dd2d2e6 100644
--- a/platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/entity/HistoryOverdue.java
+++ b/platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/entity/HistoryOverdue.java
@@ -55,4 +55,12 @@
 	@Column(columnDefinition="decimal(10,0) comment '閫炬湡鏃堕暱  /澶�'")
 	private BigDecimal overdueDuration;
 
+	@Schema(description = "闃舵ID")
+	@Column(columnDefinition = "bigint comment '闃舵ID'")
+	private Long scheduleId;
+
+	@Schema(description = "闃舵鍚嶇О")
+	@Column(columnDefinition = "VARCHAR(64) comment '闃舵鍚嶇О'")
+	private String scheduleName;
+
 }
diff --git a/platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/entity/PaymentConfirm.java b/platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/entity/PaymentConfirm.java
index 450c43c..c59bd42 100644
--- a/platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/entity/PaymentConfirm.java
+++ b/platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/entity/PaymentConfirm.java
@@ -36,6 +36,10 @@
 	@Column(columnDefinition="bigint comment '鍚堝悓ID'")
 	private Long contractId;
 
+	@Schema(description = "鍚堝悓缂栧彿")
+	@Column(columnDefinition = "VARCHAR(64) comment '鍚堝悓缂栧彿'")
+	private String contractNo;
+
 	@Schema(description = "鏀跺埌鎬诲叕鍙搁�氱煡鏃堕棿")
 	@Column(columnDefinition="datetime comment '鏀跺埌鎬诲叕鍙搁�氱煡鏃堕棿'")
 	private Date confirmTime;
@@ -63,4 +67,12 @@
 	@Schema(description = "鎬婚")
 	@Column(columnDefinition="decimal(10,2) comment '鎬婚  /鍏� 涓や綅灏忔暟'")
 	private BigDecimal totalAmount;
+
+	@Schema(description = "闃舵ID")
+	@Column(columnDefinition = "bigint comment '闃舵ID'")
+	private Long scheduleId;
+
+	@Schema(description = "闃舵鍚嶇О")
+	@Column(columnDefinition = "VARCHAR(64) comment '闃舵鍚嶇О'")
+	private String scheduleName;
 }
diff --git a/platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/vo/ContractDetailVo.java b/platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/vo/ContractDetailVo.java
new file mode 100644
index 0000000..42ed018
--- /dev/null
+++ b/platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/vo/ContractDetailVo.java
@@ -0,0 +1,76 @@
+package com.by4cloud.platformx.business.vo;
+
+import com.by4cloud.platformx.business.dto.ContractPaymentScheduleAddDTO;
+import com.by4cloud.platformx.business.dto.ContractSubjectMatterAddDTO;
+import com.by4cloud.platformx.business.entity.ContractPaymentSchedule;
+import com.by4cloud.platformx.business.entity.ContractSubjectMatter;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.util.List;
+
+@Data
+public class ContractDetailVo {
+
+	private Long id;
+
+	@Schema(description = "鍚堝悓鍚嶇О")
+	private String contractName;
+
+	@Schema(description = "鐢叉柟id")
+	private Long partyAId;
+
+	@Schema(description = "鐢叉柟鍚嶇О")
+	private String partyA;
+
+	@Schema(description = "涔欐柟id")
+	private Long partyBId;
+
+	@Schema(description = "涔欐柟鍚嶇О")
+	private String partyB;
+
+	@Schema(description = "鍚堝悓閲戦")
+	private Double amount;
+
+	@Schema(description = "甯佺锛圕NY/USD绛夛級")
+	private String currency;
+
+	@Schema(description = "鍚堝悓绫诲瀷锛�0-鐢熸垚寮� 1-澶囨寮忥級")
+	private Integer contractType;
+
+	@Schema(description = "渚涘簲灞炴�� 0-鎴愬搧 1-澶囦欢 2-澶т慨 3-鍏朵粬")
+	private Integer supplyAttribute;
+
+	@Schema(description = "鍚堝悓鐘舵�侊紙0-鑽夌 1-宸茬敓鏁� 2-宸茬粓姝� 3-宸茶繃鏈燂級")
+	private Integer contractStatus;
+
+	@Schema(description = "鍚堝悓鏈嶅姟灞炴�э紙0-浜у搧閿�鍞� 1-鏃犲舰鏈嶅姟锛�")
+	private Integer contractAttribute;
+
+	@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm")
+	@JsonFormat(pattern = "yyyy-MM-dd HH:mm")
+	@Schema(description = "绛剧讲鏃ユ湡")
+	private String signDate;
+
+	@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm")
+	@JsonFormat(pattern = "yyyy-MM-dd HH:mm")
+	@Schema(description = "鐢熸晥鏃ユ湡")
+	private String effectiveDate;
+
+	@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm")
+	@JsonFormat(pattern = "yyyy-MM-dd HH:mm")
+	@Schema(description = "鍒版湡鏃ユ湡")
+	private String expirationDate;
+
+	@Schema(description = "鍚堝悓闄勪欢URL")
+	private String attachmentUrl;
+
+	@Schema(description = "澶囨敞")
+	private String remark;
+
+	private List<ContractPaymentSchedule> contractPaymentSchedule;
+
+	private List<ContractSubjectMatter> contractSubjectMatter;
+}
diff --git a/platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/vo/ContractPaymentScheduleVo.java b/platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/vo/ContractPaymentScheduleVo.java
new file mode 100644
index 0000000..cb265a6
--- /dev/null
+++ b/platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/vo/ContractPaymentScheduleVo.java
@@ -0,0 +1,47 @@
+package com.by4cloud.platformx.business.vo;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.persistence.Column;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.math.BigDecimal;
+import java.util.Date;
+import java.util.List;
+
+@Data
+public class ContractPaymentScheduleVo {
+
+	private Long id;
+
+	@Schema(description = "鏀舵闃舵鍚嶇О锛堟樉鎬ц绱狅紝濡傦細鍚堝悓绛捐棰勪粯銆佸彂璐у墠浠樻銆佽揣鍒扮鏀朵粯娆俱�佽皟璇曞畬鎴愪粯娆俱�佽川淇濋噾锛�")
+	private String stageName;
+
+	@Schema(description = "璁″垝鏀舵閲戦锛堟牴鎹悎鍚屾�婚噾棰�*姣斾緥鑷姩璁$畻锛�")
+	private BigDecimal plannedAmount;
+
+	@Schema(description = "瀹為檯鏀舵閲戦")
+	private BigDecimal actualAmount;
+
+	@Schema(description = "鏀舵闃舵鐢熸晥鏃ユ湡锛堥殣鎬ц绱� - 灞ョ害鏃堕棿璧风偣锛屽嵆璇ヨ妭鐐瑰疄闄呰揪鎴愮殑鏃ユ湡锛�")
+	@DateTimeFormat(pattern = "yyyy-MM-dd")
+	@JsonFormat(pattern = "yyyy-MM-dd")
+	private Date effectiveDate;
+
+	@Schema(description = "鏀舵闃舵鎴鏃ユ湡")
+	@DateTimeFormat(pattern = "yyyy-MM-dd")
+	@JsonFormat(pattern = "yyyy-MM-dd")
+	private Date effectiveEndDate;
+
+	@Schema(description = "鏀舵鏃ユ湡")
+	@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+	private Date paymentDate;
+
+	@Schema(description = "鏀舵鐘舵�侊紙0-鏈敹娆� 1-閮ㄥ垎鏀舵 2-宸叉敹娆� 3-閫炬湡锛�")
+	private Integer paymentStatus;
+
+	private List<ScheduleProcessVo> processVoList;
+
+}
diff --git a/platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/vo/ScheduleProcessVo.java b/platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/vo/ScheduleProcessVo.java
new file mode 100644
index 0000000..1738159
--- /dev/null
+++ b/platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/vo/ScheduleProcessVo.java
@@ -0,0 +1,24 @@
+package com.by4cloud.platformx.business.vo;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.util.Date;
+
+@Data
+public class ScheduleProcessVo {
+
+	@Schema(description = "灞ョ害鏃堕棿")
+	@DateTimeFormat(pattern = "yyyy-MM-dd")
+	@JsonFormat(pattern = "yyyy-MM-dd")
+	private Date processDate;
+
+	@Schema(description = "灞ョ害鍗曟嵁鍚嶇О")
+	private String outBoundAttNames;
+
+	@Schema(description = "灞ョ害鍗曟嵁璺緞")
+	private String outBoundAttPaths;
+
+}
diff --git a/platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/controller/ContractBillingController.java b/platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/controller/ContractBillingController.java
new file mode 100644
index 0000000..54ea8d5
--- /dev/null
+++ b/platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/controller/ContractBillingController.java
@@ -0,0 +1,61 @@
+package com.by4cloud.platformx.business.controller;
+
+/**
+ * 鍚堝悓绠$悊
+ *
+ * @author syt
+ * @date 2026-04-29 16:46:26
+ */
+
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.by4cloud.platformx.business.entity.Contract;
+import com.by4cloud.platformx.business.service.ContractService;
+import com.by4cloud.platformx.common.core.util.R;
+import com.by4cloud.platformx.common.data.mybatis.BaseModel;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.security.SecurityRequirement;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import lombok.RequiredArgsConstructor;
+import org.apache.commons.lang3.StringUtils;
+import org.springdoc.core.annotations.ParameterObject;
+import org.springframework.http.HttpHeaders;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequiredArgsConstructor
+@RequestMapping("/contractBilling" )
+@Tag(description = "contractBilling" , name = "鍚堝悓寮�绁ㄧ鐞�" )
+@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)
+public class ContractBillingController {
+
+	private final ContractService contractService;
+
+	/**
+	 * 鍒嗛〉鏌ヨ
+	 * @param page 鍒嗛〉瀵硅薄
+	 * @param contract 鍚堝悓绠$悊
+	 * @return
+	 */
+	@Operation(summary = "鍒嗛〉鏌ヨ" , description = "鍒嗛〉鏌ヨ" )
+	@GetMapping("/page" )
+	public R getContractPage(@ParameterObject Page page, @ParameterObject Contract contract) {
+		LambdaQueryWrapper<Contract> wrapper = Wrappers.lambdaQuery();
+		wrapper.like(StringUtils.isNotBlank(contract.getContractName()),Contract::getContractName,contract.getContractName());
+		wrapper.like(StringUtils.isNotBlank(contract.getPartyA()),Contract::getPartyA,contract.getPartyA());
+		wrapper.eq(Contract::getBillingStatus,contract.getBillingStatus());
+		if (StrUtil.equals(contract.getBillingStatus(),"1")){
+			wrapper.orderByDesc(BaseModel::getCreateTime);
+		}else {
+			wrapper.orderByAsc(BaseModel::getCreateTime);
+		}
+
+		return R.ok(contractService.pageByScope(page, wrapper));
+	}
+
+}
diff --git a/platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/controller/ContractController.java b/platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/controller/ContractController.java
index 5910bc1..41126ca 100644
--- a/platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/controller/ContractController.java
+++ b/platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/controller/ContractController.java
@@ -5,11 +5,14 @@
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.by4cloud.platformx.business.dto.ContractAddDTO;
+import com.by4cloud.platformx.business.dto.ContractUpdateDTO;
 import com.by4cloud.platformx.business.entity.Contract;
 import com.by4cloud.platformx.common.core.util.R;
 import com.by4cloud.platformx.common.data.mybatis.BaseModel;
 import com.by4cloud.platformx.common.log.annotation.SysLog;
 import com.by4cloud.platformx.business.service.ContractService;
+import com.by4cloud.platformx.common.security.annotation.Inner;
 import com.by4cloud.platformx.common.security.util.SecurityUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.security.access.prepost.PreAuthorize;
@@ -67,36 +70,33 @@
     @GetMapping("/{id}" )
     @PreAuthorize("@pms.hasPermission('business_contract_view')" )
     public R getById(@PathVariable("id" ) Long id) {
-        return R.ok(contractService.getById(id));
+        return R.ok(contractService.detail(id));
     }
 
     /**
      * 鏂板鍚堝悓绠$悊
-     * @param contract 鍚堝悓绠$悊
+     * @param addDTO 鍚堝悓绠$悊
      * @return R
      */
     @Operation(summary = "鏂板鍚堝悓绠$悊" , description = "鏂板鍚堝悓绠$悊" )
     @SysLog("鏂板鍚堝悓绠$悊" )
     @PostMapping
     @PreAuthorize("@pms.hasPermission('business_contract_add')" )
-    public R save(@RequestBody Contract contract) {
-        Long compId = SecurityUtils.getUser().getCompId();
-        contract.setPartyBId(contract.getCompId());
-        contract.setPartyB(contract.getCompName());
-        return R.ok(contractService.save(contract));
+    public R save(@RequestBody ContractAddDTO addDTO) {
+        return contractService.add(addDTO);
     }
 
     /**
      * 淇敼鍚堝悓绠$悊
-     * @param contract 鍚堝悓绠$悊
+     * @param updateDTO 鍚堝悓绠$悊
      * @return R
      */
     @Operation(summary = "淇敼鍚堝悓绠$悊" , description = "淇敼鍚堝悓绠$悊" )
     @SysLog("淇敼鍚堝悓绠$悊" )
     @PutMapping
     @PreAuthorize("@pms.hasPermission('business_contract_edit')" )
-    public R updateById(@RequestBody Contract contract) {
-        return R.ok(contractService.updateById(contract));
+    public R updateById(@RequestBody ContractUpdateDTO updateDTO) {
+        return contractService.edit(updateDTO);
     }
 
     /**
@@ -125,4 +125,27 @@
     public List<Contract> export(Contract contract,Long[] ids) {
         return contractService.list(Wrappers.lambdaQuery(contract).in(ArrayUtil.isNotEmpty(ids), Contract::getId, ids));
     }
+
+	/**
+	 * 閫氳繃id鍚堝悓鐢熸晥
+	 * @param id id
+	 * @return R
+	 */
+	@Operation(summary = "閫氳繃id鍚堝悓鐢熸晥" , description = "閫氳繃id鍚堝悓鐢熸晥" )
+	@GetMapping("/takeEffect/{id}" )
+	@PreAuthorize("@pms.hasPermission('business_contract_effect')" )
+	public R takeEffect(@PathVariable("id" ) Long id) {
+		return R.ok(contractService.takeEffect(id));
+	}
+
+
+	/**
+	 * 瀹氭椂鐢熸垚搴旀敹娆捐处鐩�
+	 * @return R
+	 */
+	@GetMapping("/genCurrentOverdue" )
+	@Inner(value = false)
+	public R genCurrentOverdue() {
+		return contractService.genCurrentOverdue();
+	}
 }
\ No newline at end of file
diff --git a/platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/controller/ContractPaymentScheduleProcessController.java b/platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/controller/ContractPaymentScheduleProcessController.java
new file mode 100644
index 0000000..9087884
--- /dev/null
+++ b/platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/controller/ContractPaymentScheduleProcessController.java
@@ -0,0 +1,129 @@
+package com.by4cloud.platformx.business.controller;
+
+import cn.hutool.core.util.ArrayUtil;
+import cn.hutool.core.collection.CollUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.by4cloud.platformx.business.dto.ContractPaymentScheduleProcessAddDTO;
+import com.by4cloud.platformx.common.core.util.R;
+import com.by4cloud.platformx.common.log.annotation.SysLog;
+import com.by4cloud.platformx.business.entity.ContractPaymentScheduleProcess;
+import com.by4cloud.platformx.business.service.ContractPaymentScheduleProcessService;
+import org.springframework.security.access.prepost.PreAuthorize;
+import com.by4cloud.platformx.common.excel.annotation.ResponseExcel;
+import io.swagger.v3.oas.annotations.security.SecurityRequirement;
+import org.springdoc.core.annotations.ParameterObject;
+import org.springframework.http.HttpHeaders;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import io.swagger.v3.oas.annotations.Operation;
+import lombok.RequiredArgsConstructor;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * 灞ョ害鑺傜偣
+ *
+ * @author syt
+ * @date 2026-05-11 11:10:26
+ */
+@RestController
+@RequiredArgsConstructor
+@RequestMapping("/contractPaymentScheduleProcess" )
+@Tag(description = "contractPaymentScheduleProcess" , name = "灞ョ害鑺傜偣绠$悊" )
+@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)
+public class ContractPaymentScheduleProcessController {
+
+    private final  ContractPaymentScheduleProcessService contractPaymentScheduleProcessService;
+
+    /**
+     * 鍒嗛〉鏌ヨ
+     * @param page 鍒嗛〉瀵硅薄
+     * @param contractPaymentScheduleProcess 灞ョ害鑺傜偣
+     * @return
+     */
+    @Operation(summary = "鍒嗛〉鏌ヨ" , description = "鍒嗛〉鏌ヨ" )
+    @GetMapping("/page" )
+    @PreAuthorize("@pms.hasPermission('business_contractPaymentScheduleProcess_view')" )
+    public R getContractPaymentScheduleProcessPage(@ParameterObject Page page, @ParameterObject ContractPaymentScheduleProcess contractPaymentScheduleProcess) {
+        LambdaQueryWrapper<ContractPaymentScheduleProcess> wrapper = Wrappers.lambdaQuery();
+        return R.ok(contractPaymentScheduleProcessService.page(page, wrapper));
+    }
+
+
+    /**
+     * 閫氳繃id鏌ヨ灞ョ害鑺傜偣
+     * @param id id
+     * @return R
+     */
+    @Operation(summary = "閫氳繃id鏌ヨ" , description = "閫氳繃id鏌ヨ" )
+    @GetMapping("/{id}" )
+    @PreAuthorize("@pms.hasPermission('business_contractPaymentScheduleProcess_view')" )
+    public R getById(@PathVariable("id" ) Long id) {
+        return R.ok(contractPaymentScheduleProcessService.getById(id));
+    }
+
+	/**
+	 * 閫氳繃鍚堝悓id鏌ヨ灞ョ害鑺傜偣
+	 * @param id id
+	 * @return R
+	 */
+	@GetMapping("/selectScheduleProcess/{id}" )
+	public R selectScheduleProcess(@PathVariable("id" ) Long id) {
+		return contractPaymentScheduleProcessService.selectScheduleProcess(id);
+	}
+
+    /**
+     * 鏂板灞ョ害鑺傜偣
+     * @param addDTO 灞ョ害鑺傜偣
+     * @return R
+     */
+    @Operation(summary = "鏂板灞ョ害鑺傜偣" , description = "鏂板灞ョ害鑺傜偣" )
+    @SysLog("鏂板灞ョ害鑺傜偣" )
+    @PostMapping
+    public R save(@RequestBody ContractPaymentScheduleProcessAddDTO addDTO) {
+        return contractPaymentScheduleProcessService.add(addDTO);
+    }
+
+    /**
+     * 淇敼灞ョ害鑺傜偣
+     * @param contractPaymentScheduleProcess 灞ョ害鑺傜偣
+     * @return R
+     */
+    @Operation(summary = "淇敼灞ョ害鑺傜偣" , description = "淇敼灞ョ害鑺傜偣" )
+    @SysLog("淇敼灞ョ害鑺傜偣" )
+    @PutMapping
+    @PreAuthorize("@pms.hasPermission('business_contractPaymentScheduleProcess_edit')" )
+    public R updateById(@RequestBody ContractPaymentScheduleProcess contractPaymentScheduleProcess) {
+        return R.ok(contractPaymentScheduleProcessService.updateById(contractPaymentScheduleProcess));
+    }
+
+    /**
+     * 閫氳繃id鍒犻櫎灞ョ害鑺傜偣
+     * @param ids id鍒楄〃
+     * @return R
+     */
+    @Operation(summary = "閫氳繃id鍒犻櫎灞ョ害鑺傜偣" , description = "閫氳繃id鍒犻櫎灞ョ害鑺傜偣" )
+    @SysLog("閫氳繃id鍒犻櫎灞ョ害鑺傜偣" )
+    @DeleteMapping
+    @PreAuthorize("@pms.hasPermission('business_contractPaymentScheduleProcess_del')" )
+    public R removeById(@RequestBody Long[] ids) {
+        return R.ok(contractPaymentScheduleProcessService.removeBatchByIds(CollUtil.toList(ids)));
+    }
+
+
+    /**
+     * 瀵煎嚭excel 琛ㄦ牸
+     * @param contractPaymentScheduleProcess 鏌ヨ鏉′欢
+   	 * @param ids 瀵煎嚭鎸囧畾ID
+     * @return excel 鏂囦欢娴�
+     */
+    @ResponseExcel
+    @GetMapping("/export")
+    @PreAuthorize("@pms.hasPermission('business_contractPaymentScheduleProcess_export')" )
+    public List<ContractPaymentScheduleProcess> export(ContractPaymentScheduleProcess contractPaymentScheduleProcess,Long[] ids) {
+        return contractPaymentScheduleProcessService.list(Wrappers.lambdaQuery(contractPaymentScheduleProcess).in(ArrayUtil.isNotEmpty(ids), ContractPaymentScheduleProcess::getId, ids));
+    }
+}
\ No newline at end of file
diff --git a/platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/controller/CurrentOverdueController.java b/platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/controller/CurrentOverdueController.java
index 42aeb06..105d30e 100644
--- a/platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/controller/CurrentOverdueController.java
+++ b/platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/controller/CurrentOverdueController.java
@@ -54,7 +54,7 @@
 		wrapper.like(StrUtil.isNotBlank(currentOverdue.getBusGuestName()),CurrentOverdue::getBusGuestName,currentOverdue.getBusGuestName());
 		wrapper.like(StrUtil.isNotBlank(currentOverdue.getContractName()),CurrentOverdue::getContractName,currentOverdue.getContractName());
 		wrapper.orderByDesc(CurrentOverdue::getCreateTime);
-        return R.ok(currentOverdueService.page(page, wrapper));
+        return R.ok(currentOverdueService.pageByScope(page, wrapper));
     }
 
 
diff --git a/platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/controller/HistoryOverdueController.java b/platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/controller/HistoryOverdueController.java
index dd86c8d..2ec735c 100644
--- a/platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/controller/HistoryOverdueController.java
+++ b/platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/controller/HistoryOverdueController.java
@@ -52,7 +52,7 @@
 		wrapper.like(StrUtil.isNotBlank(historyOverdue.getBusGuestName()),HistoryOverdue::getBusGuestName,historyOverdue.getBusGuestName());
 		wrapper.like(StrUtil.isNotBlank(historyOverdue.getContractName()),HistoryOverdue::getContractName,historyOverdue.getContractName());
 		wrapper.orderByDesc(HistoryOverdue::getCreateTime);
-        return R.ok(historyOverdueService.page(page, wrapper));
+        return R.ok(historyOverdueService.pageByScope(page, wrapper));
     }
 
 
diff --git a/platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/controller/OutBoundController.java b/platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/controller/OutBoundController.java
index 4aef0cf..16f9a4f 100644
--- a/platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/controller/OutBoundController.java
+++ b/platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/controller/OutBoundController.java
@@ -6,6 +6,7 @@
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.by4cloud.platformx.business.dto.OutBoundAddDTO;
 import com.by4cloud.platformx.common.core.util.R;
 import com.by4cloud.platformx.common.log.annotation.SysLog;
 import com.by4cloud.platformx.business.entity.OutBound;
@@ -36,7 +37,7 @@
 @SecurityRequirement(name = HttpHeaders.AUTHORIZATION)
 public class OutBoundController {
 
-    private final  OutBoundService outBoundService;
+    private final OutBoundService outBoundService;
 
     /**
      * 鍒嗛〉鏌ヨ
@@ -52,7 +53,7 @@
 		wrapper.like(StrUtil.isNotBlank(outBound.getBusGuestName()),OutBound::getBusGuestName,outBound.getBusGuestName());
 		wrapper.like(StrUtil.isNotBlank(outBound.getSubjectMatterName()),OutBound::getSubjectMatterName,outBound.getSubjectMatterName());
 		wrapper.orderByDesc(OutBound::getCreateTime);
-        return R.ok(outBoundService.page(page, wrapper));
+        return R.ok(outBoundService.pageByScope(page, wrapper));
     }
 
 
@@ -70,15 +71,15 @@
 
     /**
      * 鏂板EPR鍑哄簱璁板綍
-     * @param outBound EPR鍑哄簱璁板綍
+     * @param addDTO EPR鍑哄簱璁板綍
      * @return R
      */
     @Operation(summary = "鏂板EPR鍑哄簱璁板綍" , description = "鏂板EPR鍑哄簱璁板綍" )
     @SysLog("鏂板EPR鍑哄簱璁板綍" )
     @PostMapping
     @PreAuthorize("@pms.hasPermission('business_outBound_add')" )
-    public R save(@RequestBody OutBound outBound) {
-        return R.ok(outBoundService.save(outBound));
+    public R save(@RequestBody OutBoundAddDTO addDTO) {
+        return outBoundService.add(addDTO);
     }
 
     /**
diff --git a/platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/controller/PaymentConfirmController.java b/platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/controller/PaymentConfirmController.java
index 7032be9..f9af450 100644
--- a/platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/controller/PaymentConfirmController.java
+++ b/platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/controller/PaymentConfirmController.java
@@ -6,6 +6,7 @@
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.by4cloud.platformx.business.dto.PaymentConfirmAddDTO;
 import com.by4cloud.platformx.common.core.util.R;
 import com.by4cloud.platformx.common.log.annotation.SysLog;
 import com.by4cloud.platformx.business.entity.PaymentConfirm;
@@ -51,8 +52,9 @@
         LambdaQueryWrapper<PaymentConfirm> wrapper = Wrappers.lambdaQuery();
 		wrapper.like(StrUtil.isNotBlank(paymentConfirm.getBusGuestName()),PaymentConfirm::getBusGuestName,paymentConfirm.getBusGuestName());
 		wrapper.like(StrUtil.isNotBlank(paymentConfirm.getContractName()),PaymentConfirm::getContractName,paymentConfirm.getContractName());
+		wrapper.like(StrUtil.isNotBlank(paymentConfirm.getBusinessType()),PaymentConfirm::getBusinessType,paymentConfirm.getBusinessType());
 		wrapper.orderByDesc(PaymentConfirm::getCreateTime);
-        return R.ok(paymentConfirmService.page(page, wrapper));
+        return R.ok(paymentConfirmService.pageByScope(page, wrapper));
     }
 
 
@@ -70,15 +72,15 @@
 
     /**
      * 鏂板鏀舵纭
-     * @param paymentConfirm 鏀舵纭
+     * @param addDTO 鏀舵纭
      * @return R
      */
     @Operation(summary = "鏂板鏀舵纭" , description = "鏂板鏀舵纭" )
     @SysLog("鏂板鏀舵纭" )
     @PostMapping
     @PreAuthorize("@pms.hasPermission('business_paymentConfirm_add')" )
-    public R save(@RequestBody PaymentConfirm paymentConfirm) {
-        return R.ok(paymentConfirmService.save(paymentConfirm));
+    public R save(@RequestBody PaymentConfirmAddDTO addDTO) {
+        return paymentConfirmService.add(addDTO);
     }
 
     /**
diff --git a/platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/mapper/ContractPaymentScheduleProcessMapper.java b/platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/mapper/ContractPaymentScheduleProcessMapper.java
new file mode 100644
index 0000000..b0c6896
--- /dev/null
+++ b/platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/mapper/ContractPaymentScheduleProcessMapper.java
@@ -0,0 +1,11 @@
+package com.by4cloud.platformx.business.mapper;
+
+import com.by4cloud.platformx.common.data.datascope.PlatformxBaseMapper;
+import com.by4cloud.platformx.business.entity.ContractPaymentScheduleProcess;
+import org.apache.ibatis.annotations.Mapper;
+
+@Mapper
+public interface ContractPaymentScheduleProcessMapper extends PlatformxBaseMapper<ContractPaymentScheduleProcess> {
+
+
+}
\ No newline at end of file
diff --git a/platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/service/ContractPaymentScheduleProcessService.java b/platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/service/ContractPaymentScheduleProcessService.java
new file mode 100644
index 0000000..f23cd26
--- /dev/null
+++ b/platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/service/ContractPaymentScheduleProcessService.java
@@ -0,0 +1,13 @@
+package com.by4cloud.platformx.business.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.by4cloud.platformx.business.dto.ContractPaymentScheduleProcessAddDTO;
+import com.by4cloud.platformx.business.entity.ContractPaymentScheduleProcess;
+import com.by4cloud.platformx.common.core.util.R;
+
+public interface ContractPaymentScheduleProcessService extends IService<ContractPaymentScheduleProcess> {
+
+	R add(ContractPaymentScheduleProcessAddDTO addDTO);
+
+	R selectScheduleProcess(Long id);
+}
\ No newline at end of file
diff --git a/platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/service/ContractService.java b/platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/service/ContractService.java
index 44dda29..d9eda69 100644
--- a/platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/service/ContractService.java
+++ b/platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/service/ContractService.java
@@ -1,7 +1,11 @@
 package com.by4cloud.platformx.business.service;
 
 
+import com.by4cloud.platformx.business.dto.ContractAddDTO;
+import com.by4cloud.platformx.business.dto.ContractUpdateDTO;
 import com.by4cloud.platformx.business.entity.Contract;
+import com.by4cloud.platformx.business.vo.ContractDetailVo;
+import com.by4cloud.platformx.common.core.util.R;
 import com.by4cloud.platformx.common.data.mybatis.IIService;
 
 /**
@@ -9,4 +13,13 @@
  */
 public interface ContractService extends IIService<Contract> {
 
+    R add(ContractAddDTO addDTO);
+
+	R edit(ContractUpdateDTO updateDTO);
+
+	ContractDetailVo detail(Long id);
+
+	Boolean takeEffect(Long id);
+
+	R genCurrentOverdue();
 }
diff --git a/platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/service/CurrentOverdueService.java b/platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/service/CurrentOverdueService.java
index 9f3b829..f50f017 100644
--- a/platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/service/CurrentOverdueService.java
+++ b/platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/service/CurrentOverdueService.java
@@ -1,8 +1,8 @@
 package com.by4cloud.platformx.business.service;
 
-import com.baomidou.mybatisplus.extension.service.IService;
 import com.by4cloud.platformx.business.entity.CurrentOverdue;
+import com.by4cloud.platformx.common.data.mybatis.IIService;
 
-public interface CurrentOverdueService extends IService<CurrentOverdue> {
+public interface CurrentOverdueService extends IIService<CurrentOverdue> {
 
 }
\ No newline at end of file
diff --git a/platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/service/HistoryOverdueService.java b/platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/service/HistoryOverdueService.java
index 31dfb50..4e576e1 100644
--- a/platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/service/HistoryOverdueService.java
+++ b/platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/service/HistoryOverdueService.java
@@ -1,8 +1,8 @@
 package com.by4cloud.platformx.business.service;
 
-import com.baomidou.mybatisplus.extension.service.IService;
 import com.by4cloud.platformx.business.entity.HistoryOverdue;
+import com.by4cloud.platformx.common.data.mybatis.IIService;
 
-public interface HistoryOverdueService extends IService<HistoryOverdue> {
+public interface HistoryOverdueService extends IIService<HistoryOverdue> {
 
 }
\ No newline at end of file
diff --git a/platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/service/OutBoundService.java b/platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/service/OutBoundService.java
index cf90c97..b1a795b 100644
--- a/platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/service/OutBoundService.java
+++ b/platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/service/OutBoundService.java
@@ -1,8 +1,11 @@
 package com.by4cloud.platformx.business.service;
 
-import com.baomidou.mybatisplus.extension.service.IService;
+import com.by4cloud.platformx.business.dto.OutBoundAddDTO;
 import com.by4cloud.platformx.business.entity.OutBound;
+import com.by4cloud.platformx.common.core.util.R;
+import com.by4cloud.platformx.common.data.mybatis.IIService;
 
-public interface OutBoundService extends IService<OutBound> {
+public interface OutBoundService extends IIService<OutBound> {
 
+	R add(OutBoundAddDTO addDTO);
 }
\ No newline at end of file
diff --git a/platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/service/PaymentConfirmService.java b/platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/service/PaymentConfirmService.java
index c501d70..0909fa5 100644
--- a/platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/service/PaymentConfirmService.java
+++ b/platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/service/PaymentConfirmService.java
@@ -1,8 +1,11 @@
 package com.by4cloud.platformx.business.service;
 
-import com.baomidou.mybatisplus.extension.service.IService;
+import com.by4cloud.platformx.business.dto.PaymentConfirmAddDTO;
 import com.by4cloud.platformx.business.entity.PaymentConfirm;
+import com.by4cloud.platformx.common.core.util.R;
+import com.by4cloud.platformx.common.data.mybatis.IIService;
 
-public interface PaymentConfirmService extends IService<PaymentConfirm> {
+public interface PaymentConfirmService extends IIService<PaymentConfirm> {
 
+	R add(PaymentConfirmAddDTO addDTO);
 }
\ No newline at end of file
diff --git a/platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/service/impl/ContractPaymentScheduleProcessServiceImpl.java b/platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/service/impl/ContractPaymentScheduleProcessServiceImpl.java
new file mode 100644
index 0000000..4e6bf29
--- /dev/null
+++ b/platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/service/impl/ContractPaymentScheduleProcessServiceImpl.java
@@ -0,0 +1,181 @@
+package com.by4cloud.platformx.business.service.impl;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.util.ArrayUtil;
+import cn.hutool.core.util.ObjUtil;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.by4cloud.platformx.business.dto.ContractPaymentScheduleProcessAddDTO;
+import com.by4cloud.platformx.business.entity.Contract;
+import com.by4cloud.platformx.business.entity.ContractPaymentSchedule;
+import com.by4cloud.platformx.business.entity.ContractPaymentScheduleProcess;
+import com.by4cloud.platformx.business.entity.PaymentConfirm;
+import com.by4cloud.platformx.business.mapper.ContractMapper;
+import com.by4cloud.platformx.business.mapper.ContractPaymentScheduleMapper;
+import com.by4cloud.platformx.business.mapper.ContractPaymentScheduleProcessMapper;
+import com.by4cloud.platformx.business.mapper.PaymentConfirmMapper;
+import com.by4cloud.platformx.business.service.ContractPaymentScheduleProcessService;
+import com.by4cloud.platformx.business.vo.ContractPaymentScheduleVo;
+import com.by4cloud.platformx.business.vo.ScheduleProcessVo;
+import com.by4cloud.platformx.common.core.util.R;
+import com.github.yulichang.wrapper.MPJLambdaWrapper;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+
+import java.math.BigDecimal;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 灞ョ害鑺傜偣
+ *
+ * @author syt
+ * @date 2026-05-11 11:10:26
+ */
+@Service
+@RequiredArgsConstructor
+public class ContractPaymentScheduleProcessServiceImpl extends ServiceImpl<ContractPaymentScheduleProcessMapper, ContractPaymentScheduleProcess> implements ContractPaymentScheduleProcessService {
+
+	private final ContractPaymentScheduleMapper contractPaymentScheduleMapper;
+	private final ContractPaymentScheduleProcessMapper processMapper;
+	private final ContractMapper contractMapper;
+	private final PaymentConfirmMapper paymentConfirmMapper;
+
+	@Override
+	public R add(ContractPaymentScheduleProcessAddDTO addDTO) {
+		ContractPaymentSchedule schedule = contractPaymentScheduleMapper.selectById(addDTO.getScheduleId());
+		if (ObjUtil.isNull(schedule)){
+			return R.failed("灞ョ害闃舵涓庡悎鍚屼笉涓�鑷达紝璇疯仈绯绘妧鏈汉鍛�");
+		}
+		//鍚堝悓
+		Contract contract = contractMapper.selectById(schedule.getContractId());
+		//鏂板褰撳墠闃舵搴旀敹
+		PaymentConfirm currentConfim = new PaymentConfirm();
+		currentConfim.setBusinessType(schedule.getStageName()+"搴旀敹");
+		currentConfim.setBusGuestId(contract.getPartyAId());
+		currentConfim.setBusGuestName(contract.getPartyA());
+		currentConfim.setContractId(contract.getId());
+		currentConfim.setContractName(contract.getContractName());
+		currentConfim.setContractNo(contract.getContractNo());
+		currentConfim.setScheduleId(schedule.getId());
+		currentConfim.setScheduleName(schedule.getStageName());
+		currentConfim.setConfirmTime(addDTO.getProcessDate());
+		currentConfim.setTransationAmount(schedule.getPlannedAmount());
+		currentConfim.setReceivableAmount(schedule.getPlannedAmount());
+		PaymentConfirm lastConfirm = paymentConfirmMapper.selectOne(Wrappers.<PaymentConfirm>lambdaQuery().eq(PaymentConfirm::getContractId,contract.getId())
+				.orderByDesc(PaymentConfirm::getCreateTime).last("limit 1"));
+		BigDecimal lastTotal = new BigDecimal("0");
+		if(ObjUtil.isNotNull(lastConfirm)){
+			lastTotal = lastConfirm.getTotalAmount();
+		}
+		currentConfim.setTotalAmount(lastTotal.subtract(currentConfim.getReceivableAmount()));
+		paymentConfirmMapper.insert(currentConfim);
+		//灞ョ害
+		ContractPaymentScheduleProcess contractPaymentScheduleProcess = BeanUtil.copyProperties(addDTO,ContractPaymentScheduleProcess.class);
+		contractPaymentScheduleProcess.setContractId(schedule.getContractId());
+		contractPaymentScheduleProcess.setContractName(schedule.getContractName());
+		contractPaymentScheduleProcess.setScheduleId(schedule.getId());
+		contractPaymentScheduleProcess.setScheduleName(schedule.getStageName());
+		baseMapper.insert(contractPaymentScheduleProcess);
+		//鏇存柊褰撳墠闃舵
+		if (ObjUtil.isNull(schedule.getEffectiveDate())) {
+			schedule.setEffectiveDate(DateUtil.offsetDay(addDTO.getProcessDate(),schedule.getAgreedDays()));
+			contractPaymentScheduleMapper.updateById(schedule);
+		}
+		//鏌ヨ鏄惁鏈変箣鍓嶉樁娈�
+		ContractPaymentSchedule beforeSchedule = contractPaymentScheduleMapper.selectOne(Wrappers.<ContractPaymentSchedule>lambdaQuery().eq(ContractPaymentSchedule::getContractId, schedule.getContractId())
+				.lt(ContractPaymentSchedule::getStageOrder, schedule.getStageOrder()).orderByDesc(ContractPaymentSchedule::getCreateTime).last("limit 1"));
+		if (ObjUtil.isNotNull(beforeSchedule)){
+			beforeSchedule.setEffectiveEndDate(DateUtil.offsetDay(addDTO.getProcessDate(),beforeSchedule.getAgreedDays()));
+			contractPaymentScheduleMapper.updateById(beforeSchedule);
+			//涔嬪墠闃舵鏄惁鏀舵瀹屾垚
+//			if (beforeSchedule.getPaymentStatus()!=2){
+//				//鏂板涔嬪墠闃舵瓒呮湡
+//				PaymentConfirm beforeConfim = new PaymentConfirm();
+//				beforeConfim.setBusinessType("搴旀敹瓒呮湡");
+//				beforeConfim.setBusGuestId(contract.getPartyAId());
+//				beforeConfim.setBusGuestName(contract.getPartyA());
+//				beforeConfim.setContractId(contract.getId());
+//				beforeConfim.setContractName(contract.getContractName());
+//				beforeConfim.setContractNo(contract.getContractNo());
+//				beforeConfim.setScheduleId(schedule.getId());
+//				beforeConfim.setScheduleName(schedule.getStageName());
+//				beforeConfim.setConfirmTime(addDTO.getProcessDate());
+//				beforeConfim.setTransationAmount(schedule.getPlannedAmount());
+//				PaymentConfirm newLastConfirm = paymentConfirmMapper.selectOne(Wrappers.<PaymentConfirm>lambdaQuery().eq(PaymentConfirm::getContractId,contract.getId())
+//						.orderByDesc(PaymentConfirm::getCreateTime).last("limit 1"));
+//				beforeConfim.setOverdueAmount(StrUtil.equals(schedule.getPaymentStatus()+"","0")?
+//						schedule.getPlannedAmount():
+//						schedule.getPlannedAmount().subtract(schedule.getActualAmount()));
+//				beforeConfim.setTotalAmount(newLastConfirm.getTotalAmount());
+//				paymentConfirmMapper.insert(beforeConfim);
+//			}
+
+		}
+		//鏌ヨ鏄惁鏈夊悗缁樁娈�
+		List<ContractPaymentSchedule> afterSchedule = contractPaymentScheduleMapper.selectList(Wrappers.<ContractPaymentSchedule>lambdaQuery()
+				.eq(ContractPaymentSchedule::getContractId, schedule.getContractId())
+				.gt(ContractPaymentSchedule::getStageOrder, schedule.getStageOrder()));
+		if (ArrayUtil.isNotEmpty(afterSchedule.toArray())&&afterSchedule.size()==1){
+			//鏈�鍚庨樁娈电敓鏁堟椂闂�
+			ContractPaymentSchedule endSchedule = afterSchedule.get(0);
+			endSchedule.setEffectiveDate(DateUtil.offsetDay(addDTO.getProcessDate(),endSchedule.getAgreedDays()));
+			endSchedule.setEffectiveEndDate(contract.getExpirationDate());
+			contractPaymentScheduleMapper.updateById(endSchedule);
+			//褰撳墠闃舵鐢熸晥鏃堕棿
+			schedule.setEffectiveDate(DateUtil.offsetDay(addDTO.getProcessDate(),schedule.getAgreedDays()));
+			schedule.setEffectiveEndDate(endSchedule.getEffectiveDate());
+			contractPaymentScheduleMapper.updateById(schedule);
+			//鏈�鍚庨樁娈靛簲鏀�
+			PaymentConfirm newConfim = new PaymentConfirm();
+			newConfim.setBusinessType(endSchedule.getStageName()+"搴旀敹");
+			newConfim.setBusGuestId(contract.getPartyAId());
+			newConfim.setBusGuestName(contract.getPartyA());
+			newConfim.setContractId(contract.getId());
+			newConfim.setContractName(contract.getContractName());
+			newConfim.setContractNo(contract.getContractNo());
+			newConfim.setScheduleId(endSchedule.getId());
+			newConfim.setScheduleName(schedule.getStageName());
+			newConfim.setConfirmTime(addDTO.getProcessDate());
+			newConfim.setTransationAmount(endSchedule.getPlannedAmount());
+			newConfim.setReceivableAmount(endSchedule.getPlannedAmount());
+			PaymentConfirm lastNewConfirm = paymentConfirmMapper.selectOne(Wrappers.<PaymentConfirm>lambdaQuery().eq(PaymentConfirm::getContractId,contract.getId())
+					.orderByDesc(PaymentConfirm::getCreateTime).last("limit 1"));
+			BigDecimal lastNewTotal = new BigDecimal("0");
+			if(ObjUtil.isNotNull(lastNewConfirm)){
+				lastNewTotal = lastNewConfirm.getTotalAmount();
+			}
+			newConfim.setTotalAmount(lastNewTotal.subtract(newConfim.getReceivableAmount()));
+			paymentConfirmMapper.insert(newConfim);
+		}else {
+			schedule.setEffectiveEndDate(contract.getExpirationDate());
+			contractPaymentScheduleMapper.updateById(schedule);
+		}
+		return R.ok();
+	}
+
+	@Override
+	public R selectScheduleProcess(Long id) {
+		MPJLambdaWrapper<ContractPaymentSchedule> wrapper = new MPJLambdaWrapper<ContractPaymentSchedule>()
+				.select(ContractPaymentSchedule::getId,ContractPaymentSchedule::getStageName,ContractPaymentSchedule::getEffectiveDate,
+						ContractPaymentSchedule::getPlannedAmount,ContractPaymentSchedule::getPlannedAmount,
+						ContractPaymentSchedule::getEffectiveEndDate,ContractPaymentSchedule::getPaymentDate,
+						ContractPaymentSchedule::getPaymentStatus,ContractPaymentSchedule::getActualAmount)
+				.eq(ContractPaymentSchedule::getContractId,id)
+				.orderByAsc(ContractPaymentSchedule::getCreateTime);
+		List<ContractPaymentScheduleVo> scheduleVoList = contractPaymentScheduleMapper.selectJoinList(ContractPaymentScheduleVo.class,wrapper);
+		if (ArrayUtil.isEmpty(scheduleVoList.toArray())){
+			scheduleVoList.stream().forEach(contractPaymentScheduleVo -> {
+				List<ContractPaymentScheduleProcess> paymentScheduleProcessList = processMapper.selectList(Wrappers.<ContractPaymentScheduleProcess>lambdaQuery()
+						.eq(ContractPaymentScheduleProcess::getContractId,contractPaymentScheduleVo.getId())
+						.orderByAsc(ContractPaymentScheduleProcess::getCreateTime));
+				if (ArrayUtil.isNotEmpty(paymentScheduleProcessList.toArray())){
+					contractPaymentScheduleVo.setProcessVoList(BeanUtil.copyToList(paymentScheduleProcessList, ScheduleProcessVo.class));
+				}
+			});
+		}
+		return R.ok(scheduleVoList);
+	}
+}
\ No newline at end of file
diff --git a/platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/service/impl/ContractServiceImpl.java b/platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/service/impl/ContractServiceImpl.java
index 2997cf9..629e3cb 100644
--- a/platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/service/impl/ContractServiceImpl.java
+++ b/platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/service/impl/ContractServiceImpl.java
@@ -1,10 +1,29 @@
 package com.by4cloud.platformx.business.service.impl;
 
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.util.ArrayUtil;
+import cn.hutool.core.util.ObjUtil;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import com.by4cloud.platformx.business.entity.Contract;
-import com.by4cloud.platformx.business.mapper.ContractMapper;
+import com.by4cloud.platformx.business.dto.ContractAddDTO;
+import com.by4cloud.platformx.business.dto.ContractUpdateDTO;
+import com.by4cloud.platformx.business.entity.*;
+import com.by4cloud.platformx.business.mapper.*;
 import com.by4cloud.platformx.business.service.ContractService;
+import com.by4cloud.platformx.business.utils.ContractNumberGenerator;
+import com.by4cloud.platformx.business.vo.ContractDetailVo;
+import com.by4cloud.platformx.common.core.util.R;
+import com.by4cloud.platformx.common.security.util.SecurityUtils;
+import lombok.RequiredArgsConstructor;
 import org.springframework.stereotype.Service;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.Date;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
 
 /**
  * @author cd
@@ -12,6 +31,280 @@
  * @date 2026/4/29 14:07
  **/
 @Service
+@RequiredArgsConstructor
 public class ContractServiceImpl extends ServiceImpl<ContractMapper, Contract> implements ContractService {
 
+	private final ContractSubjectMatterMapper contractSubjectMatterMapper;
+	private final ContractPaymentScheduleMapper contractPaymentScheduleMapper;
+	private final ContractPaymentScheduleProcessMapper contractPaymentScheduleProcessMapper;
+	private final PaymentConfirmMapper paymentConfirmMapper;
+	private final CurrentOverdueMapper currentOverdueMapper;
+
+	@Override
+	public R add(ContractAddDTO addDTO) {
+		Contract contract = BeanUtil.copyProperties(addDTO,Contract.class);
+		contract.setPartyBId(SecurityUtils.getUser().getCompId());
+		contract.setPartyB(SecurityUtils.getUser().getCompName());
+		contract.setContractNo(ContractNumberGenerator.generateContractNumber());
+		contract.setBillingStatus("0");
+		contract.setErpPushFlag("0");
+		List<Contract> contracts;
+		contracts = baseMapper.selectList(Wrappers.<Contract>lambdaQuery().eq(Contract::getContractNo,contract.getContractNo()));
+		while (ArrayUtil.isNotEmpty(contracts.toArray())){
+			contract.setContractNo(ContractNumberGenerator.generateContractNumber());
+			contracts = baseMapper.selectList(Wrappers.<Contract>lambdaQuery().eq(Contract::getContractNo,contract.getContractNo()));
+		}
+		baseMapper.insert(contract);
+
+		if (ArrayUtil.isNotEmpty(addDTO.getContractSubjectMatter())){
+			addDTO.getContractSubjectMatter().stream().forEach(contractSubjectMatterAddDTO -> {
+				ContractSubjectMatter subjectMatter = BeanUtil.copyProperties(contractSubjectMatterAddDTO, ContractSubjectMatter.class);
+				subjectMatter.setContractId(contract.getId());
+				subjectMatter.setContractName(contract.getContractName());
+				subjectMatter.setDeliveredQuantity(new BigDecimal("0"));
+				subjectMatter.setDeliveryStatus(0);
+				subjectMatter.setTotalAmount(contractSubjectMatterAddDTO.getQuantity().multiply(contractSubjectMatterAddDTO.getUnitPrice()));
+				contractSubjectMatterMapper.insert(subjectMatter);
+			});
+		}
+
+		if (ArrayUtil.isNotEmpty(addDTO.getContractPaymentSchedule())){
+			AtomicInteger index = new AtomicInteger(1);
+			addDTO.getContractPaymentSchedule().stream().forEach(contractPaymentScheduleAddDTO -> {
+				int currentIndex = index.getAndIncrement();
+				ContractPaymentSchedule schedule = BeanUtil.copyProperties(contractPaymentScheduleAddDTO, ContractPaymentSchedule.class);
+				if (contractPaymentScheduleAddDTO.getStageName().equals("鍚堝悓绛捐")){
+					schedule.setEffectiveDate(DateUtil.offsetDay(contract.getSignDate(),contractPaymentScheduleAddDTO.getAgreedDays()));
+				}
+				if (ObjUtil.isNotNull(schedule.getEffectiveDate())) {
+					if (schedule.getEffectiveDate().before(DateUtil.date())) {
+						schedule.setFulfillmentStatus(1);
+					} else {
+						schedule.setFulfillmentStatus(0);
+					}
+				}
+				schedule.setPaymentStatus(0);
+				schedule.setContractId(contract.getId());
+				schedule.setContractName(contract.getContractName());
+				schedule.setPlannedAmount(contract.getAmount().multiply(schedule.getPaymentRatio().divide(new BigDecimal("100"))));
+				schedule.setStageOrder(currentIndex);
+				contractPaymentScheduleMapper.insert(schedule);
+				if (contractPaymentScheduleAddDTO.getStageName().equals("璐у埌绛炬敹")){
+					contract.setArrivalScheduleId(schedule.getId());
+					baseMapper.updateById(contract);
+				}
+				if (contractPaymentScheduleAddDTO.getStageName().equals("璋冭瘯瀹屾垚鎴栭獙鏀�")){
+					contract.setAcceptScheduleId(schedule.getId());
+					baseMapper.updateById(contract);
+				}
+			});
+
+		}
+
+
+
+		return R.ok();
+	}
+
+	@Override
+	public R edit(ContractUpdateDTO updateDTO) {
+		Contract entity = baseMapper.selectById(updateDTO.getId());
+		if (!StrUtil.equals(entity.getContractStatus()+"","0")){
+			return R.failed("褰撳墠鐘舵�佹棤娉曚慨鏀瑰悎鍚�");
+		}
+		Contract contract = BeanUtil.copyProperties(updateDTO,Contract.class);
+		contract.setContractNo(ContractNumberGenerator.generateContractNumber());
+		baseMapper.updateById(contract);
+
+		if (ArrayUtil.isNotEmpty(updateDTO.getContractSubjectMatter())){
+			contractSubjectMatterMapper.delete(Wrappers.<ContractSubjectMatter>lambdaQuery().eq(ContractSubjectMatter::getContractId,contract.getId()));
+
+			updateDTO.getContractSubjectMatter().stream().forEach(contractSubjectMatterAddDTO -> {
+				ContractSubjectMatter subjectMatter = BeanUtil.copyProperties(contractSubjectMatterAddDTO, ContractSubjectMatter.class);
+				subjectMatter.setContractId(contract.getId());
+				subjectMatter.setContractName(contract.getContractName());
+				subjectMatter.setDeliveredQuantity(new BigDecimal("0"));
+				subjectMatter.setDeliveryStatus(0);
+				contractSubjectMatterMapper.insert(subjectMatter);
+			});
+		}
+
+		if (ArrayUtil.isNotEmpty(updateDTO.getContractPaymentSchedule())){
+			contractPaymentScheduleMapper.delete(Wrappers.<ContractPaymentSchedule>lambdaQuery().eq(ContractPaymentSchedule::getContractId,contract.getId()));
+
+			AtomicInteger index = new AtomicInteger(1);
+			updateDTO.getContractPaymentSchedule().stream().forEach(contractPaymentScheduleAddDTO -> {
+				int currentIndex = index.getAndIncrement();
+				ContractPaymentSchedule subjectMatter = BeanUtil.copyProperties(contractPaymentScheduleAddDTO, ContractPaymentSchedule.class);
+				subjectMatter.setContractId(contract.getId());
+				subjectMatter.setContractName(contract.getContractName());
+				subjectMatter.setPlannedAmount(contract.getAmount().multiply(subjectMatter.getPaymentRatio().divide(new BigDecimal("100"))));
+				subjectMatter.setStageOrder(currentIndex);
+				contractPaymentScheduleMapper.insert(subjectMatter);
+			});
+
+		}
+
+		return R.ok();
+	}
+
+	@Override
+	public ContractDetailVo detail(Long id) {
+		Contract contract = baseMapper.selectById(id);
+		ContractDetailVo detailVo = BeanUtil.copyProperties(contract,ContractDetailVo.class);
+		List<ContractSubjectMatter> subjectMatterList = contractSubjectMatterMapper.selectList(Wrappers.<ContractSubjectMatter>lambdaQuery().eq(ContractSubjectMatter::getContractId,id));
+		detailVo.setContractSubjectMatter(subjectMatterList);
+		List<ContractPaymentSchedule> paymentScheduleList = contractPaymentScheduleMapper.selectList(Wrappers.<ContractPaymentSchedule>lambdaQuery().eq(ContractPaymentSchedule::getContractId,contract.getId()));
+		detailVo.setContractPaymentSchedule(paymentScheduleList);
+		return detailVo;
+	}
+
+	@Override
+	public Boolean takeEffect(Long id) {
+		Contract contract = baseMapper.selectById(id);
+		contract.setContractStatus(1);
+		baseMapper.updateById(contract);
+		ContractPaymentSchedule fitstSchedule = contractPaymentScheduleMapper.selectOne(Wrappers.<ContractPaymentSchedule>lambdaQuery().eq(ContractPaymentSchedule::getContractId,contract.getId())
+				.orderByAsc(ContractPaymentSchedule::getCreateTime).last("limit 1"));
+//		PaymentConfirm entity = new PaymentConfirm();
+//		entity.setContractId(contract.getId());
+//		entity.setContractName(contract.getContractName());
+//		entity.setContractNo(contract.getContractNo());
+//		entity.setBusGuestId(contract.getPartyAId());
+//		entity.setBusGuestName(contract.getPartyA());
+//		entity.setBusinessType(fitstSchedule.getStageName()+"搴旀敹");
+//		entity.setTransationAmount(new BigDecimal(fitstSchedule.getPlannedAmount()));
+//		entity.setReceivableAmount(new BigDecimal(fitstSchedule.getPlannedAmount()));
+//		entity.setTotalAmount(new BigDecimal("0").subtract(new BigDecimal(fitstSchedule.getPlannedAmount())));
+//		entity.setConfirmTime(new Date());
+//		paymentConfirmMapper.insert(entity);
+
+		if (fitstSchedule.getStageName().equals("鍚堝悓绛捐")){
+			//鏂板搴旀敹
+			PaymentConfirm paymentConfirm = new PaymentConfirm();
+			paymentConfirm.setBusinessType("鍚堝悓绛捐搴旀敹");
+			paymentConfirm.setBusGuestId(contract.getPartyAId());
+			paymentConfirm.setBusGuestName(contract.getPartyA());
+			paymentConfirm.setContractId(contract.getId());
+			paymentConfirm.setContractName(contract.getContractName());
+			paymentConfirm.setContractNo(contract.getContractNo());
+			paymentConfirm.setScheduleId(fitstSchedule.getId());
+			paymentConfirm.setScheduleName(fitstSchedule.getStageName());
+			paymentConfirm.setConfirmTime(new Date());
+			paymentConfirm.setTransationAmount(fitstSchedule.getPlannedAmount());
+			paymentConfirm.setReceivableAmount(fitstSchedule.getPlannedAmount());
+			paymentConfirm.setTotalAmount(fitstSchedule.getPlannedAmount().multiply(new BigDecimal("-1")));
+			paymentConfirmMapper.insert(paymentConfirm);
+			//鏂板鍚堝悓灞ョ害璁板綍
+			ContractPaymentScheduleProcess process = new ContractPaymentScheduleProcess();
+			process.setContractId(contract.getId());
+			process.setContractName(contract.getContractName());
+			process.setScheduleId(fitstSchedule.getId());
+			process.setScheduleName(fitstSchedule.getStageName());
+			process.setProcessDate(contract.getSignDate());
+			contractPaymentScheduleProcessMapper.insert(process);
+		}
+		//鏌ヨ鏄惁鏈夊悗缁樁娈�
+		List<ContractPaymentSchedule> afterSchedule = contractPaymentScheduleMapper.selectList(Wrappers.<ContractPaymentSchedule>lambdaQuery()
+				.eq(ContractPaymentSchedule::getContractId, fitstSchedule.getContractId())
+				.gt(ContractPaymentSchedule::getStageOrder, fitstSchedule.getStageOrder()));
+		if (ArrayUtil.isNotEmpty(afterSchedule.toArray())&&afterSchedule.size()==1){
+			//鏈�鍚庨樁娈电敓鏁堟椂闂�
+			ContractPaymentSchedule endSchedule = afterSchedule.get(0);
+			endSchedule.setEffectiveDate(DateUtil.offsetDay(new Date(),endSchedule.getAgreedDays()));
+			endSchedule.setEffectiveEndDate(contract.getExpirationDate());
+			contractPaymentScheduleMapper.updateById(endSchedule);
+			//绗竴闃舵鐢熸晥鏃堕棿
+			fitstSchedule.setEffectiveDate(DateUtil.offsetDay(new Date(),fitstSchedule.getAgreedDays()));
+			fitstSchedule.setEffectiveEndDate(endSchedule.getEffectiveDate());
+			contractPaymentScheduleMapper.updateById(fitstSchedule);
+
+			//鏈�鍚庨樁娈靛簲鏀�
+			PaymentConfirm newConfim = new PaymentConfirm();
+			newConfim.setBusinessType(endSchedule.getStageName()+"搴旀敹");
+			newConfim.setBusGuestId(contract.getPartyAId());
+			newConfim.setBusGuestName(contract.getPartyA());
+			newConfim.setContractId(contract.getId());
+			newConfim.setContractName(contract.getContractName());
+			newConfim.setContractNo(contract.getContractNo());
+			newConfim.setScheduleId(endSchedule.getId());
+			newConfim.setScheduleName(endSchedule.getStageName());
+			newConfim.setConfirmTime(new Date());
+			newConfim.setTransationAmount(endSchedule.getPlannedAmount());
+			newConfim.setReceivableAmount(endSchedule.getPlannedAmount());
+			PaymentConfirm lastNewConfirm = paymentConfirmMapper.selectOne(Wrappers.<PaymentConfirm>lambdaQuery().eq(PaymentConfirm::getContractId,contract.getId())
+					.orderByDesc(PaymentConfirm::getCreateTime).last("limit 1"));
+			BigDecimal lastNewTotal = new BigDecimal("0");
+			if(ObjUtil.isNotNull(lastNewConfirm)){
+				lastNewTotal = lastNewConfirm.getTotalAmount();
+			}
+			newConfim.setTotalAmount(lastNewTotal.subtract(newConfim.getReceivableAmount()));
+			paymentConfirmMapper.insert(newConfim);
+		}
+		if(ArrayUtil.isEmpty(afterSchedule.toArray())){
+			fitstSchedule.setEffectiveEndDate(contract.getExpirationDate());
+			contractPaymentScheduleMapper.updateById(fitstSchedule);
+		}
+		return Boolean.TRUE;
+	}
+
+	@Override
+	public R genCurrentOverdue() {
+		List<ContractPaymentSchedule> scheduleList = contractPaymentScheduleMapper.selectList(Wrappers.<ContractPaymentSchedule>lambdaQuery()
+				.lt(ContractPaymentSchedule::getEffectiveEndDate, DateUtil.today())
+				.ne(ContractPaymentSchedule::getPaymentStatus,"2"));
+		if (ArrayUtil.isNotEmpty(scheduleList.toArray())){
+			scheduleList.stream().forEach(contractPaymentSchedule -> {
+				Contract contract = baseMapper.selectById(contractPaymentSchedule.getContractId());
+				//搴旀敹瓒呮湡
+				PaymentConfirm overdueConfirm = new PaymentConfirm();
+				overdueConfirm.setBusinessType("搴旀敹瓒呮湡");
+				overdueConfirm.setBusGuestId(contract.getPartyAId());
+				overdueConfirm.setBusGuestName(contract.getPartyA());
+				overdueConfirm.setContractId(contract.getId());
+				overdueConfirm.setContractName(contract.getContractName());
+				overdueConfirm.setContractNo(contract.getContractNo());
+				overdueConfirm.setConfirmTime(new Date());
+				overdueConfirm.setScheduleId(contractPaymentSchedule.getId());
+				overdueConfirm.setScheduleName(contractPaymentSchedule.getStageName());
+				PaymentConfirm newLastConfirm = paymentConfirmMapper.selectOne(Wrappers.<PaymentConfirm>lambdaQuery().eq(PaymentConfirm::getContractId,contract.getId())
+						.orderByDesc(PaymentConfirm::getCreateTime).last("limit 1"));
+				overdueConfirm.setTransationAmount(StrUtil.equals(contractPaymentSchedule.getPaymentStatus()+"","0")?
+						contractPaymentSchedule.getPlannedAmount():
+						contractPaymentSchedule.getPlannedAmount().subtract(contractPaymentSchedule.getActualAmount()));
+				overdueConfirm.setReceivableAmount(newLastConfirm.getTotalAmount().multiply(new BigDecimal("-1")));
+				overdueConfirm.setOverdueAmount(overdueConfirm.getTransationAmount());
+				overdueConfirm.setTotalAmount(newLastConfirm.getTotalAmount());
+				overdueConfirm.setCompId(contract.getCompId());
+				//鍒ゆ柇褰撳墠闃舵鏄惁宸茬敓鎴愪笂闃舵搴旀敹瓒呮湡
+				PaymentConfirm oiverdueConfirm = paymentConfirmMapper.selectOne(Wrappers.<PaymentConfirm>lambdaQuery().eq(PaymentConfirm::getScheduleId, contractPaymentSchedule.getId())
+						.eq(PaymentConfirm::getBusinessType, "搴旀敹瓒呮湡"));
+				if (ObjUtil.isNull(oiverdueConfirm)) {
+					paymentConfirmMapper.insert(overdueConfirm);
+				}
+				//褰撳墠閫炬湡
+				CurrentOverdue currentOverdue = new CurrentOverdue();
+				currentOverdue.setBusGuestId(contract.getPartyAId());
+				currentOverdue.setBusGuestName(contract.getPartyA());
+				currentOverdue.setContractId(contractPaymentSchedule.getContractId());
+				currentOverdue.setContractName(contractPaymentSchedule.getContractName());
+				currentOverdue.setScheduleId(contractPaymentSchedule.getId());
+				currentOverdue.setScheduleName(contractPaymentSchedule.getStageName());
+				currentOverdue.setCompId(contract.getCompId());
+				currentOverdue.setContractExpirTime(contractPaymentSchedule.getEffectiveEndDate());
+				currentOverdue.setReceivableAmount(StrUtil.equals(contractPaymentSchedule.getPaymentStatus()+"","0")?
+						contractPaymentSchedule.getPlannedAmount():contractPaymentSchedule.getPlannedAmount().subtract(contractPaymentSchedule.getActualAmount()));
+				currentOverdue.setOverdueDuration(BigDecimal.valueOf(DateUtil.betweenDay(contractPaymentSchedule.getEffectiveEndDate(),new Date(),true)));
+				CurrentOverdue overdue = currentOverdueMapper.selectOne(Wrappers.<CurrentOverdue>lambdaQuery().eq(CurrentOverdue::getContractId,currentOverdue.getContractId())
+						.eq(CurrentOverdue::getScheduleId,currentOverdue.getScheduleId()).last("limit 1"));
+				if (ObjUtil.isNull(overdue)){
+					currentOverdueMapper.insert(currentOverdue);
+				}else {
+					overdue.setOverdueDuration(BigDecimal.valueOf(DateUtil.betweenDay(contractPaymentSchedule.getEffectiveEndDate(),new Date(),true)));
+					currentOverdueMapper.updateById(overdue);
+				}
+			});
+		}
+		return R.ok();
+	}
 }
diff --git a/platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/service/impl/OutBoundServiceImpl.java b/platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/service/impl/OutBoundServiceImpl.java
index e8e8581..ab084f0 100644
--- a/platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/service/impl/OutBoundServiceImpl.java
+++ b/platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/service/impl/OutBoundServiceImpl.java
@@ -1,12 +1,29 @@
 package com.by4cloud.platformx.business.service.impl;
 
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.util.ArrayUtil;
+import cn.hutool.core.util.ObjUtil;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import com.by4cloud.platformx.business.entity.OutBound;
-import com.by4cloud.platformx.business.mapper.OutBoundMapper;
+import com.by4cloud.platformx.business.dto.OutBoundAddDTO;
+import com.by4cloud.platformx.business.dto.OutSubjectMatterAddDTO;
+import com.by4cloud.platformx.business.entity.*;
+import com.by4cloud.platformx.business.mapper.*;
 import com.by4cloud.platformx.business.service.OutBoundService;
+import com.by4cloud.platformx.common.core.util.R;
+import com.github.yulichang.wrapper.MPJLambdaWrapper;
+import lombok.RequiredArgsConstructor;
 import org.springframework.stereotype.Service;
 
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.util.ArrayList;
 import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
 
 /**
  * EPR鍑哄簱璁板綍
@@ -15,11 +32,231 @@
  * @date 2026-04-29 11:32:05
  */
 @Service
+@RequiredArgsConstructor
 public class OutBoundServiceImpl extends ServiceImpl<OutBoundMapper, OutBound> implements OutBoundService {
 
+	private final ContractPaymentScheduleMapper scheduleMapper;
+	private final ContractSubjectMatterMapper contractSubjectMatterMapper;
+	private final PaymentConfirmMapper paymentConfirmMapper;
+	private final ContractMapper contractMapper;
+	private final ContractPaymentScheduleProcessMapper scheduleProcessMapper;
+
 	@Override
-	public boolean save(OutBound entity) {
-		entity.setOutBoundTime(new Date());
-		return super.save(entity);
+	public R add(OutBoundAddDTO addDTO) {
+		if (ArrayUtil.isEmpty(addDTO.getSubjectMatterList().toArray())) {
+			return R.failed("鍑哄簱鏍囩殑鐗╀笉鑳戒负绌�");
+		}
+		MPJLambdaWrapper<ContractSubjectMatter> wrapper = new MPJLambdaWrapper<ContractSubjectMatter>()
+				.selectAll(ContractSubjectMatter.class)
+				.ne(ContractSubjectMatter::getDeliveryStatus, 2)
+				.exists(Contract.class, contractQuery ->
+						contractQuery.select(ContractSubjectMatter::getId)
+								.eq(Contract::getId, ContractSubjectMatter::getContractId)
+								.eq(StrUtil.isNotBlank(addDTO.getBusGuestName()), Contract::getPartyA, addDTO.getBusGuestName())
+								.eq(ObjUtil.isNotNull(addDTO.getBusGuestId()), Contract::getPartyAId, addDTO.getBusGuestId())
+				)
+				.orderByAsc(ContractSubjectMatter::getCreateTime);
+		List<ContractSubjectMatter> subjectMatterList = contractSubjectMatterMapper.selectList(wrapper);
+		if (ArrayUtil.isEmpty(subjectMatterList.toArray())) {
+			return R.failed("娌℃湁鏌ヨ鍒扮浉鍏冲悎鍚岃鍗�");
+		}
+		Double outTotal = subjectMatterList.stream().mapToDouble(item -> {
+			// 浼樺厛鍒ゆ柇 remainNum
+			if (item.getRemainingQuantity() != null && item.getRemainingQuantity().compareTo(new BigDecimal("0")) > 0) {
+				return item.getRemainingQuantity().doubleValue();
+			} else {
+				// remainNum 涓� null 鎴� 0 鏃讹紝浣跨敤 quantity
+				return item.getQuantity() == null ? 0.0 : item.getQuantity().doubleValue();
+			}
+		}).sum();
+		BigDecimal orderNum = addDTO.getSubjectMatterList().stream().map(OutSubjectMatterAddDTO::getOutBoundNum)
+				.filter(num -> num != null) // 杩囨护鎺� null 鍊硷紝闃叉 NullPointerException
+				.reduce(BigDecimal.ZERO, BigDecimal::add);
+		if (new BigDecimal(outTotal).compareTo(orderNum) < 0) {
+			return R.failed("鍑哄簱鏁伴噺瓒呭嚭鍚堝悓璁㈠崟鏁伴噺");
+		}
+		//褰撳墠鍏ュ簱鏍囩殑鐗�
+		List<ContractSubjectMatter> currentOutList = new ArrayList<>();
+		addDTO.getSubjectMatterList().stream().forEach(outSubjectMatterAddDTO -> {
+			BigDecimal remainNum = outSubjectMatterAddDTO.getOutBoundNum();
+			for (ContractSubjectMatter subjectMatter : subjectMatterList) {
+
+				if (subjectMatter.getDeliveredQuantity().compareTo(new BigDecimal("0")) > 0) {
+					remainNum = remainNum.subtract(subjectMatter.getRemainingQuantity());
+					//閮ㄥ垎浜や粯鐘舵�佷笅 鍏ㄩ儴鍑哄簱
+					if (remainNum.compareTo(new BigDecimal("0")) >= 0) {
+						BigDecimal currentOut = subjectMatter.getRemainingQuantity();
+						subjectMatter.setDeliveredQuantity(subjectMatter.getQuantity());
+						subjectMatter.setRemainingQuantity(new BigDecimal("0"));
+						subjectMatter.setActualDeliveryDate(DateUtil.today());
+						subjectMatter.setDeliveryStatus(2);
+						subjectMatter.setLastDeliveredQuantity(currentOut);
+						contractSubjectMatterMapper.updateById(subjectMatter);
+						currentOutList.add(subjectMatter);
+					} else {
+						BigDecimal currentOut = remainNum.add(subjectMatter.getRemainingQuantity());
+						subjectMatter.setDeliveredQuantity(subjectMatter.getQuantity().add(remainNum));
+						subjectMatter.setRemainingQuantity(remainNum.multiply(new BigDecimal("-1")));
+						subjectMatter.setActualDeliveryDate(DateUtil.today());
+						subjectMatter.setDeliveryStatus(1);
+						subjectMatter.setLastDeliveredQuantity(currentOut);
+						contractSubjectMatterMapper.updateById(subjectMatter);
+						currentOutList.add(subjectMatter);
+						break;
+					}
+
+				} else {
+					//鏈氦浠樼姸鎬佷笅
+					remainNum = remainNum.subtract(subjectMatter.getQuantity());
+					if (remainNum.compareTo(new BigDecimal("0")) >= 0) {
+						subjectMatter.setDeliveredQuantity(subjectMatter.getQuantity());
+						subjectMatter.setRemainingQuantity(new BigDecimal("0"));
+						subjectMatter.setActualDeliveryDate(DateUtil.today());
+						subjectMatter.setDeliveryStatus(2);
+						contractSubjectMatterMapper.updateById(subjectMatter);
+						subjectMatter.setLastDeliveredQuantity(subjectMatter.getQuantity());
+						currentOutList.add(subjectMatter);
+					} else {
+						BigDecimal currentOut = remainNum.add(subjectMatter.getQuantity());
+						subjectMatter.setDeliveredQuantity(subjectMatter.getQuantity().add(remainNum));
+						subjectMatter.setRemainingQuantity(remainNum.multiply(new BigDecimal("-1")));
+						subjectMatter.setActualDeliveryDate(DateUtil.today());
+						subjectMatter.setDeliveryStatus(1);
+						subjectMatter.setLastDeliveredQuantity(currentOut);
+						contractSubjectMatterMapper.updateById(subjectMatter);
+						currentOutList.add(subjectMatter);
+						break;
+					}
+				}
+			}
+			OutBound outBound = BeanUtil.copyProperties(outSubjectMatterAddDTO, OutBound.class);
+			outBound.setBusGuestName(addDTO.getBusGuestName());
+			outBound.setBusGuestId(addDTO.getBusGuestId());
+			outBound.setOutBoundTime(addDTO.getOutBoundTime());
+			baseMapper.insert(outBound);
+		});
+
+		//鍑哄簱搴旀敹娆炬槑缁�
+		if (ArrayUtil.isNotEmpty(currentOutList.toArray())) {
+			//鏍规嵁鍚堝悓id鎷嗗垎搴旀敹鏄庣粏
+			Map<Long, List<ContractSubjectMatter>> conSubMatMap = currentOutList.stream().collect(Collectors.groupingBy(ContractSubjectMatter::getContractId));
+
+			conSubMatMap.forEach((key, value) -> {
+				//鏌ヨ鍚堝悓鏄惁鏈夊嚭搴撻樁娈�
+				ContractPaymentSchedule schedule = scheduleMapper.selectOne(Wrappers.<ContractPaymentSchedule>lambdaQuery().eq(ContractPaymentSchedule::getContractId, key)
+						.eq(ContractPaymentSchedule::getStageName, "鍙戣揣鍓�"));
+				//褰撳墠鍑哄簱閲戦
+				BigDecimal outPirce = value.stream()
+						.filter(item -> item.getLastDeliveredQuantity() != null && item.getUnitPrice() != null)
+						.map(item -> item.getLastDeliveredQuantity().multiply(item.getUnitPrice()))
+						.reduce(BigDecimal.ZERO, BigDecimal::add);
+				//鍚堝悓閲戦
+				Contract contract = contractMapper.selectById(key);
+				//鍑哄簱鏄惁瀹屾垚
+				if (outPirce.compareTo(contract.getAmount())<0){
+					contract.setBillingStatus("1");
+					contractMapper.updateById(contract);
+				}
+				if (outPirce.compareTo(contract.getAmount())==0){
+					contract.setBillingStatus("2");
+					contractMapper.updateById(contract);
+				}
+				if (ObjUtil.isNotNull(schedule)) {
+
+					//鎸夊嚭搴撹祫閲戞瘮渚� 璁$畻鍙戣揣鍓嶅簲鏀舵洿鏂拌祫閲戞槑缁�
+					PaymentConfirm paymentConfirm = new PaymentConfirm();
+					paymentConfirm.setBusinessType("鍙戣揣鍓嶅簲鏀�");
+					paymentConfirm.setBusGuestId(contract.getPartyAId());
+					paymentConfirm.setBusGuestName(contract.getPartyA());
+					paymentConfirm.setContractId(contract.getId());
+					paymentConfirm.setContractName(contract.getContractName());
+					paymentConfirm.setContractNo(contract.getContractNo());
+					paymentConfirm.setScheduleId(schedule.getId());
+					paymentConfirm.setScheduleName(schedule.getStageName());
+					paymentConfirm.setConfirmTime(addDTO.getOutBoundTime());
+					paymentConfirm.setTransationAmount(outPirce.divide(contract.getAmount(), 10, RoundingMode.HALF_UP).multiply(schedule.getPlannedAmount()));
+					paymentConfirm.setReceivableAmount(paymentConfirm.getTransationAmount());
+					paymentConfirm.setTotalAmount(paymentConfirm.getTransationAmount().multiply(new BigDecimal("-1")));
+					//鏈�杩戝簲鏀�
+					PaymentConfirm lastConfirm = paymentConfirmMapper.selectOne(Wrappers.<PaymentConfirm>lambdaQuery().eq(PaymentConfirm::getContractId, contract.getId())
+							.orderByDesc(PaymentConfirm::getCreateTime).last("limit 1"));
+					if (ObjUtil.isNotNull(lastConfirm)) {
+						paymentConfirm.setTotalAmount(paymentConfirm.getTotalAmount().add(lastConfirm.getTotalAmount()));
+						paymentConfirmMapper.insert(paymentConfirm);
+					} else {
+						paymentConfirmMapper.insert(paymentConfirm);
+					}
+					//鏇存柊鍙戣揣鍓嶆敹娆剧敓鏁堟椂闂�
+					if (ObjUtil.isNull(schedule.getEffectiveDate())){
+						schedule.setEffectiveDate(DateUtil.offsetDay(addDTO.getOutBoundTime(),schedule.getAgreedDays()));
+						//鏌ヨ鏄惁鏈夊悗缁樁娈�
+						List<ContractPaymentSchedule> afterSchedule = scheduleMapper.selectList(Wrappers.<ContractPaymentSchedule>lambdaQuery().eq(ContractPaymentSchedule::getContractId, key)
+								.gt(ContractPaymentSchedule::getStageOrder, schedule.getStageOrder()));
+						if (ArrayUtil.isEmpty(afterSchedule.toArray())){
+							schedule.setEffectiveEndDate(contract.getExpirationDate());
+						}
+						scheduleMapper.updateById(schedule);
+						//鏌ヨ鏄惁鏈変箣鍓嶉樁娈�
+						ContractPaymentSchedule beforeSchedule = scheduleMapper.selectOne(Wrappers.<ContractPaymentSchedule>lambdaQuery().eq(ContractPaymentSchedule::getContractId, schedule.getContractId())
+								.lt(ContractPaymentSchedule::getStageOrder, schedule.getStageOrder()).orderByDesc(ContractPaymentSchedule::getCreateTime).last("limit 1"));
+						if (ObjUtil.isNotNull(beforeSchedule)){
+							beforeSchedule.setEffectiveEndDate(DateUtil.offsetDay(addDTO.getOutBoundTime(),beforeSchedule.getAgreedDays()));
+							scheduleMapper.updateById(beforeSchedule);
+						}
+					}
+					//鏇存柊灞ョ害
+					ContractPaymentScheduleProcess contractPaymentScheduleProcess = new ContractPaymentScheduleProcess();
+					contractPaymentScheduleProcess.setContractId(schedule.getContractId());
+					contractPaymentScheduleProcess.setContractName(schedule.getContractName());
+					contractPaymentScheduleProcess.setScheduleId(schedule.getId());
+					contractPaymentScheduleProcess.setScheduleName(schedule.getStageName());
+					contractPaymentScheduleProcess.setProcessDate(addDTO.getOutBoundTime());
+					scheduleProcessMapper.insert(contractPaymentScheduleProcess);
+					//鏌ヨ鏄惁鏈夊悗缁樁娈�
+					List<ContractPaymentSchedule> afterSchedule = scheduleMapper.selectList(Wrappers.<ContractPaymentSchedule>lambdaQuery()
+							.eq(ContractPaymentSchedule::getContractId, schedule.getContractId())
+							.gt(ContractPaymentSchedule::getStageOrder, schedule.getStageOrder()));
+					if (ArrayUtil.isNotEmpty(afterSchedule.toArray())&&afterSchedule.size()==1){
+
+						//鏈�鍚庨樁娈电敓鏁堟椂闂�
+						ContractPaymentSchedule endSchedule = afterSchedule.get(0);
+						endSchedule.setEffectiveDate(DateUtil.offsetDay(addDTO.getOutBoundTime(),endSchedule.getAgreedDays()));
+						endSchedule.setEffectiveEndDate(contract.getExpirationDate());
+						scheduleMapper.updateById(endSchedule);
+						//褰撳墠闃舵鐢熸晥鏃堕棿
+						schedule.setEffectiveDate(DateUtil.offsetDay(addDTO.getOutBoundTime(),schedule.getAgreedDays()));
+						schedule.setEffectiveEndDate(endSchedule.getEffectiveDate());
+						scheduleMapper.updateById(schedule);
+						//鏈�鍚庨樁娈靛簲鏀�
+						PaymentConfirm newConfim = new PaymentConfirm();
+						newConfim.setBusinessType(endSchedule.getStageName()+"搴旀敹");
+						newConfim.setBusGuestId(contract.getPartyAId());
+						newConfim.setBusGuestName(contract.getPartyA());
+						newConfim.setContractId(contract.getId());
+						newConfim.setContractName(contract.getContractName());
+						newConfim.setContractNo(contract.getContractNo());
+						newConfim.setScheduleId(endSchedule.getId());
+						newConfim.setScheduleName(schedule.getStageName());
+						newConfim.setConfirmTime(addDTO.getOutBoundTime());
+						newConfim.setTransationAmount(endSchedule.getPlannedAmount());
+						newConfim.setReceivableAmount(endSchedule.getPlannedAmount());
+						PaymentConfirm lastNewConfirm = paymentConfirmMapper.selectOne(Wrappers.<PaymentConfirm>lambdaQuery().eq(PaymentConfirm::getContractId,contract.getId())
+								.orderByDesc(PaymentConfirm::getCreateTime).last("limit 1"));
+						BigDecimal lastNewTotal = new BigDecimal("0");
+						if(ObjUtil.isNotNull(lastNewConfirm)){
+							lastNewTotal = lastNewConfirm.getTotalAmount();
+						}
+						newConfim.setTotalAmount(lastNewTotal.subtract(newConfim.getReceivableAmount()));
+						paymentConfirmMapper.insert(newConfim);
+					}
+					if(ArrayUtil.isEmpty(afterSchedule.toArray())){
+						schedule.setEffectiveEndDate(contract.getExpirationDate());
+						scheduleMapper.updateById(schedule);
+					}
+				}
+			});
+		}
+
+		return R.ok();
 	}
 }
\ No newline at end of file
diff --git a/platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/service/impl/PaymentConfirmServiceImpl.java b/platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/service/impl/PaymentConfirmServiceImpl.java
index 36991f3..8451ea7 100644
--- a/platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/service/impl/PaymentConfirmServiceImpl.java
+++ b/platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/service/impl/PaymentConfirmServiceImpl.java
@@ -1,12 +1,28 @@
 package com.by4cloud.platformx.business.service.impl;
 
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.util.ArrayUtil;
+import cn.hutool.core.util.ObjUtil;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import com.by4cloud.platformx.business.entity.PaymentConfirm;
+import com.by4cloud.platformx.business.dto.PaymentConfirmAddDTO;
+import com.by4cloud.platformx.business.entity.*;
+import com.by4cloud.platformx.business.mapper.ContractPaymentScheduleMapper;
+import com.by4cloud.platformx.business.mapper.CurrentOverdueMapper;
+import com.by4cloud.platformx.business.mapper.HistoryOverdueMapper;
 import com.by4cloud.platformx.business.mapper.PaymentConfirmMapper;
+import com.by4cloud.platformx.business.service.BusinessCustomerService;
+import com.by4cloud.platformx.business.service.ContractPaymentScheduleService;
+import com.by4cloud.platformx.business.service.ContractService;
 import com.by4cloud.platformx.business.service.PaymentConfirmService;
+import com.by4cloud.platformx.common.core.util.R;
+import lombok.RequiredArgsConstructor;
 import org.springframework.stereotype.Service;
 
+import java.math.BigDecimal;
 import java.util.Date;
+import java.util.List;
 
 /**
  * 鏀舵纭
@@ -15,11 +31,125 @@
  * @date 2026-04-29 11:33:26
  */
 @Service
+@RequiredArgsConstructor
 public class PaymentConfirmServiceImpl extends ServiceImpl<PaymentConfirmMapper, PaymentConfirm> implements PaymentConfirmService {
 
+	private final ContractService contractService;
+	private final BusinessCustomerService businessCustomerService;
+	private final ContractPaymentScheduleMapper contractPaymentScheduleMapper;
+	private final CurrentOverdueMapper currentOverdueMapper;
+	private final HistoryOverdueMapper historyOverdueMapper;
+
 	@Override
-	public boolean save(PaymentConfirm entity) {
-		entity.setConfirmTime(new Date());
-		return super.save(entity);
+	public R add(PaymentConfirmAddDTO addDTO) {
+		Contract contract = contractService.getOne(Wrappers.<Contract>lambdaQuery().eq(Contract::getContractNo,addDTO.getContractNo()));
+		if(ObjUtil.isNull(contract)){
+			return R.failed("鍚堝悓鏌ヨ澶辫触锛岃妫�鏌ュ悎鍚岀紪鍙�");
+		}
+		BusinessCustomer customer = businessCustomerService.getOne(Wrappers.<BusinessCustomer>lambdaQuery()
+				.eq(StrUtil.isNotBlank(addDTO.getBusGuestName()),BusinessCustomer::getCompanyName,addDTO.getBusGuestName())
+				.eq(StrUtil.isNotBlank(addDTO.getBusGuestId()),BusinessCustomer::getId,addDTO.getBusGuestId()));
+		if(ObjUtil.isNull(customer)){
+			return R.failed("瀹㈠晢鏌ヨ澶辫触锛岃妫�鏌ュ鍟�");
+		}
+
+		PaymentConfirm lastConfirm = baseMapper.selectOne(Wrappers.<PaymentConfirm>lambdaQuery().eq(PaymentConfirm::getContractId,contract.getId())
+				.orderByDesc(PaymentConfirm::getCreateTime).last("limit 1"));
+		BigDecimal lastTotal = new BigDecimal("0");
+		if(ObjUtil.isNotNull(lastConfirm)){
+			lastTotal = lastConfirm.getTotalAmount();
+		}
+
+		//杞叆
+		if (StrUtil.equals(addDTO.getInOrOut(),"1")){
+			BigDecimal newtotal = addDTO.getTransationAmount().add(lastTotal);
+			PaymentConfirm entity = new PaymentConfirm();
+			entity.setContractId(contract.getId());
+			entity.setContractName(contract.getContractName());
+			entity.setContractNo(addDTO.getContractNo());
+			if(ObjUtil.isNotNull(lastConfirm)){
+				entity.setScheduleId(lastConfirm.getScheduleId());
+				entity.setScheduleName(lastConfirm.getScheduleName());
+			}
+			entity.setBusGuestId(customer.getId());
+			entity.setBusGuestName(customer.getCompanyName());
+			entity.setBusinessType("瀹㈡埛浠樻");
+			if (newtotal.compareTo(new BigDecimal("0"))>0){
+				entity.setTransationAmount(addDTO.getTransationAmount());
+				entity.setAdvanceAmount(newtotal);
+				entity.setTotalAmount(newtotal);
+				entity.setConfirmTime(new Date());
+				baseMapper.insert(entity);
+			}else if (newtotal.compareTo(new BigDecimal("0"))==0){
+				entity.setTransationAmount(addDTO.getTransationAmount());
+				entity.setTotalAmount(newtotal);
+				entity.setConfirmTime(new Date());
+				baseMapper.insert(entity);
+			}else {
+				entity.setTransationAmount(addDTO.getTransationAmount());
+				entity.setReceivableAmount(newtotal.multiply(new BigDecimal("-1")));
+				entity.setTotalAmount(newtotal);
+				entity.setConfirmTime(new Date());
+				baseMapper.insert(entity);
+			}
+			List<ContractPaymentSchedule> scheduleList = contractPaymentScheduleMapper.selectList(Wrappers.<ContractPaymentSchedule>lambdaQuery()
+					.eq(ContractPaymentSchedule::getContractId,contract.getId()).ne(ContractPaymentSchedule::getPaymentStatus,2)
+					.orderByAsc(ContractPaymentSchedule::getCreateTime));
+			if (ArrayUtil.isNotEmpty(scheduleList.toArray())){
+				BigDecimal remain = addDTO.getTransationAmount();
+				for (ContractPaymentSchedule schedule:scheduleList) {
+					remain = remain.subtract(StrUtil.equals(schedule.getPaymentStatus()+"","0")?schedule.getPlannedAmount():
+							schedule.getPlannedAmount().subtract(schedule.getActualAmount()));
+					if (remain.compareTo(new BigDecimal("0"))>=0){
+						schedule.setActualAmount(schedule.getPlannedAmount());
+						schedule.setPaymentDate(addDTO.getConfirmTime());
+						schedule.setPaymentStatus(2);
+						contractPaymentScheduleMapper.updateById(schedule);
+						//鏌ヨ鏄惁鏈夊綋鍓嶉�炬湡
+						CurrentOverdue currentOverdue = currentOverdueMapper.selectOne(Wrappers.<CurrentOverdue>lambdaQuery().eq(CurrentOverdue::getScheduleId,schedule.getId())
+								.eq(CurrentOverdue::getContractId,schedule.getContractId()).last("limit 1"));
+						if (ObjUtil.isNotNull(currentOverdue)){
+							//鏂板閫炬湡鍘嗗彶
+							HistoryOverdue historyOverdue = BeanUtil.copyProperties(currentOverdue,HistoryOverdue.class,"id");
+							historyOverdue.setPaymentTime(addDTO.getConfirmTime());
+							historyOverdueMapper.insert(historyOverdue);
+							//鍒犻櫎褰撳墠閫炬湡
+							currentOverdueMapper.deleteById(currentOverdue);
+						}
+					}else {
+						schedule.setActualAmount(StrUtil.equals(schedule.getPaymentStatus()+"","0")?schedule.getPlannedAmount().add(remain):
+								schedule.getPlannedAmount().subtract(schedule.getActualAmount()).add(remain));
+						schedule.setPaymentDate(addDTO.getConfirmTime());
+						schedule.setPaymentStatus(1);
+						contractPaymentScheduleMapper.updateById(schedule);
+						break;
+					}
+				}
+			}
+		}
+		//杞嚭
+		if (StrUtil.equals(addDTO.getInOrOut(),"2")){
+			PaymentConfirm entity = new PaymentConfirm();
+			entity.setContractId(contract.getId());
+			entity.setContractName(contract.getContractName());
+			entity.setContractNo(addDTO.getContractNo());
+
+			entity.setBusGuestId(customer.getId());
+			entity.setBusGuestName(customer.getCompanyName());
+			entity.setBusinessType("");
+			entity.setTransationAmount(addDTO.getTransationAmount());
+			BigDecimal newtotal = addDTO.getTransationAmount().multiply(new BigDecimal("-1")).add(lastConfirm.getTotalAmount());
+			if (newtotal.compareTo(new BigDecimal("0"))>0){
+				entity.setAdvanceAmount(newtotal);
+				entity.setTotalAmount(newtotal);
+			}else if (newtotal.compareTo(new BigDecimal("0"))==0){
+				entity.setTotalAmount(newtotal);
+			}else {
+				return R.failed("褰撳墠瀹㈡埛浣欓涓�"+lastConfirm.getTotalAmount()+"涓嶈冻浠ユ弧瓒冲綋鍓嶅彂鐢熼噾棰濓紝鏃犳硶鎿嶄綔");
+			}
+			entity.setConfirmTime(new Date());
+			baseMapper.insert(entity);
+		}
+		return R.ok();
 	}
 }
\ No newline at end of file
diff --git a/platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/utils/ContractNumberGenerator.java b/platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/utils/ContractNumberGenerator.java
new file mode 100644
index 0000000..5961933
--- /dev/null
+++ b/platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/utils/ContractNumberGenerator.java
@@ -0,0 +1,40 @@
+package com.by4cloud.platformx.business.utils;
+
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicInteger;
+
+public class ContractNumberGenerator {
+
+	// 鐢ㄤ簬瀛樺偍姣忓ぉ鐨勫簭鍒楀彿璁℃暟鍣紝Key涓烘棩鏈熷瓧绗︿覆锛孷alue涓哄師瀛愭暣鏁�
+	private static final ConcurrentHashMap<String, AtomicInteger> counterMap = new ConcurrentHashMap<>();
+
+	// 鏃ユ湡鏍煎紡鍖栧櫒锛屾牸寮忎负 yyyyMMdd
+	private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyyMMdd");
+
+	/**
+	 * 鐢熸垚鍚堝悓缂栧彿
+	 * 鏍煎紡: yyyyMMdd-XXXX (XXXX涓哄綋鏃ヨ嚜澧炲簭鍒楋紝涓嶈冻4浣嶈ˉ0)
+	 *
+	 * @return 鍚堝悓缂栧彿瀛楃涓�
+	 */
+	public static String generateContractNumber() {
+		// 1. 鑾峰彇褰撳墠鏃ユ湡瀛楃涓�
+		String dateStr = LocalDate.now().format(DATE_FORMATTER);
+
+		// 2. 鑾峰彇鎴栧垱寤哄綋澶╃殑璁℃暟鍣�
+		// computeIfAbsent 淇濊瘉鍘熷瓙鎬э紝濡傛灉key涓嶅瓨鍦ㄥ垯鍒涘缓鏂扮殑AtomicInteger(0)
+		AtomicInteger counter = counterMap.computeIfAbsent(dateStr, k -> new AtomicInteger(0));
+
+		// 3. 閫掑骞惰幏鍙栧綋鍓嶅簭鍒楀彿
+		int sequence = counter.incrementAndGet();
+
+		// 4. 鏍煎紡鍖栧簭鍒楀彿锛屼緥濡� 1 -> "0001"
+		String formattedSequence = String.format("%04d", sequence);
+
+		// 5. 缁勫悎杩斿洖
+		return dateStr + "-" + formattedSequence;
+	}
+
+}
diff --git a/platformx-business-finance-biz/src/main/resources/mapper/ContractPaymentScheduleProcessMapper.xml b/platformx-business-finance-biz/src/main/resources/mapper/ContractPaymentScheduleProcessMapper.xml
new file mode 100644
index 0000000..22fe7df
--- /dev/null
+++ b/platformx-business-finance-biz/src/main/resources/mapper/ContractPaymentScheduleProcessMapper.xml
@@ -0,0 +1,22 @@
+<?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="com.by4cloud.platformx.business.mapper.ContractPaymentScheduleProcessMapper">
+
+  <resultMap id="contractPaymentScheduleProcessMap" type="com.by4cloud.platformx.business.entity.ContractPaymentScheduleProcess">
+        <id property="id" column="id"/>
+        <result property="compId" column="comp_id"/>
+        <result property="contractId" column="contract_id"/>
+        <result property="contractName" column="contract_name"/>
+        <result property="outBoundAttNames" column="out_bound_att_names"/>
+        <result property="outBoundAttPaths" column="out_bound_att_paths"/>
+        <result property="processDate" column="process_date"/>
+        <result property="scheduleId" column="schedule_id"/>
+        <result property="scheduleName" column="schedule_name"/>
+        <result property="createBy" column="create_by"/>
+        <result property="createTime" column="create_time"/>
+        <result property="updateBy" column="update_by"/>
+        <result property="updateTime" column="update_time"/>
+        <result property="delFlag" column="del_flag"/>
+  </resultMap>
+</mapper>
\ No newline at end of file

--
Gitblit v1.9.1