修改支付逻辑
diff --git a/backend/src/main/java/com/supwisdom/dlpay/framework/jpa/UpperTableStrategy.java b/backend/src/main/java/com/supwisdom/dlpay/framework/jpa/UpperTableStrategy.java
new file mode 100644
index 0000000..ede2417
--- /dev/null
+++ b/backend/src/main/java/com/supwisdom/dlpay/framework/jpa/UpperTableStrategy.java
@@ -0,0 +1,22 @@
+package com.supwisdom.dlpay.framework.jpa;
+
+import org.hibernate.boot.model.naming.Identifier;
+import org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl;
+import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
+
+public class UpperTableStrategy extends PhysicalNamingStrategyStandardImpl {
+
+  private static final long serialVersionUID = 1383021413247872469L;
+
+  @Override
+  public Identifier toPhysicalTableName(Identifier name, JdbcEnvironment context) {
+    String tableName = name.getText();
+    // 医疗的表名为大写
+    if (tableName.startsWith("pt") || tableName.startsWith("PT")) {
+      tableName = tableName.toUpperCase();
+    } else {
+      tableName = tableName.toLowerCase();
+    }
+    return new Identifier(tableName, name.isQuoted());
+  }
+}
diff --git a/backend/src/main/java/com/supwisdom/dlpay/framework/util/MoneyUtil.java b/backend/src/main/java/com/supwisdom/dlpay/framework/util/MoneyUtil.java
index d384340..db8e848 100644
--- a/backend/src/main/java/com/supwisdom/dlpay/framework/util/MoneyUtil.java
+++ b/backend/src/main/java/com/supwisdom/dlpay/framework/util/MoneyUtil.java
@@ -1,5 +1,6 @@
 package com.supwisdom.dlpay.framework.util;
 
+import java.math.BigDecimal;
 import java.text.DecimalFormat;
 
 public class MoneyUtil {
@@ -32,4 +33,7 @@
     return formatYuan(fen / 100.0);
   }
 
+  public static double add(double value1, double value2) {
+    return new BigDecimal(String.valueOf(value1)).add(new BigDecimal(String.valueOf(value2))).doubleValue();
+  }
 }
diff --git a/backend/src/main/java/com/supwisdom/dlpay/medical/domain/TBExamReport.java b/backend/src/main/java/com/supwisdom/dlpay/medical/domain/TBExamReport.java
index 7285dc0..40946c6 100644
--- a/backend/src/main/java/com/supwisdom/dlpay/medical/domain/TBExamReport.java
+++ b/backend/src/main/java/com/supwisdom/dlpay/medical/domain/TBExamReport.java
@@ -1,91 +1,348 @@
 package com.supwisdom.dlpay.medical.domain;
 
 import javax.persistence.Column;
+import javax.persistence.Entity;
 import javax.persistence.Id;
+import javax.persistence.Table;
 import java.sql.Date;
 
+@Entity
+@Table(name = "`PT_EXAMREPORT`")
 public class TBExamReport {
-  @Id
-  @Column(name = "PATIENTID", length = 64)
-  private String patientId;
   /**
    * 检查流水号
    */
-  @Column(name = "JCLSH", length = 32)
+  @Id
+  @Column(name = "`JCLSH`", length = 32)
   private String JCLSH;
+  @Column(name = "`PATIENTID`", length = 64)
+  private String patientId;
   /**
    * 患者身份证号码
    */
-  @Column(name = "HZSFZ", length = 20)
+  @Column(name = "`HZSFZ`", length = 20)
   private String HZSFZ;
   /**
    * 就诊流水号
    */
-  @Column(name = "JZLSH", length = 32)
+  @Column(name = "`JZLSH`", length = 32)
   private String JZLSH;
   /**
    * 患者姓名
    */
-  @Column(name = "HZXM", length = 50)
+  @Column(name = "`HZXM`", length = 50)
   private String HZXM;
   /**
    * 病床号
    */
-  @Column(name = "BCH", length = 20)
+  @Column(name = "`BCH`", length = 20)
   private String BCH;
   /**
    * 病区名称
    */
-  @Column(name = "BQMC", length = 50)
+  @Column(name = "`BQMC`", length = 50)
   private String BQMC;
   /**
    * 标本样本采样时间
    */
-  @Column(name = "BBCYRQ")
+  @Column(name = "`BBCYRQ`")
   private Date BBCYRQ;
   /**
    * 检查项目名称
    */
-  @Column(name = "JCXMMC")
+  @Column(name = "`JCXMMC`",length = 60)
   private String JCXMMC;
   /**
    * 检查定量结果
    */
-  @Column(name = "JCDLJG", precision = 14, scale = 4)
+  @Column(name = "`JCDLJG`", precision = 14, scale = 4)
   private Double JCDLJG;
   /**
    * 检查定量结果计量单位
    */
-  @Column(name = "JCDLJGJLDW", length = 20)
+  @Column(name = "`JCDLJGJLDW`", length = 20)
   private String JCDLJGJLDW;
   /**
    * 性别代码
    */
-  @Column(name = "XB", length = 5)
+  @Column(name = "`XB`", length = 5)
   private String XB;
   /**
    * 报告医生姓名
    */
-  @Column(name = "BGYSXM", length = 50)
+  @Column(name = "`BGYSXM`", length = 50)
   private String BGYSXM;
   /**
+   * 检查日期
+   */
+  @Column(name = "`JCRQ`")
+  private Date JCRQ;
+  /**
    * 检查报告日期
    */
-  @Column(name = "BGSJ")
+  @Column(name = "`BGSJ`")
   private Date BGSJ;
   /**
+   * 申请科室名称
+   */
+  @Column(name = "`SQKSMC`", length = 50)
+  private String SQKSMC;
+  /**
+   * 检查报告单机构(科室)
+   */
+  @Column(name = "`BCKSMC`", length = 70)
+  private String BCKSMC;
+  /**
+   * 检查部位ACR编码
+   */
+  @Column(name = "`JCBW`", length = 50)
+  private String JCBW;
+  /**
+   * 阴阳性
+   */
+  @Column(name = "`YYX`", length = 1)
+  private String YYX;
+  /**
+   * 检查报告结果-客观所见
+   */
+  @Column(name = "`BCKGSJ`", length = 2000)
+  private String BCKGSJ;
+  /**
+   * 检查诊断或提示
+   */
+  @Column(name = "`JCZDHTS`", length = 500)
+  private String JCZDHTS;
+  /**
    * 审核医师姓名
    */
-  @Column(name = "SHYSXM", length = 50)
+  @Column(name = "`SHYSXM`", length = 50)
   private String SHYSXM;
   /**
    * 医疗机构代码
    */
-  @Column(name = "YLJGDM", length = 30)
+  @Column(name = "`YLJGDM`", length = 30)
   private String YLJGDM;
   /**
    * 医疗机构名称
    */
-  @Column(name = "YLJGMC", length = 50)
+  @Column(name = "`YLJGMC`", length = 50)
   private String YLJGMC;
+  /**
+   * 检查报告单编号
+   */
+  @Column(name = "`JCBGDH`", length = 20)
+  private String JCBGDH;
+  /**
+   * 报告备注
+   */
+  @Column(name = "`BGBZ`", length = 500)
+  private String BGBZ;
+
+  public String getPatientId() {
+    return patientId;
+  }
+
+  public void setPatientId(String patientId) {
+    this.patientId = patientId;
+  }
+
+  public String getJCLSH() {
+    return JCLSH;
+  }
+
+  public void setJCLSH(String JCLSH) {
+    this.JCLSH = JCLSH;
+  }
+
+  public String getHZSFZ() {
+    return HZSFZ;
+  }
+
+  public void setHZSFZ(String HZSFZ) {
+    this.HZSFZ = HZSFZ;
+  }
+
+  public String getJZLSH() {
+    return JZLSH;
+  }
+
+  public void setJZLSH(String JZLSH) {
+    this.JZLSH = JZLSH;
+  }
+
+  public String getHZXM() {
+    return HZXM;
+  }
+
+  public void setHZXM(String HZXM) {
+    this.HZXM = HZXM;
+  }
+
+  public String getBCH() {
+    return BCH;
+  }
+
+  public void setBCH(String BCH) {
+    this.BCH = BCH;
+  }
+
+  public String getBQMC() {
+    return BQMC;
+  }
+
+  public void setBQMC(String BQMC) {
+    this.BQMC = BQMC;
+  }
+
+  public Date getBBCYRQ() {
+    return BBCYRQ;
+  }
+
+  public void setBBCYRQ(Date BBCYRQ) {
+    this.BBCYRQ = BBCYRQ;
+  }
+
+  public String getJCXMMC() {
+    return JCXMMC;
+  }
+
+  public void setJCXMMC(String JCXMMC) {
+    this.JCXMMC = JCXMMC;
+  }
+
+  public Double getJCDLJG() {
+    return JCDLJG;
+  }
+
+  public void setJCDLJG(Double JCDLJG) {
+    this.JCDLJG = JCDLJG;
+  }
+
+  public String getJCDLJGJLDW() {
+    return JCDLJGJLDW;
+  }
+
+  public void setJCDLJGJLDW(String JCDLJGJLDW) {
+    this.JCDLJGJLDW = JCDLJGJLDW;
+  }
+
+  public String getXB() {
+    return XB;
+  }
+
+  public void setXB(String XB) {
+    this.XB = XB;
+  }
+
+  public String getBGYSXM() {
+    return BGYSXM;
+  }
+
+  public void setBGYSXM(String BGYSXM) {
+    this.BGYSXM = BGYSXM;
+  }
+
+  public Date getBGSJ() {
+    return BGSJ;
+  }
+
+  public void setBGSJ(Date BGSJ) {
+    this.BGSJ = BGSJ;
+  }
+
+  public String getSHYSXM() {
+    return SHYSXM;
+  }
+
+  public void setSHYSXM(String SHYSXM) {
+    this.SHYSXM = SHYSXM;
+  }
+
+  public String getYLJGDM() {
+    return YLJGDM;
+  }
+
+  public void setYLJGDM(String YLJGDM) {
+    this.YLJGDM = YLJGDM;
+  }
+
+  public String getYLJGMC() {
+    return YLJGMC;
+  }
+
+  public void setYLJGMC(String YLJGMC) {
+    this.YLJGMC = YLJGMC;
+  }
+
+  public String getJCBGDH() {
+    return JCBGDH;
+  }
+
+  public void setJCBGDH(String JCBGDH) {
+    this.JCBGDH = JCBGDH;
+  }
+
+  public Date getJCRQ() {
+    return JCRQ;
+  }
+
+  public void setJCRQ(Date JCRQ) {
+    this.JCRQ = JCRQ;
+  }
+
+  public String getSQKSMC() {
+    return SQKSMC;
+  }
+
+  public void setSQKSMC(String SQKSMC) {
+    this.SQKSMC = SQKSMC;
+  }
+
+  public String getBCKSMC() {
+    return BCKSMC;
+  }
+
+  public void setBCKSMC(String BCKSMC) {
+    this.BCKSMC = BCKSMC;
+  }
+
+  public String getJCBW() {
+    return JCBW;
+  }
+
+  public void setJCBW(String JCBW) {
+    this.JCBW = JCBW;
+  }
+
+  public String getYYX() {
+    return YYX;
+  }
+
+  public void setYYX(String YYX) {
+    this.YYX = YYX;
+  }
+
+  public String getBCKGSJ() {
+    return BCKGSJ;
+  }
+
+  public void setBCKGSJ(String BCKGSJ) {
+    this.BCKGSJ = BCKGSJ;
+  }
+
+  public String getJCZDHTS() {
+    return JCZDHTS;
+  }
+
+  public void setJCZDHTS(String JCZDHTS) {
+    this.JCZDHTS = JCZDHTS;
+  }
+
+  public String getBGBZ() {
+    return BGBZ;
+  }
+
+  public void setBGBZ(String BGBZ) {
+    this.BGBZ = BGBZ;
+  }
 }
diff --git a/backend/src/main/java/com/supwisdom/dlpay/medical/domain/TBHISDtlJson.java b/backend/src/main/java/com/supwisdom/dlpay/medical/domain/TBHISDtlJson.java
new file mode 100644
index 0000000..cccf15e
--- /dev/null
+++ b/backend/src/main/java/com/supwisdom/dlpay/medical/domain/TBHISDtlJson.java
@@ -0,0 +1,93 @@
+package com.supwisdom.dlpay.medical.domain;
+
+import org.hibernate.annotations.GenericGenerator;
+
+import javax.persistence.*;
+
+@Entity
+@Table(name = "th_hisdtl_json", indexes = {
+    @Index(name = "his_json_idx", columnList = "transdate,transtime"),
+    @Index(name = "his_json_idx2", columnList = "uid,patientid,organizationid")
+})
+public class TBHISDtlJson {
+  @Id
+  @GenericGenerator(name = "idGenerator", strategy = "uuid")
+  @GeneratedValue(generator = "idGenerator")
+  @Column(name = "id", nullable = false, length = 32)
+  private String id;
+
+  @Lob
+  @Column(name = "content", columnDefinition = "TEXT")
+  private String content;
+
+  @Column(name = "transdate", length = 8)
+  private String transdate;
+
+  @Column(name = "transtime", length = 6)
+  private String transtime;
+
+  @Column(name = "uid", length = 32)
+  private String uid;
+
+  @Column(name = "patientid", length = 64)
+  private String patientid;
+
+  @Column(name = "organizationid", length = 30)
+  private String organizationid;
+
+  public String getId() {
+    return id;
+  }
+
+  public void setId(String id) {
+    this.id = id;
+  }
+
+  public String getContent() {
+    return content;
+  }
+
+  public void setContent(String content) {
+    this.content = content;
+  }
+
+  public String getTransdate() {
+    return transdate;
+  }
+
+  public void setTransdate(String transdate) {
+    this.transdate = transdate;
+  }
+
+  public String getTranstime() {
+    return transtime;
+  }
+
+  public void setTranstime(String transtime) {
+    this.transtime = transtime;
+  }
+
+  public String getUid() {
+    return uid;
+  }
+
+  public void setUid(String uid) {
+    this.uid = uid;
+  }
+
+  public String getPatientid() {
+    return patientid;
+  }
+
+  public void setPatientid(String patientid) {
+    this.patientid = patientid;
+  }
+
+  public String getOrganizationid() {
+    return organizationid;
+  }
+
+  public void setOrganizationid(String organizationid) {
+    this.organizationid = organizationid;
+  }
+}
diff --git a/backend/src/main/java/com/supwisdom/dlpay/medical/domain/TBLabDetail.java b/backend/src/main/java/com/supwisdom/dlpay/medical/domain/TBLabDetail.java
index b529ed4..93c8684 100644
--- a/backend/src/main/java/com/supwisdom/dlpay/medical/domain/TBLabDetail.java
+++ b/backend/src/main/java/com/supwisdom/dlpay/medical/domain/TBLabDetail.java
@@ -1,58 +1,155 @@
 package com.supwisdom.dlpay.medical.domain;
 
 import javax.persistence.Column;
+import javax.persistence.Entity;
 import javax.persistence.Id;
+import javax.persistence.Table;
 
+@Entity
+@Table(name = "`PT_LABDETAIL`")
 public class TBLabDetail {
   /**
    * 检验明细流水号
    */
   @Id
-  @Column(name = "JYMXLSH", length = 32)
+  @Column(name = "`JYMXLSH`", length = 32)
   private String JYMXLSH;
   /**
    * 就诊流水号
    */
-  @Column(name = "JZLSH", length = 32)
+  @Column(name = "`JZLSH`", length = 32)
   private String JZLSH;
   /**
    * 检验报告单号
    */
-  @Column(name = "JYBGDH", length = 32)
+  @Column(name = "`JYBGDH`", length = 32)
   private String JYBGDH;
   /**
    * 检验结果
    */
-  @Column(name = "JYJG", length = 100)
+  @Column(name = "`JYJG`", length = 100)
   private String JYJG;
   /**
    * 检测定量结果:患者检验结果的测量值(定量)
    */
-  @Column(name = "JYDLJG", length = 40)
+  @Column(name = "`JYDLJG`", length = 40)
   private String JYDLJG;
   /**
    * 检查/检验计量单位
    */
-  @Column(name = "JLDW", length = 20)
+  @Column(name = "`JLDW`", length = 20)
   private String JLDW;
   /**
    * 参考值范围
    */
-  @Column(name = "CKDX", length = 1000)
+  @Column(name = "`CKDX`", length = 1000)
   private String CKDX;
   /**
    * 检验项目名称
    */
-  @Column(name = "JYXMMC", length = 80)
+  @Column(name = "`JYXMMC`", length = 80)
   private String JYXMMC;
   /**
    * 检验项目英文简称
    */
-  @Column(name = "JYXMYWMC", length = 100)
+  @Column(name = "`JYXMYWMC`", length = 100)
   private String JYXMYWMC;
   /**
    * 显示顺序
    */
-  @Column(name = "XSSX", length = 40)
+  @Column(name = "`XSSX`", length = 40)
   private String XSSX;
+  /**
+   * 医疗机构代码
+   */
+  @Column(name = "`YLJGDM`", length = 30)
+  private String YLJGDM;
+
+  public String getJYMXLSH() {
+    return JYMXLSH;
+  }
+
+  public void setJYMXLSH(String JYMXLSH) {
+    this.JYMXLSH = JYMXLSH;
+  }
+
+  public String getJZLSH() {
+    return JZLSH;
+  }
+
+  public void setJZLSH(String JZLSH) {
+    this.JZLSH = JZLSH;
+  }
+
+  public String getJYBGDH() {
+    return JYBGDH;
+  }
+
+  public void setJYBGDH(String JYBGDH) {
+    this.JYBGDH = JYBGDH;
+  }
+
+  public String getJYJG() {
+    return JYJG;
+  }
+
+  public void setJYJG(String JYJG) {
+    this.JYJG = JYJG;
+  }
+
+  public String getJYDLJG() {
+    return JYDLJG;
+  }
+
+  public void setJYDLJG(String JYDLJG) {
+    this.JYDLJG = JYDLJG;
+  }
+
+  public String getJLDW() {
+    return JLDW;
+  }
+
+  public void setJLDW(String JLDW) {
+    this.JLDW = JLDW;
+  }
+
+  public String getCKDX() {
+    return CKDX;
+  }
+
+  public void setCKDX(String CKDX) {
+    this.CKDX = CKDX;
+  }
+
+  public String getJYXMMC() {
+    return JYXMMC;
+  }
+
+  public void setJYXMMC(String JYXMMC) {
+    this.JYXMMC = JYXMMC;
+  }
+
+  public String getJYXMYWMC() {
+    return JYXMYWMC;
+  }
+
+  public void setJYXMYWMC(String JYXMYWMC) {
+    this.JYXMYWMC = JYXMYWMC;
+  }
+
+  public String getXSSX() {
+    return XSSX;
+  }
+
+  public void setXSSX(String XSSX) {
+    this.XSSX = XSSX;
+  }
+
+  public String getYLJGDM() {
+    return YLJGDM;
+  }
+
+  public void setYLJGDM(String YLJGDM) {
+    this.YLJGDM = YLJGDM;
+  }
 }
diff --git a/backend/src/main/java/com/supwisdom/dlpay/medical/domain/TBLabReport.java b/backend/src/main/java/com/supwisdom/dlpay/medical/domain/TBLabReport.java
index c0d30c1..f96e736 100644
--- a/backend/src/main/java/com/supwisdom/dlpay/medical/domain/TBLabReport.java
+++ b/backend/src/main/java/com/supwisdom/dlpay/medical/domain/TBLabReport.java
@@ -1,107 +1,126 @@
 package com.supwisdom.dlpay.medical.domain;
 
 import javax.persistence.Column;
+import javax.persistence.Entity;
 import javax.persistence.Id;
+import javax.persistence.Table;
 import java.sql.Date;
 
+@Entity
+@Table(name = "`PT_LABREPORT`")
 public class TBLabReport {
   @Id
-  @Column(name = "PATIENTID", length = 64)
+  @Column(name = "`PATIENTID`", length = 64)
   private String patientId;
   /**
    * 检验报告单号
    */
-  @Column(name = "JYBGDH", length = 32)
+  @Column(name = "`JYBGDH`", length = 32)
   private String JYBGDH;
   /**
    * 患者身份证
    */
-  @Column(name = "HZSFZ", length = 20)
+  @Column(name = "`HZSFZ`", length = 20)
   private String HZSFZ;
   /**
+   * 就诊流水号(门诊/住院号)
+   */
+  @Column(name = "`JZLSH`", length = 32)
+  private String JZLSH;
+  /**
+   * 病人标识类别
+   */
+  @Column(name = "`BRBSLB`", length = 50)
+  private String BRBSLB;
+  /**
    * 病床号
    */
-  @Column(name = "BCH", length = 20)
+  @Column(name = "`BCH`", length = 20)
   private String BCH;
   /**
    * 病区名称
    */
-  @Column(name = "BQMC", length = 50)
+  @Column(name = "`BQMC`", length = 50)
   private String BQMC;
   /**
    * 患者姓名
    */
-  @Column(name = "HZXM", length = 20)
+  @Column(name = "`HZXM`", length = 20)
   private String HZXM;
   /**
    * 性别代码
    */
-  @Column(name = "XB", length = 5)
+  @Column(name = "`XB`", length = 5)
   private String XB;
   /**
    * 诊断日期
    */
-  @Column(name = "ZDRQ")
+  @Column(name = "`ZDRQ`")
   private Date ZDRQ;
   /**
    * 标本类别(字典DE04.50.134.00)
    */
-  @Column(name = "BZLB", length = 20)
+  @Column(name = "`BZLB`", length = 20)
   private String BZLB;
   /**
+   * 检验报告单—项目名称(检查目的)
+   */
+  @Column(name = "`JYBGDMC`", length = 200)
+  private String JYBGDMC;
+  /**
    * 检验报告单机构(科室)
    */
-  @Column(name = "JYBGDJG", length = 50)
+  @Column(name = "`JYBGDJG`", length = 50)
   private String JYBGDJG;
   /**
    * 检验报告机构名称
    */
-  @Column(name = "JYBGJGMC", length = 50)
+  @Column(name = "`JYBGJGMC`", length = 50)
   private String JYBGJGMC;
   /**
    * 检验报告结果
    */
-  @Column(name = "JYBGJG", length = 200)
+  @Column(name = "`JYBGJG`", length = 200)
   private String JYBGJG;
   /**
    * 检验报告备注
    */
-  @Column(name = "BZ", length = 500)
+  @Column(name = "`BZ`", length = 500)
   private String BZ;
   /**
    * 检验报告日期
    */
-  @Column(name = "JYBGRQ")
+  @Column(name = "`JYBGRQ`")
   private Date JYBGRQ;
   /**
    * 审核医生姓名
    */
-  @Column(name = "SHYSXM", length = 50)
+  @Column(name = "`SHYSXM`", length = 50)
   private String SHYSXM;
   /**
    * 报告医生姓名
    */
-  @Column(name = "BGYSXM", length = 50)
+  @Column(name = "`BGYSXM`", length = 50)
   private String BGYSXM;
   /**
    * 检验日期(检验报告执行时间)
    */
-  @Column(name = "JYRQ")
+  @Column(name = "`JYRQ`")
   private Date JYRQ;
   /**
    * 诊断机构名称
    */
-  @Column(name = "ZDJGMC", length = 50)
+  @Column(name = "`ZDJGMC`", length = 50)
   private String ZDJGMC;
   /**
    * 医疗机构代码
    */
-  @Column(name = "YLJGDM", length = 30)
+  @Column(name = "`YLJGDM`", length = 30)
   private String YLJGDM;
   /**
    * 医疗机构名称
    */
-  @Column(name = "YLJGMC", length = 50)
+  @Column(name = "`YLJGMC`", length = 50)
   private String YLJGMC;
 
   public String getPatientId() {
@@ -263,4 +282,28 @@
   public void setYLJGMC(String YLJGMC) {
     this.YLJGMC = YLJGMC;
   }
+
+  public String getJZLSH() {
+    return JZLSH;
+  }
+
+  public void setJZLSH(String JZLSH) {
+    this.JZLSH = JZLSH;
+  }
+
+  public String getBRBSLB() {
+    return BRBSLB;
+  }
+
+  public void setBRBSLB(String BRBSLB) {
+    this.BRBSLB = BRBSLB;
+  }
+
+  public String getJYBGDMC() {
+    return JYBGDMC;
+  }
+
+  public void setJYBGDMC(String JYBGDMC) {
+    this.JYBGDMC = JYBGDMC;
+  }
 }
diff --git a/backend/src/main/java/com/supwisdom/dlpay/medical/domain/TBMedicalDtl.java b/backend/src/main/java/com/supwisdom/dlpay/medical/domain/TBMedicalDtl.java
index 8fc6d2e..ea3f193 100644
--- a/backend/src/main/java/com/supwisdom/dlpay/medical/domain/TBMedicalDtl.java
+++ b/backend/src/main/java/com/supwisdom/dlpay/medical/domain/TBMedicalDtl.java
@@ -6,7 +6,7 @@
 @Table(name = "th_medicaldtl", indexes = {
     @Index(name = "medicaldtl_idx", columnList = "uid,emergency,feeno,organizationid"),
     @Index(name = "medicaldtl_idx2", columnList = "uid,accdate,organizationid"),
-    @Index(name = "medicaldtl_idx3", columnList = "paystatus,resultid,organizationid"),
+    @Index(name = "medicaldtl_idx3", columnList = "medicaldate,paystatus,resultid,organizationid"),
     @Index(name = "medicaldtl_idx4", columnList = "patientid")})
 public class TBMedicalDtl {
   @Id
@@ -17,14 +17,24 @@
   @Column(name = "uid", length = 32)
   private String uid;
   /**
-   * 总金额
+   * 预结算接口返回,作为支付确认接口的参数,本地不做业务逻辑
    */
   @Column(name = "totalfee", precision = 10, scale = 3)
   private Double totalfee;
   /**
+   * 预结算接口返回,作为支付确认接口的参数,本地不做业务逻辑
+   */
+  @Column(name = "payamount", precision = 10, scale = 3)
+  private Double payamount;
+  /**
+   * 本地扣费实际金额
+   */
+  @Column(name = "mergingsubtotal", precision = 10, scale = 3)
+  private Double mergingsubtotal;
+  /**
    * 归并费用名称
    */
-  @Column(name = "mergingname",length = 32)
+  @Column(name = "mergingname",length = 100)
   private String mergingname;
   /**
    * 加收费用描述
@@ -42,6 +52,11 @@
   @Column(name = "feetypecode", length = 32)
   private String feetypecode;
   /**
+   * 收费类型名称
+   */
+  @Column(name = "feetypename", length = 32)
+  private String feetypename;
+  /**
    * 患者就诊序号
    */
   @Column(name = "emergency", length = 64)
@@ -49,7 +64,7 @@
   /**
    * 就诊日期
    */
-  @Column(name = "medicaldate", length = 8)
+  @Column(name = "medicaldate", length = 14)
   private String medicaldate;
   /**
    * 医院code
@@ -87,8 +102,12 @@
   /**
    * HIS结算日期
    */
-  @Column(name = "resultdate", length = 8)
+  @Column(name = "resultdate", length = 14)
   private String resultdate;
+  @Column(name = "hisjson", length = 32)
+  private String hisjson;
+  @Transient
+  private Boolean created;
 
   public String getBillno() {
     return billno;
@@ -249,4 +268,44 @@
   public void setMedicaldate(String medicaldate) {
     this.medicaldate = medicaldate;
   }
+
+  public String getFeetypename() {
+    return feetypename;
+  }
+
+  public void setFeetypename(String feetypename) {
+    this.feetypename = feetypename;
+  }
+
+  public Boolean getCreated() {
+    return created;
+  }
+
+  public void setCreated(Boolean created) {
+    this.created = created;
+  }
+
+  public Double getPayamount() {
+    return payamount;
+  }
+
+  public void setPayamount(Double payamount) {
+    this.payamount = payamount;
+  }
+
+  public Double getMergingsubtotal() {
+    return mergingsubtotal;
+  }
+
+  public void setMergingsubtotal(Double mergingsubtotal) {
+    this.mergingsubtotal = mergingsubtotal;
+  }
+
+  public String getHisjson() {
+    return hisjson;
+  }
+
+  public void setHisjson(String hisjson) {
+    this.hisjson = hisjson;
+  }
 }
diff --git a/backend/src/main/java/com/supwisdom/dlpay/medical/util/MedicalClient.java b/backend/src/main/java/com/supwisdom/dlpay/medical/util/MedicalClient.java
index 03b2825..0f63c8d 100644
--- a/backend/src/main/java/com/supwisdom/dlpay/medical/util/MedicalClient.java
+++ b/backend/src/main/java/com/supwisdom/dlpay/medical/util/MedicalClient.java
@@ -2,9 +2,12 @@
 
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.TypeReference;
+import com.supwisdom.dlpay.framework.data.SystemDateTime;
 import com.supwisdom.dlpay.framework.service.SystemUtilService;
 import com.supwisdom.dlpay.framework.util.StringUtil;
 import com.supwisdom.dlpay.medical.bean.*;
+import com.supwisdom.dlpay.medical.dao.HisDtlJsonDao;
+import com.supwisdom.dlpay.medical.domain.TBHISDtlJson;
 import com.supwisdom.dlpay.medical.exception.MedicineException;
 import com.supwisdom.dlpay.portal.util.PortalConstant;
 import org.slf4j.Logger;
@@ -25,6 +28,8 @@
   private RestTemplate restTemplate;
   @Autowired
   private SystemUtilService systemUtilService;
+  @Autowired
+  private HisDtlJsonDao hisDtlJsonDao;
   private Logger logger = LoggerFactory.getLogger(MedicalClient.class);
 
   public PatientInfoResponse getPatientMedicalCardList(AddPatientBean bean) {
@@ -113,20 +118,24 @@
     Map<String, Object> param = new HashMap<>(4);
     param.put("organizationId", bean.getOrganizationId());
     param.put("queryType", bean.getQueryType());
+    param.put("beginTime", bean.getBeginTime());
+    param.put("endTime", bean.getEndTime());
     param.put("patientIdentityCardList", bean.getPatientIdentityCardList());
+    param.put("patientIdList", bean.getPatientIdList());
     String response;
     try {
       response = httpPost(url + "getUnpayedList", JSON.toJSONString(param));
     } catch (HttpServerErrorException e) {
       //  当前用户在HIS中没有档案时,会返回500 异常
-      logger.error("调用HIS异常",e);
+      logger.error("调用HIS异常", e);
       return new UnPayedResponse();
     }
     MedicalResponse<UnPayedResponse> result = JSON.parseObject(response, new TypeReference<MedicalResponse<UnPayedResponse>>() {
     });
     if (result.getCode() != MedicalConstant.MEDICAL_RESPONSE_SUCCESS) {
+      // 当前用户没有待支付订单时,会返回 code:100;message:未查询到待支付信息!
       logger.error("调用医疗待支付列表接口异常,code:" + result.getCode() + ";message:" + result.getMessage());
-      throw new MedicineException("请求医疗系统异常");
+      return new UnPayedResponse();
     }
     return result.getData().get(0);
   }
@@ -135,8 +144,11 @@
     String url = getMedicalUrl();
     Map<String, Object> param = new HashMap<>(8);
     param.put("organizationId", bean.getOrganizationId());
+    param.put("beginTime", bean.getBeginTime());
+    param.put("endTime", bean.getEndTime());
     param.put("queryType", bean.getQueryType());
     param.put("patientIdList", bean.getPatientIdList());
+    param.put("patientIdentityCardList", bean.getPatientIdentityCardList());
     param.put("executeFlag", bean.getExecuteFlag());
     param.put("outpatientType", bean.getOutpatientType());
     String response = httpPost(url + "getPayedList", JSON.toJSONString(param));
@@ -163,13 +175,28 @@
       logger.error("调用医疗预结算接口异常,code:" + result.getCode() + ";message:" + result.getMessage());
       throw new MedicineException("请求医疗系统异常");
     }
-    return result.getData().get(0);
+    PreFeeResponse preFeeResponse = result.getData().get(0);
+    // 保存返回json作为日后对账凭证
+    if (!bean.getHasJson() &&
+        PortalConstant.YES.equals(systemUtilService.getBusinessValue(PortalConstant.SYSPARA_MEDICAL_SAVEJSON))) {
+      SystemDateTime datetime = systemUtilService.getSysdatetime();
+      TBHISDtlJson jsonStr = new TBHISDtlJson();
+      jsonStr.setContent(response);
+      jsonStr.setTransdate(datetime.getHostdate());
+      jsonStr.setTranstime(datetime.getHosttime());
+      jsonStr.setUid(bean.getUid());
+      jsonStr.setPatientid(bean.getPatientId());
+      jsonStr.setOrganizationid(bean.getOrganizationId());
+      hisDtlJsonDao.save(jsonStr);
+      preFeeResponse.setHisJsonId(jsonStr.getId());
+    }
+    return preFeeResponse;
   }
 
   /**
    * 费用结算处理确认
    */
-  public NotifyPayedResponse notifyPayed(NotifyPayedRequest bean) {
+  public MedicalResponse<NotifyPayedResponse> notifyPayed(NotifyPayedRequest bean) {
     String url = getMedicalUrl();
     Map<String, Object> param = new HashMap<>(8);
     param.put("organizationId", bean.getOrganizationId());
@@ -181,17 +208,12 @@
     param.put("payAmount", bean.getPayAmount());
     param.put("outOrderNumber", bean.getOutOrderNumber());
     param.put("payer", bean.getPayer());
-    param.put("totalFee ", bean.getTotalFee());
-    param.put("brid ", bean.getBrid());
-    param.put("feeRecords ", bean.getFeeRecords());
+    param.put("totalFee", bean.getTotalFee());
+    param.put("brid", bean.getBrid());
+    param.put("feeRecords", bean.getFeeRecords());
     String response = httpPost(url + "notifyPayed", JSON.toJSONString(param));
-    MedicalResponse<NotifyPayedResponse> result = JSON.parseObject(response, new TypeReference<MedicalResponse<NotifyPayedResponse>>() {
+    return JSON.parseObject(response, new TypeReference<MedicalResponse<NotifyPayedResponse>>() {
     });
-    if (result.getCode() != MedicalConstant.MEDICAL_RESPONSE_SUCCESS) {
-      logger.error("调用医疗结算确认接口异常,code:" + result.getCode() + ";message:" + result.getMessage());
-      throw new MedicineException("请求医疗系统异常");
-    }
-    return result.getData().get(0);
   }
 
   private String getMedicalUrl() {
diff --git a/backend/src/main/java/com/supwisdom/dlpay/portal/util/PortalConstant.java b/backend/src/main/java/com/supwisdom/dlpay/portal/util/PortalConstant.java
index e0a12ca..c5fb1ce 100644
--- a/backend/src/main/java/com/supwisdom/dlpay/portal/util/PortalConstant.java
+++ b/backend/src/main/java/com/supwisdom/dlpay/portal/util/PortalConstant.java
@@ -20,6 +20,7 @@
   public static final String SYSPARA_PORTAL_AMAPURL = "portal.amapurl";
   public static final String SYSPARA_MEDICAL_URL = "medical.url";
   public static final String SYSPARA_MEDICAL_SHOPACCNO = "medical.shopaccno";
+  public static final String SYSPARA_MEDICAL_SAVEJSON = "medical.savejson";
 
   public static final String ARTICLE_STATUS_SAVE = "save";
   public static final String ARTICLE_STATUS_PASS = "pass";
diff --git a/backend/src/main/kotlin/com/supwisdom/dlpay/api/scheduler_task.kt b/backend/src/main/kotlin/com/supwisdom/dlpay/api/scheduler_task.kt
index 8592797..4b6bd3b 100644
--- a/backend/src/main/kotlin/com/supwisdom/dlpay/api/scheduler_task.kt
+++ b/backend/src/main/kotlin/com/supwisdom/dlpay/api/scheduler_task.kt
@@ -1,5 +1,6 @@
 package com.supwisdom.dlpay.api
 
+import com.supwisdom.dlpay.framework.service.SystemUtilService
 import com.supwisdom.dlpay.medical.dao.MedicalDtlDao
 import com.supwisdom.dlpay.medical.task.NotifyHISAsyncTask
 import com.supwisdom.dlpay.medical.util.MedicalConstant
@@ -11,6 +12,9 @@
 import org.springframework.data.domain.PageRequest
 import org.springframework.scheduling.annotation.Scheduled
 import org.springframework.stereotype.Component
+import java.text.SimpleDateFormat
+import java.time.Duration
+import java.time.Instant
 
 @Component
 class RefreshJwtSchedulerTask {
@@ -34,11 +38,20 @@
     private lateinit var medicalDtlDao: MedicalDtlDao
     @Autowired
     private lateinit var notifyHISAsyncTask: NotifyHISAsyncTask
+    @Autowired
+    private lateinit var systemUtilService: SystemUtilService
 
 //    @Scheduled(cron = "0 */1 * * * ?")
 //    @SchedulerLock(name = "dealNotifyHISPayed", lockAtMostForString = "PT10M")
 //    fun notifyHISPayed() {
-//        val medicalDtlList = medicalDtlDao.findByPaystatusAndResultidIsNull(MedicalConstant.DTL_STATUS_SUCCESS, PageRequest.of(0, 10))
+//        // 查询近三天的本地支付成功但未通知HIS的流水
+//        val sdf = SimpleDateFormat("yyyyMMdd")
+//        val endTime = systemUtilService.sysdatetime.hostdate
+//        val beginTime = sdf.format(Instant.ofEpochMilli(sdf.parse(endTime).time).minus(Duration.ofDays(2)).toEpochMilli())
+//
+//        val medicalDtlList = medicalDtlDao.findByMedicaldateBetweenAndPaystatusAndResultidIsNull(
+//                beginTime + "000000", endTime + "235959",
+//                MedicalConstant.DTL_STATUS_SUCCESS, PageRequest.of(0, 10))
 //        if (medicalDtlList.isNullOrEmpty()) {
 //            return
 //        }
diff --git a/backend/src/main/kotlin/com/supwisdom/dlpay/medical/MedicalApi.kt b/backend/src/main/kotlin/com/supwisdom/dlpay/medical/MedicalApi.kt
index c5660ac..691b594 100644
--- a/backend/src/main/kotlin/com/supwisdom/dlpay/medical/MedicalApi.kt
+++ b/backend/src/main/kotlin/com/supwisdom/dlpay/medical/MedicalApi.kt
@@ -18,6 +18,7 @@
 import mu.KotlinLogging
 import org.springframework.beans.factory.annotation.Autowired
 import org.springframework.security.core.context.SecurityContextHolder
+import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder
 import org.springframework.web.bind.annotation.*
 
 @RestController
@@ -42,7 +43,7 @@
     /**
      * 查询医院列表
      */
-    /*@GetMapping("/hospital/list")
+    @GetMapping("/hospital/list")
     fun getHospitalList(pageno: Int, pagesize: Int, name: String?): JsonResult? {
         val data = medicalService.getHospitalList(pageno, pagesize, name)
         return JsonResult.ok().put("data", data)
@@ -198,12 +199,12 @@
      * 获取已支付列表
      */
     @PostMapping("/payed/list")
-    fun getPayedList(hospitalcode: String): JsonResult? {
+    fun getPayedList(pageno: Int, pagesize: Int, hospitalcode: String): JsonResult? {
         try {
             val p = SecurityContextHolder.getContext().authentication
             val user = mobileApiService.findUserById(p.name)
                     ?: return JsonResult.error("用户不存在,请注册")
-            val data = medicalService.getPayedList(user.uid, hospitalcode)
+            val data = medicalService.getPayedList(user.uid, hospitalcode, pageno, pagesize)
             return JsonResult.ok().put("data", data)
         } catch (e: Exception) {
             logger.error("系统异常", e)
@@ -218,13 +219,32 @@
      * 支付接口
      */
     @PostMapping("/pay/{billno}")
-    fun medicalPayment(@PathVariable billno: String): JsonResult? {
+    fun medicalPayment(@PathVariable billno: String,@RequestBody bean: PaymentRequestBean): JsonResult? {
         try {
             val p = SecurityContextHolder.getContext().authentication
             val user = mobileApiService.findUserById(p.name)
                     ?: return JsonResult.error("用户不存在,请注册")
-            val bean = PaymentRequestBean()
             bean.billno = billno
+            if (user.paypwd.isNullOrEmpty()) {
+                return JsonResult.error("支付密码未设置,请先设置")
+            }
+            val paypwdtimes = user.checkPaypwdtime()
+            if (paypwdtimes == -1) {
+                return JsonResult.error("支付密码错误次数过多,请30分钟后再试")
+            } else if (paypwdtimes == 1) {
+                mobileApiService.saveUser(user)
+            }
+            val encoder = BCryptPasswordEncoder()
+            if (!encoder.matches(bean.paypwd, user.paypwd)) {
+                user.updatePaypwderror(false).also {
+                    if (it) mobileApiService.saveUser(user)
+                }
+                return JsonResult.error("支付密码错误")
+            } else {
+                user.updatePaypwderror(true).also {
+                    if (it) mobileApiService.saveUser(user)
+                }
+            }
             val checkResult = checkUserConsume(user, bean)
             if (checkResult?.get("code") != 200) {
                 return checkResult
@@ -282,6 +302,33 @@
         }
     }
 
+    /**
+     * 通知医疗系统支付成功
+     */
+    @PostMapping("/pay/notify/{billno}")
+    fun notifyHis(@PathVariable billno: String): JsonResult? {
+        try {
+            val p = SecurityContextHolder.getContext().authentication
+            val user = mobileApiService.findUserById(p.name)
+                    ?: return JsonResult.error("用户不存在,请注册")
+            val medicalDtl = medicalService.findMedicalDtlByBillNo(billno, user.uid)
+            if (medicalDtl.paystatus != MedicalConstant.DTL_STATUS_SUCCESS) {
+                return JsonResult.error("当前流水状态异常,请查询后再试")
+            }
+            if (!medicalDtl.resultid.isNullOrEmpty()) {
+                return JsonResult.error("已成功通知医疗系统,无须重复通知")
+            }
+            notifyHISAsyncTask.notifyHIS(billno)
+            return JsonResult.ok("已通知医疗系统,请稍后查询结果")
+        } catch (e: Exception) {
+            logger.error("系统异常", e)
+            if (e is MedicineException) {
+                return JsonResult.error(e.message)
+            }
+            return JsonResult.error("系统异常,请稍后重试")
+        }
+    }
+
     fun checkUserConsume(user: TBMobileUser, bean: PaymentRequestBean): JsonResult? {
         if (TradeDict.STATUS_NORMAL != user.status) {
             return JsonResult.error("用户状态异常")
@@ -316,10 +363,119 @@
     }
 
     /**
-     * 获取报告(检验、检查报告)
+     * 获取检验报告列表
      */
-    @PostMapping("/report")
-    fun getDiagnosticReport() {
+    @PostMapping("/labreport/list")
+    fun getLabReportList(hospitalcode: String): JsonResult? {
+        try {
+            val p = SecurityContextHolder.getContext().authentication
+            val user = mobileApiService.findUserById(p.name)
+                    ?: return JsonResult.error("用户不存在,请注册")
+            if (user.userid.isNullOrEmpty()) {
+                return JsonResult.error("请绑定银行卡")
+            }
+            val userInfo = userProxy.querybycardno(QueryUserParam().apply {
+                this.userid = user.userid
+            })
+            if (userInfo.retcode != 0) {
+                logger.error { "获取userid为${user.userid}的用户信息失败,错误信息:${userInfo.retmsg}" }
+                return JsonResult.error("获取用户信息失败")
+            }
+            val list = medicalService.getLabReportList(userInfo.idno, hospitalcode)
+            return JsonResult.ok().put("data", list)
+        } catch (e: Exception) {
+            logger.error("系统异常", e)
+            return JsonResult.error("系统异常,请稍后重试")
+        }
+    }
 
-    }*/
+    /**
+     * 获取检验报告详情
+     */
+    @PostMapping("/labreport/{reportno}")
+    fun getLabReportDetail(@PathVariable reportno: String, hospitalcode: String): JsonResult? {
+        try {
+            val p = SecurityContextHolder.getContext().authentication
+            val user = mobileApiService.findUserById(p.name)
+                    ?: return JsonResult.error("用户不存在,请注册")
+            if (user.userid.isNullOrEmpty()) {
+                return JsonResult.error("请绑定银行卡")
+            }
+            val userInfo = userProxy.querybycardno(QueryUserParam().apply {
+                this.userid = user.userid
+            })
+            if (userInfo.retcode != 0) {
+                logger.error { "获取userid为${user.userid}的用户信息失败,错误信息:${userInfo.retmsg}" }
+                return JsonResult.error("获取用户信息失败")
+            }
+            val report = medicalService.getLabReportDetail(reportno, hospitalcode, userInfo.idno)
+            return JsonResult.ok().put("data", report)
+        } catch (e: Exception) {
+            logger.error("系统异常", e)
+            if (e is MedicineException) {
+                return JsonResult.error(e.message)
+            }
+            return JsonResult.error("系统异常,请稍后重试")
+        }
+    }
+
+    /**
+     * 获取检查报告列表
+     */
+    @PostMapping("/examreport/list")
+    fun getExamReportList(hospitalcode: String): JsonResult? {
+        try {
+            val p = SecurityContextHolder.getContext().authentication
+            val user = mobileApiService.findUserById(p.name)
+                    ?: return JsonResult.error("用户不存在,请注册")
+            if (user.userid.isNullOrEmpty()) {
+                return JsonResult.error("请绑定银行卡")
+            }
+            val userInfo = userProxy.querybycardno(QueryUserParam().apply {
+                this.userid = user.userid
+            })
+            if (userInfo.retcode != 0) {
+                logger.error { "获取userid为${user.userid}的用户信息失败,错误信息:${userInfo.retmsg}" }
+                return JsonResult.error("获取用户信息失败")
+            }
+            val list = medicalService.getExamReportList(userInfo.idno, hospitalcode)
+            return JsonResult.ok().put("data", list)
+        } catch (e: Exception) {
+            logger.error("系统异常", e)
+            if (e is MedicineException) {
+                return JsonResult.error(e.message)
+            }
+            return JsonResult.error("系统异常,请稍后重试")
+        }
+    }
+
+    /**
+     * 获取检查报告详情
+     */
+    @PostMapping("/examreport/{reportno}")
+    fun getExamReportDetail(@PathVariable reportno: String, hospitalcode: String): JsonResult? {
+        try {
+            val p = SecurityContextHolder.getContext().authentication
+            val user = mobileApiService.findUserById(p.name)
+                    ?: return JsonResult.error("用户不存在,请注册")
+            if (user.userid.isNullOrEmpty()) {
+                return JsonResult.error("请绑定银行卡")
+            }
+            val userInfo = userProxy.querybycardno(QueryUserParam().apply {
+                this.userid = user.userid
+            })
+            if (userInfo.retcode != 0) {
+                logger.error { "获取userid为${user.userid}的用户信息失败,错误信息:${userInfo.retmsg}" }
+                return JsonResult.error("获取用户信息失败")
+            }
+            val report = medicalService.getExamReportDetail(reportno, hospitalcode, userInfo.idno)
+            return JsonResult.ok().put("data", report)
+        } catch (e: Exception) {
+            logger.error("系统异常", e)
+            if (e is MedicineException) {
+                return JsonResult.error(e.message)
+            }
+            return JsonResult.error("系统异常,请稍后重试")
+        }
+    }
 }
\ No newline at end of file
diff --git a/backend/src/main/kotlin/com/supwisdom/dlpay/medical/bean/ExamReportDTO.kt b/backend/src/main/kotlin/com/supwisdom/dlpay/medical/bean/ExamReportDTO.kt
new file mode 100644
index 0000000..3240e4a
--- /dev/null
+++ b/backend/src/main/kotlin/com/supwisdom/dlpay/medical/bean/ExamReportDTO.kt
@@ -0,0 +1,17 @@
+package com.supwisdom.dlpay.medical.bean
+
+class ExamReportDTO {
+    var examno: String? = ""
+    var name: String? = ""
+    var sex: String? = ""
+    var projectname: String? = ""
+    var examdate: String? = ""
+    var applydep: String? = ""
+    var examdep: String? = ""
+    var exampart: String? = ""
+    var yinyang: String? = ""
+    var description: String? = ""
+    var diagnosis: String? = ""
+    var remark: String? = ""
+    var reportdate: String? = ""
+}
\ No newline at end of file
diff --git a/backend/src/main/kotlin/com/supwisdom/dlpay/medical/bean/LabReportBean.kt b/backend/src/main/kotlin/com/supwisdom/dlpay/medical/bean/LabReportBean.kt
new file mode 100644
index 0000000..8157acf
--- /dev/null
+++ b/backend/src/main/kotlin/com/supwisdom/dlpay/medical/bean/LabReportBean.kt
@@ -0,0 +1,20 @@
+package com.supwisdom.dlpay.medical.bean
+
+class LabReportDTO {
+    var projectname: String? = ""
+    var patientype: String? = ""
+    var reportno: String? = ""
+    var patientname: String? = ""
+    var sex: String? = ""
+    var sampletype: String = ""
+    var clinicno: String? = ""
+    var department: String? = ""
+    var details = ArrayList<LabDetailDTO>()
+}
+
+class LabDetailDTO {
+    var name: String? = ""
+    var result: String? = ""
+    var unit: String? = ""
+    var referange: String? = ""
+}
diff --git a/backend/src/main/kotlin/com/supwisdom/dlpay/medical/bean/PayedBean.kt b/backend/src/main/kotlin/com/supwisdom/dlpay/medical/bean/PayedBean.kt
index 93e35ee..eb25cec 100644
--- a/backend/src/main/kotlin/com/supwisdom/dlpay/medical/bean/PayedBean.kt
+++ b/backend/src/main/kotlin/com/supwisdom/dlpay/medical/bean/PayedBean.kt
@@ -1,13 +1,17 @@
 package com.supwisdom.dlpay.medical.bean
 
 class PayedRequest {
+    var beginTime = ""
+    var endTime = ""
     var organizationId = ""
     var outpatientType = 0
     var executeFlag = 0
     var queryType = 0
-    var patientIdList = ArrayList<String>()
+    var patientIdList = ArrayList<PatientId>()
+    var patientIdentityCardList = ArrayList<IdentityCardBean>()
 }
 
+
 class PayedResponse {
     var patientId: String? = ""
     var patientMedicalCardType: Int? = 0
@@ -20,6 +24,8 @@
     var medicalDate: String? = ""
     var admNumber: String? = ""
     var costList = ArrayList<costItem>()
+    var invoiceStatus: String? = ""
+    var payStatus: String? = ""  //支付状态: 0已支付1已退款 2未知
 }
 
 class costItem {
@@ -38,7 +44,17 @@
     var mergingName: String? = ""
     var executionStatus: Int? = 0
     var execute: String? = ""
-    var totalFee: Double? = 0.0
+    var mergingsubtotal: Double? = 0.0
     var admNumber: String? = ""
     var notifyStatus: Boolean? = false
+}
+
+class PayedDtlDTO {
+    var billno: String = ""
+    var medicaldate: String? = ""
+    var mergingname: String? = ""
+    var mergingsubtotal: Double? = 0.0
+    var notifyStatus: Boolean? = false
+    var transdate: String? = ""
+    var transtime: String? = ""
 }
\ No newline at end of file
diff --git a/backend/src/main/kotlin/com/supwisdom/dlpay/medical/bean/PaymentRequestBean.kt b/backend/src/main/kotlin/com/supwisdom/dlpay/medical/bean/PaymentRequestBean.kt
index 5131801..36af3dc 100644
--- a/backend/src/main/kotlin/com/supwisdom/dlpay/medical/bean/PaymentRequestBean.kt
+++ b/backend/src/main/kotlin/com/supwisdom/dlpay/medical/bean/PaymentRequestBean.kt
@@ -4,4 +4,5 @@
     var billno = ""
     var cardNo = ""
     var idno = ""
+    var paypwd:String = ""
 }
\ No newline at end of file
diff --git a/backend/src/main/kotlin/com/supwisdom/dlpay/medical/bean/PrecalculatedFeeBean.kt b/backend/src/main/kotlin/com/supwisdom/dlpay/medical/bean/PrecalculatedFeeBean.kt
index 4dfce60..508ace7 100644
--- a/backend/src/main/kotlin/com/supwisdom/dlpay/medical/bean/PrecalculatedFeeBean.kt
+++ b/backend/src/main/kotlin/com/supwisdom/dlpay/medical/bean/PrecalculatedFeeBean.kt
@@ -5,6 +5,8 @@
     var boilSign = 0
     var feeRecords = ArrayList<FeeRecordItem>()
     var patientId = ""
+    var uid = ""
+    var hasJson = false
 }
 
 class FeeRecordItem {
@@ -20,4 +22,5 @@
     var totalFee: Double? = 0.0
     var paymentBudgetNumber: String? = ""    //预结算标识
     var extraFeeDesc: String? = ""   //加收费费用描述
+    var hisJsonId: String? = ""  //本地保存的json记录id,只是方便方法数据传递,并非HIS返回
 }
\ No newline at end of file
diff --git a/backend/src/main/kotlin/com/supwisdom/dlpay/medical/bean/UnPayedBean.kt b/backend/src/main/kotlin/com/supwisdom/dlpay/medical/bean/UnPayedBean.kt
index f455de6..2a72213 100644
--- a/backend/src/main/kotlin/com/supwisdom/dlpay/medical/bean/UnPayedBean.kt
+++ b/backend/src/main/kotlin/com/supwisdom/dlpay/medical/bean/UnPayedBean.kt
@@ -3,11 +3,17 @@
 import kotlin.collections.ArrayList
 
 class UnPayedRequest {
+    var beginTime = ""
+    var endTime = ""
     var organizationId = ""
     var queryType = 0
     var patientIdentityCardList = ArrayList<IdentityCardBean>()
     var patientMedicalCardList = ArrayList<PatientMedicalCardBean>()
-    var patientIdList = ArrayList<String>()
+    var patientIdList = ArrayList<PatientId>()
+}
+
+class PatientId{
+    var patientId = ""
 }
 
 class IdentityCardBean {
@@ -31,7 +37,7 @@
 }
 
 class MedicalInformation {
-    var medicalDate: String? = ""
+    var medicalDate: Long? = 0
     var doctorName: String? = ""
     var doctorCode: String? = ""
     var departmentName: String? = ""
@@ -62,5 +68,6 @@
     var feeNo: String? = ""
     var status: String? = ""
     var mergingName: String? = ""
+    var hospitalName: String? = ""
 }
 
diff --git a/backend/src/main/kotlin/com/supwisdom/dlpay/medical/dao/ExamReportDao.kt b/backend/src/main/kotlin/com/supwisdom/dlpay/medical/dao/ExamReportDao.kt
new file mode 100644
index 0000000..a85b1c1
--- /dev/null
+++ b/backend/src/main/kotlin/com/supwisdom/dlpay/medical/dao/ExamReportDao.kt
@@ -0,0 +1,11 @@
+package com.supwisdom.dlpay.medical.dao
+
+import com.supwisdom.dlpay.medical.domain.TBExamReport
+import org.springframework.data.jpa.repository.JpaRepository
+import org.springframework.stereotype.Repository
+
+@Repository
+interface ExamReportDao : JpaRepository<TBExamReport, String> {
+//    fun findByHZSFZAndYLJGDM(hzsfz: String, yljgdm: String): List<TBExamReport>?
+//    fun findByHZSFZAndJCBGDHAndYLJGDM(hzsfz: String, jcbgdh: String, yljgdm: String): TBExamReport?
+}
\ No newline at end of file
diff --git a/backend/src/main/kotlin/com/supwisdom/dlpay/medical/dao/HisDtlJsonDao.kt b/backend/src/main/kotlin/com/supwisdom/dlpay/medical/dao/HisDtlJsonDao.kt
new file mode 100644
index 0000000..6d49055
--- /dev/null
+++ b/backend/src/main/kotlin/com/supwisdom/dlpay/medical/dao/HisDtlJsonDao.kt
@@ -0,0 +1,6 @@
+package com.supwisdom.dlpay.medical.dao
+
+import com.supwisdom.dlpay.medical.domain.TBHISDtlJson
+import org.springframework.data.jpa.repository.JpaRepository
+
+interface HisDtlJsonDao :JpaRepository<TBHISDtlJson,String>
\ No newline at end of file
diff --git a/backend/src/main/kotlin/com/supwisdom/dlpay/medical/dao/HospitalDao.kt b/backend/src/main/kotlin/com/supwisdom/dlpay/medical/dao/HospitalDao.kt
index 0a4525a..907472b 100644
--- a/backend/src/main/kotlin/com/supwisdom/dlpay/medical/dao/HospitalDao.kt
+++ b/backend/src/main/kotlin/com/supwisdom/dlpay/medical/dao/HospitalDao.kt
@@ -5,4 +5,6 @@
 import org.springframework.stereotype.Repository
 
 @Repository
-interface HospitalDao : JpaRepository<TBHospital, String>, HospitalRepository
\ No newline at end of file
+interface HospitalDao : JpaRepository<TBHospital, String>, HospitalRepository {
+    fun findByHospitalcodeAndStatus(hospitalcode: String, status: String): TBHospital?
+}
\ No newline at end of file
diff --git a/backend/src/main/kotlin/com/supwisdom/dlpay/medical/dao/LabDetailDao.kt b/backend/src/main/kotlin/com/supwisdom/dlpay/medical/dao/LabDetailDao.kt
new file mode 100644
index 0000000..970ab51
--- /dev/null
+++ b/backend/src/main/kotlin/com/supwisdom/dlpay/medical/dao/LabDetailDao.kt
@@ -0,0 +1,11 @@
+package com.supwisdom.dlpay.medical.dao
+
+import com.supwisdom.dlpay.medical.domain.TBLabDetail
+import org.springframework.data.jpa.repository.JpaRepository
+import org.springframework.stereotype.Repository
+
+@Repository
+interface LabDetailDao : JpaRepository<TBLabDetail, String> {
+//    fun findByJYBGDHAndYLJGDM(jybgdh: String, yljgdm: String): List<TBLabDetail>?
+
+}
\ No newline at end of file
diff --git a/backend/src/main/kotlin/com/supwisdom/dlpay/medical/dao/LabReportDao.kt b/backend/src/main/kotlin/com/supwisdom/dlpay/medical/dao/LabReportDao.kt
new file mode 100644
index 0000000..2110463
--- /dev/null
+++ b/backend/src/main/kotlin/com/supwisdom/dlpay/medical/dao/LabReportDao.kt
@@ -0,0 +1,11 @@
+package com.supwisdom.dlpay.medical.dao
+
+import com.supwisdom.dlpay.medical.domain.TBLabReport
+import org.springframework.data.jpa.repository.JpaRepository
+import org.springframework.stereotype.Repository
+
+@Repository
+interface LabReportDao : JpaRepository<TBLabReport, String> {
+//    fun findByHZSFZAndYLJGDM(hzsfz: String, yljgdm: String): List<TBLabReport>?
+//    fun findByHZSFZAndJYBGDHAndYLJGDM(hzsfz: String, jybgdh: String, yljgdm: String): TBLabReport?
+}
\ No newline at end of file
diff --git a/backend/src/main/kotlin/com/supwisdom/dlpay/medical/dao/MedicalDtlDao.kt b/backend/src/main/kotlin/com/supwisdom/dlpay/medical/dao/MedicalDtlDao.kt
index 065db64..8582c10 100644
--- a/backend/src/main/kotlin/com/supwisdom/dlpay/medical/dao/MedicalDtlDao.kt
+++ b/backend/src/main/kotlin/com/supwisdom/dlpay/medical/dao/MedicalDtlDao.kt
@@ -17,9 +17,10 @@
     @QueryHints(QueryHint(name = "javax.persistence.lock.timeout", value = "0"))
     fun findByBillnoForUpdate(billno: String?): TBMedicalDtl?
 
-    fun findByPaystatusAndResultidIsNull(status: String, pageable: Pageable): List<TBMedicalDtl>?
+    fun findByMedicaldateBetweenAndPaystatusAndResultidIsNull(beginTime: String, endTime: String, status: String, pageable: Pageable): List<TBMedicalDtl>?
 
-    fun findByUidAndEmergencyAndFeenoAndOrganizationidAndPaystatusNot(uid: String, emergency: String, feeNo: String, organizationId: String, payStatus: String): TBMedicalDtl?
+    fun findByUidAndEmergencyAndFeenoAndOrganizationidAndPaystatusNot(
+            uid: String, emergency: String, feeNo: String, organizationId: String, payStatus: String): TBMedicalDtl?
 
-    fun findByUidAndOrganizationidAndPaystatusOrderByAccdateDesc(uid: String, organizationId: String, payStatus: String, pageable: Pageable): List<TBMedicalDtl>?
+    fun findByUidAndOrganizationidAndPaystatusOrderByTransdateDescTranstimeDesc(uid: String, organizationId: String, payStatus: String, pageable: Pageable): List<TBMedicalDtl>?
 }
\ No newline at end of file
diff --git a/backend/src/main/kotlin/com/supwisdom/dlpay/medical/service/MedicalService.kt b/backend/src/main/kotlin/com/supwisdom/dlpay/medical/service/MedicalService.kt
index 512377e..427f300 100644
--- a/backend/src/main/kotlin/com/supwisdom/dlpay/medical/service/MedicalService.kt
+++ b/backend/src/main/kotlin/com/supwisdom/dlpay/medical/service/MedicalService.kt
@@ -4,6 +4,7 @@
 import com.supwisdom.dlpay.framework.jpa.page.Pagination
 import com.supwisdom.dlpay.medical.bean.*
 import com.supwisdom.dlpay.medical.domain.TBMedicalCard
+import com.supwisdom.dlpay.medical.domain.TBMedicalDtl
 import org.springframework.transaction.annotation.Transactional
 
 interface MedicalService {
@@ -44,7 +45,7 @@
      * 从本地数据查询已支付列表
      */
     @Transactional
-    fun getPayedList(uid: String, organizationId: String): ArrayList<PayedDTO>
+    fun getPayedList(uid: String, organizationId: String,pageno: Int, pagesize: Int): ArrayList<PayedDtlDTO>
 
     @Transactional
     fun medicalPayPreInit(uid: String, bean: PaymentRequestBean)
@@ -59,6 +60,17 @@
     fun queryMedicalPayResult(billNo: String, uid: String): JsonResult?
 
     @Transactional
-    fun getDiagnosticReport(uid: String): JsonResult?
+    fun findMedicalDtlByBillNo(billNo: String, uid: String): TBMedicalDtl
 
+    @Transactional
+    fun getLabReportList(idNo: String, organizationId: String): List<LabReportDTO>
+
+    @Transactional
+    fun getLabReportDetail(reportNo: String, organizationId: String, idNo: String): LabReportDTO
+
+    @Transactional
+    fun getExamReportList(idNo: String, organizationId: String): List<ExamReportDTO>
+
+    @Transactional
+    fun getExamReportDetail(reportNo: String, organizationId: String, idNo: String): ExamReportDTO
 }
\ No newline at end of file
diff --git a/backend/src/main/kotlin/com/supwisdom/dlpay/medical/service/impl/MedicalServiceImpl.kt b/backend/src/main/kotlin/com/supwisdom/dlpay/medical/service/impl/MedicalServiceImpl.kt
index eb8da0d..07f9f4f 100644
--- a/backend/src/main/kotlin/com/supwisdom/dlpay/medical/service/impl/MedicalServiceImpl.kt
+++ b/backend/src/main/kotlin/com/supwisdom/dlpay/medical/service/impl/MedicalServiceImpl.kt
@@ -8,6 +8,7 @@
 import com.supwisdom.dlpay.framework.service.SystemUtilService
 import com.supwisdom.dlpay.framework.util.MoneyUtil
 import com.supwisdom.dlpay.framework.util.StringUtil
+import com.supwisdom.dlpay.framework.util.TradeDict
 import com.supwisdom.dlpay.medical.bean.*
 import com.supwisdom.dlpay.medical.dao.*
 import com.supwisdom.dlpay.medical.domain.TBAppointmentDtl
@@ -24,6 +25,11 @@
 import org.springframework.beans.factory.annotation.Autowired
 import org.springframework.data.domain.PageRequest
 import org.springframework.stereotype.Service
+import java.text.SimpleDateFormat
+import java.time.Duration
+import java.time.Instant
+import java.util.*
+import kotlin.collections.ArrayList
 
 @Service
 class MedicalServiceImpl : MedicalService {
@@ -43,6 +49,12 @@
     lateinit var citizenCardPayProxy: CitizenCardPayProxy
     @Autowired
     lateinit var transactionProxy: TransactionProxy
+    @Autowired
+    lateinit var labReportDao: LabReportDao
+    @Autowired
+    lateinit var labDetailDao: LabDetailDao
+    @Autowired
+    lateinit var examReportDao: ExamReportDao
     val logger = KotlinLogging.logger { }
 
     override fun getHospitalList(pageno: Int, pageSize: Int, name: String?): Pagination {
@@ -166,6 +178,13 @@
 
     fun getUnPayedResponse(organizationId: String, data: String, queryType: Int): UnPayedResponse {
         val upPayedRequest = UnPayedRequest().apply {
+            val sdf = SimpleDateFormat("yyyy-MM-dd")
+            val currentDate = SimpleDateFormat("yyyyMMdd").parse(systemUtilService.sysdatetime.hostdate)
+            val endTime = sdf.format(currentDate)
+            val beginTime = sdf.format(Instant.ofEpochMilli(currentDate.time).minus(Duration.ofDays(2)).toEpochMilli())
+
+            this.beginTime = "$beginTime 00:00:00"
+            this.endTime = "$endTime 23:59:59"
             this.organizationId = organizationId
             this.queryType = queryType
         }
@@ -181,8 +200,8 @@
             }
             MedicalConstant.ORDER_QUERYTYPE_PATIENTID -> {
                 //  根据患者id查询
-                val unPayedPatientList = ArrayList<String>()
-                unPayedPatientList.add(data)
+                val unPayedPatientList = ArrayList<PatientId>()
+                unPayedPatientList.add(PatientId().apply { this.patientId = data })
                 upPayedRequest.patientIdList = unPayedPatientList
             }
             MedicalConstant.ORDER_QUERYTYPE_MEDICALCARD -> {
@@ -202,54 +221,83 @@
     }
 
     override fun getUnPayedList(uid: String, organizationId: String, data: String, queryType: Int): List<UnPayedDTO> {
-        //根据证件号或医疗卡查询未支付账单
+        // 根据证件号或医疗卡查询未支付账单
         val unPayedResponse = getUnPayedResponse(organizationId, data, queryType)
         val unPayedDTOList = ArrayList<UnPayedDTO>()
-        //拆分每次就诊下的每个项目为一条展示数据
+        val hospital = hospitalDao.findByHospitalcodeAndStatus(organizationId, TradeDict.STATUS_NORMAL)
+                ?: throw MedicineException("未找到该医院")
+        // 拆分每次就诊下的每个项目为一条展示数据(一次就诊中可能有几个项目共用一个feeNo,只能一起结算)
         unPayedResponse.medicalInformation.forEach { medicalInformation ->
+            val map = HashMap<String, TBMedicalDtl>()
             for (mergingItems in medicalInformation.mergingItems) {
-                // 因为异步通知HIS,HIS中数据延迟,所以本地扣费成功后的流水仍有可能拉到
+                // 因为异步通知HIS,HIS中数据有延迟,所以本地扣费成功后的流水仍有可能被查询到
                 val localDtl = medicalDtlDao.findByUidAndEmergencyAndFeenoAndOrganizationidAndPaystatusNot(
-                        uid, medicalInformation.emergencyNumber!!, mergingItems.feeNo!!, organizationId, MedicalConstant.DTL_STATUS_FAIL)
+                        uid, medicalInformation.emergencyNumber!!, mergingItems.feeNo!!,
+                        organizationId, MedicalConstant.DTL_STATUS_FAIL)
                 var skip = false
                 if (localDtl != null) {
                     if (localDtl.paystatus == MedicalConstant.DTL_STATUS_SUCCESS) {
-                        //  已扣费成功,等待通知HIS成功,此处无须额外处理
+                        //  已扣费成功,等待通知HIS成功,此处无须处理
                         continue
                     } else {
                         //  当流水为init或wip时都跳过生成本地流水
                         skip = true
                     }
                 }
-                var medicalDtl: TBMedicalDtl
-                if (!skip) {
-                    medicalDtl = TBMedicalDtl().apply {
-                        this.billno = systemUtilService.refno
-                        this.emergency = medicalInformation.emergencyNumber
-                        this.feeno = mergingItems.feeNo
-                        this.feetypecode = mergingItems.feeTypeCode
-                        this.uid = uid
-                        this.mergingname = mergingItems.mergingName
-                        this.paystatus = MedicalConstant.DTL_STATUS_INIT
-                        this.organizationid = organizationId
-                        this.patientid = unPayedResponse.patientId
-                        this.totalfee = mergingItems.mergingSubtotal
-                        this.medicaldate = medicalInformation.medicalDate?.replace("-", "")
+                // 查看该feeNo的是否已出现过
+                if (!map.containsKey(mergingItems.feeNo!!)) {
+                    // 该feeNo首次出现
+                    if (!skip) {
+                        val medicalDtl = TBMedicalDtl().apply {
+                            this.billno = systemUtilService.refno
+                            this.emergency = medicalInformation.emergencyNumber
+                            this.feeno = mergingItems.feeNo
+                            this.feetypecode = mergingItems.feeTypeCode
+                            this.feetypename = mergingItems.feeTypeName
+                            this.uid = uid
+                            this.mergingname = mergingItems.mergingName
+                            this.paystatus = MedicalConstant.DTL_STATUS_INIT
+                            this.organizationid = organizationId
+                            this.patientid = unPayedResponse.patientId
+                            this.mergingsubtotal = mergingItems.mergingSubtotal
+                            if (medicalInformation.medicalDate != null) {
+                                this.medicaldate = SimpleDateFormat("yyyyMMddHHmmss")
+                                        .format(Date(medicalInformation.medicalDate!!))
+                            }
+                            this.created = false // 本地流水未生成
+                        }
+                        map[mergingItems.feeNo!!] = medicalDtl // 将feeNo放入map中
+                    } else {
+                        localDtl!!.created = true   // 本地流水已生成
+                        map[mergingItems.feeNo!!] = localDtl
                     }
-                    medicalDtlDao.save(medicalDtl)
                 } else {
-                    medicalDtl = localDtl!!
+                    // 该feeNo已出现,将该条数据同之前的数据合并成一条流水
+                    val medicalDtl = map[mergingItems.feeNo!!]!!
+                    // 如果本地流水已生成,此处无需处理
+                    if (!medicalDtl.created) {
+                        // 将金额累加
+                        medicalDtl.mergingsubtotal = MoneyUtil.add(medicalDtl.mergingsubtotal, mergingItems.mergingSubtotal!!)
+                        medicalDtl.mergingname = medicalDtl.mergingname + "," + mergingItems.mergingName
+                    }
+                }
+            }
+            map.forEach { (_, medicalDtl) ->
+                // 本地流水未创建,生成本地流水
+                if (!medicalDtl.created) {
+                    medicalDtlDao.save(medicalDtl)
                 }
                 val unPayedDTO = UnPayedDTO().apply {
                     this.billNo = medicalDtl.billno
-                    this.medicalDate = medicalInformation.medicalDate
+                    this.medicalDate = medicalDtl.medicaldate
                     this.subjectName = medicalInformation.departmentName
                     this.doctorName = medicalInformation.doctorName
                     this.emergencyNumber = medicalInformation.emergencyNumber
-                    this.feeNo = mergingItems.feeNo
-                    this.mergingSubtotal = mergingItems.mergingSubtotal
+                    this.feeNo = medicalDtl.feeno
+                    this.mergingSubtotal = medicalDtl.mergingsubtotal
                     this.status = medicalDtl.paystatus
-                    this.mergingName = mergingItems.mergingName
+                    this.mergingName = medicalDtl.mergingname
+                    this.hospitalName = hospital.name
                 }
                 unPayedDTOList.add(unPayedDTO)
             }
@@ -260,21 +308,31 @@
     override fun getPayedList(uid: String, organizationId: String, cardId: String): ArrayList<PayedDTO> {
         val medicalCard = medicalCardDao.findByCardidAndUid(cardId, uid)
                 ?: throw MedicineException("未找到该就诊卡")
-        val payedPatientIdList = ArrayList<String>()
-        payedPatientIdList.add(medicalCard.patientid)
+        val payedPatientIdList = ArrayList<PatientId>()
+        payedPatientIdList.add(PatientId().apply { this.patientId = medicalCard.patientid })
+        //查询近三天的流水,医疗系统时间格式为 yyyy-MM-dd HH:mm:ss
+        val sdf = SimpleDateFormat("yyyy-MM-dd")
+        val date = systemUtilService.sysdatetime.hostdate
+        val n = Instant.ofEpochMilli(SimpleDateFormat("yyyyMMdd").parse(date).time)
+        n.minus(Duration.ofDays(2))
+        val endTime = sdf.format(date)
+        val beginTime = sdf.format(n.toEpochMilli())
+
         val payedRequest = PayedRequest()
         payedRequest.organizationId = organizationId
         payedRequest.queryType = MedicalConstant.ORDER_QUERYTYPE_PATIENTID
         payedRequest.patientIdList = payedPatientIdList
         payedRequest.executeFlag = MedicalConstant.PAYED_EXECUTEFLAG_INVALID
         payedRequest.outpatientType = MedicalConstant.PAYED_OUTPATIENTTYPE_NORMAL
+        payedRequest.beginTime = "$beginTime 00:00:00"
+        payedRequest.endTime = "$endTime 23:59:59"
         val payedResponse = medicalClient.getPayedList(payedRequest)
         val payedDTOList = ArrayList<PayedDTO>()
         //拆分每次就诊下的每个项目为一条展示数据
         payedResponse.invoiceList.forEach { invoiceItem ->
             invoiceItem.costList.forEach { costItem ->
                 val payedDTO = PayedDTO().apply {
-                    this.totalFee = costItem.totalFee
+                    this.mergingsubtotal = costItem.totalFee
                     this.medicalDate = invoiceItem.medicalDate
                     this.executionStatus = costItem.executionStatus
                     this.execute = costItem.execute
@@ -287,25 +345,27 @@
         return payedDTOList
     }
 
-    override fun getPayedList(uid: String, organizationId: String): ArrayList<PayedDTO> {
-        val medicalDtlList = medicalDtlDao.findByUidAndOrganizationidAndPaystatusOrderByAccdateDesc(
-                uid, organizationId, MedicalConstant.DTL_STATUS_SUCCESS, PageRequest.of(0, 10))
-        val payedDTOList = ArrayList<PayedDTO>()
+    override fun getPayedList(uid: String, organizationId: String, pageno: Int, pagesize: Int): ArrayList<PayedDtlDTO> {
+        val medicalDtlList = medicalDtlDao.findByUidAndOrganizationidAndPaystatusOrderByTransdateDescTranstimeDesc(
+                uid, organizationId, MedicalConstant.DTL_STATUS_SUCCESS, PageRequest.of(pageno - 1, pagesize))
+        val payedDtlDTOList = ArrayList<PayedDtlDTO>()
         if (!medicalDtlList.isNullOrEmpty()) {
             medicalDtlList.forEach {
-                val payedDTO = PayedDTO().apply {
-                    this.billNo = it.billno
-                    this.totalFee = it.totalfee
-                    this.medicalDate = it.medicaldate
-                    this.mergingName = it.mergingname
+                val payedDtlDTO = PayedDtlDTO().apply {
+                    this.billno = it.billno
+                    this.mergingsubtotal = it.mergingsubtotal
+                    this.medicaldate = it.medicaldate
+                    this.mergingname = it.mergingname
+                    this.transdate = it.transdate
+                    this.transtime = it.transtime
                     if (!StringUtil.isEmpty(it.resultid)) {
                         this.notifyStatus = true
                     }
                 }
-                payedDTOList.add(payedDTO)
+                payedDtlDTOList.add(payedDtlDTO)
             }
         }
-        return payedDTOList
+        return payedDtlDTOList
     }
 
     override fun medicalPayPreInit(uid: String, bean: PaymentRequestBean) {
@@ -318,39 +378,61 @@
         val unPayedResponse = getUnPayedResponse(
                 medicalDtl.organizationid, medicalDtl.patientid, MedicalConstant.ORDER_QUERYTYPE_PATIENTID)
         var mergingItems: MergingItems? = null
-        unPayedResponse.medicalInformation.forEach { medicalInformation ->
+        for (medicalInformation in unPayedResponse.medicalInformation) {
             if (medicalInformation.emergencyNumber == medicalDtl.emergency) {
-                medicalInformation.mergingItems.forEach { queryMergingItems ->
+                for (queryMergingItems in medicalInformation.mergingItems) {
                     if (queryMergingItems.feeNo == medicalDtl.feeno) {
-                        mergingItems = queryMergingItems
+                        if (mergingItems == null) {
+                            mergingItems = queryMergingItems
+                        } else {
+                            mergingItems.mergingSubtotal = MoneyUtil.add(
+                                    mergingItems.mergingSubtotal!!, queryMergingItems.mergingSubtotal!!)
+                        }
                     }
                 }
+                break
             }
         }
         if (mergingItems == null) {
             throw MedicineException("未找到该条待缴费记录")
         }
+        if (mergingItems.mergingSubtotal != medicalDtl.mergingsubtotal) {
+            throw MedicineException("该流水缴费金额异常")
+        }
         //2.向HIS预结算
         val feeRecords = ArrayList<FeeRecordItem>()
         feeRecords.add(FeeRecordItem().apply {
-            this.feeNo = mergingItems!!.feeNo
-            this.feeTypeCode = mergingItems!!.feeTypeCode
-            this.feeTypeName = mergingItems!!.feeTypeName
+            this.feeNo = mergingItems.feeNo
+            this.feeTypeCode = mergingItems.feeTypeCode
+            this.feeTypeName = mergingItems.feeTypeName
         })
 
         val preFeeRequest = PreFeeRequest().apply {
-            this.boilSign = mergingItems!!.boilSign!!
+            this.boilSign = mergingItems.boilSign!!
             this.organizationId = medicalDtl.organizationid
             this.feeRecords = feeRecords
             this.patientId = unPayedResponse.patientId!!
+            this.uid = uid
+            if (!medicalDtl.hisjson.isNullOrEmpty()) {
+                this.hasJson = true
+            }
         }
         val preFeeResponse = medicalClient.getPreCalculatedFee(preFeeRequest)
+        if (preFeeResponse.payAmount != medicalDtl.mergingsubtotal || preFeeResponse.totalFee != medicalDtl.mergingsubtotal) {
+            throw MedicineException("该流水缴费金额异常")
+        }
+        val datetime = systemUtilService.sysdatetime
         medicalDtl.apply {
             this.citizencardno = bean.cardNo
             this.extrafeedesc = preFeeResponse.extraFeeDesc
             this.invoiceno = preFeeResponse.invoiceNumber
-            this.transdate = systemUtilService.sysdatetime.hostdate
-            this.transtime = systemUtilService.sysdatetime.hosttime
+            this.payamount = preFeeResponse.payAmount
+            this.totalfee = preFeeResponse.totalFee
+            this.transdate = datetime.hostdate
+            this.transtime = datetime.hosttime
+            if (!preFeeResponse.hisJsonId.isNullOrEmpty()) {
+                this.hisjson = preFeeResponse.hisJsonId
+            }
         }
         medicalDtlDao.save(medicalDtl)
     }
@@ -376,7 +458,7 @@
             val initParam = CitizenCardPayinitParam().apply {
                 this.billno = medicalDtl.billno
                 this.cardNo = medicalDtl.citizencardno
-                this.amount = MoneyUtil.YuanToFen(medicalDtl.totalfee)
+                this.amount = MoneyUtil.YuanToFen(medicalDtl.mergingsubtotal)
                 this.dtltype = MedicalConstant.DTLTYPE_MEDICAL
                 this.transdate = medicalDtl.transdate
                 this.transtime = medicalDtl.transtime
@@ -496,7 +578,118 @@
         return JsonResult.ok(MedicalConstant.DTL_STATUS_WIP)
     }
 
-    override fun getDiagnosticReport(uid: String): JsonResult? {
-        TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
+    override fun findMedicalDtlByBillNo(billNo: String, uid: String): TBMedicalDtl {
+        val medicalDtl = medicalDtlDao.findByBillnoForUpdate(billNo)
+                ?: throw MedicineException("未找到流水为[${billNo}]的流水")
+        if (uid != medicalDtl.uid) {
+            throw MedicineException("未在当前用户的账户下查询到该条流水")
+        }
+        return medicalDtl
+    }
+
+    override fun getLabReportList(idNo: String, organizationId: String): List<LabReportDTO> {
+        val result = ArrayList<LabReportDTO>()
+//        val reportList = labReportDao.findByHZSFZAndYLJGDM(idNo, organizationId)
+//        if (!reportList.isNullOrEmpty()) {
+//            reportList.forEach {
+//                val reportDTO = LabReportDTO().apply {
+//                    this.projectname = it.jybgdmc
+//                    this.patientype = it.brbslb
+//                    this.reportno = it.jybgdh
+//                    this.patientname = it.hzxm
+//                    this.sex = it.xb
+//                    this.sampletype = it.bzlb
+//                    this.clinicno = it.jzlsh
+//                    this.department = it.jybgdjg
+//                }
+//                result.add(reportDTO)
+//            }
+//        }
+        return result
+    }
+
+    override fun getLabReportDetail(reportNo: String, organizationId: String, idNo: String): LabReportDTO {
+//        val report = labReportDao.findByHZSFZAndJYBGDHAndYLJGDM(idNo, reportNo, organizationId)
+//                ?: throw MedicineException("未找到检验报告编号为[${reportNo}]的报告")
+        val reportDTO = LabReportDTO().apply {
+            //            this.projectname = report.jybgdmc
+//            this.patientype = report.brbslb
+//            this.reportno = report.jybgdh
+//            this.patientname = report.hzxm
+//            this.sex = report.xb
+//            this.sampletype = report.bzlb
+//            this.clinicno = report.jzlsh
+//            this.department = report.jybgdjg
+//        }
+//        val detailList = labDetailDao.findByJYBGDHAndYLJGDM(reportNo, organizationId)
+//        if (!detailList.isNullOrEmpty()) {
+//            val details = ArrayList<LabDetailDTO>()
+//            detailList.forEach {
+//                val detailDTO = LabDetailDTO().apply {
+//                    this.name = it.jyxmmc
+//                    this.result = it.jydljg
+//                    this.unit = it.jldw
+//                    this.referange = it.ckdx
+//                }
+//                details.add(detailDTO)
+//            }
+//            reportDTO.details = details
+        }
+        return reportDTO
+    }
+
+    override fun getExamReportList(idNo: String, organizationId: String): List<ExamReportDTO> {
+        val result = ArrayList<ExamReportDTO>()
+//        val reportList = examReportDao.findByHZSFZAndYLJGDM(idNo, organizationId)
+//        if (!reportList.isNullOrEmpty()) {
+//            reportList.forEach {
+//                val reportDTO = ExamReportDTO().apply {
+//                    this.examno = it.jcbgdh
+//                    this.name = it.hzxm
+//                    this.sex = it.xb
+//                    this.projectname = it.jcxmmc
+//                    if (it.jcrq != null) {
+//                        this.examdate = SimpleDateFormat("yyyyMMddHHmmss")
+//                                .format(it.jcrq)
+//                    }
+//                    this.applydep = it.sqksmc
+//                    this.examdep = it.bcksmc
+//                    this.exampart = it.jcbw
+//                    this.yinyang = it.yyx
+//                    if (it.jcrq != null) {
+//                        this.reportdate = SimpleDateFormat("yyyyMMddHHmmss")
+//                                .format(it.bgsj)
+//                    }
+//                }
+//                result.add(reportDTO)
+//            }
+//        }
+        return result
+    }
+
+    override fun getExamReportDetail(reportNo: String, organizationId: String, idNo: String): ExamReportDTO {
+//        val report = examReportDao.findByHZSFZAndJCBGDHAndYLJGDM(idNo, reportNo, organizationId)
+//                ?: throw MedicineException("未找到检查报告编号为[${reportNo}]的报告")
+        return ExamReportDTO().apply {
+            //            examno = report.jcbgdh
+//            name = report.hzxm
+//            sex = report.xb
+//            projectname = report.jcxmmc
+//            applydep = report.sqksmc
+//            examdep = report.bcksmc
+//            exampart = report.jcbw
+//            yinyang = report.yyx
+//            description = report.bckgsj
+//            diagnosis = report.jczdhts
+//            remark = report.bgbz
+//            if (report.jcrq != null) {
+//                examdate = SimpleDateFormat("yyyyMMddHHmmss")
+//                        .format(report.jcrq)
+//            }
+//            if (report.jcrq != null) {
+//                reportdate = SimpleDateFormat("yyyyMMddHHmmss")
+//                        .format(report.bgsj)
+//            }
+        }
     }
 }
\ No newline at end of file
diff --git a/backend/src/main/kotlin/com/supwisdom/dlpay/medical/task/NotifyHISAsyncTask.kt b/backend/src/main/kotlin/com/supwisdom/dlpay/medical/task/NotifyHISAsyncTask.kt
index abfafa2..77c0dfd 100644
--- a/backend/src/main/kotlin/com/supwisdom/dlpay/medical/task/NotifyHISAsyncTask.kt
+++ b/backend/src/main/kotlin/com/supwisdom/dlpay/medical/task/NotifyHISAsyncTask.kt
@@ -1,8 +1,7 @@
 package com.supwisdom.dlpay.medical.task
 
 import com.supwisdom.dlpay.framework.service.SystemUtilService
-import com.supwisdom.dlpay.medical.bean.FeeRecordItem
-import com.supwisdom.dlpay.medical.bean.NotifyPayedRequest
+import com.supwisdom.dlpay.medical.bean.*
 import com.supwisdom.dlpay.medical.dao.MedicalDtlDao
 import com.supwisdom.dlpay.medical.exception.MedicineException
 import com.supwisdom.dlpay.medical.util.MedicalClient
@@ -14,6 +13,9 @@
 import org.springframework.scheduling.annotation.Async
 import org.springframework.stereotype.Component
 import org.springframework.transaction.annotation.Transactional
+import java.text.SimpleDateFormat
+import java.time.Duration
+import java.time.Instant
 
 @Component
 class NotifyHISAsyncTask {
@@ -56,7 +58,7 @@
             this.payMode = MedicalConstant.PAY_MODE_DLSMK
             this.payState = MedicalConstant.PAY_STATE_PAYED
             this.agtOrderNumber = medicalDtl.refno
-            this.payAmount = medicalDtl.totalfee
+            this.payAmount = medicalDtl.payamount
             this.outOrderNumber = medicalDtl.billno
             this.payer = personResponse.person.name
             this.totalFee = medicalDtl.totalfee
@@ -68,13 +70,47 @@
             })
             this.feeRecords = feeRecords
         }
-        val notifyPayedResponse = medicalClient.notifyPayed(notifyPayedRequest)
-        if (notifyPayedResponse != null && !notifyPayedResponse.feeRecords.isNullOrEmpty()) {
-            medicalDtl.resultid = notifyPayedResponse.resultId
-            medicalDtl.resultdate = systemUtilService.sysdatetime.hostdate
-            medicalDtlDao.save(medicalDtl)
+        val result = medicalClient.notifyPayed(notifyPayedRequest)
+        if (result.code == MedicalConstant.MEDICAL_RESPONSE_SUCCESS) {
+            val notifyPayedResponse = result.data[0]
+            if (notifyPayedResponse != null && !notifyPayedResponse.feeRecords.isNullOrEmpty()) {
+                medicalDtl.resultid = notifyPayedResponse.resultId
+                medicalDtl.resultdate = systemUtilService.sysdatetime.hostdate
+                medicalDtlDao.save(medicalDtl)
+            } else {
+                logger.error("向HIS结算确认失败")
+            }
         } else {
-            logger.error("向HIS结算确认失败")
+            logger.error("调用医疗结算确认接口异常,code:" + result.code + ";message:" + result.message)
+            //如果确认接口重复调用会报错,此处可以查询已支付列表中是否有该订单来确认是否已通知HIS成功
+            val payedPatientIdList = ArrayList<PatientId>()
+            payedPatientIdList.add(PatientId().apply { medicalDtl.patientid })
+            //查询近三天的流水,医疗系统时间格式为 yyyy-MM-dd HH:mm:ss
+            val sdf = SimpleDateFormat("yyyy-MM-dd")
+            val currentDate = SimpleDateFormat("yyyyMMdd").parse(systemUtilService.sysdatetime.hostdate)
+            val endTime = sdf.format(currentDate)
+            val beginTime = sdf.format(Instant.ofEpochMilli(currentDate.time).minus(Duration.ofDays(2)).toEpochMilli())
+
+            val payedRequest = PayedRequest()
+            payedRequest.organizationId = medicalDtl.organizationid
+            payedRequest.queryType = MedicalConstant.ORDER_QUERYTYPE_PATIENTID
+            payedRequest.patientIdList = payedPatientIdList
+            payedRequest.executeFlag = MedicalConstant.PAYED_EXECUTEFLAG_INVALID
+            payedRequest.outpatientType = MedicalConstant.PAYED_OUTPATIENTTYPE_NORMAL
+            payedRequest.beginTime = "$beginTime 00:00:00"
+            payedRequest.endTime = "$endTime 23:59:59"
+            val payedResponse = medicalClient.getPayedList(payedRequest)
+            if (!payedResponse.invoiceList.isNullOrEmpty()) {
+                payedResponse.invoiceList.forEach {
+                    // 在已支付列表中查到发票号一致的流水说明通知成功
+                    if (it.invoiceNumber == medicalDtl.invoiceno && it.payStatus == "0") {
+                        // 已支付接口返回数据中无resultId参数,暂以"success"代替
+                        medicalDtl.resultid = MedicalConstant.DTL_STATUS_SUCCESS
+                        medicalDtl.resultdate = systemUtilService.sysdatetime.hostdatetime
+                        medicalDtlDao.save(medicalDtl)
+                    }
+                }
+            }
         }
     }
 }
\ No newline at end of file
diff --git a/backend/src/main/resources/data-postgresql.sql b/backend/src/main/resources/data-postgresql.sql
index 06cac44..3e2e5e2 100644
--- a/backend/src/main/resources/data-postgresql.sql
+++ b/backend/src/main/resources/data-postgresql.sql
@@ -24,6 +24,8 @@
 INSERT INTO "tb_businesspara"("parakey", "paraval", "tenantid") VALUES ('portal.amapurl', 'https://webapi.amap.com/maps?v=1.4.15&key=', '{tenentid}');
 INSERT INTO "tb_businesspara"("parakey", "paraval", "tenantid") VALUES ('medical.url', 'http://1.10.10.252:8380/phis/', '{tenentid}');
 INSERT INTO "tb_businesspara"("parakey", "paraval", "tenantid") VALUES ('medical.shopaccno', '462078377', '{tenentid}');
+INSERT INTO "tb_businesspara"("parakey", "paraval", "tenantid") VALUES ('medical.savejson', '1', '{tenentid}');
+
 
 
 
diff --git a/config/application-devel-pg.properties b/config/application-devel-pg.properties
index 3967e95..e512487 100644
--- a/config/application-devel-pg.properties
+++ b/config/application-devel-pg.properties
@@ -2,6 +2,7 @@
 # create and drop tables and sequences, loads import.sql
 spring.jpa.hibernate.ddl-auto=update
 spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
+spring.jpa.hibernate.naming.physical-strategy=com.supwisdom.dlpay.framework.jpa.UpperTableStrategy
 spring.jpa.properties.hibernate.temp.use_jdbc_metadata_defaults=false
 # Postgresql settings
 spring.datasource.platform=postgresql