Parcourir la source

feature 微信支付以及回调相关功能完善

xiahan il y a 4 mois
Parent
commit
61e4c57301
25 fichiers modifiés avec 709 ajouts et 146 suppressions
  1. 0 15
      zhsw-common/pom.xml
  2. 3 0
      zhsw-common/src/main/java/com/rongwei/zhsw/system/dao/CommonBusinessDao.java
  3. 5 0
      zhsw-common/src/main/java/com/rongwei/zhsw/system/dao/SwBillingRecordDao.java
  4. 66 53
      zhsw-common/src/main/java/com/rongwei/zhsw/system/service/impl/SwBillingRecordServiceImpl.java
  5. 26 16
      zhsw-common/src/main/java/com/rongwei/zhsw/system/utils/WxApi.java
  6. 19 0
      zhsw-common/src/main/java/com/rongwei/zhsw/system/wechat/PayMentService.java
  7. 3 0
      zhsw-common/src/main/java/com/rongwei/zhsw/system/wechat/PaymentRecordService.java
  8. 5 1
      zhsw-common/src/main/java/com/rongwei/zhsw/system/wechat/impl/BillServiceImpl.java
  9. 182 0
      zhsw-common/src/main/java/com/rongwei/zhsw/system/wechat/impl/PayMentServiceImpl.java
  10. 117 5
      zhsw-common/src/main/java/com/rongwei/zhsw/system/wechat/impl/PaymentRecordServiceImpl.java
  11. 7 0
      zhsw-common/src/main/resources/mybatis/zhsw/CommonBusinessDao.xml
  12. 9 0
      zhsw-common/src/main/resources/mybatis/zhsw/SwBillingRecordDao.xml
  13. 13 35
      zhsw-entity/src/main/java/com/rongwe/zhsw/system/domain/SwBillingRecordDo.java
  14. 20 4
      zhsw-entity/src/main/java/com/rongwe/zhsw/system/domain/SwEnterpriseConfigInfoDo.java
  15. 3 1
      zhsw-entity/src/main/java/com/rongwe/zhsw/system/domain/SwFeedBackOpinionDo.java
  16. 3 1
      zhsw-entity/src/main/java/com/rongwe/zhsw/system/domain/SwNotificationAnnouncementDo.java
  17. 3 1
      zhsw-entity/src/main/java/com/rongwe/zhsw/system/domain/SwPrintRepairConfigDo.java
  18. 2 1
      zhsw-entity/src/main/java/com/rongwe/zhsw/system/domain/SwUserManagementDo.java
  19. 3 1
      zhsw-entity/src/main/java/com/rongwe/zhsw/system/domain/SwUserRepairDo.java
  20. 3 1
      zhsw-entity/src/main/java/com/rongwe/zhsw/system/domain/SwUserWechatDo.java
  21. 23 0
      zhsw-entity/src/main/java/com/rongwe/zhsw/system/vo/CreatePaymentRecordVo.java
  22. 65 0
      zhsw-entity/src/main/java/com/rongwe/zhsw/system/vo/PrepayNoticeVo.java
  23. 101 0
      zhsw-entity/src/main/java/com/rongwe/zhsw/system/vo/WeChatPayTransactionVo.java
  24. 26 9
      zhsw-server/src/main/java/com/rongwei/zhsw/system/controller/weChat/PayMentController.java
  25. 2 2
      zhsw-server/src/main/resources/bootstrap-dev.yml

+ 0 - 15
zhsw-common/pom.xml

@@ -28,27 +28,12 @@
             <version>1.0-SNAPSHOT</version>
             <scope>compile</scope>
         </dependency>
-        <dependency>
-            <groupId>org.jetbrains.kotlin</groupId>
-            <artifactId>kotlin-stdlib</artifactId>
-            <version>2.1.20</version>
-        </dependency>
-        <dependency>
-            <groupId>org.jetbrains.kotlin</groupId>
-            <artifactId>kotlin-stdlib-jdk8</artifactId>
-            <version>1.8.21</version>
-        </dependency>
         <dependency>
             <groupId>com.squareup.okio</groupId>
             <artifactId>okio-jvm</artifactId>
             <version>3.10.2</version>
             <scope>runtime</scope>
         </dependency>
-        <dependency>
-            <groupId>com.squareup.okhttp3</groupId>
-            <artifactId>okhttp</artifactId>
-            <version>4.12.0</version>
-        </dependency>
         <dependency>
             <groupId>com.github.wechatpay-apiv3</groupId>
             <artifactId>wechatpay-java</artifactId>

+ 3 - 0
zhsw-common/src/main/java/com/rongwei/zhsw/system/dao/CommonBusinessDao.java

@@ -1,5 +1,6 @@
 package com.rongwei.zhsw.system.dao;
 
+import com.rongwe.zhsw.system.domain.SwEnterpriseConfigInfoDo;
 import com.rongwe.zhsw.system.vo.OwnerVo;
 import com.rongwei.rwcommonentity.commonservers.domain.TenantDo;
 import org.apache.ibatis.annotations.Mapper;
@@ -17,4 +18,6 @@ public interface CommonBusinessDao {
     List<TenantDo> getByDsKey(@Param("dsKey") String dsKey);
 
     List<OwnerVo> getOwnerInfoByDsId(@Param("dsId") String dsKey);
+
+    List<SwEnterpriseConfigInfoDo> getSecretKey(@Param("dsKeys") List<String> dsKey);
 }

+ 5 - 0
zhsw-common/src/main/java/com/rongwei/zhsw/system/dao/SwBillingRecordDao.java

@@ -4,6 +4,8 @@ package com.rongwei.zhsw.system.dao;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.rongwe.zhsw.system.domain.SwBillingRecordDo;
 import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Update;
 
 /**
  * 缴费记录(SwBillingRecord)表数据库访问层
@@ -13,5 +15,8 @@ import org.apache.ibatis.annotations.Mapper;
  */
 @Mapper
 public interface SwBillingRecordDao extends BaseMapper<SwBillingRecordDo> {
+
+
+    void updateWeChatPayInfo(@Param("dseKey") String dseKey, @Param("orderNo") String orderNo, @Param("wechatNo") String wechatNo, @Param("desc") String desc);
 }
 

+ 66 - 53
zhsw-common/src/main/java/com/rongwei/zhsw/system/service/impl/SwBillingRecordServiceImpl.java

@@ -2,8 +2,12 @@ package com.rongwei.zhsw.system.service.impl;
 
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import com.rongwe.zhsw.system.domain.*;
+import com.rongwe.zhsw.system.domain.SwBillManagementPaidDo;
+import com.rongwe.zhsw.system.domain.SwBillManagementUnpaidDo;
+import com.rongwe.zhsw.system.domain.SwBillingRecordDo;
+import com.rongwe.zhsw.system.domain.SwUserManagementDo;
 import com.rongwe.zhsw.system.dto.PaymentRequestDTO;
+import com.rongwei.commonservice.service.impl.RedisServiceImpl;
 import com.rongwei.rwadmincommon.system.vo.SysUserVo;
 import com.rongwei.rwcommon.base.R;
 import com.rongwei.rwcommon.base.exception.CustomException;
@@ -57,31 +61,33 @@ public class SwBillingRecordServiceImpl extends ServiceImpl<SwBillingRecordDao,
     @Autowired
     private SwUserManagementService swUserManagementService;
 
-    private final Logger log = LoggerFactory.getLogger(this.getClass().getName());
 
+    private final Logger log = LoggerFactory.getLogger(this.getClass().getName());
 
 
     /**
      * 缴费记录生成
+     *
      * @param paymentRequestDTO
      * @return
      * @throws Exception
      */
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public R windowPayment(PaymentRequestDTO paymentRequestDTO) throws Exception {
 
         log.info("窗口缴费开始");
-        if (paymentRequestDTO.getIds()!=null && !paymentRequestDTO.getIds().isEmpty()){
+        if (paymentRequestDTO.getIds() != null && !paymentRequestDTO.getIds().isEmpty()) {
 
             // 查询待缴费账单
             List<SwBillManagementUnpaidDo> unpaidBills = queryUnpaidBills(paymentRequestDTO.getIds());
 
             //生成缴费记录
-            addNewBillRecord(paymentRequestDTO,unpaidBills);
-        }else {
+            addNewBillRecord(paymentRequestDTO, unpaidBills);
+        } else {
 
             //生成缴费记录
-            addNewBillRecord(paymentRequestDTO,null);
+            addNewBillRecord(paymentRequestDTO, null);
         }
 
         log.info("窗口缴费结束");
@@ -90,9 +96,9 @@ public class SwBillingRecordServiceImpl extends ServiceImpl<SwBillingRecordDao,
     }
 
 
-
     /**
      * 删除 待收账单数据
+     *
      * @param ids
      */
     public void deleteUnpaidBills(List<String> ids) {
@@ -101,7 +107,8 @@ public class SwBillingRecordServiceImpl extends ServiceImpl<SwBillingRecordDao,
 
 
     /**
-     *  根据户号查询 待缴费 状态 无缴费记录的 的待缴费账单
+     * 根据户号查询 待缴费 状态 无缴费记录的 的待缴费账单
+     *
      * @param ids
      * @return
      */
@@ -117,29 +124,29 @@ public class SwBillingRecordServiceImpl extends ServiceImpl<SwBillingRecordDao,
     // 提取公共字段设置
     public SwBillingRecordDo buildBaseBillingRecord( SysUserVo currentUser, SwUserManagementDo user) {
         SwBillingRecordDo record = new SwBillingRecordDo();
-
         //缴费编号
         generateBillingNumber(record);
-
-        return record.setChargedate(new Date())
-                .setPayfeesstatus(PAIDSTATUS)
-                .setYear(Calendar.getInstance().get(Calendar.YEAR))
-                .setUsername(user.getUsername())
-                .setUsernumber(user.getUsernumber())
-                .setUsertype(user.getUsertype())
-                .setWatertype(user.getWatertype())
-                .setAddress(user.getAddress())
-                .setTollcollectorid(currentUser.getId())
-                .setTollcollectorname(currentUser.getName())
-                .setTenantid(currentUser.getTenantid())
-                .setCreateuserid(currentUser.getId())
-                .setCreateusername(currentUser.getName())
-                .setCreatedate(new Date())
-                .setModifydate(new Date())
-                .setModifyuserid(currentUser.getId())
-                .setTenantid(currentUser.getTenantid())
-
-                .setModifyusername(currentUser.getName());
+        record.setId(SecurityUtil.getUUID());
+        record.setChargedate(new Date());
+        record.setPayfeesstatus(PAIDSTATUS);
+        record.setYear(Calendar.getInstance().get(Calendar.YEAR));
+        record.setUsername(user.getUsername());
+        record.setUsernumber(user.getUsernumber());
+        record.setUsertype(user.getUsertype());
+        record.setWatertype(user.getWatertype());
+        record.setAddress(user.getAddress());
+        record.setTollcollectorid(currentUser.getId());
+        record.setTollcollectorname(currentUser.getName());
+        record.setTenantid(currentUser.getTenantid());
+        record.setCreateuserid(currentUser.getId());
+        record.setCreateusername(currentUser.getName());
+        record.setCreatedate(new Date());
+        record.setModifydate(new Date());
+        record.setModifyuserid(currentUser.getId());
+        record.setTenantid(currentUser.getTenantid());
+        record.setModifyusername(currentUser.getName());
+
+        return record;
     }
 
 
@@ -155,13 +162,13 @@ public class SwBillingRecordServiceImpl extends ServiceImpl<SwBillingRecordDao,
 
         SysUserVo currentUser = ZHSWCommonUtils.getCurrentUser();
 
-        List<SwBillManagementPaidDo> bills =new ArrayList<>();
+        List<SwBillManagementPaidDo> bills = new ArrayList<>();
 
         //根据户号获取 用户记录
         SwUserManagementDo user = swUserManagementService.getBaseMapper().
                 selectOne(new LambdaQueryWrapper<SwUserManagementDo>().eq(SwUserManagementDo::getUsernumber, paymentRequestDTO.getUsernumber()));
 
-        if(user==null){
+        if (user == null) {
             throw new CustomException("户号不存在");
         }
 
@@ -175,7 +182,7 @@ public class SwBillingRecordServiceImpl extends ServiceImpl<SwBillingRecordDao,
         // 计算费用
         calculateFees(list, add, user);
 
-        if(list!=null){
+        if (list != null) {
             //生成已缴费账单
             bills = createBills(list, add);
 
@@ -195,6 +202,7 @@ public class SwBillingRecordServiceImpl extends ServiceImpl<SwBillingRecordDao,
 
     /**
      * 存储,修改数据
+     *
      * @param add
      * @param user
      * @param bills
@@ -206,20 +214,20 @@ public class SwBillingRecordServiceImpl extends ServiceImpl<SwBillingRecordDao,
         //账单缴费记录生成
         this.baseMapper.insert(add);
         //已缴费账单生成
-        if (!bills.isEmpty()){
+        if (!bills.isEmpty()) {
             swBillManagementPaidService.saveBatch(bills);
         }
-        if (ids!=null && !ids.isEmpty()){
+        if (ids != null && !ids.isEmpty()) {
             //删除 待收账单数据
             deleteUnpaidBills(ids);
         }
 
         //更新用户余额
-        updateUserBalance(add,user);
+        updateUserBalance(add, user);
 
     }
 
-    private List<SwBillManagementPaidDo> createBills(List<SwBillManagementUnpaidDo> list, SwBillingRecordDo add) {
+    public List<SwBillManagementPaidDo> createBills(List<SwBillManagementUnpaidDo> list, SwBillingRecordDo add) {
         List<SwBillManagementPaidDo> paidList = new ArrayList<>();
         SwBillManagementPaidDo paid;
         for (SwBillManagementUnpaidDo unpaid : list) {
@@ -229,7 +237,7 @@ public class SwBillingRecordServiceImpl extends ServiceImpl<SwBillingRecordDao,
             paid.setStatus(PAIDINSTATUS)
                     //缴费记录ID
                     .setPaymentrecordid(add.getId());
-            ZHSWCommonUtils.initModelGeneralParameters(paid,null);
+            ZHSWCommonUtils.initModelGeneralParameters(paid, null);
             paidList.add(paid);
         }
         // 保存已缴费账单
@@ -248,31 +256,35 @@ public class SwBillingRecordServiceImpl extends ServiceImpl<SwBillingRecordDao,
         swUserManagementService.balanceAdd(user.getId(), balanceChange);
     }
 
-
-
+    /**
+     * 设置减免金额 原应缴 滞纳金 账户余额 原余额 余额抵扣 实际应缴 缴费后余额
+     * @param list
+     * @param add
+     * @param user
+     */
     public void calculateFees(List<SwBillManagementUnpaidDo> list, SwBillingRecordDo add, SwUserManagementDo user) {
 
 
         // 用户 账户余额
-        BigDecimal accountbalance = user.getAccountbalance()==null?BigDecimal.ZERO:user.getAccountbalance();
-        BigDecimal totalWaivers =BigDecimal.ZERO;
-        BigDecimal totalOught =BigDecimal.ZERO;
-        BigDecimal totalLateFees =BigDecimal.ZERO;
+        BigDecimal accountbalance = user.getAccountbalance() == null ? BigDecimal.ZERO : user.getAccountbalance();
+        BigDecimal totalWaivers = BigDecimal.ZERO;
+        BigDecimal totalOught = BigDecimal.ZERO;
+        BigDecimal totalLateFees = BigDecimal.ZERO;
 
 
-        if (list!=null){
+        if (list != null) {
             // 使用Stream API进行汇总计算
-             totalWaivers = list.stream()
+            totalWaivers = list.stream()
                     .map(SwBillManagementUnpaidDo::getFeewaiver)
                     .filter(Objects::nonNull)
                     .reduce(BigDecimal.ZERO, BigDecimal::add);
 
-             totalOught = list.stream()
+            totalOught = list.stream()
                     .map(SwBillManagementUnpaidDo::getOughttohavepaid)
                     .filter(Objects::nonNull)
                     .reduce(BigDecimal.ZERO, BigDecimal::add);
 
-             totalLateFees = list.stream()
+            totalLateFees = list.stream()
                     .map(SwBillManagementUnpaidDo::getLatefees)
                     .filter(Objects::nonNull)
                     .reduce(BigDecimal.ZERO, BigDecimal::add);
@@ -291,15 +303,15 @@ public class SwBillingRecordServiceImpl extends ServiceImpl<SwBillingRecordDao,
         add.setOriginalbalance(accountbalance);
         //1、当 【余额】 >=【原应缴(元)】-【总减免(元)】 +【滞纳金(元)】  时,【余额抵扣】字段=【原应缴(元)】-【总减免(元)】 +【滞纳金(元)】
         //2、当 【余额】 <【原应缴(元)】-【总减免(元)】 +【滞纳金(元)】  时,【余额抵扣】字段=【账户余额(元)】
-        if(totalOught.subtract(totalWaivers).add(totalLateFees).compareTo(accountbalance)<0){
+        if (totalOught.subtract(totalWaivers).add(totalLateFees).compareTo(accountbalance) < 0) {
             add.setBalancededuction(totalOught.add(totalWaivers).subtract(totalLateFees));
-        }else {
+        } else {
             add.setBalancededuction(accountbalance);
         }
         // 【实际应缴(元)】  【原应缴(元)】-【总减免(元)】 +【滞纳金(元)】 >0 = 【原应缴(元)】-【总减免(元)】 +【滞纳金(元)】 else  0
-        BigDecimal actualdue =BigDecimal.ZERO;
-        if (totalOught.subtract(totalWaivers).add(totalLateFees).compareTo(BigDecimal.ZERO)>-1){
-            actualdue=totalOught.subtract(totalWaivers).add(totalLateFees);
+        BigDecimal actualdue = BigDecimal.ZERO;
+        if (totalOught.subtract(totalWaivers).add(totalLateFees).compareTo(BigDecimal.ZERO) > -1) {
+            actualdue = totalOught.subtract(totalWaivers).add(totalLateFees);
         }
         add.setActualdue(actualdue);
 
@@ -311,9 +323,10 @@ public class SwBillingRecordServiceImpl extends ServiceImpl<SwBillingRecordDao,
 
     /**
      * 年月日 +
+     *
      * @param add 3位数 随机数
      */
-    private void generateBillingNumber(SwBillingRecordDo add) {
+    public void generateBillingNumber(SwBillingRecordDo add) {
         SecureRandom random = new SecureRandom();
         int randomNumber = random.nextInt(1000);
         String randomStr = String.format("%03d", randomNumber);

+ 26 - 16
zhsw-common/src/main/java/com/rongwei/zhsw/system/utils/WxApi.java

@@ -4,46 +4,56 @@ import com.rongwe.zhsw.system.vo.WxPrepayOrderVo;
 import com.wechat.pay.java.core.Config;
 import com.wechat.pay.java.core.RSAAutoCertificateConfig;
 import com.wechat.pay.java.service.payments.jsapi.JsapiServiceExtension;
-import com.wechat.pay.java.service.payments.jsapi.model.Amount;
-import com.wechat.pay.java.service.payments.jsapi.model.Payer;
-import com.wechat.pay.java.service.payments.jsapi.model.PrepayRequest;
-import com.wechat.pay.java.service.payments.jsapi.model.PrepayWithRequestPaymentResponse;
-import org.springframework.core.io.ClassPathResource;
+import com.wechat.pay.java.service.payments.jsapi.model.*;
 import com.wechat.pay.java.service.payments.model.Transaction;
-import com.wechat.pay.java.service.payments.jsapi.model.QueryOrderByIdRequest;
-import com.wechat.pay.java.service.payments.jsapi.model.QueryOrderByOutTradeNoRequest;
+import lombok.SneakyThrows;
 
+import java.net.URLDecoder;
+import java.nio.charset.StandardCharsets;
 
-public class WxApi {
+
+public class WxPayApi {
     /**
      * 商户号
      */
-    public String merchantId = "1711246421";
+    public String merchantId;
 
     /**
      * 商户API私钥路径
      */
-    public String privateKeyPath = "D:\\code\\project\\zhsw\\zhsw_service\\zhsw-server\\src\\main\\resources\\cert\\apiclient_key.pem";
+    public String privateKeyPath;
 
     /**
      * 商户证书序列号
      */
-    public String merchantSerialNumber = "6F46F471C22D410F9ECEDC8B197979A4CA42BC96";
+    public String merchantSerialNumber;
 
     /**
      * 商户APIV3密钥
      */
-    public String apiV3Key = "GBA67AVWJESPJ3TFJ3GT3NLQBEOTO1FW";
+    public String apiV3Key;
+
+    private String appId;
+
+    public WxPayApi(String merchantId, String privateKeyPath , String merchantSerialNumber, String apiV3Key, String appId) {
+       this.merchantId = merchantId;
+       this.privateKeyPath = privateKeyPath;
+       this.merchantSerialNumber = merchantSerialNumber;
+       this.apiV3Key = apiV3Key;
+       this.appId = appId;
+    }
 
     public JsapiServiceExtension service;
 
+    @SneakyThrows
     public void initMerchant() {
-        ClassPathResource classPathResource = new ClassPathResource("cert/apiclient_key.pem");
+        String keyPath = WxPayApi.class.getClassLoader().getResource("").getPath() + privateKeyPath+"/apiclient_key.pem";
+        keyPath = URLDecoder.decode(keyPath, StandardCharsets.UTF_8.toString());
         Config config =
                 new RSAAutoCertificateConfig.Builder()
                         .merchantId(merchantId)
                         // 使用 com.wechat.pay.java.core.util 中的函数从本地文件中加载商户私钥,商户私钥会用来生成请求的签名
-                        .privateKeyFromPath(privateKeyPath)
+                        .privateKeyFromPath(keyPath)
                         .merchantSerialNumber(merchantSerialNumber)
                         .apiV3Key(apiV3Key)
                         .build();
@@ -56,13 +66,13 @@ public class WxApi {
     public PrepayWithRequestPaymentResponse prepayWithRequestPayment(WxPrepayOrderVo vo) {
         PrepayRequest request = new PrepayRequest();
         // 小程序appid
-        request.setAppid("wxaec1c618349b81a5");
+        request.setAppid(appId);
         // 商户id
         request.setMchid(merchantId);
         request.setDescription(vo.getDescription());
         request.setOutTradeNo(vo.getOutTradeNo());
         // 接收通知的url
-        request.setNotifyUrl("https://www.weixin.qq.com/wxpay/pay.php");
+        request.setNotifyUrl("http://61.177.40.178:8000/zhsw/wechat/payment/prepay/notice");
         Amount amount = new Amount();
         amount.setTotal(vo.getTotalAmount());
         amount.setCurrency("CNY");

+ 19 - 0
zhsw-common/src/main/java/com/rongwei/zhsw/system/wechat/PayMentService.java

@@ -0,0 +1,19 @@
+package com.rongwei.zhsw.system.wechat;
+
+import com.rongwe.zhsw.system.vo.PrepayNoticeVo;
+import com.rongwe.zhsw.system.vo.WxPrepayOrderVo;
+import com.rongwei.rwcommon.base.R;
+
+import java.io.IOException;
+
+/**
+ * PayMentService class
+ *
+ * @author XH
+ * @date 2025/03/25
+ */
+public interface PayMentService {
+    R paymentInitiation(WxPrepayOrderVo vo);
+
+    R prepayNotice(PrepayNoticeVo prepayNoticeVo) throws IOException;
+}

+ 3 - 0
zhsw-common/src/main/java/com/rongwei/zhsw/system/wechat/PaymentRecordService.java

@@ -1,9 +1,12 @@
 package com.rongwei.zhsw.system.wechat;
 
+import com.rongwe.zhsw.system.vo.CreatePaymentRecordVo;
 import com.rongwe.zhsw.system.vo.PaymentRocordVo;
 import com.rongwei.rwcommon.base.R;
 
 public interface PaymentRecordService {
 
     R getPaymentRecordList(PaymentRocordVo paymentRocordVo);
+
+    R createRecord(CreatePaymentRecordVo createPaymentRecordVo);
 }

+ 5 - 1
zhsw-common/src/main/java/com/rongwei/zhsw/system/wechat/impl/BillServiceImpl.java

@@ -25,6 +25,7 @@ import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.stream.Collectors;
 
 /**
  * BillServiceImpl class
@@ -62,6 +63,7 @@ public class BillServiceImpl implements BillService {
                 .eq(SwBillManagementUnpaidDo::getDeleted, 0)
                 .eq(SwBillManagementUnpaidDo::getUsernumber, accountNum)
                 .eq(SwBillManagementUnpaidDo::getYear, year)
+                .eq(SwBillManagementUnpaidDo::getStatus,2)
                 .orderByDesc(SwBillManagementUnpaidDo::getYear)
                 .orderByDesc(SwBillManagementUnpaidDo::getMonth));
         // 已缴账单
@@ -122,14 +124,16 @@ public class BillServiceImpl implements BillService {
         // 获取所有待缴费账单
         List<SwBillManagementUnpaidDo> outstandingBills = swBillManagementUnpaidService.list(new LambdaQueryWrapper<SwBillManagementUnpaidDo>()
                 .eq(SwBillManagementUnpaidDo::getDeleted, 0)
+                .eq(SwBillManagementUnpaidDo::getStatus,2)
                 .eq(SwBillManagementUnpaidDo::getUsernumber, accountNumber));
         // 获取余额信息
         SwUserManagementDo swUserManagementDo = swUserManagementService.getOne(new LambdaQueryWrapper<SwUserManagementDo>()
                 .eq(BaseDo::getDeleted, "0")
                 .eq(SwUserManagementDo::getUsernumber, accountNumber));
-        Map<String, BigDecimal> returnMao = new HashMap<String, BigDecimal>();
+        Map<String, Object> returnMao = new HashMap<String, Object>();
         returnMao.put("yj",outstandingBills.stream().map(SwBillManagementUnpaidDo::getActualdue).reduce(BigDecimal.ZERO, BigDecimal::add));
         returnMao.put("ye",swUserManagementDo.getAccountbalance());
+        returnMao.put("zdId",outstandingBills.stream().map(SwBillManagementUnpaidDo::getId).collect(Collectors.joining(",")));
         return R.ok(returnMao);
     }
 }

+ 182 - 0
zhsw-common/src/main/java/com/rongwei/zhsw/system/wechat/impl/PayMentServiceImpl.java

@@ -0,0 +1,182 @@
+package com.rongwei.zhsw.system.wechat.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.rongwe.zhsw.system.domain.SwEnterpriseConfigInfoDo;
+import com.rongwe.zhsw.system.vo.PrepayNoticeVo;
+import com.rongwe.zhsw.system.vo.WeChatPayTransactionVo;
+import com.rongwe.zhsw.system.vo.WxPrepayOrderVo;
+import com.rongwei.commonservice.service.impl.RedisServiceImpl;
+import com.rongwei.rwcommon.base.BaseDo;
+import com.rongwei.rwcommon.base.R;
+import com.rongwei.rwcommon.base.exception.CustomException;
+import com.rongwei.rwcommonentity.commonservers.domain.TenantDo;
+import com.rongwei.zhsw.system.config.WeChatLoginApiPara;
+import com.rongwei.zhsw.system.dao.CommonBusinessDao;
+import com.rongwei.zhsw.system.service.impl.SwBillingRecordServiceImpl;
+import com.rongwei.zhsw.system.service.impl.SwEnterpriseConfigInfoServiceImpl;
+import com.rongwei.zhsw.system.utils.WxPayApi;
+import com.rongwei.zhsw.system.wechat.PayMentService;
+import com.wechat.pay.java.service.payments.jsapi.model.PrepayWithRequestPaymentResponse;
+import org.apache.commons.lang.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import javax.crypto.Cipher;
+import javax.crypto.spec.GCMParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
+import java.io.IOException;
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * PayMentServiceImpl class
+ *
+ * @author XH
+ * @date 2025/03/25
+ */
+@Service
+public class PayMentServiceImpl implements PayMentService {
+    private static final Logger log = LoggerFactory.getLogger(PayMentServiceImpl.class);
+
+
+    @Autowired
+    private SwEnterpriseConfigInfoServiceImpl swEnterpriseConfigInfoService;
+    @Autowired
+    private WeChatLoginApiPara weChatLoginApiPara;
+    @Autowired
+    private RedisServiceImpl redisService;
+    @Autowired
+    private CommonBusinessDao commonBusinessDao;
+    @Autowired
+    private SwBillingRecordServiceImpl swBillingRecordService;
+
+
+    static final int TAG_LENGTH_BIT = 128;
+
+    @Override
+    public R paymentInitiation(WxPrepayOrderVo vo) {
+        log.info("开始发起付款申请");
+        // 获取商户基本信息
+        SwEnterpriseConfigInfoDo swEnterpriseConfigInfoDo = swEnterpriseConfigInfoService.getOne(new LambdaQueryWrapper<SwEnterpriseConfigInfoDo>().eq(BaseDo::getDeleted, "0"));
+        if (swEnterpriseConfigInfoDo == null) {
+            throw new CustomException("商户配置异常");
+        }
+        log.debug("获取到商户信息:{}", swEnterpriseConfigInfoDo.getEnterprisename());
+        String enterpriseno = swEnterpriseConfigInfoDo.getEnterpriseno();
+        String merchantid = swEnterpriseConfigInfoDo.getMerchantid();
+        String merchantname = swEnterpriseConfigInfoDo.getMerchantname();
+        String merchantprivatekey = swEnterpriseConfigInfoDo.getMerchantprivatekey();
+        String merchantserialnumber = swEnterpriseConfigInfoDo.getMerchantserialnumber();
+        String merchantsecretkey = swEnterpriseConfigInfoDo.getMerchantsecretkey();
+        if (StringUtils.isBlank(enterpriseno)) {
+            log.error("支付参数:企业编号 为空");
+            throw new CustomException("商户支付配置错误,请联系系统管理员!");
+        }
+        if (StringUtils.isBlank(merchantid)) {
+            log.error("支付参数:商户ID 为空");
+            throw new CustomException("商户支付配置错误,请联系系统管理员!");
+        }
+        if (StringUtils.isBlank(merchantname)) {
+            log.error("支付参数:商户名称 为空");
+            throw new CustomException("商户支付配置错误,请联系系统管理员!");
+        }
+        if (StringUtils.isBlank(merchantprivatekey)) {
+            log.error("支付参数:商户私钥 为空");
+            throw new CustomException("商户支付配置错误,请联系系统管理员!");
+        }
+        if (StringUtils.isBlank(merchantserialnumber)) {
+            log.error("支付参数:商户序列号 为空");
+            throw new CustomException("商户支付配置错误,请联系系统管理员!");
+        }
+        if (StringUtils.isBlank(merchantsecretkey)) {
+            log.error("支付参数:商户密钥 为空");
+            throw new CustomException("商户支付配置错误,请联系系统管理员!");
+        }
+        if (vo.getTotalAmount() == null || vo.getTotalAmount() <= 0) {
+            log.error("金额验证失败");
+            throw new CustomException("商户支付配置错误,请联系系统管理员!");
+        }
+
+        WxPayApi wxPayApi = new WxPayApi(merchantid, merchantprivatekey, merchantserialnumber, merchantsecretkey, weChatLoginApiPara.getAppid());
+        wxPayApi.initMerchant();
+        // 生成订单号 规则
+        String nonceStr = UUID.randomUUID().toString().replaceAll("-", "");
+        vo.setOutTradeNo(nonceStr);
+        // 商户名称+
+        vo.setDescription(merchantname + "-水费");
+        PrepayWithRequestPaymentResponse prepayWithRequestPaymentResponse = wxPayApi.prepayWithRequestPayment(vo);
+        Map<String, Object> paymentReturnMap = new HashMap<>();
+        paymentReturnMap.put("paymentSign", prepayWithRequestPaymentResponse);
+        paymentReturnMap.put("orderNo", nonceStr);
+        return R.ok(paymentReturnMap);
+    }
+
+    /**
+     * 微信支付成功回调函数
+     *
+     * @param prepayNoticeVo
+     * @return
+     */
+    @Override
+    @Transactional
+    public R prepayNotice(PrepayNoticeVo prepayNoticeVo)  {
+        log.info("获取到的回调信息接口:{}", prepayNoticeVo);
+        List<TenantDo> tenantList = (List<TenantDo>) redisService.getRedisCatchObj("allTenants");
+        if (tenantList == null || tenantList.isEmpty()) {
+            log.error("无法获取到租户信息");
+            return R.error();
+        }
+        // 获取 所有的主库信息
+        List<String> dsKeys = tenantList.stream().map(TenantDo::getDskey).collect(Collectors.toList());
+        dsKeys.remove("incontrol");
+        // 获取所有商户的密钥
+        List<SwEnterpriseConfigInfoDo> secretKeyList = commonBusinessDao.getSecretKey(dsKeys);
+        String analysisStr = null;
+        String deKey = null;
+        for (SwEnterpriseConfigInfoDo swEnterpriseConfigInfoDo : secretKeyList) {
+            byte[] apiV3Key = Base64.getDecoder().decode(swEnterpriseConfigInfoDo.getMerchantsecretkey());
+            byte[] nonce = Base64.getDecoder().decode(prepayNoticeVo.getResource().getNonce());
+            byte[] ciphertext = Base64.getDecoder().decode(prepayNoticeVo.getResource().getCiphertext());
+            byte[] associatedData = Base64.getDecoder().decode(prepayNoticeVo.getResource().getAssociated_data());
+            log.error("微信回调函数");
+            Cipher cipher = null;
+            try {
+                cipher = Cipher.getInstance("AES/GCM/NoPadding");
+                SecretKeySpec key = new SecretKeySpec(apiV3Key, "AES");
+                GCMParameterSpec spec = new GCMParameterSpec(TAG_LENGTH_BIT, nonce);
+                cipher.init(Cipher.DECRYPT_MODE, key, spec);
+                cipher.updateAAD(associatedData);
+                analysisStr = new String(cipher.doFinal(Base64.getDecoder().decode(ciphertext)), "utf-8");
+                deKey = swEnterpriseConfigInfoDo.getTenantid();
+                if (StringUtils.isNotBlank(analysisStr)) {
+                    break;
+                }
+            } catch (Exception e) {
+                log.error("解密异常");
+            }
+        }
+        if (StringUtils.isBlank(analysisStr)) {
+            return R.error();
+        }
+        ObjectMapper mapper = new ObjectMapper();
+        WeChatPayTransactionVo transaction = null;
+        try {
+            transaction = mapper.readValue(analysisStr, WeChatPayTransactionVo.class);
+        } catch (IOException e) {
+            e.printStackTrace();
+           log.error("JSON转换异常");
+            return R.error();
+        }
+        // 微信订单号
+        String transactionId = transaction.getTransactionId();
+        // 商户号
+        String outTradeNo = transaction.getOutTradeNo();
+        // 更新缴费记录相关信息
+        swBillingRecordService.getBaseMapper().updateWeChatPayInfo(deKey,outTradeNo,transactionId,analysisStr);
+        return R.ok();
+    }
+}

+ 117 - 5
zhsw-common/src/main/java/com/rongwei/zhsw/system/wechat/impl/PaymentRecordServiceImpl.java

@@ -2,25 +2,35 @@ package com.rongwei.zhsw.system.wechat.impl;
 
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.rongwe.zhsw.system.domain.SwBillManagementPaidDo;
+import com.rongwe.zhsw.system.domain.SwBillManagementUnpaidDo;
 import com.rongwe.zhsw.system.domain.SwBillingRecordDo;
+import com.rongwe.zhsw.system.domain.SwUserManagementDo;
+import com.rongwe.zhsw.system.vo.CreatePaymentRecordVo;
 import com.rongwe.zhsw.system.vo.PaymentRocordVo;
+import com.rongwei.commonservice.service.impl.RedisServiceImpl;
+import com.rongwei.rwcommon.base.BaseDo;
 import com.rongwei.rwcommon.base.R;
 import com.rongwei.rwcommon.base.exception.CustomException;
+import com.rongwei.rwcommon.utils.SecurityUtil;
 import com.rongwei.zhsw.system.service.impl.SwBillManagementPaidServiceImpl;
+import com.rongwei.zhsw.system.service.impl.SwBillManagementUnpaidServiceImpl;
 import com.rongwei.zhsw.system.service.impl.SwBillingRecordServiceImpl;
+import com.rongwei.zhsw.system.service.impl.SwUserManagementServiceImpl;
+import com.rongwei.zhsw.system.utils.WeChatUtils;
 import com.rongwei.zhsw.system.wechat.PaymentRecordService;
 import org.apache.commons.lang.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.math.BigDecimal;
+import java.util.*;
 import java.util.stream.Collectors;
 
+import static com.rongwei.zhsw.system.utils.SaveConstans.billReccord.PAIDSTATUS;
+
 @Service
 public class PaymentRecordServiceImpl implements PaymentRecordService {
     private static final Logger log = LoggerFactory.getLogger(PaymentRecordServiceImpl.class);
@@ -31,8 +41,15 @@ public class PaymentRecordServiceImpl implements PaymentRecordService {
     @Autowired
     private SwBillManagementPaidServiceImpl swBillManagementPaidService;
 
+    @Autowired
+    private SwUserManagementServiceImpl swUserManagementService;
+
+    @Autowired
+    private SwBillManagementUnpaidServiceImpl swBillManagementUnpaidService;
+
     /**
      * 获取缴费记录及其对应的所有账单
+     *
      * @return
      */
 
@@ -92,7 +109,7 @@ public class PaymentRecordServiceImpl implements PaymentRecordService {
                 billInfo.put("thismeterreadingdate", bill.getThismeterreadingdate());
                 billInfo.put("currentwateruse", bill.getCurrentwateruse());
                 billInfo.put("meterReading", bill.getLastmeterreading().stripTrailingZeros().toPlainString()
-                    + "-" + bill.getThismeterreading().stripTrailingZeros().toPlainString());
+                        + "-" + bill.getThismeterreading().stripTrailingZeros().toPlainString());
                 billInfo.put("feewaiver", bill.getFeewaiver());
                 billInfo.put("latefees", bill.getLatefees());
                 billInfo.put("actualdue", bill.getActualdue());
@@ -105,4 +122,99 @@ public class PaymentRecordServiceImpl implements PaymentRecordService {
 
         return R.ok(returnList);
     }
+
+    /**
+     * 微信缴费记录生成
+     *
+     * @return
+     */
+    @Override
+    public R createRecord(CreatePaymentRecordVo createPaymentRecordVo) {
+        // 微信的openId
+        String currentWeChatOpenId = WeChatUtils.getCurrentWeChatOpenId();
+        String userNUMBER = createPaymentRecordVo.getUserNumber();
+        if (StringUtils.isBlank(userNUMBER)) {
+            log.error("参数错误,户号为空");
+            throw new CustomException("户号为空");
+        }
+        SwUserManagementDo swUserManagementDo = swUserManagementService.getOne(new LambdaQueryWrapper<SwUserManagementDo>()
+                .eq(SwUserManagementDo::getUsernumber, userNUMBER)
+                .eq(BaseDo::getDeleted, "0"));
+        List<SwBillManagementUnpaidDo> unpaidDoList = null;
+        String zdId = createPaymentRecordVo.getZdId();
+        if (StringUtils.isNotBlank(zdId)) {
+            unpaidDoList = swBillManagementUnpaidService.getBaseMapper().selectBatchIds(Arrays.asList(zdId.split(",")));
+        }
+        // 生成缴费记录
+        SwBillingRecordDo swBillingRecordDo = generateRecord(swUserManagementDo, unpaidDoList, createPaymentRecordVo.getPaymentAmount(),
+                createPaymentRecordVo.getOrderNo(), currentWeChatOpenId);
+        // 待缴账单转为已缴账单
+        List<SwBillManagementPaidDo> bills = swBillingRecordService.createBills(unpaidDoList, swBillingRecordDo);
+        dataUpdate(swBillingRecordDo,swUserManagementDo,bills,unpaidDoList);
+        return R.ok();
+    }
+
+    /**
+     * 数据更新
+     */
+    @Transactional
+    public void dataUpdate(SwBillingRecordDo swBillingRecordDo,SwUserManagementDo swUserManagementDo,List<SwBillManagementPaidDo> bills,
+            List<SwBillManagementUnpaidDo> unpaidDoList){
+        BigDecimal balanceChange = swBillingRecordDo.getAfterpaymentbalance().subtract(swUserManagementDo.getAccountbalance());
+        swUserManagementService.balanceAdd(swUserManagementDo.getId(), balanceChange);
+        swBillingRecordService.save(swBillingRecordDo);
+        if(!bills.isEmpty()){
+            swBillManagementPaidService.saveBatch(bills);
+        }
+        if(!unpaidDoList.isEmpty()){
+            swBillManagementUnpaidService.getBaseMapper().deleteByIds(unpaidDoList.stream().map(SwBillManagementUnpaidDo::getId).collect(Collectors.toList()));
+        }
+
+    }
+
+
+    public SwBillingRecordDo generateRecord(SwUserManagementDo swUserManagementDo, List<SwBillManagementUnpaidDo> unpaidDoList,
+                                            BigDecimal paymentAmount,String orderNo,String openId) {
+        Date now = new Date();
+        // 缴费记录
+        SwBillingRecordDo swBillingRecordDo = new SwBillingRecordDo();
+        swBillingRecordDo.setId(SecurityUtil.getUUID());
+        //缴费编号
+        swBillingRecordService.generateBillingNumber(swBillingRecordDo);
+        swBillingRecordDo.setChargedate(now);
+        swBillingRecordDo.setPayfeesstatus(PAIDSTATUS);
+        swBillingRecordDo.setYear(Calendar.getInstance().get(Calendar.YEAR));
+        swBillingRecordDo.setUsername(swUserManagementDo.getUsername());
+        swBillingRecordDo.setUsernumber(swUserManagementDo.getUsernumber());
+        swBillingRecordDo.setUsertype(swUserManagementDo.getUsertypeid());
+        swBillingRecordDo.setWatertype(swUserManagementDo.getWatertype());
+        swBillingRecordDo.setAddress(swUserManagementDo.getAddress());
+        swBillingRecordDo.setTollcollectorid("");
+        swBillingRecordDo.setTollcollectorname("");
+        swBillingRecordDo.setOriginalbalance(swUserManagementDo.getAccountbalance());
+
+        /******************实缴******************/
+        swBillingRecordDo.setPaidin(paymentAmount);
+        swBillingRecordService.calculateFees(unpaidDoList, swBillingRecordDo,swUserManagementDo);
+        swBillingRecordDo.setPaymentmethod("微信");
+        // 微信支付
+        swBillingRecordDo.setDatasource("3");
+        swBillingRecordDo.setMerchantpaymentnumber(orderNo);
+        swBillingRecordDo.setProductdescription("水费");
+        swBillingRecordDo.setAmountpaid(paymentAmount);
+        swBillingRecordDo.setPaymentcompletiontime(now);
+        swBillingRecordDo.setOrdercreationtime(now);
+        swBillingRecordDo.setYear(now.getYear());
+        swBillingRecordDo.setCreateuserid(openId);
+        swBillingRecordDo.setCreateusername(openId);
+        swBillingRecordDo.setCreatedate(now);
+        swBillingRecordDo.setModifydate(now);
+        swBillingRecordDo.setModifyuserid(openId);
+        swBillingRecordDo.setModifyusername(openId);
+        // 暂不新增 通过微信支付回调函数进行新增
+        // swBillingRecordDo.setWechatpayordernumber();
+        // swBillingRecordDo.setPaymentstatus();
+        swBillingRecordDo.setRefundamount(BigDecimal.ZERO);
+        return swBillingRecordDo;
+    }
 }

+ 7 - 0
zhsw-common/src/main/resources/mybatis/zhsw/CommonBusinessDao.xml

@@ -30,4 +30,11 @@
             left join ${dsId}.sw_user_wechat suw on suw.USERID=swm.ID and suw.DELETED='0'
             where swm.DELETED='0'
     </select>
+    <select id="getSecretKey" resultType="com.rongwe.zhsw.system.domain.SwEnterpriseConfigInfoDo">
+        select * from
+        <foreach collection="dsKeys" item="dsKey" open="(" close=") a" separator="union all"  >
+            select #{dsKey} as tenantid, MERCHANTSECRETKEY from ${dsKey}.sw_enterprise_config_info
+        </foreach>
+        where MERCHANTSECRETKEY !='' or MERCHANTSECRETKEY is not null
+    </select>
 </mapper>

+ 9 - 0
zhsw-common/src/main/resources/mybatis/zhsw/SwBillingRecordDao.xml

@@ -0,0 +1,9 @@
+<?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.rongwei.zhsw.system.dao.SwBillingRecordDao">
+        <update id="updateWeChatPayInfo">
+            update ${dseKey}.sw_billing_record set NOTICEDETAILS=#{desc},WECHATPAYORDERNUMBER=#{wechatNo} where MERCHANTPAYMENTNUMBER=#{orderNo}
+        </update>
+</mapper>

+ 13 - 35
zhsw-entity/src/main/java/com/rongwe/zhsw/system/domain/SwBillingRecordDo.java

@@ -2,6 +2,7 @@ package com.rongwe.zhsw.system.domain;
 
 import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableName;
+import com.rongwei.rwcommon.base.BaseDo;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.experimental.Accessors;
@@ -20,7 +21,7 @@ import java.util.Date;
 @EqualsAndHashCode(callSuper = false)
 @Accessors(chain = true)
 @TableName("sw_billing_record")
-public class SwBillingRecordDo implements Serializable {
+public class SwBillingRecordDo extends BaseDo implements Serializable {
     private static final long serialVersionUID = -25780597568495659L;
     /**
      * 主键
@@ -34,38 +35,7 @@ public class SwBillingRecordDo implements Serializable {
      * 扩展json格式配置
      */
     private String roption;
-    /**
-     * 是否删除Y/N
-     */
-    private String deleted;
-    /**
-     * 备注
-     */
-    private String remark;
-    /**
-     * 创建时间
-     */
-    private Date createdate;
-    /**
-     * 创建用户ID
-     */
-    private String createuserid;
-    /**
-     * 修改日期
-     */
-    private Date modifydate;
-    /**
-     * 修改用户ID
-     */
-    private String modifyuserid;
-    /**
-     * 创建人
-     */
-    private String createusername;
-    /**
-     * 修改人
-     */
-    private String modifyusername;
+
     /**
      * 缴费编号
      */
@@ -155,6 +125,7 @@ public class SwBillingRecordDo implements Serializable {
      * 支付金额
      * (元)
      */
+    @Deprecated
     private BigDecimal amountpaid;
     /**
      * 支付完成时间
@@ -183,6 +154,7 @@ public class SwBillingRecordDo implements Serializable {
     /**
      * 总已缴
      */
+    @Deprecated
     private BigDecimal totalpaidin;
     /**
      * 充值缴费金额
@@ -216,7 +188,13 @@ public class SwBillingRecordDo implements Serializable {
      * 退款操作人
      */
     private String refundoperatorname;
-
-
+    /**
+     * 收费方式
+     */
+    private String chargemethod;
+    /**
+     * 支付方式
+     */
+    private String paymentmethod;
 }
 

+ 20 - 4
zhsw-entity/src/main/java/com/rongwe/zhsw/system/domain/SwEnterpriseConfigInfoDo.java

@@ -2,18 +2,20 @@ package com.rongwe.zhsw.system.domain;
 
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
-import java.util.Date;
-
 import com.rongwei.rwcommon.base.BaseDo;
 import lombok.Data;
 
+import java.io.Serializable;
+import java.util.Date;
+
 /**
  * 企业配置信息
+ *
  * @TableName sw_enterprise_config_info
  */
-@TableName(value ="sw_enterprise_config_info")
+@TableName(value = "sw_enterprise_config_info")
 @Data
-public class SwEnterpriseConfigInfoDo extends BaseDo {
+public class SwEnterpriseConfigInfoDo extends BaseDo implements Serializable {
     /**
      * 主键
      */
@@ -94,4 +96,18 @@ public class SwEnterpriseConfigInfoDo extends BaseDo {
      * 商户名称
      */
     private String merchantname;
+
+    /**
+     * 商户私钥目录
+     */
+    private String merchantprivatekey;
+
+    /**
+     * 商户序列号
+     */
+    private String merchantserialnumber;
+    /**
+     * 商户密钥
+     */
+    private String merchantsecretkey;
 }

+ 3 - 1
zhsw-entity/src/main/java/com/rongwe/zhsw/system/domain/SwFeedBackOpinionDo.java

@@ -1,6 +1,8 @@
 package com.rongwe.zhsw.system.domain;
 
 import com.baomidou.mybatisplus.annotation.TableName;
+
+import java.io.Serializable;
 import java.util.Date;
 
 import com.rongwei.rwcommon.base.BaseDo;
@@ -12,7 +14,7 @@ import lombok.Data;
  */
 @TableName(value ="sw_feed_back_opinion")
 @Data
-public class SwFeedBackOpinionDo extends BaseDo {
+public class SwFeedBackOpinionDo extends BaseDo implements Serializable {
     /**
      * 主键
      */

+ 3 - 1
zhsw-entity/src/main/java/com/rongwe/zhsw/system/domain/SwNotificationAnnouncementDo.java

@@ -2,6 +2,8 @@ package com.rongwe.zhsw.system.domain;
 
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
+
+import java.io.Serializable;
 import java.util.Date;
 
 import com.rongwei.rwcommon.base.BaseDo;
@@ -13,7 +15,7 @@ import lombok.Data;
  */
 @TableName(value ="sw_notification_announcement")
 @Data
-public class SwNotificationAnnouncementDo extends BaseDo {
+public class SwNotificationAnnouncementDo extends BaseDo implements Serializable {
     /**
      * 主键
      */

+ 3 - 1
zhsw-entity/src/main/java/com/rongwe/zhsw/system/domain/SwPrintRepairConfigDo.java

@@ -7,13 +7,15 @@ import com.baomidou.mybatisplus.annotation.TableName;
 import com.rongwei.rwcommon.base.BaseDo;
 import lombok.Data;
 
+import java.io.Serializable;
+
 /**
  * 票据打印配置信息
  * @TableName sw_print_repair_config
  */
 @TableName(value ="sw_print_repair_config")
 @Data
-public class SwPrintRepairConfigDo extends BaseDo {
+public class SwPrintRepairConfigDo extends BaseDo implements Serializable {
     /**
      * 主键
      */

+ 2 - 1
zhsw-entity/src/main/java/com/rongwe/zhsw/system/domain/SwUserManagementDo.java

@@ -6,6 +6,7 @@ import com.baomidou.mybatisplus.annotation.TableName;
 import com.rongwei.rwcommon.base.BaseDo;
 import lombok.Data;
 
+import java.io.Serializable;
 import java.math.BigDecimal;
 import java.util.Date;
 
@@ -15,7 +16,7 @@ import java.util.Date;
  */
 @TableName(value ="sw_user_management")
 @Data
-public class SwUserManagementDo extends BaseDo {
+public class SwUserManagementDo extends BaseDo  implements Serializable {
     /**
      * 主键
      */

+ 3 - 1
zhsw-entity/src/main/java/com/rongwe/zhsw/system/domain/SwUserRepairDo.java

@@ -1,6 +1,8 @@
 package com.rongwe.zhsw.system.domain;
 
 import com.baomidou.mybatisplus.annotation.TableName;
+
+import java.io.Serializable;
 import java.util.Date;
 
 import com.rongwei.rwcommon.base.BaseDo;
@@ -12,7 +14,7 @@ import lombok.Data;
  */
 @TableName(value ="sw_user_repair")
 @Data
-public class SwUserRepairDo extends BaseDo {
+public class SwUserRepairDo extends BaseDo implements Serializable {
     /**
      * 主键
      */

+ 3 - 1
zhsw-entity/src/main/java/com/rongwe/zhsw/system/domain/SwUserWechatDo.java

@@ -5,13 +5,15 @@ import com.baomidou.mybatisplus.annotation.TableName;
 import com.rongwei.rwcommon.base.BaseDo;
 import lombok.Data;
 
+import java.io.Serializable;
+
 /**
  * 业主微信关系表
  * @TableName sw_user_wechat
  */
 @TableName(value ="sw_user_wechat")
 @Data
-public class SwUserWechatDo  extends BaseDo {
+public class SwUserWechatDo  extends BaseDo implements Serializable {
     /**
      * 主键
      */

+ 23 - 0
zhsw-entity/src/main/java/com/rongwe/zhsw/system/vo/CreatePaymentRecordVo.java

@@ -0,0 +1,23 @@
+package com.rongwe.zhsw.system.vo;
+
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+/**
+ * CreatrePaymentRecordVo class
+ *
+ * @author XH
+ * @date 2025/03/25
+ */
+@Data
+public class CreatePaymentRecordVo {
+    // 商户订单号
+    private String orderNo;
+    // 付款金额
+    private BigDecimal paymentAmount;
+    // 关联的账单信息
+    private String zdId;
+    // 户号
+    private String userNumber;
+}

+ 65 - 0
zhsw-entity/src/main/java/com/rongwe/zhsw/system/vo/PrepayNoticeVo.java

@@ -0,0 +1,65 @@
+package com.rongwe.zhsw.system.vo;
+
+import lombok.Data;
+
+/**
+ * PrepayNoticeVo class
+ *
+ * @author XH
+ * @date 2025/03/25
+ */
+@Data
+public class PrepayNoticeVo {
+
+    /**
+     * id
+     */
+    private String id;
+    /**
+     * 通知创建时间
+     */
+    private String create_time;
+    /**
+     * 【通知数据类型】通知的资源数据类型,固定为encrypt-resource。
+     */
+    private String resource_type;
+    /**
+     * 【通知的类型】微信支付回调通知的类型。
+     * 支付成功通知的类型为TRANSACTION.SUCCESS。
+     */
+    private String event_type;
+    /**
+     * 回调内容摘要
+     */
+    private String summary;
+    /**
+     * 通知资源属性
+     */
+    private Resource resource;
+
+
+    @Data
+    public static class Resource {
+        /**
+         * 【原始回调类型】加密前的对象类型,为transaction。
+         */
+        private String original_type;
+        /**
+         * 回调数据密文的加密算法类型,目前为AEAD_AES_256_GCM,开发者需要使用同样类型的数据进行解密。
+         */
+        private String algorithm;
+        /**
+         * 【数据密文】Base64编码后的回调数据密文,商户需Base64解码并使用APIV3密钥解密
+         */
+        private String ciphertext;
+        /**
+         * 【附加数据】参与解密的附加数据,该字段可能为空。
+         */
+        private String associated_data;
+        /**
+         * 【随机串】参与解密的随机串。
+         */
+        private String nonce;
+    }
+
+}

+ 101 - 0
zhsw-entity/src/main/java/com/rongwe/zhsw/system/vo/WeChatPayTransactionVo.java

@@ -0,0 +1,101 @@
+package com.rongwe.zhsw.system.vo;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * WeChatPayTransactionVo class
+ *
+ * @author XH
+ * @date 2025/03/25
+ */
+@Data
+public class WeChatPayTransactionVo {
+    @JsonProperty("transaction_id")
+    private String transactionId;
+    private Amount amount;
+    @JsonProperty("mchid")
+    private String merchantId;
+    @JsonProperty("trade_state")
+    private String tradeState;
+    @JsonProperty("bank_type")
+    private String bankType;
+    @JsonProperty("promotion_detail")
+    private List<PromotionDetail> promotionDetails;
+    @JsonProperty("success_time")
+    private Date successTime;
+    private Payer payer;
+    @JsonProperty("out_trade_no")
+    private String outTradeNo;
+    private String appid;
+    @JsonProperty("trade_state_desc")
+    private String tradeStateDesc;
+    @JsonProperty("trade_type")
+    private String tradeType;
+    private String attach;
+    @JsonProperty("scene_info")
+    private SceneInfo sceneInfo;
+
+    @Data
+    class Amount {
+        @JsonProperty("payer_total")
+        private int payerTotal;
+        private int total;
+        private String currency;
+        @JsonProperty("payer_currency")
+        private String payerCurrency;
+
+        // Getters and Setters
+    }
+
+    class PromotionDetail {
+        private int amount;
+        @JsonProperty("wechatpay_contribute")
+        private int wechatpayContribute;
+        @JsonProperty("coupon_id")
+        private String couponId;
+        private String scope;
+        @JsonProperty("merchant_contribute")
+        private int merchantContribute;
+        private String name;
+        @JsonProperty("other_contribute")
+        private int otherContribute;
+        private String currency;
+        @JsonProperty("stock_id")
+        private String stockId;
+        @JsonProperty("goods_detail")
+        private List<GoodsDetail> goodsDetails;
+
+        // Getters and Setters
+    }
+
+    class GoodsDetail {
+        @JsonProperty("goods_remark")
+        private String goodsRemark;
+        private int quantity;
+        @JsonProperty("discount_amount")
+        private int discountAmount;
+        @JsonProperty("goods_id")
+        private String goodsId;
+        @JsonProperty("unit_price")
+        private int unitPrice;
+
+        // Getters and Setters
+    }
+
+    class Payer {
+        private String openid;
+
+        // Getters and Setters
+    }
+
+    class SceneInfo {
+        @JsonProperty("device_id")
+        private String deviceId;
+
+        // Getters and Setters
+    }
+}

+ 26 - 9
zhsw-server/src/main/java/com/rongwei/zhsw/system/controller/weChat/PayMentController.java

@@ -1,10 +1,13 @@
 package com.rongwei.zhsw.system.controller.weChat;
 
+import com.rongwe.zhsw.system.vo.CreatePaymentRecordVo;
 import com.rongwe.zhsw.system.vo.PaymentRocordVo;
+import com.rongwe.zhsw.system.vo.PrepayNoticeVo;
 import com.rongwe.zhsw.system.vo.WxPrepayOrderVo;
 import com.rongwei.rwcommon.base.R;
-import com.rongwei.zhsw.system.utils.WxApi;
+import com.rongwei.zhsw.system.utils.WxPayApi;
 import com.rongwei.zhsw.system.wechat.PaymentRecordService;
+import com.rongwei.zhsw.system.wechat.impl.PayMentServiceImpl;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -13,8 +16,6 @@ import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 import java.util.UUID;
-import java.util.HashMap;
-import java.util.Map;
 
 @RestController
 @RequestMapping("/wechat/payment")
@@ -23,12 +24,23 @@ public class PayMentController {
 
     @Autowired
     private PaymentRecordService paymentRecordService;
+    @Autowired
+    private PayMentServiceImpl payMentService;
 
     @PostMapping("/record")
     private R info(@RequestBody PaymentRocordVo payMentRocordVo) {
         return paymentRecordService.getPaymentRecordList(payMentRocordVo);
     }
 
+    /**
+     * 生成缴费记录
+     * @param createPaymentRecordVo
+     * @return
+     */
+    @PostMapping("/record/create")
+    private R createRecord(@RequestBody CreatePaymentRecordVo createPaymentRecordVo) {
+        return paymentRecordService.createRecord(createPaymentRecordVo);
+    }
     /**
      * 预下单
      * @param vo
@@ -36,11 +48,16 @@ public class PayMentController {
      */
     @PostMapping("/prepayOrder")
     public R prepayOrder(@RequestBody WxPrepayOrderVo vo) {
-        WxApi wxApi = new WxApi();
-        wxApi.initMerchant();
-        // 生成订单号
-        String nonceStr = UUID.randomUUID().toString().replaceAll("-", "");
-        vo.setOutTradeNo(nonceStr);
-        return R.ok(wxApi.prepayWithRequestPayment(vo));
+     return payMentService.paymentInitiation(vo);
+    }
+
+    /**
+     * 微信支付成功回调函数
+     * @param prepayNoticeVo
+     * @return
+     */
+    @PostMapping("/prepay/notice")
+    public R prepayNotice(@RequestBody PrepayNoticeVo prepayNoticeVo) {
+      return  payMentService.prepayNotice(prepayNoticeVo);
     }
 }

+ 2 - 2
zhsw-server/src/main/resources/bootstrap-dev.yml

@@ -4,10 +4,10 @@ spring:
       config:
         file-extension: yaml
         server-addr: 127.0.0.1:8848
-        namespace: cd047569-9470-4dfb-8663-b113d01cd30f
+        namespace: 9caed6dc-3784-4d73-bd4c-a8e8153bc358
         ext-config[0]:
           data-id: common-config.yaml
       discovery:
         server-addr: 127.0.0.1:8848
-        namespace: cd047569-9470-4dfb-8663-b113d01cd30f
+        namespace: 9caed6dc-3784-4d73-bd4c-a8e8153bc358
         #cd047569-9470-4dfb-8663-b113d01cd30f