From 0527f90adf2aea086af681fb8f3dbf49c0a5ed31 Mon Sep 17 00:00:00 2001
From: shiyunteng <shiyunteng@example.com>
Date: 星期三, 27 五月 2026 17:21:27 +0800
Subject: [PATCH] feat:新增非主营业务水电代缴/房屋租赁合同

---
 platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/entity/ContractExecDate.java                 |   41 ++
 platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/entity/Contract.java                         |   18 +
 platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/dto/MeterReadRecordUpdateDTO.java            |   10 
 platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/entity/MeterReadRecord.java                  |   64 ++++
 platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/service/impl/MeterReadRecordServiceImpl.java |   92 ++++++
 platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/controller/MeterReadRecordController.java    |  124 ++++++++
 platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/controller/ContractController.java           |   12 
 platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/mapper/ContractExecDateMapper.java           |   11 
 platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/service/ContractService.java                 |    2 
 platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/dto/ContractSubjectMatterAddDTO.java         |   12 
 platformx-business-finance-biz/src/main/resources/mapper/MeterReadRecordMapper.xml                                        |   24 +
 platformx-business-finance-biz/src/main/resources/mapper/ContractExecDateMapper.xml                                       |   18 +
 platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/service/MeterReadRecordService.java          |   11 
 platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/mapper/MeterReadRecordMapper.java            |   11 
 platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/service/impl/ContractServiceImpl.java        |  284 +++++++++++++++-----
 platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/service/impl/PaymentConfirmServiceImpl.java  |    4 
 platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/dto/MeterReadRecordAddDTO.java               |   46 +++
 platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/entity/ContractSubjectMatter.java            |   17 +
 platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/dto/ContractAddDTO.java                      |   25 +
 19 files changed, 740 insertions(+), 86 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
index dc99a95..4b11d85 100644
--- 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
@@ -4,10 +4,12 @@
 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.Date;
 import java.util.List;
 
 @Data
@@ -48,15 +50,10 @@
 	@Schema(description = "鍚堝悓鏈嶅姟灞炴�э紙0-浜у搧閿�鍞� 1-鏃犲舰鏈嶅姟锛�")
 	private Integer contractAttribute;
 
-	@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm")
-	@JsonFormat(pattern = "yyyy-MM-dd HH:mm")
+	@DateTimeFormat(pattern = "yyyy-MM-dd")
+	@JsonFormat(pattern = "yyyy-MM-dd")
 	@Schema(description = "绛剧讲鏃ユ湡")
-	private String signDate;
-
-	@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm")
-	@JsonFormat(pattern = "yyyy-MM-dd HH:mm")
-	@Schema(description = "鐢熸晥鏃ユ湡")
-	private String effectiveDate;
+	private Date signDate;
 
 	@Schema(description = "浜や粯鍛ㄦ湡")
 	private Integer deliveryCycle;
@@ -75,6 +72,18 @@
 	@Schema(description = "妯$増ID")
 	private Long templateId;
 
+	@Schema(description = "鍚堝悓鍒嗙被")
+	private String contractCategory;
+
+	@Schema(description = "鎵ц鍛ㄦ湡 1/鍛� 2/鏈� 3/瀛e害 4/鍗婂勾 5/骞�")
+	private String execFrequency;
+
+	@Schema(description = "鎵ц娆℃暟")
+	private Integer execTimes;
+
+	@Schema(description = "鎵ц鏃ユ湡鍚庡灏戝ぉ鐢熸垚搴旀敹")
+	private Integer execDay;
+
 	private List<ContractPaymentScheduleAddDTO> contractPaymentSchedule;
 
 	private List<ContractSubjectMatterAddDTO> contractSubjectMatter;
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
index d5755a1..352d76f 100644
--- 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
@@ -27,4 +27,16 @@
 	@Schema(description = "鍗曚环")
 	private BigDecimal unitPrice;
 
+	@Schema(description = "鎶勮〃缂栧彿")
+	private String meterReadCode;
+
+	@Schema(description = "鎶勮〃鏁板瓧")
+	private BigDecimal meterReadNum;
+
+	@Schema(description = "鎶勮〃鍗曟嵁鍚嶇О")
+	private String meterReadAttNames;
+
+	@Schema(description = "鎶勮〃鍗曟嵁璺緞")
+	private String meterReadAttPaths;
+
 }
diff --git a/platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/dto/MeterReadRecordAddDTO.java b/platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/dto/MeterReadRecordAddDTO.java
new file mode 100644
index 0000000..89fc3bf
--- /dev/null
+++ b/platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/dto/MeterReadRecordAddDTO.java
@@ -0,0 +1,46 @@
+package com.by4cloud.platformx.business.dto;
+
+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.math.BigDecimal;
+import java.util.Date;
+
+@Data
+public class MeterReadRecordAddDTO {
+
+	@Schema(description = "鍏宠仈鍚堝悓ID")
+	private Long contractId;
+
+	@Schema(description = "鍏宠仈鏍囩殑鐗㊣D")
+	private Long matterId;
+
+	@Schema(description = "鍚堝悓鍚嶇О")
+	private String contractName;
+
+	@Schema(description = "瀹㈠晢鍚嶇О")
+	private String busGuestName;
+
+	@Schema(description = "瀹㈠晢ID")
+	private Long busGuestId;
+
+	@Schema(description = "鎶勮〃缂栧彿")
+	private String meterReadCode;
+
+	@Schema(description = "鎶勮〃鏁板瓧")
+	private BigDecimal meterReadNum;
+
+	@Schema(description = "鎶勮〃鏃堕棿")
+	@JsonFormat(pattern = "yyyy-MM-dd HH:mm")
+	@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm")
+	private Date meterReadTime;
+
+	@Schema(description = "鎶勮〃鍗曟嵁鍚嶇О")
+	private String meterReadAttNames;
+
+	@Schema(description = "鎶勮〃鍗曟嵁璺緞")
+	private String meterReadAttPaths;
+
+}
diff --git a/platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/dto/MeterReadRecordUpdateDTO.java b/platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/dto/MeterReadRecordUpdateDTO.java
new file mode 100644
index 0000000..031d439
--- /dev/null
+++ b/platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/dto/MeterReadRecordUpdateDTO.java
@@ -0,0 +1,10 @@
+package com.by4cloud.platformx.business.dto;
+
+import lombok.Data;
+
+@Data
+public class MeterReadRecordUpdateDTO extends MeterReadRecordAddDTO{
+
+	private Long id;
+
+}
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 eeaccdb..533c01b 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
@@ -159,7 +159,23 @@
 	@Column(columnDefinition = "decimal(10,2) comment '宸蹭粯娆鹃噾棰�'")
 	private BigDecimal paidAmount;
 
-    /**
+	@Schema(description = "鍚堝悓鍒嗙被")
+	@Column(columnDefinition = "VARCHAR(64) comment '鍚堝悓鍒嗙被 water_house 姘寸數鎴垮眿绉熻祦'")
+	private String contractCategory;
+
+	@Schema(description = "鎵ц鍛ㄦ湡")
+	@Column(columnDefinition = "char comment '鎵ц鍛ㄦ湡 1/鍛� 2/鏈� 3/瀛e害 4/鍗婂勾 5/骞�'")
+	private String execFrequency;
+
+	@Schema(description = "鎵ц娆℃暟")
+	@Column(columnDefinition = "int comment '鍚堝悓鍒嗙被 water_house 姘寸數鎴垮眿绉熻祦'")
+	private Integer execTimes;
+
+	@Schema(description = "鎵ц鏃ユ湡鍚庡灏戝ぉ鐢熸垚搴旀敹")
+	@Column(columnDefinition = "int comment '鎵ц鏃ユ湡鍚庡灏戝ぉ鐢熸垚搴旀敹'")
+	private Integer execDay;
+
+	/**
      * 涓存椂瀛楁 - 鐢ㄤ簬鎺ユ敹瀹℃壒浜哄悕绉扮瓑鍏宠仈鏌ヨ缁撴灉
      */
     @Transient
diff --git a/platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/entity/ContractExecDate.java b/platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/entity/ContractExecDate.java
new file mode 100644
index 0000000..bb876bf
--- /dev/null
+++ b/platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/entity/ContractExecDate.java
@@ -0,0 +1,41 @@
+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 lombok.Data;
+import org.hibernate.annotations.Table;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * 2026骞�4鏈�29鏃� 10:46:07
+ * syt
+ */
+@Data
+@Entity//鍔犱簡鎵嶈兘鑷姩鐢熸垚琛�
+@Table(appliesTo="contract_exec_date",comment = "鍛ㄦ湡鍚堝悓鎵ц鏃�")//缁欒〃鍔犳敞閲�
+@jakarta.persistence.Table(name = "contract_exec_date")//鏁版嵁搴撳垱寤虹殑琛ㄦ槑
+public class ContractExecDate extends BaseModel<ContractExecDate> {
+
+	@Schema(description = "鍏宠仈鍚堝悓ID")
+	@Column(columnDefinition = "bigint not null comment '鍏宠仈鍚堝悓ID'")
+	private Long contractId;
+
+	@Schema(description = "鍏宠仈鏍囩殑鐗㊣D")
+	@Column(columnDefinition = "bigint not null comment '鍏宠仈鏍囩殑鐗㊣D'")
+	private Long matterId;
+
+	@Schema(description = "鎵ц鏃ユ湡")
+	@Column(columnDefinition="date comment '鎵ц鏃ユ湡'")
+	@JsonFormat(pattern = "yyyy-MM-dd")
+	private Date execDate;
+
+	@Schema(description = "鐢熸垚鏍囪瘑")
+	@Column(columnDefinition="char comment '鐢熸垚鏍囪瘑 0/鏈敓 1/宸茬敓'")
+	private String genFlag;
+
+}
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 cede782..12ac3db 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
@@ -14,6 +14,7 @@
 import org.springframework.format.annotation.DateTimeFormat;
 
 import java.math.BigDecimal;
+import java.util.Date;
 
 /**
  * 鍚堝悓鏍囩殑鐗╂槑缁嗗疄浣撶被
@@ -156,4 +157,20 @@
 	@Schema(description = "鏈�杩戜竴娆′氦浠樻暟閲�")
 	@Column(columnDefinition = "decimal(10,2) comment '鏈�杩戜竴娆′氦浠樻暟閲�'")
 	private BigDecimal lastDeliveredQuantity;
+
+	@Schema(description = "鎶勮〃缂栧彿")
+	@Column(columnDefinition="VARCHAR(64) comment '鎶勮〃琛ㄥ彿'")
+	private String meterReadCode;
+
+	@Schema(description = "鎶勮〃鏁板瓧")
+	@Column(columnDefinition="decimal(10,0) comment '鎶勮〃鏁板瓧'")
+	private BigDecimal meterReadNum;
+
+	@Schema(description = "鎶勮〃鍗曟嵁鍚嶇О")
+	@Column(columnDefinition="text comment '鍗曟嵁鍚嶇О'")
+	private String meterReadAttNames;
+
+	@Schema(description = "鎶勮〃鍗曟嵁璺緞")
+	@Column(columnDefinition="text comment '鍗曟嵁璺緞'")
+	private String meterReadAttPaths;
 }
\ No newline at end of file
diff --git a/platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/entity/MeterReadRecord.java b/platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/entity/MeterReadRecord.java
new file mode 100644
index 0000000..cd274fb
--- /dev/null
+++ b/platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/entity/MeterReadRecord.java
@@ -0,0 +1,64 @@
+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 lombok.Data;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * 2026骞�5鏈�27鏃� 10:40:16
+ * syt
+ */
+@Data
+@Entity//鍔犱簡鎵嶈兘鑷姩鐢熸垚琛�
+@org.hibernate.annotations.Table(appliesTo="meter_read_record",comment = "姘寸數鎶勮〃璁板綍")//缁欒〃鍔犳敞閲�
+@jakarta.persistence.Table(name = "meter_read_record")//鏁版嵁搴撳垱寤虹殑琛ㄦ槑
+public class MeterReadRecord  extends BaseModel<MeterReadRecord>{
+
+	@Schema(description = "鍏宠仈鍚堝悓ID")
+	@Column(columnDefinition = "bigint not null comment '鍏宠仈鍚堝悓ID'")
+	private Long contractId;
+
+	@Schema(description = "鍏宠仈鏍囩殑鐗㊣D")
+	@Column(columnDefinition = "bigint not null comment '鍏宠仈鏍囩殑鐗㊣D'")
+	private Long matterId;
+
+	@Schema(description = "鍚堝悓鍚嶇О")
+	@Column(columnDefinition = "VARCHAR(64) comment '鍚堝悓鍚嶇О'")
+	private String contractName;
+
+	@Schema(description = "瀹㈠晢鍚嶇О")
+	@Column(columnDefinition="VARCHAR(64) comment '瀹㈠晢鍚嶇О'")
+	private String busGuestName;
+
+	@Schema(description = "瀹㈠晢ID")
+	@Column(columnDefinition="bigint comment '瀹㈠晢ID'")
+	private Long busGuestId;
+
+	@Schema(description = "鎶勮〃缂栧彿")
+	@Column(columnDefinition="VARCHAR(64) comment '鎶勮〃鏁板瓧'")
+	private String meterReadCode;
+
+	@Schema(description = "鎶勮〃鏁板瓧")
+	@Column(columnDefinition="decimal(10,0) comment '鎶勮〃鏁板瓧'")
+	private BigDecimal meterReadNum;
+
+	@Schema(description = "鎶勮〃鏃堕棿")
+	@Column(columnDefinition="datetime comment '鍑哄簱鏃堕棿'")
+	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+	private Date meterReadTime;
+
+	@Schema(description = "鎶勮〃鍗曟嵁鍚嶇О")
+	@Column(columnDefinition="text comment '鍗曟嵁鍚嶇О'")
+	private String meterReadAttNames;
+
+	@Schema(description = "鎶勮〃鍗曟嵁璺緞")
+	@Column(columnDefinition="text comment '鍗曟嵁璺緞'")
+	private String meterReadAttPaths;
+
+}
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 1608d7e..ef61fb2 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
@@ -143,7 +143,7 @@
 
 
 	/**
-	 * 瀹氭椂鐢熸垚搴旀敹娆捐处鐩�
+	 * 瀹氭椂鐢熸垚搴旀敹閫炬湡
 	 * @return R
 	 */
 	@GetMapping("/genCurrentOverdue" )
@@ -153,6 +153,16 @@
 	}
 
 	/**
+	 * 瀹氭椂鐢熸垚鍛ㄦ湡鎬у簲鏀�
+	 * @return R
+	 */
+	@GetMapping("/genCycleReceiced" )
+	@Inner(value = false)
+	public R genCycleReceiced() {
+		return contractService.genCycleReceiced();
+	}
+
+	/**
 	 * 鐢熸垚鏂板悎鍚�
 	 * @param id id
 	 * @return R
diff --git a/platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/controller/MeterReadRecordController.java b/platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/controller/MeterReadRecordController.java
new file mode 100644
index 0000000..1128128
--- /dev/null
+++ b/platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/controller/MeterReadRecordController.java
@@ -0,0 +1,124 @@
+package com.by4cloud.platformx.business.controller;
+
+import cn.hutool.core.util.StrUtil;
+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.MeterReadRecordUpdateDTO;
+import com.by4cloud.platformx.common.core.util.R;
+import com.by4cloud.platformx.common.log.annotation.SysLog;
+import com.by4cloud.platformx.business.entity.MeterReadRecord;
+import com.by4cloud.platformx.business.service.MeterReadRecordService;
+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-27 13:58:57
+ */
+@RestController
+@RequiredArgsConstructor
+@RequestMapping("/meterReadRecord" )
+@Tag(description = "meterReadRecord" , name = "姘寸數鎶勮〃绠$悊" )
+@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)
+public class MeterReadRecordController {
+
+    private final  MeterReadRecordService meterReadRecordService;
+
+    /**
+     * 鍒嗛〉鏌ヨ
+     * @param page 鍒嗛〉瀵硅薄
+     * @param meterReadRecord 姘寸數鎶勮〃
+     * @return
+     */
+    @Operation(summary = "鍒嗛〉鏌ヨ" , description = "鍒嗛〉鏌ヨ" )
+    @GetMapping("/page" )
+    @PreAuthorize("@pms.hasPermission('business_meterReadRecord_view')" )
+    public R getMeterReadRecordPage(@ParameterObject Page page, @ParameterObject MeterReadRecord meterReadRecord) {
+        LambdaQueryWrapper<MeterReadRecord> wrapper = Wrappers.lambdaQuery();
+		wrapper.like(StrUtil.isNotBlank(meterReadRecord.getBusGuestName()),MeterReadRecord::getBusGuestName,meterReadRecord.getBusGuestName());
+		wrapper.like(StrUtil.isNotBlank(meterReadRecord.getContractName()),MeterReadRecord::getContractName,meterReadRecord.getContractName());
+		wrapper.orderByDesc(MeterReadRecord::getCreateTime);
+        return R.ok(meterReadRecordService.page(page, wrapper));
+    }
+
+
+    /**
+     * 閫氳繃id鏌ヨ姘寸數鎶勮〃
+     * @param id id
+     * @return R
+     */
+    @Operation(summary = "閫氳繃id鏌ヨ" , description = "閫氳繃id鏌ヨ" )
+    @GetMapping("/{id}" )
+    @PreAuthorize("@pms.hasPermission('business_meterReadRecord_view')" )
+    public R getById(@PathVariable("id" ) Long id) {
+        return R.ok(meterReadRecordService.getById(id));
+    }
+
+    /**
+     * 鏂板姘寸數鎶勮〃
+     * @param meterReadRecord 姘寸數鎶勮〃
+     * @return R
+     */
+    @Operation(summary = "鏂板姘寸數鎶勮〃" , description = "鏂板姘寸數鎶勮〃" )
+    @SysLog("鏂板姘寸數鎶勮〃" )
+    @PostMapping
+    @PreAuthorize("@pms.hasPermission('business_meterReadRecord_add')" )
+    public R save(@RequestBody MeterReadRecord meterReadRecord) {
+        return R.ok(meterReadRecordService.save(meterReadRecord));
+    }
+
+    /**
+     * 淇敼姘寸數鎶勮〃
+     * @param updateDTO 姘寸數鎶勮〃
+     * @return R
+     */
+    @Operation(summary = "淇敼姘寸數鎶勮〃" , description = "淇敼姘寸數鎶勮〃" )
+    @SysLog("淇敼姘寸數鎶勮〃" )
+    @PutMapping
+    @PreAuthorize("@pms.hasPermission('business_meterReadRecord_edit')" )
+    public R updateById(@RequestBody MeterReadRecordUpdateDTO updateDTO) {
+        return meterReadRecordService.edit(updateDTO);
+    }
+
+    /**
+     * 閫氳繃id鍒犻櫎姘寸數鎶勮〃
+     * @param ids id鍒楄〃
+     * @return R
+     */
+    @Operation(summary = "閫氳繃id鍒犻櫎姘寸數鎶勮〃" , description = "閫氳繃id鍒犻櫎姘寸數鎶勮〃" )
+    @SysLog("閫氳繃id鍒犻櫎姘寸數鎶勮〃" )
+    @DeleteMapping
+    @PreAuthorize("@pms.hasPermission('business_meterReadRecord_del')" )
+    public R removeById(@RequestBody Long[] ids) {
+        return R.ok(meterReadRecordService.removeBatchByIds(CollUtil.toList(ids)));
+    }
+
+
+    /**
+     * 瀵煎嚭excel 琛ㄦ牸
+     * @param meterReadRecord 鏌ヨ鏉′欢
+   	 * @param ids 瀵煎嚭鎸囧畾ID
+     * @return excel 鏂囦欢娴�
+     */
+    @ResponseExcel
+    @GetMapping("/export")
+    @PreAuthorize("@pms.hasPermission('business_meterReadRecord_export')" )
+    public List<MeterReadRecord> export(MeterReadRecord meterReadRecord,Long[] ids) {
+        return meterReadRecordService.list(Wrappers.lambdaQuery(meterReadRecord).in(ArrayUtil.isNotEmpty(ids), MeterReadRecord::getId, ids));
+    }
+}
\ No newline at end of file
diff --git a/platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/mapper/ContractExecDateMapper.java b/platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/mapper/ContractExecDateMapper.java
new file mode 100644
index 0000000..e4f0397
--- /dev/null
+++ b/platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/mapper/ContractExecDateMapper.java
@@ -0,0 +1,11 @@
+package com.by4cloud.platformx.business.mapper;
+
+import com.by4cloud.platformx.business.entity.ContractExecDate;
+import com.by4cloud.platformx.common.data.datascope.PlatformxBaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+
+@Mapper
+public interface ContractExecDateMapper extends PlatformxBaseMapper<ContractExecDate> {
+
+
+}
\ No newline at end of file
diff --git a/platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/mapper/MeterReadRecordMapper.java b/platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/mapper/MeterReadRecordMapper.java
new file mode 100644
index 0000000..813a46f
--- /dev/null
+++ b/platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/mapper/MeterReadRecordMapper.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.MeterReadRecord;
+import org.apache.ibatis.annotations.Mapper;
+
+@Mapper
+public interface MeterReadRecordMapper extends PlatformxBaseMapper<MeterReadRecord> {
+
+
+}
\ 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 4110226..1e2679d 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
@@ -36,4 +36,6 @@
 	 * @param response
 	 */
 	void exportContractYMJJGCLWord(Long id,HttpServletResponse response);
+
+	R genCycleReceiced();
 }
diff --git a/platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/service/MeterReadRecordService.java b/platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/service/MeterReadRecordService.java
new file mode 100644
index 0000000..6cd1a8c
--- /dev/null
+++ b/platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/service/MeterReadRecordService.java
@@ -0,0 +1,11 @@
+package com.by4cloud.platformx.business.service;
+
+import com.by4cloud.platformx.business.dto.MeterReadRecordUpdateDTO;
+import com.by4cloud.platformx.business.entity.MeterReadRecord;
+import com.by4cloud.platformx.common.core.util.R;
+import com.by4cloud.platformx.common.data.mybatis.IIService;
+
+public interface MeterReadRecordService extends IIService<MeterReadRecord> {
+
+    R edit(MeterReadRecordUpdateDTO updateDTO);
+}
\ 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 fd7e0b9..029813d 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
@@ -55,6 +55,8 @@
 	private final PaymentConfirmMapper paymentConfirmMapper;
 	private final CurrentOverdueMapper currentOverdueMapper;
 	private final BusinessCustomerMapper businessCustomerMapper;
+	private final MeterReadRecordMapper meterReadRecordMapper;
+	private final ContractExecDateMapper contractExecDateMapper;
 	private final RemoteFlowProcessService remoteFlowProcessService;
 	private final ContractTemplateMapper contractTemplateMapper;
 	private final RemoteDeptService remoteDeptService;
@@ -88,7 +90,20 @@
 				subjectMatter.setDeliveryStatus(0);
 				subjectMatter.setTotalAmount(contractSubjectMatterAddDTO.getQuantity().multiply(contractSubjectMatterAddDTO.getUnitPrice()));
 				contractSubjectMatterMapper.insert(subjectMatter);
+				//姘寸數绫诲繀椤绘湁鍒濇琛ㄥ彿
+				if (StrUtil.isNotEmpty(contractSubjectMatterAddDTO.getMeterReadCode()) &&
+						ObjUtil.isNotNull(contractSubjectMatterAddDTO.getMeterReadNum())) {
+					MeterReadRecord record = BeanUtil.copyProperties(contractSubjectMatterAddDTO, MeterReadRecord.class,"id");
+					record.setContractId(contract.getId());
+					record.setMatterId(subjectMatter.getId());
+					record.setContractName(contract.getContractName());
+					record.setBusGuestId(contract.getPartyAId());
+					record.setBusGuestName(contract.getPartyA());
+					record.setMeterReadTime(new Date());
+					meterReadRecordMapper.insert(record);
+				}
 			});
+
 		}
 
 		if (ArrayUtil.isNotEmpty(addDTO.getContractPaymentSchedule())) {
@@ -128,6 +143,9 @@
 
 		}
 
+		if (StrUtil.isNotEmpty(addDTO.getContractCategory()) && StrUtil.equals(addDTO.getContractCategory(), "water_house")) {
+
+		}
 
 		return R.ok();
 	}
@@ -228,20 +246,78 @@
 		Contract contract = baseMapper.selectById(id);
 		contract.setContractStatus(2);
 		baseMapper.updateById(contract);
-		ContractPaymentSchedule fitstSchedule = contractPaymentScheduleMapper.selectOne(Wrappers.<ContractPaymentSchedule>lambdaQuery().eq(ContractPaymentSchedule::getContractId, contract.getId())
-				.orderByAsc(ContractPaymentSchedule::getCreateTime).last("limit 1"));
-		if (fitstSchedule.getStageName().equals("鍚堝悓绛捐")) {
-			//鏂板搴旀敹
-			savePaymentConfirm(contract, fitstSchedule);
+		if (StrUtil.isNotEmpty(contract.getContractCategory()) && StrUtil.equals(contract.getContractCategory(), "water_house")) {
+			List<ContractSubjectMatter> subjectMatterList = contractSubjectMatterMapper.selectList(Wrappers.<ContractSubjectMatter>lambdaQuery()
+					.eq(ContractSubjectMatter::getContractId,id));
+			if (ArrayUtil.isNotEmpty(subjectMatterList.toArray())) {
+				subjectMatterList.stream().forEach(contractSubjectMatter -> {
 
-			//鏂板鍚堝悓灞ョ害璁板綍
-			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);
+					//寰幆鏃ユ湡
+					Date execDate0 = DateUtil.offsetDay(contract.getSignDate(), contract.getExecDay());
+					for (int i = 0; i < contract.getExecTimes(); i++) {
+						if (StrUtil.equals(contract.getExecFrequency(), "1")) {
+							Date execDatei = DateUtil.offsetWeek(execDate0, i);
+							ContractExecDate execDate = new ContractExecDate();
+							execDate.setContractId(contract.getId());
+							execDate.setMatterId(contractSubjectMatter.getId());
+							execDate.setExecDate(execDatei);
+							execDate.setGenFlag("0");
+							contractExecDateMapper.insert(execDate);
+						}
+						if (StrUtil.equals(contract.getExecFrequency(), "2")) {
+							Date execDatei = DateUtil.offsetMonth(execDate0, i );
+							ContractExecDate execDate = new ContractExecDate();
+							execDate.setContractId(contract.getId());
+							execDate.setMatterId(contractSubjectMatter.getId());
+							execDate.setExecDate(execDatei);
+							execDate.setGenFlag("0");
+							contractExecDateMapper.insert(execDate);
+						}
+						if (StrUtil.equals(contract.getExecFrequency(), "3")) {
+							Date execDatei = DateUtil.offsetMonth(execDate0, i * 3);
+							ContractExecDate execDate = new ContractExecDate();
+							execDate.setContractId(contract.getId());
+							execDate.setMatterId(contractSubjectMatter.getId());
+							execDate.setExecDate(execDatei);
+							execDate.setGenFlag("0");
+							contractExecDateMapper.insert(execDate);
+						}
+						if (StrUtil.equals(contract.getExecFrequency(), "4")) {
+							Date execDatei = DateUtil.offsetMonth(execDate0, i * 6);
+							ContractExecDate execDate = new ContractExecDate();
+							execDate.setContractId(contract.getId());
+							execDate.setMatterId(contractSubjectMatter.getId());
+							execDate.setExecDate(execDatei);
+							execDate.setGenFlag("0");
+							contractExecDateMapper.insert(execDate);
+						}
+						if (StrUtil.equals(contract.getExecFrequency(), "5")) {
+							Date execDatei = DateUtil.offsetYear(execDate0, i);
+							ContractExecDate execDate = new ContractExecDate();
+							execDate.setContractId(contract.getId());
+							execDate.setMatterId(contractSubjectMatter.getId());
+							execDate.setExecDate(execDatei);
+							execDate.setGenFlag("0");
+							contractExecDateMapper.insert(execDate);
+						}
+					}
+				});
+			}
+		} else {
+			ContractPaymentSchedule fitstSchedule = contractPaymentScheduleMapper.selectOne(Wrappers.<ContractPaymentSchedule>lambdaQuery().eq(ContractPaymentSchedule::getContractId, contract.getId())
+					.orderByAsc(ContractPaymentSchedule::getCreateTime).last("limit 1"));
+			if (fitstSchedule.getStageName().equals("鍚堝悓绛捐")) {
+				//鏂板搴旀敹
+				savePaymentConfirm(contract, fitstSchedule);
+
+				//鏂板鍚堝悓灞ョ害璁板綍
+				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);
 //			//褰撳墠涓哄悎鍚屾渶鍚庨樁娈�
 //			PaymentConfirm newConfirm = paymentConfirmMapper.selectOne(Wrappers.<PaymentConfirm>lambdaQuery().eq(PaymentConfirm::getContractId,contract.getId())
 //					.orderByDesc(PaymentConfirm::getCreateTime).last("limit 1"));
@@ -250,74 +326,75 @@
 //				contract.setContractStatus(3);
 //				baseMapper.updateById(contract);
 //			}
-		} else if (fitstSchedule.getStageName().equals("鍙戣揣鍓�")) {
-			//鏇存柊鍚堝悓涓嬩釜闃舵
-			contract.setNextScheduleName("鏃�");
-			baseMapper.updateById(contract);
-		} else if (fitstSchedule.getStageName().equals("璐у埌绛炬敹")) {
-			//鏇存柊鍚堝悓涓嬩釜闃舵
-			contract.setNextScheduleName("璐у埌绛炬敹");
-			baseMapper.updateById(contract);
-		} else if (fitstSchedule.getStageName().equals("璋冭瘯瀹屾垚鎴栭獙鏀�")) {
-			//鏇存柊鍚堝悓涓嬩釜闃舵
-			contract.setNextScheduleName("璋冭瘯瀹屾垚鎴栭獙鏀�");
-			baseMapper.updateById(contract);
-		} else {
-			//鏂板搴旀敹
-			savePaymentConfirm(contract, fitstSchedule);
-		}
-		//鏌ヨ鏄惁鏈夊悗缁樁娈�
-		List<ContractPaymentSchedule> afterSchedule = contractPaymentScheduleMapper.selectList(Wrappers.<ContractPaymentSchedule>lambdaQuery()
-				.eq(ContractPaymentSchedule::getContractId, fitstSchedule.getContractId())
-				.gt(ContractPaymentSchedule::getStageOrder, fitstSchedule.getStageOrder())
-				.orderByAsc(ContractPaymentSchedule::getCreateTime));
-		if (ArrayUtil.isNotEmpty(afterSchedule.toArray()) && afterSchedule.size() == 1) {
-			//鏈�鍚庨樁娈电敓鏁堟椂闂�
-			ContractPaymentSchedule endSchedule = afterSchedule.get(0);
-			if (StrUtil.equals(endSchedule.getStageName(), "璐ㄤ繚閲�")) {
+			} else if (fitstSchedule.getStageName().equals("鍙戣揣鍓�")) {
+				//鏇存柊鍚堝悓涓嬩釜闃舵
+				contract.setNextScheduleName("鏃�");
+				baseMapper.updateById(contract);
+			} else if (fitstSchedule.getStageName().equals("璐у埌绛炬敹")) {
+				//鏇存柊鍚堝悓涓嬩釜闃舵
+				contract.setNextScheduleName("璐у埌绛炬敹");
+				baseMapper.updateById(contract);
+			} else if (fitstSchedule.getStageName().equals("璋冭瘯瀹屾垚鎴栭獙鏀�")) {
+				//鏇存柊鍚堝悓涓嬩釜闃舵
+				contract.setNextScheduleName("璋冭瘯瀹屾垚鎴栭獙鏀�");
+				baseMapper.updateById(contract);
+			} else {
+				//鏂板搴旀敹
+				savePaymentConfirm(contract, fitstSchedule);
+			}
+			//鏌ヨ鏄惁鏈夊悗缁樁娈�
+			List<ContractPaymentSchedule> afterSchedule = contractPaymentScheduleMapper.selectList(Wrappers.<ContractPaymentSchedule>lambdaQuery()
+					.eq(ContractPaymentSchedule::getContractId, fitstSchedule.getContractId())
+					.gt(ContractPaymentSchedule::getStageOrder, fitstSchedule.getStageOrder())
+					.orderByAsc(ContractPaymentSchedule::getCreateTime));
+			if (ArrayUtil.isNotEmpty(afterSchedule.toArray()) && afterSchedule.size() == 1) {
+				//鏈�鍚庨樁娈电敓鏁堟椂闂�
+				ContractPaymentSchedule endSchedule = afterSchedule.get(0);
+				if (StrUtil.equals(endSchedule.getStageName(), "璐ㄤ繚閲�")) {
 //				endSchedule.setEffectiveEndDate(DateUtil.offsetDay(new Date(),endSchedule.getAgreedDays()));
 //				contractPaymentScheduleMapper.updateById(endSchedule);
-				//鏈�鍚庨樁娈靛簲鏀�
-				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();
+					//鏈�鍚庨樁娈靛簲鏀�
+					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()));
+					if (endSchedule.getPaymentRatio().compareTo(new BigDecimal("0")) > 0) {
+						paymentConfirmMapper.insert(newConfim);
+					}
 				}
-				newConfim.setTotalAmount(lastNewTotal.subtract(newConfim.getReceivableAmount()));
-				if (endSchedule.getPaymentRatio().compareTo(new BigDecimal("0")) > 0) {
-					paymentConfirmMapper.insert(newConfim);
-				}
+				//鏇存柊鍚堝悓涓嬩釜闃舵
+				contract.setNextScheduleName(endSchedule.getStageName());
+				baseMapper.updateById(contract);
 			}
-			//鏇存柊鍚堝悓涓嬩釜闃舵
-			contract.setNextScheduleName(endSchedule.getStageName());
-			baseMapper.updateById(contract);
-		}
-		if (ArrayUtil.isNotEmpty(afterSchedule.toArray()) && afterSchedule.size() > 1) {
-			//绗竴闃舵鐢熸晥鏃堕棿
+			if (ArrayUtil.isNotEmpty(afterSchedule.toArray()) && afterSchedule.size() > 1) {
+				//绗竴闃舵鐢熸晥鏃堕棿
 //			fitstSchedule.setEffectiveEndDate(DateUtil.offsetDay(contract.getSignDate(),fitstSchedule.getAgreedDays()));
 //			contractPaymentScheduleMapper.updateById(fitstSchedule);
-			//鏇存柊鍚堝悓涓嬩釜闃舵
-			contract.setNextScheduleName(afterSchedule.get(0).getStageName());
-			baseMapper.updateById(contract);
-		}
-		//鍙湁褰撳墠鍚堝悓绛惧瓧闃舵
+				//鏇存柊鍚堝悓涓嬩釜闃舵
+				contract.setNextScheduleName(afterSchedule.get(0).getStageName());
+				baseMapper.updateById(contract);
+			}
+			//鍙湁褰撳墠鍚堝悓绛惧瓧闃舵
 //		if(ArrayUtil.isEmpty(afterSchedule.toArray())){
 //			fitstSchedule.setEffectiveEndDate(DateUtil.offsetDay(contract.getSignDate(),fitstSchedule.getAgreedDays()));
 //			contractPaymentScheduleMapper.updateById(fitstSchedule);
 //		}
+		}
 	}
 
 	private void savePaymentConfirm(Contract contract, ContractPaymentSchedule schedule) {
@@ -378,9 +455,9 @@
 				//鏇存柊褰撳墠闃舵瀹為檯鏀舵 鍜� 鏀舵鐘舵��
 				schedule.setActualAmount(inConfirm.getTransationAmount());
 				schedule.setPaymentStatus(2);
-				if (inConfirm.getTotalAmount().compareTo(new BigDecimal("0")) > 0){
+				if (inConfirm.getTotalAmount().compareTo(new BigDecimal("0")) > 0) {
 					inConfirm.setAdvanceAmount(inConfirm.getTotalAmount());
-				}else if (inConfirm.getTotalAmount().compareTo(new BigDecimal("0")) < 0) {
+				} else if (inConfirm.getTotalAmount().compareTo(new BigDecimal("0")) < 0) {
 					inConfirm.setReceivableAmount(inConfirm.getTotalAmount().multiply(new BigDecimal("-1")));
 					schedule.setActualAmount(currentInSum);
 					schedule.setPaymentStatus(1);
@@ -391,7 +468,7 @@
 			}
 
 
-		}else {
+		} else {
 			paymentConfirmMapper.insert(paymentConfirm);
 		}
 	}
@@ -592,4 +669,63 @@
 			e.printStackTrace();
 		}
 	}
+
+	@Override
+	public R genCycleReceiced() {
+		List<ContractExecDate> execDateList = contractExecDateMapper.selectList(Wrappers.<ContractExecDate>lambdaQuery()
+				.le(ContractExecDate::getExecDate, DateUtil.today()).eq(ContractExecDate::getGenFlag,"0"));
+		if (ArrayUtil.isNotEmpty(execDateList.toArray())) {
+			execDateList.stream().forEach(contractExecDate -> {
+				Contract contract = baseMapper.selectById(contractExecDate.getContractId());
+				ContractSubjectMatter subjectMatter = contractSubjectMatterMapper.selectOne(Wrappers.<ContractSubjectMatter>lambdaQuery()
+						.eq(ContractSubjectMatter::getContractId, contractExecDate.getContractId())
+						.eq(ContractSubjectMatter::getId, contractExecDate.getMatterId()));
+				//鐢熸垚鎶勮〃鍗�
+				if (StrUtil.isNotEmpty(subjectMatter.getMeterReadCode()) &&
+						ObjUtil.isNotNull(subjectMatter.getMeterReadNum())) {
+					MeterReadRecord record = BeanUtil.copyProperties(subjectMatter, MeterReadRecord.class, "id","meterReadNum");
+					record.setMatterId(subjectMatter.getId());
+					record.setBusGuestId(contract.getPartyAId());
+					record.setBusGuestName(contract.getPartyA());
+					meterReadRecordMapper.insert(record);
+				}else {
+					//鎴垮眿绉熻祦鐢熸垚搴旀敹
+					PaymentConfirm confirm = new PaymentConfirm();
+					confirm.setBusinessType("鎴垮眿绉熻祦搴旀敹");
+					confirm.setBusGuestId(contract.getPartyAId());
+					confirm.setBusGuestName(contract.getPartyA());
+					confirm.setContractId(contract.getId());
+					confirm.setContractName(contract.getContractName());
+					confirm.setContractNo(contract.getContractNo());
+					confirm.setConfirmTime(contractExecDate.getExecDate());
+					confirm.setTransationAmount(subjectMatter.getUnitPrice().multiply(subjectMatter.getQuantity()));
+					confirm.setTotalAmount(confirm.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)) {
+						BigDecimal total = lastConfirm.getTotalAmount().add(confirm.getTotalAmount());
+						if (total.compareTo(new BigDecimal("0")) > 0) {
+							confirm.setAdvanceAmount(total);
+							confirm.setTotalAmount(total);
+						} else if (total.compareTo(new BigDecimal("0")) == 0) {
+							confirm.setTotalAmount(total);
+						} else {
+							confirm.setReceivableAmount(total.multiply(new BigDecimal("-1")));
+							confirm.setTotalAmount(total);
+						}
+						confirm.setCompId(contract.getCompId());
+						paymentConfirmMapper.insert(confirm);
+					} else {
+						confirm.setReceivableAmount(confirm.getTransationAmount());
+						confirm.setTotalAmount(confirm.getReceivableAmount().multiply(new BigDecimal("-1")));
+						confirm.setCompId(contract.getCompId());
+						paymentConfirmMapper.insert(confirm);
+					}
+				}
+				contractExecDate.setGenFlag("1");
+				contractExecDateMapper.updateById(contractExecDate);
+			});
+		}
+		return R.ok();
+	}
 }
diff --git a/platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/service/impl/MeterReadRecordServiceImpl.java b/platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/service/impl/MeterReadRecordServiceImpl.java
new file mode 100644
index 0000000..ffcb0f5
--- /dev/null
+++ b/platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/service/impl/MeterReadRecordServiceImpl.java
@@ -0,0 +1,92 @@
+package com.by4cloud.platformx.business.service.impl;
+
+import cn.hutool.core.util.ObjUtil;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.by4cloud.platformx.business.dto.MeterReadRecordUpdateDTO;
+import com.by4cloud.platformx.business.entity.Contract;
+import com.by4cloud.platformx.business.entity.ContractSubjectMatter;
+import com.by4cloud.platformx.business.entity.MeterReadRecord;
+import com.by4cloud.platformx.business.entity.PaymentConfirm;
+import com.by4cloud.platformx.business.mapper.ContractMapper;
+import com.by4cloud.platformx.business.mapper.ContractSubjectMatterMapper;
+import com.by4cloud.platformx.business.mapper.MeterReadRecordMapper;
+import com.by4cloud.platformx.business.mapper.PaymentConfirmMapper;
+import com.by4cloud.platformx.business.service.MeterReadRecordService;
+import com.by4cloud.platformx.common.core.util.R;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+
+import java.math.BigDecimal;
+
+/**
+ * 姘寸數鎶勮〃
+ *
+ * @author syt
+ * @date 2026-05-27 13:58:57
+ */
+@Service
+@RequiredArgsConstructor
+public class MeterReadRecordServiceImpl extends ServiceImpl<MeterReadRecordMapper, MeterReadRecord> implements MeterReadRecordService {
+
+	private final ContractMapper contractMapper;
+	private final ContractSubjectMatterMapper contractSubjectMatterMapper;
+	private final PaymentConfirmMapper paymentConfirmMapper;
+
+	@Override
+	public R edit(MeterReadRecordUpdateDTO updateDTO) {
+		MeterReadRecord record = baseMapper.selectById(updateDTO.getId());
+		MeterReadRecord lastRecord = baseMapper.selectOne(Wrappers.<MeterReadRecord>lambdaQuery().eq(MeterReadRecord::getContractId,updateDTO.getContractId())
+				.eq(MeterReadRecord::getMeterReadCode,updateDTO.getMeterReadCode()).lt(MeterReadRecord::getCreateTime,record.getCreateTime())
+				.orderByDesc(MeterReadRecord::getCreateTime).last("limit 1"));
+		if(ObjUtil.isNull(lastRecord)){
+			return R.failed("鏃犳渶杩戞妱鍙疯褰�");
+		}
+		if (updateDTO.getMeterReadNum().compareTo(lastRecord.getMeterReadNum())<0){
+			return R.failed("鎶勫彿鏁板瓧涓嶈兘姣斾笂娆″皯");
+		}
+		record.setMeterReadTime(updateDTO.getMeterReadTime());
+		record.setMeterReadNum(updateDTO.getMeterReadNum());
+		record.setMeterReadAttNames(updateDTO.getMeterReadAttNames());
+		record.setMeterReadAttPaths(updateDTO.getMeterReadAttPaths());
+		baseMapper.updateById(record);
+		//鎴垮眿绉熻祦鐢熸垚搴旀敹
+		Contract contract = contractMapper.selectById(updateDTO.getContractId());
+		ContractSubjectMatter subjectMatter = contractSubjectMatterMapper.selectById(updateDTO.getMatterId());
+		if(ObjUtil.isNull(lastRecord)){
+			R.failed("鏃犲悎鍚屼俊鎭紝璇疯仈绯绘妧鏈汉鍛�");
+		}
+		PaymentConfirm confirm = new PaymentConfirm();
+		confirm.setBusinessType(subjectMatter.getMaterialInternalName()+"搴旀敹");
+		confirm.setBusGuestId(contract.getPartyAId());
+		confirm.setBusGuestName(contract.getPartyA());
+		confirm.setContractId(contract.getId());
+		confirm.setContractName(contract.getContractName());
+		confirm.setContractNo(contract.getContractNo());
+		confirm.setConfirmTime(updateDTO.getMeterReadTime());
+		confirm.setTransationAmount(subjectMatter.getUnitPrice().multiply(updateDTO.getMeterReadNum().subtract(lastRecord.getMeterReadNum())));
+		confirm.setTotalAmount(confirm.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)) {
+			BigDecimal total = lastConfirm.getTotalAmount().add(confirm.getTotalAmount());
+			if (total.compareTo(new BigDecimal("0")) > 0) {
+				confirm.setAdvanceAmount(total);
+				confirm.setTotalAmount(total);
+			} else if (total.compareTo(new BigDecimal("0")) == 0) {
+				confirm.setTotalAmount(total);
+			} else {
+				confirm.setReceivableAmount(total.multiply(new BigDecimal("-1")));
+				confirm.setTotalAmount(total);
+			}
+			confirm.setCompId(contract.getCompId());
+			paymentConfirmMapper.insert(confirm);
+		} else {
+			confirm.setReceivableAmount(confirm.getTransationAmount());
+			confirm.setTotalAmount(confirm.getReceivableAmount().multiply(new BigDecimal("-1")));
+			confirm.setCompId(contract.getCompId());
+			paymentConfirmMapper.insert(confirm);
+		}
+		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 9846cf2..779692a 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
@@ -387,13 +387,13 @@
 					if (contract.getAmount().compareTo(contract.getPaidAmount()) == 0) {
 						contract.setBillingStatus("2");
 						contract.setContractStatus(3);
-						contractService.updateById(contract);
 						payCompleteContractList.add(contract);
 					}
 					//浠樻 涓� 浠樻鏈叏浠�
 					if (contract.getAmount().compareTo(contract.getPaidAmount()) > 0) {
 						payNoCompleteContractList.add(contract);
 					}
+					contractService.updateById(contract);
 				}
 			});
 
@@ -715,13 +715,13 @@
 				if (contract.getAmount().compareTo(contract.getPaidAmount()) == 0) {
 					contract.setBillingStatus("2");
 					contract.setContractStatus(3);
-					contractService.updateById(contract);
 					payCompleteContractList.add(contract);
 				}
 				//浠樻 涓� 浠樻鏈叏浠�
 				if (contract.getAmount().compareTo(contract.getPaidAmount()) > 0) {
 					payNoCompleteContractList.add(contract);
 				}
+				contractService.updateById(contract);
 			}
 		});
 
diff --git a/platformx-business-finance-biz/src/main/resources/mapper/ContractExecDateMapper.xml b/platformx-business-finance-biz/src/main/resources/mapper/ContractExecDateMapper.xml
new file mode 100644
index 0000000..1b42729
--- /dev/null
+++ b/platformx-business-finance-biz/src/main/resources/mapper/ContractExecDateMapper.xml
@@ -0,0 +1,18 @@
+<?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.ContractExecDateMapper">
+
+  <resultMap id="contractOutBoundMap" type="com.by4cloud.platformx.business.entity.ContractExecDate">
+        <id property="id" column="id"/>
+        <result property="compId" column="comp_id"/>
+        <result property="contractId" column="contract_id"/>
+        <result property="execDate" column="exec_date"/>
+        <result property="genFlag" column="gen_flag"/>
+        <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
diff --git a/platformx-business-finance-biz/src/main/resources/mapper/MeterReadRecordMapper.xml b/platformx-business-finance-biz/src/main/resources/mapper/MeterReadRecordMapper.xml
new file mode 100644
index 0000000..b9512fa
--- /dev/null
+++ b/platformx-business-finance-biz/src/main/resources/mapper/MeterReadRecordMapper.xml
@@ -0,0 +1,24 @@
+<?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.MeterReadRecordMapper">
+
+  <resultMap id="meterReadRecordMap" type="com.by4cloud.platformx.business.entity.MeterReadRecord">
+        <id property="id" column="id"/>
+        <result property="compId" column="comp_id"/>
+        <result property="busGuestId" column="bus_guest_id"/>
+        <result property="busGuestName" column="bus_guest_name"/>
+        <result property="contractId" column="contract_id"/>
+        <result property="contractName" column="contract_name"/>
+        <result property="meterReadAttNames" column="meter_read_att_names"/>
+        <result property="meterReadAttPaths" column="meter_read_att_paths"/>
+        <result property="meterReadCode" column="meter_read_code"/>
+        <result property="meterReadNum" column="meter_read_num"/>
+        <result property="meterReadTime" column="meter_read_time"/>
+        <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