From 303db8bc49b62101cfe2d373d58f6b23e0db45fb Mon Sep 17 00:00:00 2001 From: gong <1157756119@qq.com> Date: Fri, 26 Dec 2025 11:38:48 +0800 Subject: [PATCH 001/133] =?UTF-8?q?=E5=BE=AE=E4=BF=A1=E6=94=AF=E4=BB=98-?= =?UTF-8?q?=E4=B8=8A=E4=BC=A0=E5=9B=BE=E7=89=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cash-dependencies/pom.xml | 7 + cash-sdk/aggregation-pay/pom.xml | 30 ++++ .../java/com/czg/wechat/WechatConfig.java | 47 ++++++ .../java/com/czg/wechat/WechatEncrypt.java | 47 ++++++ .../com/czg/wechat/WechatEntryManager.java | 157 ++++++++++++++++++ .../java/com/czg/wechat/WechatPayManager.java | 11 ++ .../wechat/dto/config/WechatPayConfigDto.java | 49 ++++++ cash-sdk/pom.xml | 1 + 8 files changed, 349 insertions(+) create mode 100644 cash-sdk/aggregation-pay/pom.xml create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatConfig.java create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatEncrypt.java create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatEntryManager.java create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatPayManager.java create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/config/WechatPayConfigDto.java diff --git a/cash-dependencies/pom.xml b/cash-dependencies/pom.xml index b5163a004..cbbd275f7 100644 --- a/cash-dependencies/pom.xml +++ b/cash-dependencies/pom.xml @@ -42,6 +42,7 @@ 2.5.1 2.9.10 4.1.128.Final + 0.2.17 @@ -268,6 +269,12 @@ netty-codec-mqtt ${netty.version} + + + com.github.wechatpay-apiv3 + wechatpay-java + ${wechatpay.version} + diff --git a/cash-sdk/aggregation-pay/pom.xml b/cash-sdk/aggregation-pay/pom.xml new file mode 100644 index 000000000..3df1fb396 --- /dev/null +++ b/cash-sdk/aggregation-pay/pom.xml @@ -0,0 +1,30 @@ + + + 4.0.0 + + com.czg + cash-sdk + 1.0.0 + + + aggregation-pay + jar + 聚合支付 + + + + 21 + 21 + UTF-8 + + + + + com.github.wechatpay-apiv3 + wechatpay-java + + + + \ No newline at end of file diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatConfig.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatConfig.java new file mode 100644 index 000000000..ace7aaab8 --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatConfig.java @@ -0,0 +1,47 @@ +package com.czg.wechat; + +import com.czg.wechat.dto.config.WechatPayConfigDto; +import com.wechat.pay.java.core.Config; +import com.wechat.pay.java.core.RSAPublicKeyConfig; +import com.wechat.pay.java.service.file.FileUploadService; + +/** + * 微信支付 配置 + * + * @author yjjie + * @date 2025/12/26 09:33 + */ +public class WechatConfig { + + /** + * 获取微信支付配置 + * @param dto 微信支付配置 + * @return 微信支付配置 + */ + public static Config getConfig(WechatPayConfigDto dto) { + return new RSAPublicKeyConfig.Builder() + .merchantId(dto.getMerchantId()) + .privateKey(dto.getPrivateKey()) + .publicKey(dto.getPublicKey()) + .publicKeyId(dto.getPublicKeyId()) + .merchantSerialNumber(dto.getSerialNumber()) + .apiV3Key(dto.getApiV3Key()) + .build(); + } + + public static FileUploadService getFileUploadService(Config config) { + return new FileUploadService.Builder() + .config(config) + .build(); + } + + /** + * 获取文件上传服务 + * @param dto 微信支付配置 + * @return 文件上传服务 + */ + public static FileUploadService getFileUploadService(WechatPayConfigDto dto) { + return getFileUploadService(getConfig(dto)); + } + +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatEncrypt.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatEncrypt.java new file mode 100644 index 000000000..82c2cd179 --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatEncrypt.java @@ -0,0 +1,47 @@ +package com.czg.wechat; + +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +/** + * 微信支付加解密 + * @author yjjie + * @date 2025/12/26 10:58 + */ +public class WechatEncrypt { + + public static String getFileBytesSha256(byte[] input) throws NoSuchAlgorithmException { + return bytesToHex(calculateSha256(input)); + } + + /** + * 核心方法:计算字节数组的 SHA-256 哈希值 + * @param input 待计算的字节数组 + * @return SHA-256 哈希值(32 字节的字节数组) + */ + private static byte[] calculateSha256(byte[] input) throws NoSuchAlgorithmException { + // 获取 SHA-256 消息摘要实例(Java 21 完全兼容) + MessageDigest digest = MessageDigest.getInstance("SHA-256"); + // 计算哈希值 + return digest.digest(input); + } + + /** + * 辅助方法:将字节数组转换为十六进制字符串(SHA-256 结果常用格式) + * @param bytes 待转换的字节数组 + * @return 十六进制字符串(SHA-256 对应 64 位字符串) + */ + private static String bytesToHex(byte[] bytes) { + StringBuilder hexString = new StringBuilder(); + // Java 21 可使用 var 简化声明 + for (var b : bytes) { + // 将字节转换为两位十六进制数,不足补 0 + String hex = Integer.toHexString(0xff & b); + if (hex.length() == 1) { + hexString.append('0'); + } + hexString.append(hex); + } + return hexString.toString(); + } +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatEntryManager.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatEntryManager.java new file mode 100644 index 000000000..162a2ba72 --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatEntryManager.java @@ -0,0 +1,157 @@ +package com.czg.wechat; + +import com.alibaba.fastjson2.JSONObject; +import com.czg.wechat.dto.config.WechatPayConfigDto; +import com.wechat.pay.java.service.file.FileUploadService; +import com.wechat.pay.java.service.file.model.FileUploadResponse; +import lombok.extern.slf4j.Slf4j; + +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; + +/** + * 微信支付进件 管理 + * + * @author yjjie + * @date 2025/12/26 10:57 + */ +@Slf4j +public class WechatEntryManager { + + public static String uploadImage(WechatPayConfigDto configDto, String url) { + // 校验入参 + if (configDto == null || url == null || url.trim().isEmpty()) { + log.error("上传图片失败:配置或URL参数为空"); + return ""; + } + + FileUploadService service = WechatConfig.getFileUploadService(configDto); + + try { + // 获取图片字节数组 + byte[] bytes = downloadImage(url); + if (bytes.length == 0) { + log.error("下载的图片内容为空,URL:{}", url); + return ""; + } + + // 2. 计算SHA256 + String sha256Hex = WechatEncrypt.getFileBytesSha256(bytes); + + // 3. 构造元数据(从URL提取文件名,或自定义) + JSONObject meta = new JSONObject(); + meta.put("sha256", sha256Hex); + // 从URL提取文件名,若提取失败则使用默认名 + String fileName = extractFileNameFromUrl(url); + meta.put("filename", fileName); + + // 4. 上传图片到微信接口 + FileUploadResponse uploadResponse = service.uploadImage( + configDto.getDomain() + "/v3/merchant/media/upload", + meta.toJSONString(), + fileName, + bytes + ); + + return uploadResponse.getMediaId(); + } catch (Exception e) { + log.error("微信上传图片报错,URL:{},错误信息:{}", url, e.getMessage(), e); + } + return ""; + } + + public static byte[] downloadImage(String url) throws Exception { + HttpClient client = HttpClient.newHttpClient(); + HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(url)) + .GET() + .build(); + + HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofByteArray()); + + if (response.statusCode() != 200) { + throw new RuntimeException("Failed to download image, status code: " + response.statusCode()); + } + + return response.body(); + } + + /** + * 从URL中提取文件名 + * + * @param url 图片URL + * @return 提取的文件名,失败则返回默认名 + */ + private static String extractFileNameFromUrl(String url) { + try { + if (url.contains("/")) { + String fileName = url.substring(url.lastIndexOf("/") + 1); + // 如果文件名包含参数,截取?之前的部分 + if (fileName.contains("?")) { + fileName = fileName.substring(0, fileName.indexOf("?")); + } + // 如果提取的文件名有效,直接返回 + if (fileName.contains(".")) { + return fileName; + } + } + } catch (Exception e) { + log.warn("提取文件名失败,使用默认文件名", e); + } + // 默认文件名 + return "upload_" + System.currentTimeMillis() + ".png"; + } + + public static void main(String[] args) { + WechatPayConfigDto dto = new WechatPayConfigDto() + .setMerchantId("1643779408") + .setApiV3Key("a92baac5eb7a36ed8ec198113e769a03") + .setSerialNumber("4DE9BAC2EA584C3F274F694C9753CA814C4E9BF4") + .setPublicKey(""" + -----BEGIN PUBLIC KEY----- + MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtbeWXEEjBaYtw2OyM+SC + aCEMbryRXi4duKxx3vYG4rUVix+d5/Jz7Khev4Upml9zC+Xxvv/G9bHWAUyolzqD + wefahGurIxr43r4GJVnQ4i5G6BbBVw5d4Vuz0y/9Zd14zmc/EmBpT0Ml26H7tOZl + n1LSbQ4xNFkrRKrNEcExBLxkCd+K5K2TREZznywIi0izbHImvuzM8IneuR51FiqK + pdFnAjTwb126EIj6ECkL6KLCl8RWqpfiX8SFiolSQLs1/w79O0sIUk96X2zWpnoW + rTDFatPif/VEKl3y2dTlxxDxoZtVi48yTDW00OMzVl5D67oX3FVK0KsjHJSCfGlZ + 6wIDAQAB + -----END PUBLIC KEY-----""") + .setPrivateKey(""" + -----BEGIN PRIVATE KEY----- + MIIEwAIBADANBgkqhkiG9w0BAQEFAASCBKowggSmAgEAAoIBAQDqnAZhTxT572fo + 6wvSr8Rt0vRXg+EFKC6UvUiNE24oocQU5fjedX9KL/+fmoqay/xqIxvxvCNFTs4J + zlMqavSl6bMWCpjvf/Ry82JmN1v2kJEO4lgP8BsEiqlUpObCH8BMAVUOn1j+9q4Q + uZJJcbtRvec2fNweDM8EJp4B7RlUdDbHm86lfcDVp8iini7VjDp6D7aHT+C8A8OT + ugxQIquDec778wVd9r2Sv3+t6rAzFs+n+Zu++2xtFEPhO5N0wjrLHaukl+9crU+1 + lktjDzcPd07SwGZ+A+3BTmW3UCramI3506e/3MWBECB7ge+gM4URAV0nJJCLH/Im + WgEvPMr5AgMBAAECggEBAKv+wraoMWqiVv1tA/froAgbtcJLDranJK8qrXuvmPz0 + yzm+91qvrSgIVFEADUk67swo/R2Vng37nhWWS2Y3jy/rSr2H+2Lp3Z5ATA0/3I3A + onfU/FaC4mvL9CP32KzMdj/CYkccDzSsSCQ+x75MQNXGcTGDDCSDo2kZnpEu73j3 + aqvO1jbqTGWigRfjOIaIhStjQIT8nEm/3mJ4f5dM9M6FMz33mhax8EahSgvdahYB + t45iaGOWw81OJhmry47EvpwjXBl7jtO2HX3LiLbq5Ebcwu1zqDz5NM7ttnnGAqWC + 6y7JN5Vt4wPYrCydiUDe7dj0looffr2yw6MkNfYjLGECgYEA+FAvbEInQEi9YguS + CQtLHngqvYeai66tvyykog9o38KHnPGx2Myf+rn/Hcp7KNRfjd5G34CCNg7KLnrx + YIYh6+2bY3jirzdYUxuNKGbvM4gky/6M/P9zHF/uALKOE02yArdqemf4UxUvrYCc + JdXsAMqvbpdvW1aGgNRB32YCkG0CgYEA8d89vawsCjNCEUh0VWTMoBLFoex3qBMZ + rfzYQeBo6bDCRlAlUVzl+ouBUxSYxP/U8rzeNaRzGUwRLmlGMjyIr58FBlHsg2cR + DlsX3HVCUjpS6sgPXOqakdiLfhMcHZAspislSyVfeS3TbUWiA45+5PuNUq+EZYwl + ESsB1+yfRT0CgYEA0Ct49ksnWM8iZbXJgeeD3FFlk2rBd2TDqEem5W4Bv8T3p+0/ + 6b7yR2HyrGj5gys3yFmWFP1JLESN3xWWkhMhEQcrg+LuN3Iwi8vHNR3GXu892f7W + 96q4OAt8Hf2S+j/igkB99YyANDbIt63gOh/zMF67X/14j5wkOpC3gK+maqkCgYEA + s7nIrPoUt3ejLiiCmTmPe5q3VDzcJP4cZNau8zSHgK6hjZHcSPsYwPWMoWl6o1fe + qoiBLacHB9MoKS58xLOKdcVZ/Ho/ntylJd+2eVCAeY1xM5h5IfgJ5znbXVFh4O3S + 357L1Wzt5qOQqW/GlZH65LevKbPWU4axvHISqpnfN5kCgYEAqiqLuAPu84VSsqsE + GFh25t+1f0JY1sNfilE3/t9AdQeeCFv/5z9KB1kMt3a5ZFeVonsFIvCyaOJjhSkj + 4HCB94vWS7NuN5G9r874lMaPbZYQGwrcVaf265tN7cYYr3gUx1qB6+u+fh/kcft1 + BBmTzhb0zp5k8ngwAkA1g/LK204= + -----END PRIVATE KEY-----""") + .setPublicKeyId("PUB_KEY_ID_0116437794082025111000382377001000") + .setDomain("https://api.mch.weixin.qq.com"); + + String string = uploadImage(dto, "https://czg-qr-order.oss-cn-beijing.aliyuncs.com/indexs/shuangbackground.png"); + log.info("图片上传成功:{}", string); + } +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatPayManager.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatPayManager.java new file mode 100644 index 000000000..897ad8fc3 --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatPayManager.java @@ -0,0 +1,11 @@ +package com.czg.wechat; + +/** + * @author yjjie + * @date 2025/12/26 09:15 + */ +public class WechatPayManager { + + public static void main(String[] args) { + } +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/config/WechatPayConfigDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/config/WechatPayConfigDto.java new file mode 100644 index 000000000..a0cb78bc4 --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/config/WechatPayConfigDto.java @@ -0,0 +1,49 @@ +package com.czg.wechat.dto.config; + +import lombok.Data; +import lombok.experimental.Accessors; + +/** + * @author yjjie + * @date 2025/12/26 09:21 + */ +@Data +@Accessors(chain = true) +public class WechatPayConfigDto { + + /** + * 商户号 + */ + private String merchantId; + + /** + * Api V3密钥 + */ + private String apiV3Key; + + /** + * 商户证书序列号 + */ + private String serialNumber; + + /** + * 商户私钥 + */ + private String privateKey; + + /** + * 商户公钥 + */ + private String publicKey; + + /** + * 商户公钥 ID + */ + private String publicKeyId; + + /** + * 微信支付域名 + * + */ + private String domain; +} diff --git a/cash-sdk/pom.xml b/cash-sdk/pom.xml index 55ee0e62b..b92f22d79 100644 --- a/cash-sdk/pom.xml +++ b/cash-sdk/pom.xml @@ -13,6 +13,7 @@ 第三方内容 czg-pay + aggregation-pay cash-sdk From 6b5c451f92f28c6c8e0273d343a6478a9448c0eb Mon Sep 17 00:00:00 2001 From: gong <1157756119@qq.com> Date: Fri, 26 Dec 2025 15:08:21 +0800 Subject: [PATCH 002/133] =?UTF-8?q?=E5=BE=AE=E4=BF=A1=E6=94=AF=E4=BB=98-?= =?UTF-8?q?=20dto?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../req/entry/WechatEntryAdditionReqDto.java | 49 ++++++++++ .../entry/WechatEntryBankAccountReqDto.java | 73 +++++++++++++++ .../req/entry/WechatEntryContactReqDto.java | 13 +++ .../dto/req/entry/WechatEntryReqDto.java | 64 +++++++++++++ .../req/entry/WechatEntrySettleReqDto.java | 89 +++++++++++++++++++ .../req/entry/WechatEntrySubjectReqDto.java | 55 ++++++++++++ .../business/WechatEntryBusinessReqDto.java | 48 ++++++++++ .../WechatEntryCertificateReqDto.java | 12 +++ .../business/WechatEntryLicenseReqDto.java | 88 ++++++++++++++++++ .../sales/WechatEntryAppInfoReqDto.java | 43 +++++++++ .../sales/WechatEntryMiniProgramReqDto.java | 45 ++++++++++ .../sales/WechatEntryMpInfoReqDto.java | 43 +++++++++ .../sales/WechatEntrySalesInfoReqDto.java | 85 ++++++++++++++++++ .../sales/WechatEntryStoreInfoReqDto.java | 76 ++++++++++++++++ .../sales/WechatEntryWebInfoReqDto.java | 42 +++++++++ .../sales/WechatEntryWeworkInfoReqDto.java | 31 +++++++ 16 files changed, 856 insertions(+) create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntryAdditionReqDto.java create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntryBankAccountReqDto.java create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntryContactReqDto.java create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntryReqDto.java create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntrySettleReqDto.java create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntrySubjectReqDto.java create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryBusinessReqDto.java create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryCertificateReqDto.java create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryLicenseReqDto.java create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryAppInfoReqDto.java create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryMiniProgramReqDto.java create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryMpInfoReqDto.java create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntrySalesInfoReqDto.java create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryStoreInfoReqDto.java create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryWebInfoReqDto.java create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryWeworkInfoReqDto.java diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntryAdditionReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntryAdditionReqDto.java new file mode 100644 index 000000000..a656d8303 --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntryAdditionReqDto.java @@ -0,0 +1,49 @@ +package com.czg.wechat.dto.req.entry; + +import com.alibaba.fastjson2.annotation.JSONField; +import lombok.Data; + +import java.util.List; + +/** + * 微信进件-补充信息 + * + * @author yjjie + * @date 2025/12/26 13:43 + */ +@Data +public class WechatEntryAdditionReqDto { + + /** + * 选填 + * 法定代表人开户承诺函 + * 模板下载地址 ... + * 通过图片上传完成后 MediaID + */ + @JSONField(name = "legal_person_commitment") + private String legalPersonCommitment; + + /** + * 选填 + * 法定代表人开户意愿视频 + * 通过视频上传完成后 MediaID + */ + @JSONField(name = "legal_person_video") + private String legalPersonVideo; + + /** + * 选填 + * 补充材料 + * 最多可上传5张照片 + * 通过图片上传完成后 MediaID + */ + @JSONField(name = "business_addition_pics") + private List businessAdditionPics; + + /** + * 选填 + * 补充说明 512字以内 + */ + @JSONField(name = "business_addition_msg") + private String businessAdditionMsg; +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntryBankAccountReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntryBankAccountReqDto.java new file mode 100644 index 000000000..35d0cacdf --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntryBankAccountReqDto.java @@ -0,0 +1,73 @@ +package com.czg.wechat.dto.req.entry; + +import com.alibaba.fastjson2.annotation.JSONField; +import lombok.Data; + +/** + * 微信进件-银行账号 + * + * @author yjjie + * @date 2025/12/26 13:42 + */ +@Data +public class WechatEntryBankAccountReqDto { + + /** + * 必填 + * 账户类型 + * 1、若主体为企业/政府机关/事业单位/社会组织,可填写:对公银行账户; + * 2、若主体为个体户,可选择填写:对公银行账户或经营者个人银行卡 + * 可选取值 BANK_ACCOUNT_TYPE_CORPORATE: 对公银行账户 BANK_ACCOUNT_TYPE_PERSONAL: 经营者个人银行卡 + */ + @JSONField(name = "bank_account_type") + private String bankAccountType; + + /** + * 必填 + * 开户名称 + * 1、选择“经营者个人银行卡”时,开户名称必须与“经营者证件姓名”一致; + * 2、选择“对公银行账户”时,开户名称必须与营业执照上的“商户名称”一致; + * 3、该字段需要使用微信支付公钥加密(推荐),请参考获取微信支付公钥ID说明以及微信支付公钥加密敏感信息指引,也可以使用微信支付平台证书公钥加密,参考获取平台证书序列号、平台证书加密敏感信息指引。 + * ... + */ + @JSONField(name = "account_name") + private String accountName; + + /** + * 必填 + * 开户银行 + * 对私银行调用:查询支持个人业务的银行列表API + * 对公银行调用:查询支持对公业务的银行列表API + */ + @JSONField(name = "account_bank") + private String accountBank; + + /** + * 选填 + * 开户银行银行号 + * 1、根据开户银行查询接口中的“是否需要填写支行”判断是否需要填写。如为其他银行,开户银行全称(含支行)和开户银行联行号二选一; + * 2、详细需调用查询支行列表API查看查询结果。 ... + */ + @JSONField(name = "bank_branch_id") + private String bankBranchId; + + /** + * 选填 + * 开户银行全称(含支行) + * 1、根据开户银行查询接口中的“是否需要填写支行”判断是否需要填写。如为其他银行,开户银行全称(含支行)和开户银行联行号二选一; + * 2、详细需调用查询支行列表API查看查询结果。 ... + */ + @JSONField(name = "bank_name") + private String bankName; + + /** + * 必填 + * 开户银行账号 + * 1、选择“经营者个人银行卡”时,开户账号为经营者个人银行卡号; + * 2、选择“对公银行账户”时,开户账号为对公银行账号; + * 3、该字段需要使用微信支付公钥加密(推荐),请参考获取微信支付公钥ID说明以及微信支付公钥加密敏感信息指引,也可以使用微信支付平台证书公钥加密,参考获取平台证书序列号、平台证书加密敏感信息指引。 + * ... + */ + @JSONField(name = "account_number") + private String accountNumber; +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntryContactReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntryContactReqDto.java new file mode 100644 index 000000000..a7990dbd0 --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntryContactReqDto.java @@ -0,0 +1,13 @@ +package com.czg.wechat.dto.req.entry; + +import lombok.Data; + +/** + * 进件 联系人信息 + * + * @author yjjie + * @date 2025/12/26 13:38 + */ +@Data +public class WechatEntryContactReqDto { +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntryReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntryReqDto.java new file mode 100644 index 000000000..c0793e703 --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntryReqDto.java @@ -0,0 +1,64 @@ +package com.czg.wechat.dto.req.entry; + +import com.alibaba.fastjson2.annotation.JSONField; +import com.czg.wechat.dto.req.entry.business.WechatEntryBusinessReqDto; +import lombok.Data; + +/** + * 微信进件请求参数 + * 参考地址 ... + * @author yjjie + * @date 2025/12/26 13:36 + */ +@Data +public class WechatEntryReqDto { + + /** + * 业务申请编号 + */ + @JSONField(name = "business_code") + private String businessCode; + + /** + * 超级管理员信息 + */ + @JSONField(name = "contact_info") + private WechatEntryContactReqDto contactInfo; + + /** + * 主体资料 + */ + @JSONField(name = "subject_info") + private WechatEntrySubjectReqDto subjectInfo; + + /** + * 必填 + * 经营资料 + * 商家的经营业务信息、售卖商品/提供服务场景信息 + */ + @JSONField(name = "business_info") + private WechatEntryBusinessReqDto businessInfo; + + /** + * 必填 + * 结算规则 + * 请填写商家的结算费率规则、特殊资质等信息 + */ + @JSONField(name = "settlement_info") + private WechatEntrySettleReqDto settlementInfo; + + /** + * 必填 + * 结算银行账户 + */ + @JSONField(name = "bank_account_info") + private WechatEntryBankAccountReqDto bankAccountInfo; + + /** + * 选填 + * 补充材料 + * 根据实际审核情况,会额外要求商家提供指定的补充资料 + */ + @JSONField(name = "addition_info") + private WechatEntryAdditionReqDto additionInfo; +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntrySettleReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntrySettleReqDto.java new file mode 100644 index 000000000..55f434741 --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntrySettleReqDto.java @@ -0,0 +1,89 @@ +package com.czg.wechat.dto.req.entry; + +import com.alibaba.fastjson2.annotation.JSONField; +import lombok.Data; + +import java.util.List; + +/** + * 进件 结算信息 + * @author yjjie + * @date 2025/12/26 13:38 + */ +@Data +public class WechatEntrySettleReqDto { + + /** + * 必填 + * 入驻结算规则ID + * 请选择结算规则ID,详细参见费率结算规则对照表 + * ... + */ + @JSONField(name = "settlement_id") + private String settlementId; + + /** + * 必填 + * 所属行业 + * ... + */ + @JSONField(name = "qualification_type") + private String qualificationType; + + /** + * 选填 + * 特殊资质图片 + * 1、仅当商户选择了必需提交特殊资质的行业时,需要提供该项资料;若商户选择了无需特殊资质的行业,或未选择行业时,无需提交该项资料,详情查看《费率结算规则对照表》; + * 2、最多可上传5张照片,请填写通过图片上传API预先上传图片生成好的MediaID。 + */ + @JSONField(name = "qualifications") + private List qualifications; + + /** + * 选填 + * 优惠费率活动ID + * 如果商户有意向报名优惠费率活动,该字段必填。详细参见《优惠费率活动对照表》 + * ... + */ + @JSONField(name = "activities_id") + private String activitiesId; + + /** + * 选填 + * 优惠费率活动值 + * 根据优惠费率活动规则,由合作伙伴自定义填写,支持两个小数点,需在优惠费率活动ID指定费率范围内 + * (1)2023年7月17日-9月17日,各合作伙伴平台可选择只传入“活动费率值”,或分别传入“信用卡优惠活动费率值” 与 “非信用卡优惠活动费率值”,只传入“活动费率值”的情况下,平台将协助将申请单中的 “优惠活动费率值” 回填入新增的 “信用卡优惠活动费率值” 与 “非信用卡优惠活动费率值”中 ; + * (2)2023年9月18日起,平台将不再提供如上兼容能力,届时仅能分别传入“信用卡优惠活动费率值” 与 “非信用卡优惠活动费率值”,否则接口将会报错。为避免影响正常进件,请在兼容期间完成相关调整。 + */ + @JSONField(name = "activities_rate") + private String activitiesRate; + + /** + * 选填 + * 优惠费率活动补充材料 + * 1、根据所选优惠费率活动,提供相关材料,详细参见《优惠费率活动对照表》;... + * 2、最多可上传5张照片,请填写通过图片上传API预先上传图片生成好的MediaID。 + */ + @JSONField(name = "activities_additions") + private List activitiesAdditions; + + /** + * 选填 + * 非信用卡活动费率值 + * 用户支付方式为借记卡时收取的手续费费率: + * 1、若填写了优惠费率活动ID,则该字段必填; + * 2、仅能填入2位以内小数,且在优惠费率活动ID指定费率范围内。 + */ + @JSONField(name = "debit_activities_rate") + private String debitActivitiesRate; + + /** + * 选填 + * 信用卡活动费率值 + * 用户支付方式为信用卡时收取的手续费费率: + * 1、若填写了优惠费率活动ID,则该字段必填; + * 2、仅能填入2位以内小数,且在优惠费率活动ID指定费率范围内。 + */ + @JSONField(name = "credit_activities_rate") + private String creditActivitiesRate; +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntrySubjectReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntrySubjectReqDto.java new file mode 100644 index 000000000..a445b6a5f --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntrySubjectReqDto.java @@ -0,0 +1,55 @@ +package com.czg.wechat.dto.req.entry; + +import com.alibaba.fastjson2.annotation.JSONField; +import com.czg.wechat.dto.req.entry.business.WechatEntryCertificateReqDto; +import com.czg.wechat.dto.req.entry.business.WechatEntryLicenseReqDto; +import lombok.Data; + +/** + * 进件 主体资料 + * @author yjjie + * @date 2025/12/26 13:40 + */ +@Data +public class WechatEntrySubjectReqDto { + + /** + * 必填 + * 主体类型 主体类型需与营业执照/登记证书上一致,可参考选择主体指引。... + * 可选取值 + * SUBJECT_TYPE_INDIVIDUAL: (个体户)营业执照上的主体类型一般为个体户、个体工商户、个体经营 + * SUBJECT_TYPE_ENTERPRISE: (企业)营业执照上的主体类型一般为有限公司、有限责任公司 + * SUBJECT_TYPE_GOVERNMENT: (政府机关)包括各级、各类政府机关,如机关党委、税务、民政、人社、工商、商务、市监等 + * SUBJECT_TYPE_INSTITUTIONS: (事业单位)包括国内各类事业单位,如:医疗、教育、学校等单位 + * SUBJECT_TYPE_OTHERS:(社会组织) 包括社会团体、民办非企业、基金会、基层群众性自治组织、农村集体经济组织等组织 + */ + @JSONField(name = "subject_type") + private String subjectType; + + /** + * 选填 + * 是否是金融机构 + * 【是否是金融机构】 选填,请根据申请主体的实际情况填写,可参考选择金融机构指引: + * 1、若商户主体是金融机构,则填写:true; + * 2、若商户主体不是金融机构,则填写:false。 + * 若未传入将默认填写:false。 + */ + @JSONField(name = "finance_institution") + private Boolean financeInstitution; + + /** + * 必填 + * 营业执照 当前不允许小微注册,所以必填 + * 1、主体为个体户/企业,必填; + * 2、请上传“营业执照”,需年检章齐全,当年注册除外; + */ + @JSONField(name = "business_license_info") + private WechatEntryLicenseReqDto businessLicenseInfo; + + /** + * 选填 + * 登记证书 主体为政府机关/事业单位/其他组织时,必填。 + */ + @JSONField(name = "certificate_info") + private WechatEntryCertificateReqDto certificateInfo; +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryBusinessReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryBusinessReqDto.java new file mode 100644 index 000000000..94dcd1d39 --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryBusinessReqDto.java @@ -0,0 +1,48 @@ +package com.czg.wechat.dto.req.entry.business; + +import com.alibaba.fastjson2.annotation.JSONField; +import com.czg.wechat.dto.req.entry.business.sales.WechatEntrySalesInfoReqDto; +import lombok.Data; + +/** + * 微信进件 商户信息 经营资料 + * + * @author yjjie + * @date 2025/12/26 13:41 + */ +@Data +public class WechatEntryBusinessReqDto { + + /** + * 必填 + * 商户简称 在支付完成页向买家展示,需与微信经营类目相关 + * 1、请输入1-64个字符; + * 2、前后不能有空格、制表符、换行符; + * 3、不能仅含特殊字符; + * 4、仅能填写数字、英文字母、汉字及特殊字符; + * 5、仅支持utf-8格式; + * 6、简称要求 + * (1)不支持单纯以人名来命名,若为个体户经营,可用“个体户+经营者名称”或“经营者名称+业务”命名,如“个体户张三”或“张三餐饮店”; + * (2)不支持无实际意义的文案,如“XX特约商户”、“800”、“XX客服电话XXX”。 + */ + @JSONField(name = "merchant_shortname") + private String merchantShortname; + + /** + * 必填 + * 客服电话 将在交易记录中向买家展示,请确保电话畅通以便平台回拨确认 + * 1、前后不能有空格、制表符、换行符; + * 2、需满足以下任一条件; + * 11位数字的手机号码; + * 5-20位数字、连字符“-”、加号“+”。 + */ + @JSONField(name = "service_phone") + private String servicePhone; + + /** + * 必填 + * 经营场景 + */ + @JSONField(name = "sales_info") + private WechatEntrySalesInfoReqDto salesInfo; +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryCertificateReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryCertificateReqDto.java new file mode 100644 index 000000000..df2090102 --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryCertificateReqDto.java @@ -0,0 +1,12 @@ +package com.czg.wechat.dto.req.entry.business; + +import lombok.Data; + +/** + * 登记证书 + * @author yjjie + * @date 2025/12/26 15:07 + */ +@Data +public class WechatEntryCertificateReqDto { +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryLicenseReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryLicenseReqDto.java new file mode 100644 index 000000000..c13401254 --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryLicenseReqDto.java @@ -0,0 +1,88 @@ +package com.czg.wechat.dto.req.entry.business; + +import com.alibaba.fastjson2.annotation.JSONField; +import lombok.Data; + +/** + * 营业执照信息 + * @author yjjie + * @date 2025/12/26 14:59 + */ +@Data +public class WechatEntryLicenseReqDto { + + /** + * 必填 + * 营业执照照片 + * 1、照片应正面拍摄、清晰、四角完整、无反光或遮挡;不得翻拍、截图、镜像、PS; + * 2、上传彩色照片、彩色扫描件,复印件需加盖公章鲜章; + * 3、水印仅限于微信支付业务相关; + * 4、指引与示例可参考【指引文档】; + * 5、可上传1张图片,请填写通过图片上传API预先上传图片生成好的MediaID。 + */ + @JSONField(name = "license_copy") + private String licenseCopy; + + /** + * 必填 + * 注册号/统一社会信用代码 + */ + @JSONField(name = "license_number") + private String licenseNumber; + + /** + * 必填 + * 商户名称 + * 1、长度为2-128个字符; + * 2、前后不能有空格、制表符、换行符; + * 3、不能仅含数字、特殊字符; + * 4、仅能填写数字、英文字母、汉字及特殊字符; + * 5、仅支持utf-8格式; + * 6、个体户证件为以下情况时,按照个体户XXX命名(XXX是营业执照经营人姓名):营业执照登记名称为空、仅含数字、仅含特殊字符、“无”、“无字号”; + * 7、个体户不能使用“企业”“公司”或“农民专业合作社”结尾。 + */ + @JSONField(name = "merchant_name") + private String merchantName; + + /** + * 必填 + * 个体户经营者/法定代表人姓名 请填写营业执照的经营者/法定代表人姓名 + * 1、长度为2-100个字符; + * 2、前后不能有空格、制表符、换行符; + * 3、不能仅含特殊字符; + * 4、仅能填写数字、英文字母、汉字及特殊字符。 + */ + @JSONField(name = "legal_person") + private String legalPerson; + + /** + * 选填 + * 注册地址 建议填写营业执照的注册地址,若该字段未填写,系统将会查询国家工商信息填入。需注意若工商信息查询不到,则会被审核驳回。 + * 1、长度为4-128个字符; + * 2、前后不能有空格、制表符、换行符; + * 3、不能仅含数字、特殊字符; + * 4、仅能填写数字、英文字母、汉字及特殊字符; + * 5、仅支持utf-8格式。 + */ + @JSONField(name = "license_address") + private String licenseAddress; + + /** + * 选填 + * 有效期限开始日期 建议填写营业执照的有效期限开始时间,若该字段未填写,系统将会查询国家工商信息填入。需注意若工商信息查询不到,则会被审核驳回。 + * 1、日期格式应满足合法的YYYY-MM-DD格式; + * 2、开始时间不能小于1900-01-01; + * 3、开始时间不能大于等于当前日期。 + */ + @JSONField(name = "period_begin") + private String periodBegin; + + /** + * 选填 + * 营业期限结束日期 建议填写营业执照的有效期限结束时间,若该字段未填写,系统将会查询国家工商信息填入。需注意若工商信息查询不到,则会被审核驳回。 + * 1、日期格式应满足合法的YYYY-MM-DD格式或长期; + * 2、结束时间需大于开始时间。 + */ + @JSONField(name = "period_end") + private String periodEnd; +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryAppInfoReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryAppInfoReqDto.java new file mode 100644 index 000000000..c14b829be --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryAppInfoReqDto.java @@ -0,0 +1,43 @@ +package com.czg.wechat.dto.req.entry.business.sales; + +import com.alibaba.fastjson2.annotation.JSONField; +import lombok.Data; + +import java.util.List; + +/** + * 进件-经营资料-经营场景-App场景 + * @author yjjie + * @date 2025/12/26 14:26 + */ +@Data +public class WechatEntryAppInfoReqDto { + + /** + * 必填 + * App截图 + * 1、请提供APP首页截图、尾页截图、应用内截图、支付页截图各1张; + * 2、请填写通过图片上传API预先上传图片生成好的MediaID。 + */ + @JSONField(name = "app_pics") + private List appPics; + + /** + * 选填 + * 商家应用AppID + * 1、服务商应用AppID与商家应用AppID,二选一必填; + * 2、可填写与商家主体一致且已认证的应用AppID,需是已认证的App; + * 3、审核通过后,系统将发起特约商家商户号与该AppID的绑定(即配置为sub_appid),服务商随后可在发起支付时选择传入该AppID,以完成支付,并获取sub_openid用于数据统计,营销等业务场景。 + */ + @JSONField(name = "app_sub_appid") + private String appSubAppid; + + /** + * 选填 + * 服务商应用AppID + * 1、服务商应用AppID与商家应用AppID,二选一必填; + * 2、可填写当前服务商商户号已绑定的应用AppID。 + */ + @JSONField(name = "app_appid") + private String appAppid; +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryMiniProgramReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryMiniProgramReqDto.java new file mode 100644 index 000000000..124199c42 --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryMiniProgramReqDto.java @@ -0,0 +1,45 @@ +package com.czg.wechat.dto.req.entry.business.sales; + +import com.alibaba.fastjson2.annotation.JSONField; +import lombok.Data; + +import java.util.List; + +/** + * 进件-经营资料-经营场景-小程序场景 + * @author yjjie + * @date 2025/12/26 14:23 + */ +@Data +public class WechatEntryMiniProgramReqDto { + + /** + * 选填 + * 服务商小程序AppID + * 1、服务商小程序AppID与商家小程序AppID,二选一必填; + * 2、可填写当前服务商商户号已绑定的小程序AppID。 + */ + @JSONField(name = "mini_program_appid") + private String miniProgramAppid; + + /** + * 选填 + * 商家小程序AppID + * 1、服务商小程序AppID与商家小程序AppID,二选一必填; + * 2、请填写已认证的小程序AppID; + * 3、完成进件后,系统发起特约商户号与该AppID的绑定(即配置为sub_appid可在发起支付时传入) + * (1)若AppID主体与商家主体/服务商主体一致,则直接完成绑定; + * (2)若AppID主体与商家主体/服务商主体不一致,则商户签约时显示《联合营运承诺函》,并且AppID的管理员需登录公众平台确认绑定意愿。 + */ + @JSONField(name = "mini_program_sub_appid") + private String miniProgramSubAppid; + + /** + * 选填 + * 小程序截图 + * 1、请提供展示商品/服务的页面截图/设计稿(最多5张),若小程序未建设完善或未上线 请务必提供; + * 2、请填写通过图片上传API预先上传图片生成好的MediaID。 + */ + @JSONField(name = "mini_program_pics") + private List miniProgramPics; +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryMpInfoReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryMpInfoReqDto.java new file mode 100644 index 000000000..aa419e063 --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryMpInfoReqDto.java @@ -0,0 +1,43 @@ +package com.czg.wechat.dto.req.entry.business.sales; + +import com.alibaba.fastjson2.annotation.JSONField; +import lombok.Data; + +import java.util.List; + +/** + * 进件-经营资料-经营场景-服务号或公众号景 + * @author yjjie + * @date 2025/12/26 14:20 + */ +@Data +public class WechatEntryMpInfoReqDto { + + /** + * 必填 + * 服务号或公众号页面截图 + * 1、请提供展示商品/服务的页面截图/设计稿(最多5张),若服务号或公众号未建设完善或未上线请务必提供; + * 2、请填写通过图片上传API预先上传图片生成好的MediaID。 + */ + @JSONField(name = "mp_pics") + private List mpPics; + + /** + * 选填 + * 商家服务号或公众号AppID + * 1、服务商服务号或公众号AppID、商家服务号或公众号AppID,二选一必填; + * 2、可填写与商家主体一致且已认证的服务号或公众号AppID,需是已认证的服务号、政府或媒体类型的公众号; + * 3、审核通过后,系统将发起特约商家商户号与该AppID的绑定(即配置为sub_appid),服务商随后可在发起支付时选择传入该appid,以完成支付,并获取sub_openid用于数据统计,营销等业务场景。 + */ + @JSONField(name = "mp_sub_appid") + private String mpSubAppid; + + /** + * 选填 + * 服务商服务号或公众号AppID + * 1、服务商服务号或公众号AppID、商家服务号或公众号AppID,二选一必填; + * 2、可填写当前服务商商户号已绑定的服务号或公众号AppID。 + */ + @JSONField(name = "mp_appid") + private String mpAppid; +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntrySalesInfoReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntrySalesInfoReqDto.java new file mode 100644 index 000000000..00143fd84 --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntrySalesInfoReqDto.java @@ -0,0 +1,85 @@ +package com.czg.wechat.dto.req.entry.business.sales; + +import com.alibaba.fastjson2.annotation.JSONField; +import lombok.Data; + +import java.util.List; + +/** + * 进件-经营场景 + * @author yjjie + * @date 2025/12/26 14:07 + */ +@Data +public class WechatEntrySalesInfoReqDto { + + /** + * 必填 + * 经营场景类型 + * 1、请勾选实际售卖商品/提供服务场景(至少一项),以便为你开通需要的支付权限; + * 2、建议只勾选目前必须的场景,以便尽快通过入驻审核,其他支付权限可在入驻后再根据实际需要发起申请 + * 可选取值 + * SALES_SCENES_STORE: 线下场所 + * SALES_SCENES_MP: 服务号与公众号 + * SALES_SCENES_MINI_PROGRAM: 小程序 + * SALES_SCENES_WEB: 互联网网站 + * SALES_SCENES_APP: App + * SALES_SCENES_WEWORK: 企业微信 + */ + @JSONField(name = "sales_scenes_type") + private List salesScenesType; + + /** + * 选填 + * 线下场所场景 + * 1、审核通过后,服务商可帮商户发起付款码支付、JSAPI支付; + * 2、当"经营场景类型"选择"SALES_SCENES_STORE",该场景资料必填。 + */ + @JSONField(name = "biz_store_info") + private WechatEntryStoreInfoReqDto bizStoreInfo; + + /** + * 选填 + * 服务号或公众号场景 + * 1、审核通过后,服务商可帮商家发起JSAPI支付; + * 2、当"经营场景类型"选择"SALES_SCENES_MP",该场景资料必填。 + */ + @JSONField(name = "mp_info") + private WechatEntryMpInfoReqDto mpInfo; + + /** + * 选填 + * 小程序场景 + * 1、审核通过后,服务商可帮商家发起JSAPI支付; + * 2、当"经营场景类型"选择"SALES_SCENES_MINI_PROGRAM",该场景资料必填。 + */ + @JSONField(name = "mini_program_info") + private WechatEntryMiniProgramReqDto miniProgramInfo; + + /** + * 选填 + * App场景 + * 1、审核通过后,服务商可帮商家发起App支付; + * 2、当"经营场景类型"选择"SALES_SCENES_APP",该场景资料必填。 + */ + @JSONField(name = "app_info") + private WechatEntryAppInfoReqDto appInfo; + + /** + * 选填 + * 互联网网站场景 + * 1、审核通过后,服务商可帮商家发起JSAPI支付; + * 2、当"经营场景类型"选择"SALES_SCENES_WEB",该场景资料必填。 + */ + @JSONField(name = "web_info") + private WechatEntryWebInfoReqDto webInfo; + + /** + * 选填 + * 企业微信场景 + * 1、审核通过后,服务商可帮商家发起JSAPI支付; + * 2、当"经营场景类型"选择"SALES_SCENES_WEWORK",该场景资料必填。 + */ + @JSONField(name = "wework_info") + private WechatEntryWeworkInfoReqDto weworkInfo; +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryStoreInfoReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryStoreInfoReqDto.java new file mode 100644 index 000000000..e4c202a52 --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryStoreInfoReqDto.java @@ -0,0 +1,76 @@ +package com.czg.wechat.dto.req.entry.business.sales; + +import com.alibaba.fastjson2.annotation.JSONField; +import lombok.Data; + +import java.util.List; + +/** + * 进件-经营资料-经营场景-线下场所场景 + * @author yjjie + * @date 2025/12/26 14:10 + */ +@Data +public class WechatEntryStoreInfoReqDto { + + /** + * 必填 + * 线下场所名称 请填写门店名称 + * 1、长度为1-50个字符; + * 2、前后不能有空格、制表符、换行符; + * 3、不能仅含数字、特殊字符; + * 4、仅能填写数字、英文字母、汉字及特殊字符; + * 5、仅支持utf-8格式。 + */ + @JSONField(name = "biz_store_name") + private String bizStoreName; + + /** + * 必填 + * 线下场所省市编码 + * 1、只能由数字组成; + * 2、详细参见微信支付提供的省市对照表。 ... + */ + @JSONField(name = "biz_address_code") + private String bizAddressCode; + + /** + * 必填 + * 线下场所地址 请填写详细的经营场所信息,如有多个场所,选择一个主要场所填写即可。 + * 1、长度为4-512个字符; + * 2、前后不能有空格、制表符、换行符; + * 3、不能仅含数字、特殊字符; + * 4、仅能填写数字、英文字母、汉字及特殊字符; + * 5、仅支持utf-8格式 + */ + @JSONField(name = "biz_store_address") + private String bizStoreAddress; + + /** + * 必填 + * 线下场所门头照片 + * 1、请上传门头正面照片(要求门店招牌、门框完整、清晰、可辨识);若为停车场等无固定门头照片的经营场所,可上传岗亭/出入闸口。具体参考【指引文档】; + * 2、请填写通过图片上传API预先上传图片生成好的MediaID。 + */ + @JSONField(name = "store_entrance_pic") + private List storeEntrancePic; + + /** + * 必填 + * 线下场所内部照片 + * 1、请上传门店内部环境照片(可辨识经营内容)。若为停车场等无固定门头的经营场所,可上传停车场内部照片。具体参考【指引文档】; + * 2、请填写通过图片上传API预先上传图片生成好的MediaID。 + */ + @JSONField(name = "indoor_pic") + private List indoorPic; + + /** + * 选填 + * 线下场所对应的商家AppID + * 1、可填写与商家主体一致且已认证的服务号或公众号、小程序、APP的AppID,其中服务号或公众号AppID需是已认证的服务号、政府或媒体类型的公众号; + * 2、审核通过后,系统将额外为商家开通付款码支付、JSAPI支付的自有交易权限,并完成商家商户号与该AppID的绑定。 + */ + @JSONField(name = "biz_sub_appid") + private String bizSubAppid; + +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryWebInfoReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryWebInfoReqDto.java new file mode 100644 index 000000000..b213f88de --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryWebInfoReqDto.java @@ -0,0 +1,42 @@ +package com.czg.wechat.dto.req.entry.business.sales; + +import com.alibaba.fastjson2.annotation.JSONField; +import lombok.Data; + +/** + * 进件-经营资料-经营场景-互联网网站场景 + * @author yjjie + * @date 2025/12/26 14:29 + */ +@Data +public class WechatEntryWebInfoReqDto { + + /** + * 必填 + * 互联网网站域名 + * 1、如为PC端商城、智能终端等场景,可上传官网链接; + * 2、网站域名需ICP备案,若备案主体与申请主体不同,请上传加盖公章的网站授权函。 + */ + @JSONField(name = "domain") + private String domain; + + /** + * 必填 + * 网站授权函 + * 1、若备案主体与申请主体不同,请务必上传加盖公章的网站授权函.doc; ... + * 2、请填写通过图片上传API预先上传图片生成好的MediaID。 + */ + @JSONField(name = "web_authorisation") + private String webAuthorisation; + + /** + * 选填 + * 互联网网站对应的商家AppID + * 1、可填写已认证的服务号或公众号、小程序、APP的AppID,其中服务号或公众号AppID需是已认证的服务号、政府或媒体类型的公众号; + * 2、完成进件后,系统发起特约商户号与该AppID的绑定(即配置为sub_appid,可在发起支付时传入) + * (1)若APPID主体与商家主体一致,则直接完成绑定; + * (2)若APPID主体与商家主体不一致,则商户签约时显示《联合营运承诺函》,并且 AppID的管理员需登录公众平台确认绑定意愿;( 暂不支持绑定异主体的应用APPID)。 + */ + @JSONField(name = "web_appid") + private String webAppid; +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryWeworkInfoReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryWeworkInfoReqDto.java new file mode 100644 index 000000000..544e08d2e --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryWeworkInfoReqDto.java @@ -0,0 +1,31 @@ +package com.czg.wechat.dto.req.entry.business.sales; + +import com.alibaba.fastjson2.annotation.JSONField; +import lombok.Data; + +/** + * 进件-经营资料-经营场景-企业微信场景 + * @author yjjie + * @date 2025/12/26 14:32 + */ +@Data +public class WechatEntryWeworkInfoReqDto { + + /** + * 必填 + * 商家企业微信CorpID + * 1、可填写与商家主体一致且已认证的企业微信CorpID; + * 2、审核通过后,系统将为商家开通企业微信专区的自有交易权限,并完成商家商户号与该AppID的绑定,商家可自行发起交易。 + */ + @JSONField(name = "sub_corp_id") + private String subCorpId; + + /** + * 必填 + * 企业微信页面截图 + * 1、最多可上传5张照片; + * 2、请填写通过图片上传API预先上传图片生成好的MediaID。 + */ + @JSONField(name = "wework_pics") + private String[] weworkPics; +} From e179a910ba556af1e4d32894edba3e4e0ba2ef0b Mon Sep 17 00:00:00 2001 From: gong <1157756119@qq.com> Date: Fri, 26 Dec 2025 15:13:11 +0800 Subject: [PATCH 003/133] =?UTF-8?q?=E5=BE=AE=E4=BF=A1=E6=94=AF=E4=BB=98-?= =?UTF-8?q?=20dto1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/req/entry/business/WechatEntryCertificateReqDto.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryCertificateReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryCertificateReqDto.java index df2090102..910f94b58 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryCertificateReqDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryCertificateReqDto.java @@ -9,4 +9,9 @@ import lombok.Data; */ @Data public class WechatEntryCertificateReqDto { + + /** + * 必填 + * 登记证书照片 + */ } From 0cdad226ea75bc6bf8736014f222138860fdc19d Mon Sep 17 00:00:00 2001 From: gong <1157756119@qq.com> Date: Fri, 26 Dec 2025 16:23:46 +0800 Subject: [PATCH 004/133] =?UTF-8?q?=E5=BE=AE=E4=BF=A1=E6=94=AF=E4=BB=98-?= =?UTF-8?q?=20dto222?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../req/entry/WechatEntryContactReqDto.java | 124 ++++++++++++++++++ .../req/entry/WechatEntrySubjectReqDto.java | 50 ++++++- .../WechatEntryCertificateReqDto.java | 92 +++++++++++++ .../WechatEntryFinanceInstitutionReqDto.java | 40 ++++++ .../business/WechatEntryIdentityReqDto.java | 70 ++++++++++ .../business/WechatEntryUboInfoReqDto.java | 111 ++++++++++++++++ .../req/entry/id/WechatEntryIdCardReqDto.java | 94 +++++++++++++ .../entry/id/WechatEntryIdDocInfoReqDto.java | 98 ++++++++++++++ 8 files changed, 677 insertions(+), 2 deletions(-) create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryFinanceInstitutionReqDto.java create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryIdentityReqDto.java create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryUboInfoReqDto.java create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/id/WechatEntryIdCardReqDto.java create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/id/WechatEntryIdDocInfoReqDto.java diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntryContactReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntryContactReqDto.java index a7990dbd0..82c91ed49 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntryContactReqDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntryContactReqDto.java @@ -1,5 +1,6 @@ package com.czg.wechat.dto.req.entry; +import com.alibaba.fastjson2.annotation.JSONField; import lombok.Data; /** @@ -10,4 +11,127 @@ import lombok.Data; */ @Data public class WechatEntryContactReqDto { + + /** + * 必填 + * 超级管理员类型 + * 主体为“个体工商户/企业/政府机关/事业单位/社会组织”,可选择:LEGAL:经营者/法定代表人,SUPER:经办人 。(经办人:经商户授权办理微信支付业务的人员)。 + * 可选取值 + * LEGAL: 经营者/法定代表人 + * SUPER: 经办人 + */ + @JSONField(name = "contact_type") + private String contactType; + + /** + * 必填 + * 超级管理员姓名 + * 1、长度为2-100个字符; + * 2、前后不能有空格、制表符、换行符; + * 3、不能仅含数字、特殊字符; + * 4、仅能填写数字、英文字母、汉字及特殊字符。 + * 该字段需要使用微信支付公钥加密(推荐),请参考获取微信支付公钥ID说明以及微信支付公钥加密敏感信息指引,也可以使用微信支付平台证书公钥加密,参考获取平台证书序列号、平台证书加密敏感信息指引。 + */ + @JSONField(name = "contact_name") + private String contactName; + + /** + * 选填 + * 超级管理员证件类型 当超级管理员类型是经办人时,请上传超级管理员证件类型。 + * 可选取值 + * IDENTIFICATION_TYPE_IDCARD: 中国大陆居民-身份证 + * IDENTIFICATION_TYPE_OVERSEA_PASSPORT: 其他国家或地区居民-护照 + * IDENTIFICATION_TYPE_HONGKONG_PASSPORT: 中国香港居民-来往内地通行证 + * IDENTIFICATION_TYPE_MACAO_PASSPORT: 中国澳门居民-来往内地通行证 + * IDENTIFICATION_TYPE_TAIWAN_PASSPORT: 中国台湾居民-来往大陆通行证 + * IDENTIFICATION_TYPE_FOREIGN_RESIDENT: 外国人居留证 + * IDENTIFICATION_TYPE_HONGKONG_MACAO_RESIDENT: 港澳居民居住证 + * IDENTIFICATION_TYPE_TAIWAN_RESIDENT: 台湾居民居住证 + */ + @JSONField(name = "contact_id_type") + private String contactIdType; + + /** + * 选填 + * 超级管理员身份证件号码 + * 1、当超级管理员类型是经办人时,请上传超级管理员证件号码; + * 2、可传身份证、来往内地通行证、来往大陆通行证、护照等证件号码,号码规范如下: + * 身份证(限中国大陆居民):17位数字+1位数字|X; + * 护照(限境外人士):4-15位 数字|字母|连字符; + * 中国香港居民--来往内地通行证:H/h开头+8或10位数字/字母; + * 中国澳门居民--来往内地通行证:M/m开头+8或10位数字/字母; + * 中国台湾居民--来往大陆通行证:8位数字或10位数字; + * 外国人居留证:15位 数字|字母; + * 台湾居民居住证/港澳居民居住证:17位数字+1位数字|X; + * 3、超级管理员签约时,校验微信号绑定的银行卡实名信息,是否与该证件号码一致; + * 4、该字段需要使用微信支付公钥加密(推荐),请参考获取微信支付公钥ID说明以及微信支付公钥加密敏感信息指引,也可以使用微信支付平台证书公钥加密,参考获取平台证书序列号、平台证书加密敏感信息指引。 + */ + @JSONField(name = "contact_id_number") + private String contactIdNumber; + + /** + * 选填 + * 超级管理员证件正面照片 + * 1、当超级管理员类型是经办人时,请上传超级管理员证件的正面照片; + * 2、若证件类型为身份证,请上传人像面照片; + * 3、正面拍摄、清晰、四角完整、无反光或遮挡;不得翻拍、截图、镜像、PS; + * 4、请上传彩色照片或彩色扫描件或复印件(需加盖公章鲜章),可添加“微信支付”相关水印(如微信支付认证),见【指引文档】; + * 5、可上传1张图片,请填写通过图片上传API预先上传图片生成好的MediaID。 + */ + @JSONField(name = "contact_id_doc_copy") + private String contactIdDocCopy; + + /** + * 选填 + * 超级管理员证件反面照片 + * 1、当超级管理员类型是经办人时,请上传超级管理员证件的反面照片; + * 2、若证件类型为护照,无需上传反面照片; + * 3、正面拍摄、清晰、四角完整、无反光或遮挡;不得翻拍、截图、镜像、PS; + * 4、请上传彩色照片或彩色扫描件,复印件需加盖公章鲜章,可添加“微信支付”相关水印(如微信支付认证),见【指引文档】; + * 5、可上传1张图片,请填写通过图片上传API预先上传图片生成好的MediaID。 + */ + @JSONField(name = "contact_id_doc_copy_back") + private String contactIdDocCopyBack; + + /** + * 选填 + * 超级管理员证件有效期开始时间 + * 1、当超级管理员类型是经办人时,请上传证件有效期开始时间; + * 2、请按照示例值填写,日期格式应满足合法的YYYY-MM-DD格式; + * 3、开始时间不能小于1900-01-01,开始时间不能大于等于当前日期。 + */ + @JSONField(name = "contact_period_begin") + private String contactPeriodBegin; + + /** + * 选填 + * 超级管理员证件有效期截止时间 + * 1、当超级管理员类型是经办人时,请上传证件有效期结束时间; + * 2、请按照示例值填写,日期格式应满足合法的YYYY-MM-DD格式,若证件有效期为长期,请填写:长期; + * 3、结束时间大于开始时间。 + */ + @JSONField(name = "contact_period_end") + private String contactPeriodEnd; + + /** + * 必填 + * 联系手机 + * 1、前后不能有空格、制表符、换行符; + * 2、需满足以下任一条件: + * 11位数字的手机号码; + * 5-20位数字、连字符“-”、加号“+”; + * 3、用于接收微信支付的重要管理信息及日常操作验证码; + * 4、该字段需要使用微信支付公钥加密(推荐),请参考获取微信支付公钥ID说明以及微信支付公钥加密敏感信息指引,也可以使用微信支付平台证书公钥加密,参考获取平台证书序列号、平台证书加密敏感信息指引。 + */ + @JSONField(name = "mobile_phone") + private String mobilePhone; + + /** + * 必填 + * 联系邮箱 + * 1、用于接收微信支付的开户邮件及日常业务通知; + * 2、需要带@,遵循邮箱格式校验 ,该字段需要使用微信支付公钥加密(推荐),请参考获取微信支付公钥ID说明以及微信支付公钥加密敏感信息指引,也可以使用微信支付平台证书公钥加密,参考获取平台证书序列号、平台证书加密敏感信息指引。 + */ + @JSONField(name = "contact_email") + private String contactEmail; } diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntrySubjectReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntrySubjectReqDto.java index a445b6a5f..d8cabd000 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntrySubjectReqDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntrySubjectReqDto.java @@ -1,10 +1,11 @@ package com.czg.wechat.dto.req.entry; import com.alibaba.fastjson2.annotation.JSONField; -import com.czg.wechat.dto.req.entry.business.WechatEntryCertificateReqDto; -import com.czg.wechat.dto.req.entry.business.WechatEntryLicenseReqDto; +import com.czg.wechat.dto.req.entry.business.*; import lombok.Data; +import java.util.List; + /** * 进件 主体资料 * @author yjjie @@ -52,4 +53,49 @@ public class WechatEntrySubjectReqDto { */ @JSONField(name = "certificate_info") private WechatEntryCertificateReqDto certificateInfo; + + /** + * 选填 + * 单位证明函照片 + * 1、主体类型为政府机关、事业单位选传: + * (1)若上传,则审核通过后即可签约,无需汇款验证; + * (2)若未上传,则审核通过后,需汇款验证。 + * 2、主体为个体户、企业、其他组织等,不需要上传本字段; + * 3、请参照示例图打印单位证明函,全部信息需打印,不支持手写商户信息,并加盖公章; ... + * 4、可上传1张图片,请填写通过图片上传API预先上传图片生成好的MediaID。 + */ + @JSONField(name = "certificate_letter_copy") + private String certificateLetterCopy; + + /** + * 选填 + * 金融机构许可证信息 当主体是金融机构时,必填。 + */ + @JSONField(name = "finance_institution_info") + private WechatEntryFinanceInstitutionReqDto financeInstitutionInfo; + + /** + * 必填 + * 经营者/法定代表人身份证件 + * 1、个体户:请上传经营者的身份证件; + * 2、企业/社会组织:请上传法定代表人的身份证件; + * 3、政府机关/事业单位:请上传法定代表人/经办人的身份证件。 + */ + @JSONField(name = "identity_info") + private WechatEntryIdentityReqDto identityInfo; + + /** + * 选填 + * 最终受益人信息列表(UBO) + * 1、主体类型个体户/社会组织/政府机关/事业单位时,无需填写 + * 2、主体类型为企业时,按照下述要求填写 + * 1)若经营者/法定代表人不是最终受益所有人,则需提填写受益所有人信息,最多上传4个。 + * 2)若经营者/法定代表人是最终受益所有人之一,可在此填写其他受益所有人信息,最多上传3个。 + * 根据国家相关法律法规,需要提供公司受益所有人信息,受益所有人需符合至少以下条件之一: + * ▪️直接或者间接拥有超过25%公司股权或者表决权的自然人。 + * ▪️通过人事、财务等其他方式对公司进行控制的自然人。 + * ▪️公司的高级管理人员,包括公司的经理、副经理、财务负责人、上市公司董事会秘书和公司章程规定的其他人员。 + */ + @JSONField(name = "ubo_info_list") + private List uboInfoList; } diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryCertificateReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryCertificateReqDto.java index 910f94b58..ce09795f3 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryCertificateReqDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryCertificateReqDto.java @@ -1,5 +1,6 @@ package com.czg.wechat.dto.req.entry.business; +import com.alibaba.fastjson2.annotation.JSONField; import lombok.Data; /** @@ -13,5 +14,96 @@ public class WechatEntryCertificateReqDto { /** * 必填 * 登记证书照片 + * 1、照片应正面拍摄、清晰、四角完整、无反光或遮挡;不得翻拍、截图、镜像、PS; + * 2、上传彩色照片、彩色扫描件,复印件需加盖公章鲜章; + * 3、水印仅限于微信支付业务相关; + * 4、指引与示例可参考【指引文档】; + * 5、请填写通过图片上传API预先上传图片生成好的MediaID。 */ + @JSONField(name = "cert_copy") + private String certCopy; + + /** + * 必填 + * 登记证书类型 + * 1、主体为“政府机关/事业单位/社会组织”时,请上传登记证书类型; + * 2、主体为“个体工商户/企业”时,不填; + * 当主体为事业单位时,选择此枚举值: + * CERTIFICATE_TYPE_2388:事业单位法人证书 + * 当主体为政府机关,选择此枚举值: + * CERTIFICATE_TYPE_2389:统一社会信用代码证书 + * 当主体为社会组织,选择以下枚举值之一: + * CERTIFICATE_TYPE_2389:统一社会信用代码证书 + * CERTIFICATE_TYPE_2394:社会团体法人登记证书 + * CERTIFICATE_TYPE_2395:民办非企业单位登记证书 + * CERTIFICATE_TYPE_2396:基金会法人登记证书 + * CERTIFICATE_TYPE_2520:执业许可证/执业证 + * CERTIFICATE_TYPE_2521:基层群众性自治组织特别法人统一社会信用代码证 + * CERTIFICATE_TYPE_2522:农村集体经济组织登记证 + * CERTIFICATE_TYPE_2399:宗教活动场所登记证 + * CERTIFICATE_TYPE_2400:政府部门下发的其他有效证明文件 + */ + @JSONField(name = "cert_type") + private String certType; + + /** + * 必填 + * 证书号 请输入与所选证书类型相匹配且符合国家标准规范的证书号,其中除政府证明文件外,需满足18位阿拉伯数字或大写英文字母(不得包含英文字母I/O/Z/S/V) + */ + @JSONField(name = "cert_number") + private String certNumber; + + /** + * 必填 + * 商户名称 请填写登记证书上的商户名称 + * 1、长度为2-128个字符; + * 2、前后不能有空格、制表符、换行符; + * 3、不能仅含数字、特殊字符; + * 4、仅能填写数字、英文字母、汉字及特殊字符; + * 5、仅支持utf-8格式。 + */ + @JSONField(name = "merchant_name") + private String merchantName; + + /** + * 必填 + * 注册地址 请填写登记证书的注册地址 + * 1、长度为4-128个字符; + * 2、前后不能有空格、制表符、换行符; + * 3、不能仅含数字、特殊字符; + * 4、仅能填写数字、英文字母、汉字及特殊字符; + * 5、仅支持utf-8格式。 + */ + @JSONField(name = "company_address") + private String companyAddress; + + /** + * 必填 + * 法定代表人 请填写登记证书上的法定代表人姓名 + * 1、长度为2-100个字符; + * 2、前后不能有空格、制表符、换行符; + * 3、不能仅含特殊字符; + * 4、仅能填写数字、英文字母、汉字及特殊字符。 + */ + @JSONField(name = "legal_person") + private String legalPerson; + + /** + * 选填 + * 有效期限开始日期 建议填写营业执照的有效期限开始时间,若该字段未填写,系统将会查询国家工商信息填入。需注意若工商信息查询不到,则会被审核驳回。 + * 1、日期格式应满足合法的YYYY-MM-DD格式; + * 2、开始时间不能小于1900-01-01; + * 3、开始时间不能大于等于当前日期。 + */ + @JSONField(name = "period_begin") + private String periodBegin; + + /** + * 选填 + * 营业期限结束日期 建议填写营业执照的有效期限结束时间,若该字段未填写,系统将会查询国家工商信息填入。需注意若工商信息查询不到,则会被审核驳回。 + * 1、日期格式应满足合法的YYYY-MM-DD格式或长期; + * 2、结束时间需大于开始时间。 + */ + @JSONField(name = "period_end") + private String periodEnd; } diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryFinanceInstitutionReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryFinanceInstitutionReqDto.java new file mode 100644 index 000000000..61a450018 --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryFinanceInstitutionReqDto.java @@ -0,0 +1,40 @@ +package com.czg.wechat.dto.req.entry.business; + +import com.alibaba.fastjson2.annotation.JSONField; +import lombok.Data; + +import java.util.List; + +/** + * 金融机构许可证信息 + * @author yjjie + * @date 2025/12/26 15:21 + */ +@Data +public class WechatEntryFinanceInstitutionReqDto { + + /** + * 必填 + * 金融机构类型 金融机构类型需与营业执照/登记证书上一致,可参考选择金融机构指引。 + * BANK_AGENT:银行业, 适用于商业银行、政策性银行、农村合作银行、村镇银行、开发性金融机构等 + * PAYMENT_AGENT:支付机构, 适用于非银行类支付机构 + * INSURANCE:保险业, 适用于保险、保险中介、保险代理、保险经纪等保险类业务 + * TRADE_AND_SETTLE:交易及结算类金融机构, 适用于交易所、登记结算类机构、银行卡清算机构、资金清算中心等 + * OTHER:其他金融机构, 适用于财务公司、信托公司、金融资产管理公司、金融租赁公司、汽车金融公司、贷款公司、货币经纪公司、消费金融公司、证券业、金融控股公司、股票、期货、货币兑换、小额贷款公司、金融资产管理、担保公司、商业保理公司、典当行、融资租赁公司、财经咨询等其他金融业务 + */ + @JSONField(name = "finance_type") + private String financeType; + + /** + * 必填 + * 金融机构许可证图片 + * 1、照片应正面拍摄、清晰、四角完整、无反光或遮挡;不得翻拍、截图、镜像、PS; + * 2、上传彩色照片、彩色扫描件,复印件需加盖公章鲜章; + * 3、水印仅限于微信支付业务相关; + * 4、根据所属金融机构类型的许可证要求提供,详情查看金融机构指引; ... + * 5、请提供为“申请商家主体”所属的许可证,可授权使用总公司/分公司的特殊资质; + * 6、最多可上传5张照片,请填写通过图片上传API预先上传图片生成好的MediaID。 + */ + @JSONField(name = "finance_license_pics") + private List financeLicensePics; +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryIdentityReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryIdentityReqDto.java new file mode 100644 index 000000000..539c71e96 --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryIdentityReqDto.java @@ -0,0 +1,70 @@ +package com.czg.wechat.dto.req.entry.business; + +import com.alibaba.fastjson2.annotation.JSONField; +import com.czg.wechat.dto.req.entry.id.WechatEntryIdCardReqDto; +import com.czg.wechat.dto.req.entry.id.WechatEntryIdDocInfoReqDto; +import lombok.Data; + +/** + * 经营者/法定代表人身份证件 + * @author yjjie + * @date 2025/12/26 15:24 + */ +@Data +public class WechatEntryIdentityReqDto { + + /** + * 选填 + * 证件持有人类型 + * 1、主体类型为政府机关/事业单位时选传: + * (1)若上传的是法定代表人证件,则不需要上传该字段。 + * (2)若因政策保密等原因,无法提供法定代表人证件时,可上传经办人。 (经办人:经商户授权办理微信支付业务的人员,授权范围包括但不限于签约,入驻过程需完成账户验证)。 + * 2、主体类型为小微/个人卖家/企业/个体户/社会组织时,默认为经营者/法定代表人,不需要上传该字段。 + * LEGAL: 经营者/法定代表人 + * SUPER: 经办人 + */ + @JSONField(name = "id_holder_type") + private String idHolderType; + + /** + * 选填 + * 证件类型 + * 1、当证件持有人类型为法定代表人时,填写。其他情况,无需上传; + * 2、个体户/企业/事业单位/社会组织:可选择任一证件类型,政府机关仅支持中国大陆居民-身份证类型。 + * 可选取值 + * IDENTIFICATION_TYPE_IDCARD: 中国大陆居民-身份证 + * IDENTIFICATION_TYPE_OVERSEA_PASSPORT: 其他国家或地区居民-护照 + * IDENTIFICATION_TYPE_HONGKONG_PASSPORT: 中国香港居民-来往内地通行证 + * IDENTIFICATION_TYPE_MACAO_PASSPORT: 中国澳门居民-来往内地通行证 + * IDENTIFICATION_TYPE_TAIWAN_PASSPORT: 中国台湾居民-来往大陆通行证 + * IDENTIFICATION_TYPE_FOREIGN_RESIDENT: 外国人居留证 + * IDENTIFICATION_TYPE_HONGKONG_MACAO_RESIDENT: 港澳居民居住证 + * IDENTIFICATION_TYPE_TAIWAN_RESIDENT: 台湾居民居住证 + */ + @JSONField(name = "id_doc_type") + private String idDocType; + + /** + * 选填 + * 法定代表人说明函 + * 1、当证件持有人类型为经办人时,必须上传。其他情况,无需上传; + * 2、若因特殊情况,无法提供法定代表人证件时,请参照示例图打印法定代表人说明函,全部信息需打印,不支持手写商户信息,并加盖公章; ... + * 3、可上传1张图片,请填写通过图片上传API预先上传图片生成好的MediaID。 + */ + @JSONField(name = "authorize_letter_copy") + private String authorizeLetterCopy; + + /** + * 选填 + * 身份证信息 当证件持有人类型为经营者/法定代表人且证件类型为“身份证”时填写。 + */ + @JSONField(name = "id_card_info") + private WechatEntryIdCardReqDto idCardInfo; + + /** + * 选填 + * 其他类型证件信息 当证件持有人类型为经营者/法定代表人且证件类型不为“身份证”时填写。 + */ + @JSONField(name = "id_doc_info") + private WechatEntryIdDocInfoReqDto idDocInfo; +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryUboInfoReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryUboInfoReqDto.java new file mode 100644 index 000000000..3e01e0970 --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryUboInfoReqDto.java @@ -0,0 +1,111 @@ +package com.czg.wechat.dto.req.entry.business; + +import com.alibaba.fastjson2.annotation.JSONField; +import lombok.Data; + +/** + * 最终受益人信息 + * @author yjjie + * @date 2025/12/26 15:50 + */ +@Data +public class WechatEntryUboInfoReqDto { + + /** + * 必填 + * 证件类型 请填写受益人的证件类型。枚举值: + * 可选取值 + * IDENTIFICATION_TYPE_IDCARD: 中国大陆居民-身份证 + * IDENTIFICATION_TYPE_OVERSEA_PASSPORT: 其他国家或地区居民-护照 + * IDENTIFICATION_TYPE_HONGKONG_PASSPORT: 中国香港居民-来往内地通行证 + * IDENTIFICATION_TYPE_MACAO_PASSPORT: 中国澳门居民-来往内地通行证 + * IDENTIFICATION_TYPE_TAIWAN_PASSPORT: 中国台湾居民-来往大陆通行证 + * IDENTIFICATION_TYPE_FOREIGN_RESIDENT: 外国人居留证 + * IDENTIFICATION_TYPE_HONGKONG_MACAO_RESIDENT: 港澳居民居住证 + * IDENTIFICATION_TYPE_TAIWAN_RESIDENT: 台湾居民居住证 + */ + @JSONField(name = "ubo_id_doc_type") + private String uboIdDocType; + + /** + * 必填 + * 证件正面照片 + * 1、请上传受益人证件的正面照片; + * 2、若证件类型为身份证,请上传人像面照片; + * 3、正面拍摄、清晰、四角完整、无反光或遮挡;不得翻拍、截图、镜像、PS; + * 4、请上传彩色照片or彩色扫描件,复印件需加盖公章鲜章,可添加“微信支付”相关水印(如微信支付认证),见【指引文档】; + * 5、可上传1张图片,请填写通过图片上传API预先上传图片生成好的MediaID。 + */ + @JSONField(name = "ubo_id_doc_copy") + private String uboIdDocCopy; + + /** + * 选填 + * 证件反面照片 + * 1、请上传受益人证件的反面照片; + * 2、若证件类型为身份证,请上传国徽面照片; + * 3、若证件类型为护照,无需上传反面照片; + * 4、正面拍摄、清晰、四角完整、无反光或遮挡;不得翻拍、截图、镜像、PS; + * 5、请上传彩色照片or彩色扫描件,复印件需加盖公章鲜章,可添加“微信支付”相关水印(如微信支付认证),见【指引文档】; + * 6、可上传1张图片,请填写通过图片上传API预先上传图片生成好的MediaID。 + */ + @JSONField(name = "ubo_id_doc_copy_back") + private String uboIdDocCopyBack; + + /** + * 必填 + * 证件姓名 + * 1、长度为2-100个字符; + * 2、前后不能有空格、制表符、换行符; + * 3、不能仅含数字、特殊字符; + * 4、仅能填写数字、英文字母、汉字及特殊字符; + * 5、该字段需要使用微信支付公钥加密(推荐),请参考获取微信支付公钥ID说明以及微信支付公钥加密敏感信息指引,也可以使用微信支付平台证书公钥加密,参考获取平台证书序列号、平台证书加密敏感信息指引。 + */ + @JSONField(name = "ubo_id_doc_name") + private String uboIdDocName; + + /** + * 必填 + * 证件号码 + * 1、证件号码为证件正反面中一致的号码; + * 2、证件号码为18位或15位,或港澳居民来往内地通行证为9位; + * 3、证件号码为英文字母X或x,或港澳居民来往内地通行证为英文字母X或x; + * 4、证件号码为英文字母x或X,或港澳居民来往内地通行证为英文字母x或X; + * 5、该字段需要使用微信支付公钥加密(推荐),请参考获取微信支付公钥 + */ + @JSONField(name = "ubo_id_doc_number") + private String uboIdDocNumber; + + /** + * 必填 + * 证件居住地址 + * 1、请按照身份证住址填写,如广东省深圳市南山区xx路xx号xx室; + * 2、长度为4-128个字符; + * 3、前后不能有空格、制表符、换行符; + * 4、不能仅含数字、特殊字符; + * 5、仅能填写数字、英文字母、汉字及特殊字符; + * 6、仅支持utf-8格式; + * 7、 该字段需要使用微信支付公钥加密(推荐),请参考获取微信支付公钥ID说明以及微信支付公钥加密敏感信息指引,也可以使用微信支付平台证书公钥加密,参考获取平台证书序列号、平台证书加密敏感信息指引。 + */ + @JSONField(name = "ubo_id_doc_address") + private String uboIdDocAddress; + + /** + * 必填 + * 证件有效期开始时间 + * 1、日期格式应满足合法的YYYY-MM-DD格式; + * 2、开始时间不能小于1900-01-01; + * 3、开始时间不能大于等于当前日期。 + */ + @JSONField(name = "ubo_period_begin") + private String uboPeriodBegin; + + /** + * 必填 + * 证件有效期结束时间 + * 1、日期格式应满足合法的YYYY-MM-DD格式或长期; + * 2、结束时间需大于开始时间。 + */ + @JSONField(name = "ubo_period_end") + private String uboPeriodEnd; +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/id/WechatEntryIdCardReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/id/WechatEntryIdCardReqDto.java new file mode 100644 index 000000000..7e18cc07d --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/id/WechatEntryIdCardReqDto.java @@ -0,0 +1,94 @@ +package com.czg.wechat.dto.req.entry.id; + +import com.alibaba.fastjson2.annotation.JSONField; +import lombok.Data; + +/** + * 身份证信息 + * @author yjjie + * @date 2025/12/26 15:29 + */ +@Data +public class WechatEntryIdCardReqDto { + + /** + * 必填 + * 身份证人像面照片 + * 1、请上传个体户经营者/法定代表人的身份证人像面照片; + * 2、正面拍摄、清晰、四角完整、无反光或遮挡;不得翻拍、截图、镜像、PS; + * 3、请上传彩色照片or彩色扫描件,复印件需加盖公章鲜章,可添加“微信支付”相关水印(如微信支付认证),见【指引文档】; + * 4、可上传1张图片,请填写通过图片上传API预先上传图片生成好的MediaID。 + */ + @JSONField(name = "id_card_copy") + private String idCardCopy; + + /** + * 必填 + * 身份证国徽面照片 + * 、请上传个体户经营者/法定代表人的身份证国徽面照片; + * 2、正面拍摄、清晰、四角完整、无反光或遮挡;不得翻拍、截图、镜像、PS; + * 3、请上传彩色照片or彩色扫描件,复印件需加盖公章鲜章,可添加“微信支付”相关水印(如微信支付认证),见【指引文档】; + * 4、可上传1张图片,请填写通过图片上传API预先上传图片生成好的MediaID。 + */ + @JSONField(name = "id_card_national") + private String idCardNational; + + /** + * 必填 + * 身份证姓名 + * 1、请填写个体户经营者/法定代表人对应身份证的姓名; + * 2、长度为2-100个字符; + * 3、前后不能有空格、制表符、换行符; + * 4、不能仅含数字、特殊字符; + * 5、仅能填写数字、英文字母、汉字及特殊字符; + * 6、该字段需要使用微信支付公钥加密(推荐),请参考获取微信支付公钥ID说明以及微信支付公钥加密敏感信息指引,也可以使用微信支付平台证书公钥加密,参考获取平台证书序列号、平台证书加密敏感信息指引。 + * 加密 + */ + @JSONField(name = "id_card_name") + private String idCardName; + + /** + * 必填 + * 身份证号码 + * 1、请填写个体户经营者/法定代表人对应身份证的号码; + * 2、17位数字+1位数字|X ,该字段需要使用微信支付公钥加密(推荐),请参考获取微信支付公钥ID说明以及微信支付公钥加密敏感信息指引,也可以使用微信支付平台证书公钥加密,参考获取平台证书序列号、平台证书加密敏感信息指引。 + * 加密 + */ + @JSONField(name = "id_card_number") + private String idCardNumber; + + /** + * 选填 + * 身份证居住地址 + * 1、主体类型为企业时,需要填写。其他主体类型,无需上传; + * 2、请按照身份证住址填写,如广东省深圳市南山区xx路xx号xx室; + * 3、长度为4-128个字符; + * 4、前后不能有空格、制表符、换行符; + * 5、不能仅含数字、特殊字符; + * 6、仅能填写数字、英文字母、汉字及特殊字符; + * 7、仅支持utf-8格式; + * 8、 该字段需要使用微信支付公钥加密(推荐),请参考获取微信支付公钥ID说明以及微信支付公钥加密敏感信息指引,也可以使用微信支付平台证书公钥加密,参考获取平台证书序列号、平台证书加密敏感信息指引。 + * 加密 + */ + @JSONField(name = "id_card_address") + private String idCardAddress; + + /** + * 必填 + * 身份证有效期开始时间 + * 1、请填写身份证有效期开始时间,格式为yyyy-MM-dd; + * 2、开始时间不能小于1900-01-01; + * 3、开始时间不能大于等于当前日期。 + */ + @JSONField(name = "card_period_begin") + private String cardPeriodBegin; + + /** + * 必填 + * 身份证有效期截止时间 + * 1、日期格式应满足合法的YYYY-MM-DD格式或长期; + * 2、结束时间需大于开始时间。 + */ + @JSONField(name = "card_period_end") + private String cardPeriodEnd; +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/id/WechatEntryIdDocInfoReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/id/WechatEntryIdDocInfoReqDto.java new file mode 100644 index 000000000..47e3029b7 --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/id/WechatEntryIdDocInfoReqDto.java @@ -0,0 +1,98 @@ +package com.czg.wechat.dto.req.entry.id; + +import com.alibaba.fastjson2.annotation.JSONField; +import lombok.Data; + +/** + * 其他类型证件信息 + * @author yjjie + * @date 2025/12/26 15:42 + */ +@Data +public class WechatEntryIdDocInfoReqDto { + + /** + * 必填 + * 证件正面照片 + * 1、证件类型不为“身份证”时,上传证件正面照片; + * 2、正面拍摄、清晰、四角完整、无反光或遮挡;不得翻拍、截图、镜像、PS; + * 3、请上传彩色照片or彩色扫描件,复印件需加盖公章鲜章,可添加“微信支付”相关水印(如微信支付认证),见【指引文档】; + * 4、可上传1张图片,请填写通过图片上传API预先上传图片生成好的MediaID。 + */ + @JSONField(name = "id_doc_copy") + private String idDocCopy; + + /** + * 选填 + * 证件反面照片 + * 1、若证件类型为往来通行证、外国人居留证、港澳居民居住证、台湾居民居住证时,上传证件反面照片; + * 2、若证件类型为护照,无需上传反面照片; + * 3、正面拍摄、清晰、四角完整、无反光或遮挡;不得翻拍、截图、镜像、PS; + * 4、请上传彩色照片or彩色扫描件,复印件需加盖公章鲜章,可添加“微信支付”相关水印(如微信支付认证),见【指引文档】; + * 5、可上传1张图片,请填写通过图片上传API预先上传图片生成好的MediaID。 + */ + @JSONField(name = "id_doc_copy_back") + private String idDocCopyBack; + + /** + * 必填 + * 证件姓名 + * 1、请填写经营者/法定代表人的证件姓名; + * 2、长度为2-100个字符; + * 3、前后不能有空格、制表符、换行符; + * 4、不能仅含数字、特殊字符; + * 5、仅能填写数字、英文字母、汉字及特殊字符; + * 6、该字段需要使用微信支付公钥加密(推荐),请参考获取微信支付公钥ID说明以及微信支付公钥加密敏感信息指引,也可以使用微信支付平台证书公钥加密,参考获取平台证书序列号、平台证书加密敏感信息指引。 + */ + @JSONField(name = "id_doc_name") + private String idDocName; + + /** + * 必填 + * 证件号码 + * 1、请填写经营者/法定代表人的证件号码: + * 护照(限境外人士):4-15位 数字|字母|连字符; + * 中国香港居民--来往内地通行证:H/h开头+8或10位数字/字母; + * 中国澳门居民--来往内地通行证:M/m开头+8或10位数字/字母; + * 中国台湾居民--来往大陆通行证:8位数字或10位数字; + * 外国人居留证:15位 数字|字母; + * 台湾居民居住证/港澳居民居住证:17位数字+1位数字|X; + * 2、该字段需要使用微信支付公钥加密(推荐),请参考获取微信支付公钥ID说明以及微信支付公钥加密敏感信息指引,也可以使用微信支付平台证书公钥加密,参考获取平台证书序列号、平台证书加密敏感信息指引。 + */ + @JSONField(name = "id_doc_number") + private String idDocNumber; + + /** + * 选填 + * 证件居住地址 + * 1、主体类型为企业时,需要填写。其他主体类型,无需上传; + * 2、请按照身份证住址填写,如广东省深圳市南山区xx路xx号xx室; + * 3、长度为4-128个字符; + * 4、前后不能有空格、制表符、换行符; + * 5、不能仅含数字、特殊字符; + * 6、仅能填写数字、英文字母、汉字及特殊字符; + * 7、仅支持utf-8格式; + * 8、 该字段需要使用微信支付公钥加密(推荐),请参考获取微信支付公钥ID说明以及微信支付公钥加密敏感信息指引,也可以使用微信支付平台证书公钥加密,参考获取平台证书序列号、平台证书加密敏感信息指引。 + */ + @JSONField(name = "id_doc_address") + private String idDocAddress; + + /** + * 必填 + * 证件有效期开始时间 + * 1、日期格式应满足合法的YYYY-MM-DD格式; + * 2、开始时间不能小于1900-01-01; + * 3、开始时间不能大于等于当前日期。 + */ + @JSONField(name = "doc_period_begin") + private String docPeriodBegin; + + /** + * 必填 + * 证件有效期结束时间 + * 1、日期格式应满足合法的YYYY-MM-DD格式或长期; + * 2、结束时间需大于开始时间。 + */ + @JSONField(name = "doc_period_end") + private String docPeriodEnd; +} From 2046ad2486c0501f443bb9ca68663994b2ba5723 Mon Sep 17 00:00:00 2001 From: gong <1157756119@qq.com> Date: Fri, 26 Dec 2025 16:53:57 +0800 Subject: [PATCH 005/133] =?UTF-8?q?=E5=BE=AE=E4=BF=A1=E6=94=AF=E4=BB=98-?= =?UTF-8?q?=20dto=20=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/czg/wechat/WechatEntryManager.java | 9 ++++-- .../req/entry/WechatEntryAdditionReqDto.java | 10 ++++--- .../entry/WechatEntryBankAccountReqDto.java | 14 ++++++---- .../req/entry/WechatEntryContactReqDto.java | 22 ++++++++------- .../dto/req/entry/WechatEntryReqDto.java | 13 ++++++--- .../req/entry/WechatEntrySettleReqDto.java | 24 ++++++++-------- .../req/entry/WechatEntrySubjectReqDto.java | 28 ++++++++++--------- .../business/WechatEntryBusinessReqDto.java | 8 ++++-- .../WechatEntryCertificateReqDto.java | 18 ++++++------ .../WechatEntryFinanceInstitutionReqDto.java | 4 ++- .../business/WechatEntryIdentityReqDto.java | 12 ++++---- .../business/WechatEntryLicenseReqDto.java | 16 ++++++----- .../business/WechatEntryUboInfoReqDto.java | 6 ++-- .../sales/WechatEntryAppInfoReqDto.java | 12 ++++---- .../sales/WechatEntryMiniProgramReqDto.java | 8 ++++-- .../sales/WechatEntryMpInfoReqDto.java | 12 ++++---- .../sales/WechatEntrySalesInfoReqDto.java | 20 +++++++------ .../sales/WechatEntryStoreInfoReqDto.java | 14 ++++++---- .../sales/WechatEntryWebInfoReqDto.java | 8 ++++-- .../sales/WechatEntryWeworkInfoReqDto.java | 4 ++- .../req/entry/id/WechatEntryIdCardReqDto.java | 10 ++++--- .../entry/id/WechatEntryIdDocInfoReqDto.java | 12 ++++---- 22 files changed, 167 insertions(+), 117 deletions(-) diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatEntryManager.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatEntryManager.java index 162a2ba72..85e9e7c84 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatEntryManager.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatEntryManager.java @@ -1,7 +1,9 @@ package com.czg.wechat; import com.alibaba.fastjson2.JSONObject; +import com.alibaba.fastjson2.JSONWriter; import com.czg.wechat.dto.config.WechatPayConfigDto; +import com.czg.wechat.dto.req.entry.WechatEntryReqDto; import com.wechat.pay.java.service.file.FileUploadService; import com.wechat.pay.java.service.file.model.FileUploadResponse; import lombok.extern.slf4j.Slf4j; @@ -151,7 +153,10 @@ public class WechatEntryManager { .setPublicKeyId("PUB_KEY_ID_0116437794082025111000382377001000") .setDomain("https://api.mch.weixin.qq.com"); - String string = uploadImage(dto, "https://czg-qr-order.oss-cn-beijing.aliyuncs.com/indexs/shuangbackground.png"); - log.info("图片上传成功:{}", string); +// String string = uploadImage(dto, "https://czg-qr-order.oss-cn-beijing.aliyuncs.com/indexs/shuangbackground.png"); +// log.info("图片上传成功:{}", string); + + WechatEntryReqDto reqDto = new WechatEntryReqDto(); + System.out.println(JSONObject.toJSONString(reqDto, JSONWriter.Feature.IgnoreEmpty)); } } diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntryAdditionReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntryAdditionReqDto.java index a656d8303..af0d5ed7d 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntryAdditionReqDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntryAdditionReqDto.java @@ -2,6 +2,7 @@ package com.czg.wechat.dto.req.entry; import com.alibaba.fastjson2.annotation.JSONField; import lombok.Data; +import lombok.experimental.Accessors; import java.util.List; @@ -12,10 +13,11 @@ import java.util.List; * @date 2025/12/26 13:43 */ @Data +@Accessors(chain = true) public class WechatEntryAdditionReqDto { /** - * 选填 + * 【选填】 * 法定代表人开户承诺函 * 模板下载地址 ... * 通过图片上传完成后 MediaID @@ -24,7 +26,7 @@ public class WechatEntryAdditionReqDto { private String legalPersonCommitment; /** - * 选填 + * 【选填】 * 法定代表人开户意愿视频 * 通过视频上传完成后 MediaID */ @@ -32,7 +34,7 @@ public class WechatEntryAdditionReqDto { private String legalPersonVideo; /** - * 选填 + * 【选填】 * 补充材料 * 最多可上传5张照片 * 通过图片上传完成后 MediaID @@ -41,7 +43,7 @@ public class WechatEntryAdditionReqDto { private List businessAdditionPics; /** - * 选填 + * 【选填】 * 补充说明 512字以内 */ @JSONField(name = "business_addition_msg") diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntryBankAccountReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntryBankAccountReqDto.java index 35d0cacdf..8908d1511 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntryBankAccountReqDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntryBankAccountReqDto.java @@ -2,6 +2,7 @@ package com.czg.wechat.dto.req.entry; import com.alibaba.fastjson2.annotation.JSONField; import lombok.Data; +import lombok.experimental.Accessors; /** * 微信进件-银行账号 @@ -10,10 +11,11 @@ import lombok.Data; * @date 2025/12/26 13:42 */ @Data +@Accessors(chain = true) public class WechatEntryBankAccountReqDto { /** - * 必填 + * 【必填】 * 账户类型 * 1、若主体为企业/政府机关/事业单位/社会组织,可填写:对公银行账户; * 2、若主体为个体户,可选择填写:对公银行账户或经营者个人银行卡 @@ -23,7 +25,7 @@ public class WechatEntryBankAccountReqDto { private String bankAccountType; /** - * 必填 + * 【必填】 * 开户名称 * 1、选择“经营者个人银行卡”时,开户名称必须与“经营者证件姓名”一致; * 2、选择“对公银行账户”时,开户名称必须与营业执照上的“商户名称”一致; @@ -34,7 +36,7 @@ public class WechatEntryBankAccountReqDto { private String accountName; /** - * 必填 + * 【必填】 * 开户银行 * 对私银行调用:查询支持个人业务的银行列表API * 对公银行调用:查询支持对公业务的银行列表API @@ -43,7 +45,7 @@ public class WechatEntryBankAccountReqDto { private String accountBank; /** - * 选填 + * 【选填】 * 开户银行银行号 * 1、根据开户银行查询接口中的“是否需要填写支行”判断是否需要填写。如为其他银行,开户银行全称(含支行)和开户银行联行号二选一; * 2、详细需调用查询支行列表API查看查询结果。 ... @@ -52,7 +54,7 @@ public class WechatEntryBankAccountReqDto { private String bankBranchId; /** - * 选填 + * 【选填】 * 开户银行全称(含支行) * 1、根据开户银行查询接口中的“是否需要填写支行”判断是否需要填写。如为其他银行,开户银行全称(含支行)和开户银行联行号二选一; * 2、详细需调用查询支行列表API查看查询结果。 ... @@ -61,7 +63,7 @@ public class WechatEntryBankAccountReqDto { private String bankName; /** - * 必填 + * 【必填】 * 开户银行账号 * 1、选择“经营者个人银行卡”时,开户账号为经营者个人银行卡号; * 2、选择“对公银行账户”时,开户账号为对公银行账号; diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntryContactReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntryContactReqDto.java index 82c91ed49..635a3ff64 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntryContactReqDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntryContactReqDto.java @@ -2,6 +2,7 @@ package com.czg.wechat.dto.req.entry; import com.alibaba.fastjson2.annotation.JSONField; import lombok.Data; +import lombok.experimental.Accessors; /** * 进件 联系人信息 @@ -10,10 +11,11 @@ import lombok.Data; * @date 2025/12/26 13:38 */ @Data +@Accessors(chain = true) public class WechatEntryContactReqDto { /** - * 必填 + * 【必填】 * 超级管理员类型 * 主体为“个体工商户/企业/政府机关/事业单位/社会组织”,可选择:LEGAL:经营者/法定代表人,SUPER:经办人 。(经办人:经商户授权办理微信支付业务的人员)。 * 可选取值 @@ -24,7 +26,7 @@ public class WechatEntryContactReqDto { private String contactType; /** - * 必填 + * 【必填】 * 超级管理员姓名 * 1、长度为2-100个字符; * 2、前后不能有空格、制表符、换行符; @@ -36,7 +38,7 @@ public class WechatEntryContactReqDto { private String contactName; /** - * 选填 + * 【选填】 * 超级管理员证件类型 当超级管理员类型是经办人时,请上传超级管理员证件类型。 * 可选取值 * IDENTIFICATION_TYPE_IDCARD: 中国大陆居民-身份证 @@ -52,7 +54,7 @@ public class WechatEntryContactReqDto { private String contactIdType; /** - * 选填 + * 【选填】 * 超级管理员身份证件号码 * 1、当超级管理员类型是经办人时,请上传超级管理员证件号码; * 2、可传身份证、来往内地通行证、来往大陆通行证、护照等证件号码,号码规范如下: @@ -70,7 +72,7 @@ public class WechatEntryContactReqDto { private String contactIdNumber; /** - * 选填 + * 【选填】 * 超级管理员证件正面照片 * 1、当超级管理员类型是经办人时,请上传超级管理员证件的正面照片; * 2、若证件类型为身份证,请上传人像面照片; @@ -82,7 +84,7 @@ public class WechatEntryContactReqDto { private String contactIdDocCopy; /** - * 选填 + * 【选填】 * 超级管理员证件反面照片 * 1、当超级管理员类型是经办人时,请上传超级管理员证件的反面照片; * 2、若证件类型为护照,无需上传反面照片; @@ -94,7 +96,7 @@ public class WechatEntryContactReqDto { private String contactIdDocCopyBack; /** - * 选填 + * 【选填】 * 超级管理员证件有效期开始时间 * 1、当超级管理员类型是经办人时,请上传证件有效期开始时间; * 2、请按照示例值填写,日期格式应满足合法的YYYY-MM-DD格式; @@ -104,7 +106,7 @@ public class WechatEntryContactReqDto { private String contactPeriodBegin; /** - * 选填 + * 【选填】 * 超级管理员证件有效期截止时间 * 1、当超级管理员类型是经办人时,请上传证件有效期结束时间; * 2、请按照示例值填写,日期格式应满足合法的YYYY-MM-DD格式,若证件有效期为长期,请填写:长期; @@ -114,7 +116,7 @@ public class WechatEntryContactReqDto { private String contactPeriodEnd; /** - * 必填 + * 【必填】 * 联系手机 * 1、前后不能有空格、制表符、换行符; * 2、需满足以下任一条件: @@ -127,7 +129,7 @@ public class WechatEntryContactReqDto { private String mobilePhone; /** - * 必填 + * 【必填】 * 联系邮箱 * 1、用于接收微信支付的开户邮件及日常业务通知; * 2、需要带@,遵循邮箱格式校验 ,该字段需要使用微信支付公钥加密(推荐),请参考获取微信支付公钥ID说明以及微信支付公钥加密敏感信息指引,也可以使用微信支付平台证书公钥加密,参考获取平台证书序列号、平台证书加密敏感信息指引。 diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntryReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntryReqDto.java index c0793e703..41432c01e 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntryReqDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntryReqDto.java @@ -3,6 +3,7 @@ package com.czg.wechat.dto.req.entry; import com.alibaba.fastjson2.annotation.JSONField; import com.czg.wechat.dto.req.entry.business.WechatEntryBusinessReqDto; import lombok.Data; +import lombok.experimental.Accessors; /** * 微信进件请求参数 @@ -11,28 +12,32 @@ import lombok.Data; * @date 2025/12/26 13:36 */ @Data +@Accessors(chain = true) public class WechatEntryReqDto { /** + * 【必填】 * 业务申请编号 */ @JSONField(name = "business_code") private String businessCode; /** + * 【必填】 * 超级管理员信息 */ @JSONField(name = "contact_info") private WechatEntryContactReqDto contactInfo; /** + * 【必填】 * 主体资料 */ @JSONField(name = "subject_info") private WechatEntrySubjectReqDto subjectInfo; /** - * 必填 + * 【必填】 * 经营资料 * 商家的经营业务信息、售卖商品/提供服务场景信息 */ @@ -40,7 +45,7 @@ public class WechatEntryReqDto { private WechatEntryBusinessReqDto businessInfo; /** - * 必填 + * 【必填】 * 结算规则 * 请填写商家的结算费率规则、特殊资质等信息 */ @@ -48,14 +53,14 @@ public class WechatEntryReqDto { private WechatEntrySettleReqDto settlementInfo; /** - * 必填 + * 【必填】 * 结算银行账户 */ @JSONField(name = "bank_account_info") private WechatEntryBankAccountReqDto bankAccountInfo; /** - * 选填 + * 【选填】 * 补充材料 * 根据实际审核情况,会额外要求商家提供指定的补充资料 */ diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntrySettleReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntrySettleReqDto.java index 55f434741..3bcdf6594 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntrySettleReqDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntrySettleReqDto.java @@ -2,6 +2,7 @@ package com.czg.wechat.dto.req.entry; import com.alibaba.fastjson2.annotation.JSONField; import lombok.Data; +import lombok.experimental.Accessors; import java.util.List; @@ -11,10 +12,11 @@ import java.util.List; * @date 2025/12/26 13:38 */ @Data +@Accessors(chain = true) public class WechatEntrySettleReqDto { /** - * 必填 + * 【必填】 * 入驻结算规则ID * 请选择结算规则ID,详细参见费率结算规则对照表 * ... @@ -23,7 +25,7 @@ public class WechatEntrySettleReqDto { private String settlementId; /** - * 必填 + * 【必填】 * 所属行业 * ... */ @@ -31,7 +33,7 @@ public class WechatEntrySettleReqDto { private String qualificationType; /** - * 选填 + * 【选填】 * 特殊资质图片 * 1、仅当商户选择了必需提交特殊资质的行业时,需要提供该项资料;若商户选择了无需特殊资质的行业,或未选择行业时,无需提交该项资料,详情查看《费率结算规则对照表》; * 2、最多可上传5张照片,请填写通过图片上传API预先上传图片生成好的MediaID。 @@ -40,16 +42,16 @@ public class WechatEntrySettleReqDto { private List qualifications; /** - * 选填 + * 【选填】 * 优惠费率活动ID - * 如果商户有意向报名优惠费率活动,该字段必填。详细参见《优惠费率活动对照表》 + * 如果商户有意向报名优惠费率活动,该字段【必填】。详细参见《优惠费率活动对照表》 * ... */ @JSONField(name = "activities_id") private String activitiesId; /** - * 选填 + * 【选填】 * 优惠费率活动值 * 根据优惠费率活动规则,由合作伙伴自定义填写,支持两个小数点,需在优惠费率活动ID指定费率范围内 * (1)2023年7月17日-9月17日,各合作伙伴平台可选择只传入“活动费率值”,或分别传入“信用卡优惠活动费率值” 与 “非信用卡优惠活动费率值”,只传入“活动费率值”的情况下,平台将协助将申请单中的 “优惠活动费率值” 回填入新增的 “信用卡优惠活动费率值” 与 “非信用卡优惠活动费率值”中 ; @@ -59,7 +61,7 @@ public class WechatEntrySettleReqDto { private String activitiesRate; /** - * 选填 + * 【选填】 * 优惠费率活动补充材料 * 1、根据所选优惠费率活动,提供相关材料,详细参见《优惠费率活动对照表》;... * 2、最多可上传5张照片,请填写通过图片上传API预先上传图片生成好的MediaID。 @@ -68,20 +70,20 @@ public class WechatEntrySettleReqDto { private List activitiesAdditions; /** - * 选填 + * 【选填】 * 非信用卡活动费率值 * 用户支付方式为借记卡时收取的手续费费率: - * 1、若填写了优惠费率活动ID,则该字段必填; + * 1、若填写了优惠费率活动ID,则该字段【必填】; * 2、仅能填入2位以内小数,且在优惠费率活动ID指定费率范围内。 */ @JSONField(name = "debit_activities_rate") private String debitActivitiesRate; /** - * 选填 + * 【选填】 * 信用卡活动费率值 * 用户支付方式为信用卡时收取的手续费费率: - * 1、若填写了优惠费率活动ID,则该字段必填; + * 1、若填写了优惠费率活动ID,则该字段【必填】; * 2、仅能填入2位以内小数,且在优惠费率活动ID指定费率范围内。 */ @JSONField(name = "credit_activities_rate") diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntrySubjectReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntrySubjectReqDto.java index d8cabd000..b0c693823 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntrySubjectReqDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntrySubjectReqDto.java @@ -3,6 +3,7 @@ package com.czg.wechat.dto.req.entry; import com.alibaba.fastjson2.annotation.JSONField; import com.czg.wechat.dto.req.entry.business.*; import lombok.Data; +import lombok.experimental.Accessors; import java.util.List; @@ -12,10 +13,11 @@ import java.util.List; * @date 2025/12/26 13:40 */ @Data +@Accessors(chain = true) public class WechatEntrySubjectReqDto { /** - * 必填 + * 【必填】 * 主体类型 主体类型需与营业执照/登记证书上一致,可参考选择主体指引。... * 可选取值 * SUBJECT_TYPE_INDIVIDUAL: (个体户)营业执照上的主体类型一般为个体户、个体工商户、个体经营 @@ -28,9 +30,9 @@ public class WechatEntrySubjectReqDto { private String subjectType; /** - * 选填 + * 【选填】 * 是否是金融机构 - * 【是否是金融机构】 选填,请根据申请主体的实际情况填写,可参考选择金融机构指引: + * 【是否是金融机构】 【选填】,请根据申请主体的实际情况填写,可参考选择金融机构指引: * 1、若商户主体是金融机构,则填写:true; * 2、若商户主体不是金融机构,则填写:false。 * 若未传入将默认填写:false。 @@ -39,23 +41,23 @@ public class WechatEntrySubjectReqDto { private Boolean financeInstitution; /** - * 必填 - * 营业执照 当前不允许小微注册,所以必填 - * 1、主体为个体户/企业,必填; + * 【必填】 + * 营业执照 当前不允许小微注册,所以【必填】 + * 1、主体为个体户/企业,【必填】; * 2、请上传“营业执照”,需年检章齐全,当年注册除外; */ @JSONField(name = "business_license_info") private WechatEntryLicenseReqDto businessLicenseInfo; /** - * 选填 - * 登记证书 主体为政府机关/事业单位/其他组织时,必填。 + * 【选填】 + * 登记证书 主体为政府机关/事业单位/其他组织时,【必填】。 */ @JSONField(name = "certificate_info") private WechatEntryCertificateReqDto certificateInfo; /** - * 选填 + * 【选填】 * 单位证明函照片 * 1、主体类型为政府机关、事业单位选传: * (1)若上传,则审核通过后即可签约,无需汇款验证; @@ -68,14 +70,14 @@ public class WechatEntrySubjectReqDto { private String certificateLetterCopy; /** - * 选填 - * 金融机构许可证信息 当主体是金融机构时,必填。 + * 【选填】 + * 金融机构许可证信息 当主体是金融机构时,【必填】。 */ @JSONField(name = "finance_institution_info") private WechatEntryFinanceInstitutionReqDto financeInstitutionInfo; /** - * 必填 + * 【必填】 * 经营者/法定代表人身份证件 * 1、个体户:请上传经营者的身份证件; * 2、企业/社会组织:请上传法定代表人的身份证件; @@ -85,7 +87,7 @@ public class WechatEntrySubjectReqDto { private WechatEntryIdentityReqDto identityInfo; /** - * 选填 + * 【选填】 * 最终受益人信息列表(UBO) * 1、主体类型个体户/社会组织/政府机关/事业单位时,无需填写 * 2、主体类型为企业时,按照下述要求填写 diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryBusinessReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryBusinessReqDto.java index 94dcd1d39..e6d9b66a4 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryBusinessReqDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryBusinessReqDto.java @@ -3,6 +3,7 @@ package com.czg.wechat.dto.req.entry.business; import com.alibaba.fastjson2.annotation.JSONField; import com.czg.wechat.dto.req.entry.business.sales.WechatEntrySalesInfoReqDto; import lombok.Data; +import lombok.experimental.Accessors; /** * 微信进件 商户信息 经营资料 @@ -11,10 +12,11 @@ import lombok.Data; * @date 2025/12/26 13:41 */ @Data +@Accessors(chain = true) public class WechatEntryBusinessReqDto { /** - * 必填 + * 【必填】 * 商户简称 在支付完成页向买家展示,需与微信经营类目相关 * 1、请输入1-64个字符; * 2、前后不能有空格、制表符、换行符; @@ -29,7 +31,7 @@ public class WechatEntryBusinessReqDto { private String merchantShortname; /** - * 必填 + * 【必填】 * 客服电话 将在交易记录中向买家展示,请确保电话畅通以便平台回拨确认 * 1、前后不能有空格、制表符、换行符; * 2、需满足以下任一条件; @@ -40,7 +42,7 @@ public class WechatEntryBusinessReqDto { private String servicePhone; /** - * 必填 + * 【必填】 * 经营场景 */ @JSONField(name = "sales_info") diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryCertificateReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryCertificateReqDto.java index ce09795f3..5885b1327 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryCertificateReqDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryCertificateReqDto.java @@ -2,6 +2,7 @@ package com.czg.wechat.dto.req.entry.business; import com.alibaba.fastjson2.annotation.JSONField; import lombok.Data; +import lombok.experimental.Accessors; /** * 登记证书 @@ -9,10 +10,11 @@ import lombok.Data; * @date 2025/12/26 15:07 */ @Data +@Accessors(chain = true) public class WechatEntryCertificateReqDto { /** - * 必填 + * 【必填】 * 登记证书照片 * 1、照片应正面拍摄、清晰、四角完整、无反光或遮挡;不得翻拍、截图、镜像、PS; * 2、上传彩色照片、彩色扫描件,复印件需加盖公章鲜章; @@ -24,7 +26,7 @@ public class WechatEntryCertificateReqDto { private String certCopy; /** - * 必填 + * 【必填】 * 登记证书类型 * 1、主体为“政府机关/事业单位/社会组织”时,请上传登记证书类型; * 2、主体为“个体工商户/企业”时,不填; @@ -47,14 +49,14 @@ public class WechatEntryCertificateReqDto { private String certType; /** - * 必填 + * 【必填】 * 证书号 请输入与所选证书类型相匹配且符合国家标准规范的证书号,其中除政府证明文件外,需满足18位阿拉伯数字或大写英文字母(不得包含英文字母I/O/Z/S/V) */ @JSONField(name = "cert_number") private String certNumber; /** - * 必填 + * 【必填】 * 商户名称 请填写登记证书上的商户名称 * 1、长度为2-128个字符; * 2、前后不能有空格、制表符、换行符; @@ -66,7 +68,7 @@ public class WechatEntryCertificateReqDto { private String merchantName; /** - * 必填 + * 【必填】 * 注册地址 请填写登记证书的注册地址 * 1、长度为4-128个字符; * 2、前后不能有空格、制表符、换行符; @@ -78,7 +80,7 @@ public class WechatEntryCertificateReqDto { private String companyAddress; /** - * 必填 + * 【必填】 * 法定代表人 请填写登记证书上的法定代表人姓名 * 1、长度为2-100个字符; * 2、前后不能有空格、制表符、换行符; @@ -89,7 +91,7 @@ public class WechatEntryCertificateReqDto { private String legalPerson; /** - * 选填 + * 【选填】 * 有效期限开始日期 建议填写营业执照的有效期限开始时间,若该字段未填写,系统将会查询国家工商信息填入。需注意若工商信息查询不到,则会被审核驳回。 * 1、日期格式应满足合法的YYYY-MM-DD格式; * 2、开始时间不能小于1900-01-01; @@ -99,7 +101,7 @@ public class WechatEntryCertificateReqDto { private String periodBegin; /** - * 选填 + * 【选填】 * 营业期限结束日期 建议填写营业执照的有效期限结束时间,若该字段未填写,系统将会查询国家工商信息填入。需注意若工商信息查询不到,则会被审核驳回。 * 1、日期格式应满足合法的YYYY-MM-DD格式或长期; * 2、结束时间需大于开始时间。 diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryFinanceInstitutionReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryFinanceInstitutionReqDto.java index 61a450018..6e5c6849b 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryFinanceInstitutionReqDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryFinanceInstitutionReqDto.java @@ -2,6 +2,7 @@ package com.czg.wechat.dto.req.entry.business; import com.alibaba.fastjson2.annotation.JSONField; import lombok.Data; +import lombok.experimental.Accessors; import java.util.List; @@ -11,10 +12,11 @@ import java.util.List; * @date 2025/12/26 15:21 */ @Data +@Accessors(chain = true) public class WechatEntryFinanceInstitutionReqDto { /** - * 必填 + * 【必填】 * 金融机构类型 金融机构类型需与营业执照/登记证书上一致,可参考选择金融机构指引。 * BANK_AGENT:银行业, 适用于商业银行、政策性银行、农村合作银行、村镇银行、开发性金融机构等 * PAYMENT_AGENT:支付机构, 适用于非银行类支付机构 diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryIdentityReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryIdentityReqDto.java index 539c71e96..fbe4dedb7 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryIdentityReqDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryIdentityReqDto.java @@ -4,6 +4,7 @@ import com.alibaba.fastjson2.annotation.JSONField; import com.czg.wechat.dto.req.entry.id.WechatEntryIdCardReqDto; import com.czg.wechat.dto.req.entry.id.WechatEntryIdDocInfoReqDto; import lombok.Data; +import lombok.experimental.Accessors; /** * 经营者/法定代表人身份证件 @@ -11,10 +12,11 @@ import lombok.Data; * @date 2025/12/26 15:24 */ @Data +@Accessors(chain = true) public class WechatEntryIdentityReqDto { /** - * 选填 + * 【选填】 * 证件持有人类型 * 1、主体类型为政府机关/事业单位时选传: * (1)若上传的是法定代表人证件,则不需要上传该字段。 @@ -27,7 +29,7 @@ public class WechatEntryIdentityReqDto { private String idHolderType; /** - * 选填 + * 【选填】 * 证件类型 * 1、当证件持有人类型为法定代表人时,填写。其他情况,无需上传; * 2、个体户/企业/事业单位/社会组织:可选择任一证件类型,政府机关仅支持中国大陆居民-身份证类型。 @@ -45,7 +47,7 @@ public class WechatEntryIdentityReqDto { private String idDocType; /** - * 选填 + * 【选填】 * 法定代表人说明函 * 1、当证件持有人类型为经办人时,必须上传。其他情况,无需上传; * 2、若因特殊情况,无法提供法定代表人证件时,请参照示例图打印法定代表人说明函,全部信息需打印,不支持手写商户信息,并加盖公章; ... @@ -55,14 +57,14 @@ public class WechatEntryIdentityReqDto { private String authorizeLetterCopy; /** - * 选填 + * 【选填】 * 身份证信息 当证件持有人类型为经营者/法定代表人且证件类型为“身份证”时填写。 */ @JSONField(name = "id_card_info") private WechatEntryIdCardReqDto idCardInfo; /** - * 选填 + * 【选填】 * 其他类型证件信息 当证件持有人类型为经营者/法定代表人且证件类型不为“身份证”时填写。 */ @JSONField(name = "id_doc_info") diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryLicenseReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryLicenseReqDto.java index c13401254..c98a00d6c 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryLicenseReqDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryLicenseReqDto.java @@ -2,6 +2,7 @@ package com.czg.wechat.dto.req.entry.business; import com.alibaba.fastjson2.annotation.JSONField; import lombok.Data; +import lombok.experimental.Accessors; /** * 营业执照信息 @@ -9,10 +10,11 @@ import lombok.Data; * @date 2025/12/26 14:59 */ @Data +@Accessors(chain = true) public class WechatEntryLicenseReqDto { /** - * 必填 + * 【必填】 * 营业执照照片 * 1、照片应正面拍摄、清晰、四角完整、无反光或遮挡;不得翻拍、截图、镜像、PS; * 2、上传彩色照片、彩色扫描件,复印件需加盖公章鲜章; @@ -24,14 +26,14 @@ public class WechatEntryLicenseReqDto { private String licenseCopy; /** - * 必填 + * 【必填】 * 注册号/统一社会信用代码 */ @JSONField(name = "license_number") private String licenseNumber; /** - * 必填 + * 【必填】 * 商户名称 * 1、长度为2-128个字符; * 2、前后不能有空格、制表符、换行符; @@ -45,7 +47,7 @@ public class WechatEntryLicenseReqDto { private String merchantName; /** - * 必填 + * 【必填】 * 个体户经营者/法定代表人姓名 请填写营业执照的经营者/法定代表人姓名 * 1、长度为2-100个字符; * 2、前后不能有空格、制表符、换行符; @@ -56,7 +58,7 @@ public class WechatEntryLicenseReqDto { private String legalPerson; /** - * 选填 + * 【选填】 * 注册地址 建议填写营业执照的注册地址,若该字段未填写,系统将会查询国家工商信息填入。需注意若工商信息查询不到,则会被审核驳回。 * 1、长度为4-128个字符; * 2、前后不能有空格、制表符、换行符; @@ -68,7 +70,7 @@ public class WechatEntryLicenseReqDto { private String licenseAddress; /** - * 选填 + * 【选填】 * 有效期限开始日期 建议填写营业执照的有效期限开始时间,若该字段未填写,系统将会查询国家工商信息填入。需注意若工商信息查询不到,则会被审核驳回。 * 1、日期格式应满足合法的YYYY-MM-DD格式; * 2、开始时间不能小于1900-01-01; @@ -78,7 +80,7 @@ public class WechatEntryLicenseReqDto { private String periodBegin; /** - * 选填 + * 【选填】 * 营业期限结束日期 建议填写营业执照的有效期限结束时间,若该字段未填写,系统将会查询国家工商信息填入。需注意若工商信息查询不到,则会被审核驳回。 * 1、日期格式应满足合法的YYYY-MM-DD格式或长期; * 2、结束时间需大于开始时间。 diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryUboInfoReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryUboInfoReqDto.java index 3e01e0970..961fbd723 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryUboInfoReqDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryUboInfoReqDto.java @@ -2,6 +2,7 @@ package com.czg.wechat.dto.req.entry.business; import com.alibaba.fastjson2.annotation.JSONField; import lombok.Data; +import lombok.experimental.Accessors; /** * 最终受益人信息 @@ -9,10 +10,11 @@ import lombok.Data; * @date 2025/12/26 15:50 */ @Data +@Accessors(chain = true) public class WechatEntryUboInfoReqDto { /** - * 必填 + * 【必填】 * 证件类型 请填写受益人的证件类型。枚举值: * 可选取值 * IDENTIFICATION_TYPE_IDCARD: 中国大陆居民-身份证 @@ -40,7 +42,7 @@ public class WechatEntryUboInfoReqDto { private String uboIdDocCopy; /** - * 选填 + * 【选填】 * 证件反面照片 * 1、请上传受益人证件的反面照片; * 2、若证件类型为身份证,请上传国徽面照片; diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryAppInfoReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryAppInfoReqDto.java index c14b829be..3c2a53b6f 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryAppInfoReqDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryAppInfoReqDto.java @@ -2,6 +2,7 @@ package com.czg.wechat.dto.req.entry.business.sales; import com.alibaba.fastjson2.annotation.JSONField; import lombok.Data; +import lombok.experimental.Accessors; import java.util.List; @@ -11,10 +12,11 @@ import java.util.List; * @date 2025/12/26 14:26 */ @Data +@Accessors(chain = true) public class WechatEntryAppInfoReqDto { /** - * 必填 + * 【必填】 * App截图 * 1、请提供APP首页截图、尾页截图、应用内截图、支付页截图各1张; * 2、请填写通过图片上传API预先上传图片生成好的MediaID。 @@ -23,9 +25,9 @@ public class WechatEntryAppInfoReqDto { private List appPics; /** - * 选填 + * 【选填】 * 商家应用AppID - * 1、服务商应用AppID与商家应用AppID,二选一必填; + * 1、服务商应用AppID与商家应用AppID,二选一【必填】; * 2、可填写与商家主体一致且已认证的应用AppID,需是已认证的App; * 3、审核通过后,系统将发起特约商家商户号与该AppID的绑定(即配置为sub_appid),服务商随后可在发起支付时选择传入该AppID,以完成支付,并获取sub_openid用于数据统计,营销等业务场景。 */ @@ -33,9 +35,9 @@ public class WechatEntryAppInfoReqDto { private String appSubAppid; /** - * 选填 + * 【选填】 * 服务商应用AppID - * 1、服务商应用AppID与商家应用AppID,二选一必填; + * 1、服务商应用AppID与商家应用AppID,二选一【必填】; * 2、可填写当前服务商商户号已绑定的应用AppID。 */ @JSONField(name = "app_appid") diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryMiniProgramReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryMiniProgramReqDto.java index 124199c42..259d3ff9d 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryMiniProgramReqDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryMiniProgramReqDto.java @@ -2,6 +2,7 @@ package com.czg.wechat.dto.req.entry.business.sales; import com.alibaba.fastjson2.annotation.JSONField; import lombok.Data; +import lombok.experimental.Accessors; import java.util.List; @@ -11,10 +12,11 @@ import java.util.List; * @date 2025/12/26 14:23 */ @Data +@Accessors(chain = true) public class WechatEntryMiniProgramReqDto { /** - * 选填 + * 【选填】 * 服务商小程序AppID * 1、服务商小程序AppID与商家小程序AppID,二选一必填; * 2、可填写当前服务商商户号已绑定的小程序AppID。 @@ -23,7 +25,7 @@ public class WechatEntryMiniProgramReqDto { private String miniProgramAppid; /** - * 选填 + * 【选填】 * 商家小程序AppID * 1、服务商小程序AppID与商家小程序AppID,二选一必填; * 2、请填写已认证的小程序AppID; @@ -35,7 +37,7 @@ public class WechatEntryMiniProgramReqDto { private String miniProgramSubAppid; /** - * 选填 + * 【选填】 * 小程序截图 * 1、请提供展示商品/服务的页面截图/设计稿(最多5张),若小程序未建设完善或未上线 请务必提供; * 2、请填写通过图片上传API预先上传图片生成好的MediaID。 diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryMpInfoReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryMpInfoReqDto.java index aa419e063..e90bd0292 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryMpInfoReqDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryMpInfoReqDto.java @@ -2,6 +2,7 @@ package com.czg.wechat.dto.req.entry.business.sales; import com.alibaba.fastjson2.annotation.JSONField; import lombok.Data; +import lombok.experimental.Accessors; import java.util.List; @@ -11,10 +12,11 @@ import java.util.List; * @date 2025/12/26 14:20 */ @Data +@Accessors(chain = true) public class WechatEntryMpInfoReqDto { /** - * 必填 + * 【必填】 * 服务号或公众号页面截图 * 1、请提供展示商品/服务的页面截图/设计稿(最多5张),若服务号或公众号未建设完善或未上线请务必提供; * 2、请填写通过图片上传API预先上传图片生成好的MediaID。 @@ -23,9 +25,9 @@ public class WechatEntryMpInfoReqDto { private List mpPics; /** - * 选填 + * 【选填】 * 商家服务号或公众号AppID - * 1、服务商服务号或公众号AppID、商家服务号或公众号AppID,二选一必填; + * 1、服务商服务号或公众号AppID、商家服务号或公众号AppID,二选一【必填】; * 2、可填写与商家主体一致且已认证的服务号或公众号AppID,需是已认证的服务号、政府或媒体类型的公众号; * 3、审核通过后,系统将发起特约商家商户号与该AppID的绑定(即配置为sub_appid),服务商随后可在发起支付时选择传入该appid,以完成支付,并获取sub_openid用于数据统计,营销等业务场景。 */ @@ -33,9 +35,9 @@ public class WechatEntryMpInfoReqDto { private String mpSubAppid; /** - * 选填 + * 【选填】 * 服务商服务号或公众号AppID - * 1、服务商服务号或公众号AppID、商家服务号或公众号AppID,二选一必填; + * 1、服务商服务号或公众号AppID、商家服务号或公众号AppID,二选一【必填】; * 2、可填写当前服务商商户号已绑定的服务号或公众号AppID。 */ @JSONField(name = "mp_appid") diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntrySalesInfoReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntrySalesInfoReqDto.java index 00143fd84..e1547c633 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntrySalesInfoReqDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntrySalesInfoReqDto.java @@ -2,6 +2,7 @@ package com.czg.wechat.dto.req.entry.business.sales; import com.alibaba.fastjson2.annotation.JSONField; import lombok.Data; +import lombok.experimental.Accessors; import java.util.List; @@ -11,10 +12,11 @@ import java.util.List; * @date 2025/12/26 14:07 */ @Data +@Accessors(chain = true) public class WechatEntrySalesInfoReqDto { /** - * 必填 + * 【必填】 * 经营场景类型 * 1、请勾选实际售卖商品/提供服务场景(至少一项),以便为你开通需要的支付权限; * 2、建议只勾选目前必须的场景,以便尽快通过入驻审核,其他支付权限可在入驻后再根据实际需要发起申请 @@ -30,25 +32,25 @@ public class WechatEntrySalesInfoReqDto { private List salesScenesType; /** - * 选填 + * 【选填】 * 线下场所场景 * 1、审核通过后,服务商可帮商户发起付款码支付、JSAPI支付; - * 2、当"经营场景类型"选择"SALES_SCENES_STORE",该场景资料必填。 + * 2、当"经营场景类型"选择"SALES_SCENES_STORE",该场景资料【必填】。 */ @JSONField(name = "biz_store_info") private WechatEntryStoreInfoReqDto bizStoreInfo; /** - * 选填 + * 【选填】 * 服务号或公众号场景 * 1、审核通过后,服务商可帮商家发起JSAPI支付; - * 2、当"经营场景类型"选择"SALES_SCENES_MP",该场景资料必填。 + * 2、当"经营场景类型"选择"SALES_SCENES_MP",该场景资料【必填】。 */ @JSONField(name = "mp_info") private WechatEntryMpInfoReqDto mpInfo; /** - * 选填 + * 【选填】 * 小程序场景 * 1、审核通过后,服务商可帮商家发起JSAPI支付; * 2、当"经营场景类型"选择"SALES_SCENES_MINI_PROGRAM",该场景资料必填。 @@ -57,7 +59,7 @@ public class WechatEntrySalesInfoReqDto { private WechatEntryMiniProgramReqDto miniProgramInfo; /** - * 选填 + * 【选填】 * App场景 * 1、审核通过后,服务商可帮商家发起App支付; * 2、当"经营场景类型"选择"SALES_SCENES_APP",该场景资料必填。 @@ -66,7 +68,7 @@ public class WechatEntrySalesInfoReqDto { private WechatEntryAppInfoReqDto appInfo; /** - * 选填 + * 【选填】 * 互联网网站场景 * 1、审核通过后,服务商可帮商家发起JSAPI支付; * 2、当"经营场景类型"选择"SALES_SCENES_WEB",该场景资料必填。 @@ -75,7 +77,7 @@ public class WechatEntrySalesInfoReqDto { private WechatEntryWebInfoReqDto webInfo; /** - * 选填 + * 【选填】 * 企业微信场景 * 1、审核通过后,服务商可帮商家发起JSAPI支付; * 2、当"经营场景类型"选择"SALES_SCENES_WEWORK",该场景资料必填。 diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryStoreInfoReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryStoreInfoReqDto.java index e4c202a52..7b661eeb7 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryStoreInfoReqDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryStoreInfoReqDto.java @@ -2,6 +2,7 @@ package com.czg.wechat.dto.req.entry.business.sales; import com.alibaba.fastjson2.annotation.JSONField; import lombok.Data; +import lombok.experimental.Accessors; import java.util.List; @@ -11,10 +12,11 @@ import java.util.List; * @date 2025/12/26 14:10 */ @Data +@Accessors(chain = true) public class WechatEntryStoreInfoReqDto { /** - * 必填 + * 【必填】 * 线下场所名称 请填写门店名称 * 1、长度为1-50个字符; * 2、前后不能有空格、制表符、换行符; @@ -26,7 +28,7 @@ public class WechatEntryStoreInfoReqDto { private String bizStoreName; /** - * 必填 + * 【必填】 * 线下场所省市编码 * 1、只能由数字组成; * 2、详细参见微信支付提供的省市对照表。 ... @@ -35,7 +37,7 @@ public class WechatEntryStoreInfoReqDto { private String bizAddressCode; /** - * 必填 + * 【必填】 * 线下场所地址 请填写详细的经营场所信息,如有多个场所,选择一个主要场所填写即可。 * 1、长度为4-512个字符; * 2、前后不能有空格、制表符、换行符; @@ -47,7 +49,7 @@ public class WechatEntryStoreInfoReqDto { private String bizStoreAddress; /** - * 必填 + * 【必填】 * 线下场所门头照片 * 1、请上传门头正面照片(要求门店招牌、门框完整、清晰、可辨识);若为停车场等无固定门头照片的经营场所,可上传岗亭/出入闸口。具体参考【指引文档】; * 2、请填写通过图片上传API预先上传图片生成好的MediaID。 @@ -56,7 +58,7 @@ public class WechatEntryStoreInfoReqDto { private List storeEntrancePic; /** - * 必填 + * 【必填】 * 线下场所内部照片 * 1、请上传门店内部环境照片(可辨识经营内容)。若为停车场等无固定门头的经营场所,可上传停车场内部照片。具体参考【指引文档】; * 2、请填写通过图片上传API预先上传图片生成好的MediaID。 @@ -65,7 +67,7 @@ public class WechatEntryStoreInfoReqDto { private List indoorPic; /** - * 选填 + * 【选填】 * 线下场所对应的商家AppID * 1、可填写与商家主体一致且已认证的服务号或公众号、小程序、APP的AppID,其中服务号或公众号AppID需是已认证的服务号、政府或媒体类型的公众号; * 2、审核通过后,系统将额外为商家开通付款码支付、JSAPI支付的自有交易权限,并完成商家商户号与该AppID的绑定。 diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryWebInfoReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryWebInfoReqDto.java index b213f88de..6dc446d61 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryWebInfoReqDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryWebInfoReqDto.java @@ -2,6 +2,7 @@ package com.czg.wechat.dto.req.entry.business.sales; import com.alibaba.fastjson2.annotation.JSONField; import lombok.Data; +import lombok.experimental.Accessors; /** * 进件-经营资料-经营场景-互联网网站场景 @@ -9,10 +10,11 @@ import lombok.Data; * @date 2025/12/26 14:29 */ @Data +@Accessors(chain = true) public class WechatEntryWebInfoReqDto { /** - * 必填 + * 【必填】 * 互联网网站域名 * 1、如为PC端商城、智能终端等场景,可上传官网链接; * 2、网站域名需ICP备案,若备案主体与申请主体不同,请上传加盖公章的网站授权函。 @@ -21,7 +23,7 @@ public class WechatEntryWebInfoReqDto { private String domain; /** - * 必填 + * 【必填】 * 网站授权函 * 1、若备案主体与申请主体不同,请务必上传加盖公章的网站授权函.doc; ... * 2、请填写通过图片上传API预先上传图片生成好的MediaID。 @@ -30,7 +32,7 @@ public class WechatEntryWebInfoReqDto { private String webAuthorisation; /** - * 选填 + * 【选填】 * 互联网网站对应的商家AppID * 1、可填写已认证的服务号或公众号、小程序、APP的AppID,其中服务号或公众号AppID需是已认证的服务号、政府或媒体类型的公众号; * 2、完成进件后,系统发起特约商户号与该AppID的绑定(即配置为sub_appid,可在发起支付时传入) diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryWeworkInfoReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryWeworkInfoReqDto.java index 544e08d2e..1c4530022 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryWeworkInfoReqDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryWeworkInfoReqDto.java @@ -2,6 +2,7 @@ package com.czg.wechat.dto.req.entry.business.sales; import com.alibaba.fastjson2.annotation.JSONField; import lombok.Data; +import lombok.experimental.Accessors; /** * 进件-经营资料-经营场景-企业微信场景 @@ -9,10 +10,11 @@ import lombok.Data; * @date 2025/12/26 14:32 */ @Data +@Accessors(chain = true) public class WechatEntryWeworkInfoReqDto { /** - * 必填 + * 【必填】 * 商家企业微信CorpID * 1、可填写与商家主体一致且已认证的企业微信CorpID; * 2、审核通过后,系统将为商家开通企业微信专区的自有交易权限,并完成商家商户号与该AppID的绑定,商家可自行发起交易。 diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/id/WechatEntryIdCardReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/id/WechatEntryIdCardReqDto.java index 7e18cc07d..fdc203cb9 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/id/WechatEntryIdCardReqDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/id/WechatEntryIdCardReqDto.java @@ -2,6 +2,7 @@ package com.czg.wechat.dto.req.entry.id; import com.alibaba.fastjson2.annotation.JSONField; import lombok.Data; +import lombok.experimental.Accessors; /** * 身份证信息 @@ -9,10 +10,11 @@ import lombok.Data; * @date 2025/12/26 15:29 */ @Data +@Accessors(chain = true) public class WechatEntryIdCardReqDto { /** - * 必填 + * 【必填】 * 身份证人像面照片 * 1、请上传个体户经营者/法定代表人的身份证人像面照片; * 2、正面拍摄、清晰、四角完整、无反光或遮挡;不得翻拍、截图、镜像、PS; @@ -23,7 +25,7 @@ public class WechatEntryIdCardReqDto { private String idCardCopy; /** - * 必填 + * 【必填】 * 身份证国徽面照片 * 、请上传个体户经营者/法定代表人的身份证国徽面照片; * 2、正面拍摄、清晰、四角完整、无反光或遮挡;不得翻拍、截图、镜像、PS; @@ -34,7 +36,7 @@ public class WechatEntryIdCardReqDto { private String idCardNational; /** - * 必填 + * 【必填】 * 身份证姓名 * 1、请填写个体户经营者/法定代表人对应身份证的姓名; * 2、长度为2-100个字符; @@ -58,7 +60,7 @@ public class WechatEntryIdCardReqDto { private String idCardNumber; /** - * 选填 + * 【选填】 * 身份证居住地址 * 1、主体类型为企业时,需要填写。其他主体类型,无需上传; * 2、请按照身份证住址填写,如广东省深圳市南山区xx路xx号xx室; diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/id/WechatEntryIdDocInfoReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/id/WechatEntryIdDocInfoReqDto.java index 47e3029b7..9a959e844 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/id/WechatEntryIdDocInfoReqDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/id/WechatEntryIdDocInfoReqDto.java @@ -2,6 +2,7 @@ package com.czg.wechat.dto.req.entry.id; import com.alibaba.fastjson2.annotation.JSONField; import lombok.Data; +import lombok.experimental.Accessors; /** * 其他类型证件信息 @@ -9,10 +10,11 @@ import lombok.Data; * @date 2025/12/26 15:42 */ @Data +@Accessors(chain = true) public class WechatEntryIdDocInfoReqDto { /** - * 必填 + * 【必填】 * 证件正面照片 * 1、证件类型不为“身份证”时,上传证件正面照片; * 2、正面拍摄、清晰、四角完整、无反光或遮挡;不得翻拍、截图、镜像、PS; @@ -23,7 +25,7 @@ public class WechatEntryIdDocInfoReqDto { private String idDocCopy; /** - * 选填 + * 【选填】 * 证件反面照片 * 1、若证件类型为往来通行证、外国人居留证、港澳居民居住证、台湾居民居住证时,上传证件反面照片; * 2、若证件类型为护照,无需上传反面照片; @@ -35,7 +37,7 @@ public class WechatEntryIdDocInfoReqDto { private String idDocCopyBack; /** - * 必填 + * 【必填】 * 证件姓名 * 1、请填写经营者/法定代表人的证件姓名; * 2、长度为2-100个字符; @@ -48,7 +50,7 @@ public class WechatEntryIdDocInfoReqDto { private String idDocName; /** - * 必填 + * 【必填】 * 证件号码 * 1、请填写经营者/法定代表人的证件号码: * 护照(限境外人士):4-15位 数字|字母|连字符; @@ -63,7 +65,7 @@ public class WechatEntryIdDocInfoReqDto { private String idDocNumber; /** - * 选填 + * 【选填】 * 证件居住地址 * 1、主体类型为企业时,需要填写。其他主体类型,无需上传; * 2、请按照身份证住址填写,如广东省深圳市南山区xx路xx号xx室; From 5d7aaa2dca3eb063d05a0c7137c78927e32e7d70 Mon Sep 17 00:00:00 2001 From: wangw <1594593906@qq.com> Date: Mon, 29 Dec 2025 10:08:25 +0800 Subject: [PATCH 006/133] =?UTF-8?q?=E4=BC=81=E4=B8=9AId=20=E4=BF=A1?= =?UTF-8?q?=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/czg/account/dto/shopinfo/ShopInfoEditDTO.java | 9 +++++++++ .../main/java/com/czg/account/entity/ShopConfig.java | 8 ++++++++ .../main/java/com/czg/account/entity/ShopInfo.java | 11 +++++++++++ 3 files changed, 28 insertions(+) diff --git a/cash-common/cash-common-service/src/main/java/com/czg/account/dto/shopinfo/ShopInfoEditDTO.java b/cash-common/cash-common-service/src/main/java/com/czg/account/dto/shopinfo/ShopInfoEditDTO.java index df25a24ff..ef7865b69 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/account/dto/shopinfo/ShopInfoEditDTO.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/account/dto/shopinfo/ShopInfoEditDTO.java @@ -285,4 +285,13 @@ public class ShopInfoEditDTO { */ private Integer isCountStick; + /** + * 企业id + */ + private String weworkId; + /** + * 企业接入链接 + */ + private String weworkUrl; + } diff --git a/cash-common/cash-common-service/src/main/java/com/czg/account/entity/ShopConfig.java b/cash-common/cash-common-service/src/main/java/com/czg/account/entity/ShopConfig.java index d2659f44c..e1cfc1c4f 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/account/entity/ShopConfig.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/account/entity/ShopConfig.java @@ -135,5 +135,13 @@ public class ShopConfig implements Serializable { private String dingAppKey; private String dingAppSecret; + /** + * 企业id + */ + private String weworkId; + /** + * 企业接入链接 + */ + private String weworkUrl; } diff --git a/cash-common/cash-common-service/src/main/java/com/czg/account/entity/ShopInfo.java b/cash-common/cash-common-service/src/main/java/com/czg/account/entity/ShopInfo.java index 359870ae8..1e115c903 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/account/entity/ShopInfo.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/account/entity/ShopInfo.java @@ -363,4 +363,15 @@ public class ShopInfo implements Serializable { */ private BigDecimal amount; + /** + * 企业id + */ + @Column(ignore = true) + private String weworkId; + /** + * 企业接入链接 + */ + @Column(ignore = true) + private String weworkUrl; + } From 38ea1478cb38a733af1d1877f8250d5da20add98 Mon Sep 17 00:00:00 2001 From: gong <1157756119@qq.com> Date: Mon, 29 Dec 2025 11:42:20 +0800 Subject: [PATCH 007/133] =?UTF-8?q?=E5=BE=AE=E4=BF=A1=E8=AF=B7=E6=B1=82?= =?UTF-8?q?=E5=8A=A0=E5=AF=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/czg/wechat/WechatConfig.java | 4 +- .../java/com/czg/wechat/WechatEncrypt.java | 30 ++++++ .../com/czg/wechat/WechatEntryManager.java | 102 +++++++++++++++++- .../java/com/czg/wechat/WechatReqUtils.java | 87 +++++++++++++++ 4 files changed, 218 insertions(+), 5 deletions(-) create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatReqUtils.java diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatConfig.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatConfig.java index ace7aaab8..8be29a6e0 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatConfig.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatConfig.java @@ -18,7 +18,7 @@ public class WechatConfig { * @param dto 微信支付配置 * @return 微信支付配置 */ - public static Config getConfig(WechatPayConfigDto dto) { + public static Config getRsaConfig(WechatPayConfigDto dto) { return new RSAPublicKeyConfig.Builder() .merchantId(dto.getMerchantId()) .privateKey(dto.getPrivateKey()) @@ -41,7 +41,7 @@ public class WechatConfig { * @return 文件上传服务 */ public static FileUploadService getFileUploadService(WechatPayConfigDto dto) { - return getFileUploadService(getConfig(dto)); + return getFileUploadService(getRsaConfig(dto)); } } diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatEncrypt.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatEncrypt.java index 82c2cd179..edca7803b 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatEncrypt.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatEncrypt.java @@ -1,15 +1,45 @@ package com.czg.wechat; +import lombok.extern.slf4j.Slf4j; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.security.InvalidKeyException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.security.cert.X509Certificate; +import java.util.Base64; /** * 微信支付加解密 * @author yjjie * @date 2025/12/26 10:58 */ +@Slf4j public class WechatEncrypt { + public static String rsaEncryptOaep(String message, PublicKey publicKey) { + try { + Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-1AndMGF1Padding"); + cipher.init(Cipher.ENCRYPT_MODE, publicKey); + byte[] data = message.getBytes(StandardCharsets.UTF_8); + byte[] cipherData = cipher.doFinal(data); + return Base64.getEncoder().encodeToString(cipherData); + } catch (NoSuchAlgorithmException | NoSuchPaddingException e) { + log.error("当前Java环境不支持RSA v1.5/OAEP"); + } catch (InvalidKeyException e) { + log.error("无效的证书"); + } catch (IllegalBlockSizeException | BadPaddingException e) { + log.error("加密原串的长度不能超过214字节"); + } + return ""; + } + public static String getFileBytesSha256(byte[] input) throws NoSuchAlgorithmException { return bytesToHex(calculateSha256(input)); } diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatEntryManager.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatEntryManager.java index 85e9e7c84..7524b156c 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatEntryManager.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatEntryManager.java @@ -3,7 +3,15 @@ package com.czg.wechat; import com.alibaba.fastjson2.JSONObject; import com.alibaba.fastjson2.JSONWriter; import com.czg.wechat.dto.config.WechatPayConfigDto; -import com.czg.wechat.dto.req.entry.WechatEntryReqDto; +import com.czg.wechat.dto.req.entry.*; +import com.czg.wechat.dto.req.entry.business.WechatEntryBusinessReqDto; +import com.czg.wechat.dto.req.entry.business.WechatEntryIdentityReqDto; +import com.czg.wechat.dto.req.entry.business.WechatEntryLicenseReqDto; +import com.czg.wechat.dto.req.entry.business.sales.WechatEntrySalesInfoReqDto; +import com.czg.wechat.dto.req.entry.business.sales.WechatEntryStoreInfoReqDto; +import com.wechat.pay.java.core.Config; +import com.wechat.pay.java.core.cipher.PrivacyEncryptor; +import com.wechat.pay.java.core.cipher.Signer; import com.wechat.pay.java.service.file.FileUploadService; import com.wechat.pay.java.service.file.model.FileUploadResponse; import lombok.extern.slf4j.Slf4j; @@ -12,6 +20,8 @@ import java.net.URI; import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; +import java.util.Arrays; +import java.util.List; /** * 微信支付进件 管理 @@ -22,6 +32,21 @@ import java.net.http.HttpResponse; @Slf4j public class WechatEntryManager { + public static void entryMerchant(WechatPayConfigDto configDto, WechatEntryReqDto reqDto) { + String params = JSONObject.toJSONString(reqDto, JSONWriter.Feature.IgnoreEmpty); + +// String string = WechatReqUtils.encryptReqParam(configDto, "POST", "/v3/applyment4sub/applyment/", params); + + WechatReqUtils.postReq(configDto, "POST", "/v3/applyment4sub/applyment/", params); + } + + /** + * 上传图片 + * + * @param configDto 配置 + * @param url 图片URL + * @return 图片ID + */ public static String uploadImage(WechatPayConfigDto configDto, String url) { // 校验入参 if (configDto == null || url == null || url.trim().isEmpty()) { @@ -156,7 +181,78 @@ public class WechatEntryManager { // String string = uploadImage(dto, "https://czg-qr-order.oss-cn-beijing.aliyuncs.com/indexs/shuangbackground.png"); // log.info("图片上传成功:{}", string); - WechatEntryReqDto reqDto = new WechatEntryReqDto(); - System.out.println(JSONObject.toJSONString(reqDto, JSONWriter.Feature.IgnoreEmpty)); + Config config = WechatConfig.getRsaConfig(dto); + PrivacyEncryptor encryptor = config.createEncryptor(); + + WechatEntryReqDto reqDto = new WechatEntryReqDto() + .setBusinessCode("MER_20231025110010000010000000000001"); + + WechatEntryContactReqDto contactInfo = new WechatEntryContactReqDto() + .setContactType("LEGAL") + .setContactName(encryptor.encrypt("张三")) + .setContactIdType("IDCARD") + .setContactIdNumber(encryptor.encrypt("110101199001011234")) + .setContactIdDocCopy("https://czg-qr-order.oss-cn-beijing.aliyuncs.com/indexs/shuangbackground.png") + .setContactIdDocCopyBack("https://czg-qr-order.oss-cn-beijing.aliyuncs.com/indexs/shuangbackground.png") + .setContactPeriodBegin("2023-10-25") + .setContactPeriodEnd("2024-10-25") + .setMobilePhone(encryptor.encrypt("13888888888")) + .setContactEmail(encryptor.encrypt("123456@qq.com")); + + reqDto.setContactInfo(contactInfo); + + WechatEntrySubjectReqDto subjectInfo = new WechatEntrySubjectReqDto() + .setSubjectType("SUBJECT_TYPE_INDIVIDUAL"); + + WechatEntryLicenseReqDto licenseInfo = new WechatEntryLicenseReqDto() + .setLicenseCopy("https://czg-qr-order.oss-cn-beijing.aliyuncs.com/indexs/shuangbackground.png") + .setLicenseNumber("110101199001011234") + .setMerchantName("张三商行") + .setLegalPerson(encryptor.encrypt("张三")) + .setLicenseAddress("北京") + .setPeriodBegin("2023-10-25") + .setPeriodEnd("2024-10-25"); + subjectInfo.setBusinessLicenseInfo(licenseInfo); + + WechatEntryIdentityReqDto identityInfo = new WechatEntryIdentityReqDto() + .setIdHolderType("LEGAL"); + subjectInfo.setIdentityInfo(identityInfo); + + reqDto.setSubjectInfo(subjectInfo); + + WechatEntryBusinessReqDto businessInfo = new WechatEntryBusinessReqDto() + .setMerchantShortname("张三商行") + .setServicePhone("13888888888"); + WechatEntrySalesInfoReqDto salesInfo = new WechatEntrySalesInfoReqDto() + .setSalesScenesType(List.of("SALES_SCENES_STORE")); + WechatEntryStoreInfoReqDto storeInfo = new WechatEntryStoreInfoReqDto() + .setBizStoreName("张三商行") + .setBizAddressCode("110101") + .setBizStoreAddress("北京") + .setStoreEntrancePic(List.of("https://czg-qr-order.oss-cn-beijing.aliyuncs.com/indexs/shuangbackground.png")) + .setIndoorPic(List.of("https://czg-qr-order.oss-cn-beijing.aliyuncs.com/indexs/shuangbackground.png")); + salesInfo.setBizStoreInfo(storeInfo); + businessInfo.setSalesInfo(salesInfo); + + reqDto.setBusinessInfo(businessInfo); + + WechatEntrySettleReqDto settleInfo = new WechatEntrySettleReqDto() + .setSettlementId("719") + .setQualificationType("IDCARD") + .setQualifications(List.of("110101199001011234")) + .setActivitiesId("20191030111cff5b5e"); + + reqDto.setSettlementInfo(settleInfo); + + WechatEntryBankAccountReqDto bankAccountInfo = new WechatEntryBankAccountReqDto() + .setBankAccountType("BANK_ACCOUNT_TYPE_CORPORATE") + .setAccountBank("ICBC") + .setBankName("中国工商银行") + .setAccountName(encryptor.encrypt("张三")) + .setAccountNumber(encryptor.encrypt("110101199001011234")); + + reqDto.setBankAccountInfo(bankAccountInfo); + + entryMerchant(dto, reqDto); } } diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatReqUtils.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatReqUtils.java new file mode 100644 index 000000000..b92fb54fc --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatReqUtils.java @@ -0,0 +1,87 @@ +package com.czg.wechat; + +import cn.hutool.http.HttpRequest; +import cn.hutool.http.HttpUtil; +import com.czg.wechat.dto.config.WechatPayConfigDto; +import com.wechat.pay.java.core.Config; +import com.wechat.pay.java.core.RSAPublicKeyConfig; +import com.wechat.pay.java.core.cipher.PrivacyEncryptor; +import com.wechat.pay.java.core.cipher.Signer; +import lombok.extern.slf4j.Slf4j; + +import java.util.UUID; + +/** + * 微信请求工具类 + * + * @author yjjie + * @date 2025/12/29 10:02 + */ +@Slf4j +public class WechatReqUtils { + + public static String postReq(WechatPayConfigDto configDto, String method, String url, String body) { + long timestamp = getTimestamp(); + String nonce = getNonceStr(); + + String signature = encryptReqParam(configDto, method, url, body, timestamp, nonce); + + String authorization = String.format("WECHATPAY2-SHA256-RSA2048 mchid=\"%s\",nonce_str=\"%s\",signature=\"%s\",timestamp=\"%d\",serial_no=\"%s\"", + configDto.getMerchantId(), nonce, signature, timestamp, "4DE9BAC2EA584C3F274F694C9753CA814C4E9BF4"); + + log.info("authorization = {}", authorization); + + HttpRequest request = HttpUtil.createPost(configDto.getDomain() + url) + .header("Authorization", authorization) + .header("Content-Type", "application/json") + .header("Wechatpay-Serial", configDto.getPublicKeyId()) +// .header("Wechatpay-Serial", "4DE9BAC2EA584C3F274F694C9753CA814C4E9BF4") + .body(body); + + String s = request.execute().body(); + log.info("s = {}", s); + + return ""; + } + + /** + * 加密请求参数 + * @param configDto 配置 + * @param method 请求方法 + * @param url 请求地址 + * @param body 请求报文主体 + * @return 加密后的报文 + * + * 签名方法 + * HTTP请求方法\n + * URL\n + * 请求时间戳\n + * 请求随机串\n + * 请求报文主体\n + */ + public static String encryptReqParam(WechatPayConfigDto configDto, String method, String url, String body, long timestamp, String nonce) { + String encryptStr = String.format("%s\n%s\n%d\n%s\n%s\n", + method, url, timestamp, nonce, body); + System.out.println("encryptStr = \n" + encryptStr); + + Config config = WechatConfig.getRsaConfig(configDto); + Signer signer = config.createSigner(); + String signature = signer.sign(encryptStr).getSign(); + System.out.println("signature = " + signature); + return signature; + } + + /** + * 获取随机串 + */ + private static String getNonceStr() { + return UUID.randomUUID().toString().replaceAll("-", "").toUpperCase(); + } + + /** + * 获取时间戳 + */ + private static long getTimestamp() { + return System.currentTimeMillis()/1000; + } +} From 5d9c01f4270c0783a2c552e811311747b7d55184 Mon Sep 17 00:00:00 2001 From: wangw <1594593906@qq.com> Date: Mon, 29 Dec 2025 14:23:05 +0800 Subject: [PATCH 008/133] =?UTF-8?q?=E6=89=93=E5=8D=B0=E7=8A=B6=E6=80=81?= =?UTF-8?q?=E6=A0=87=E8=AF=86=20=E5=85=81=E8=AE=B8=E9=87=8D=E6=96=B0?= =?UTF-8?q?=E6=93=8D=E4=BD=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/czg/order/dto/OrderInfoDTO.java | 267 ------------------ .../com/czg/order/dto/OrderInfoPrintDTO.java | 4 + .../java/com/czg/order/entity/OrderInfo.java | 19 +- .../java/com/czg/order/vo/OrderInfoVo.java | 5 + .../service/order/print/PrinterHandler.java | 29 +- .../impl/OrderInfoCustomServiceImpl.java | 24 +- 6 files changed, 49 insertions(+), 299 deletions(-) delete mode 100644 cash-common/cash-common-service/src/main/java/com/czg/order/dto/OrderInfoDTO.java diff --git a/cash-common/cash-common-service/src/main/java/com/czg/order/dto/OrderInfoDTO.java b/cash-common/cash-common-service/src/main/java/com/czg/order/dto/OrderInfoDTO.java deleted file mode 100644 index 411cb3fb6..000000000 --- a/cash-common/cash-common-service/src/main/java/com/czg/order/dto/OrderInfoDTO.java +++ /dev/null @@ -1,267 +0,0 @@ - -package com.czg.order.dto; - -import java.io.Serializable; -import java.math.BigDecimal; -import java.time.LocalDateTime; - -import com.alibaba.fastjson2.annotation.JSONField; - -import java.io.Serial; - -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -/** - * 订单表 实体类。 - * - * @author ww - * @since 2025-02-13 - */ -@Data - -@NoArgsConstructor -@AllArgsConstructor -public class OrderInfoDTO implements Serializable { - - @Serial - private static final long serialVersionUID = 1L; - - private Long id; - - /** - * 订单编号 - * pc 收银机客户端 PC+雪花ID - * wechat 微信小程序 WX+雪花ID - * alipay 支付宝小程序 ALI+雪花ID - * admin-pc PC管理端 WEB+雪花ID - * admin-app APP管理端 APP+雪花ID - */ - private String orderNo; - - /** - * 店铺Id - */ - private Long shopId; - - /** - * 用户Id user_info表的id - */ - private Long userId; - - /** - * 退单金额 - */ - private BigDecimal refundAmount; - - /** - * 订单原金额 不含折扣价格 - */ - private BigDecimal originAmount; - /** - * 抹零金额 减免多少钱 - */ - private BigDecimal roundAmount; - /** - * 优惠总金额 - */ - private BigDecimal discountAllAmount; - - /** - * 订单金额 (扣除各类折扣) - */ - private BigDecimal orderAmount; - - /** - * 实际支付金额 - */ - private BigDecimal payAmount; - - /** - * 积分抵扣金额 - */ - private BigDecimal pointsDiscountAmount; - - /** - * 使用的积分数量 - */ - private Integer pointsNum; - - /** - * 商品优惠券抵扣金额 - */ - private BigDecimal productCouponDiscountAmount; - - /** - * 用户使用的卡券 - */ - private String couponInfoList; - - /** - * 满减活动抵扣金额 - */ - private BigDecimal discountActAmount; - - /** - * 折扣金额 - */ - private BigDecimal discountAmount; - -// /** -// * 折扣比例 -// */ -// private BigDecimal discountRatio; - - /** - * 打包费 - */ - private BigDecimal packFee; - - /** - * 台桌Id - */ - private String tableCode; - - /** - * 台桌名称 - */ - private String tableName; - - /** - * 订单类型- - * cash收银(除小程序以外 都属于收银) - * miniapp小程序 - */ - private String orderType; - - /** - * 平台类型 pc 收银机客户端 wechat 微信小程序 alipay 支付宝小程序 admin-pc PC管理端 admin-app APP管理端 - */ - private String platformType; - - /** - * 用餐模式 堂食 dine-in 外带 take-out 外卖 take-away - */ - private String dineMode; - - /** - * 支付模式: - * 后付费 after-pay - * 先付费 before-pay - * 无桌码 no-table - */ - private String payMode; - - /** - * 支付类型 - * 主扫 main-scan - * 被扫 back-scan - * 微信小程序 wechat-mini - * 支付宝小程序 alipay-mini - * 会员支付 vip-pay - * 现金支付 cash-pay - */ - private String payType; - - /** - * 状态: unpaid-待支付;in-production 制作中;wait_out 待取餐;;done-订单完成;refunding-申请退单;refund-退单;part_refund 部分退单;cancelled-取消订单 - */ - private String status; - - /** - * 折扣信息 json - */ - private String discountInfo; - - /** - * 限时折扣信息 json - */ - private String limitRate; - - /** - * 是否支持退款,1支持退单, 0不支持退单 - */ - private Integer refundAble; - - /** - * 支付时间 - */ - @JSONField(format = "yyyy-MM-dd HH:mm:ss") - private LocalDateTime paidTime; - - @JSONField(format = "yyyy-MM-dd HH:mm:ss") - private LocalDateTime createTime; - - @JSONField(format = "yyyy-MM-dd HH:mm:ss") - private LocalDateTime updateTime; - - /** - * 支付订单号 - * tb_order_payment.id - * tb_shop_user_flow.id - */ - private Long payOrderId; - - /** - * 交易日期 - */ - private String tradeDay; - - /** - * 备注 - */ - private String remark; - - /** - * 取餐码 - */ - private String takeCode; - - /** - * 员工id - */ - private Long staffId; - - /** - * 当前订单下单次数 - */ - private Integer placeNum; - - /** - * 用餐人数 - */ - private Integer seatNum; - - /** - * 餐位费 - */ - private BigDecimal seatAmount; - - /** - * 退款备注 - */ - private String refundRemark; - - /** - * 是否使用了霸王餐 - */ - private Integer isFreeDine; - - /** - * 是否等叫 0 否 1 等叫 - */ - private Integer isWaitCall; - - /** - * 挂账人id - */ - private Long creditBuyerId; - - /** - * 是否回收站 0-否,1回收站 - */ - private Integer isDel; - private String failMsg; - -} diff --git a/cash-common/cash-common-service/src/main/java/com/czg/order/dto/OrderInfoPrintDTO.java b/cash-common/cash-common-service/src/main/java/com/czg/order/dto/OrderInfoPrintDTO.java index 51afbc2ce..bbe02a34c 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/order/dto/OrderInfoPrintDTO.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/order/dto/OrderInfoPrintDTO.java @@ -24,5 +24,9 @@ public class OrderInfoPrintDTO implements Serializable { */ @NotNull(message = "打印类型不为空") private Integer type; + /** + * 打印机id + */ + private Long machineId; } diff --git a/cash-common/cash-common-service/src/main/java/com/czg/order/entity/OrderInfo.java b/cash-common/cash-common-service/src/main/java/com/czg/order/entity/OrderInfo.java index 1c62bce3e..8f55cef62 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/order/entity/OrderInfo.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/order/entity/OrderInfo.java @@ -1,6 +1,7 @@ package com.czg.order.entity; import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson2.JSONArray; import com.czg.order.dto.LimitRateDTO; import com.mybatisflex.annotation.Column; import com.mybatisflex.annotation.Id; @@ -298,8 +299,10 @@ public class OrderInfo implements Serializable { private Integer isDel; private String failMsg; - - + /** + * 打印状态 Json格式 + */ + private String printStatus; public String getRefundRemark() { @@ -342,4 +345,16 @@ public class OrderInfo implements Serializable { // 如果需要加上抹零金额,可以取消下面这行注释 // .add(this.getRoundAmount() != null ? this.getRoundAmount() : BigDecimal.ZERO); } + + + public JSONArray getPrintStatus() { + if (StrUtil.isBlank(printStatus)) { + return new JSONArray(); + } + try { + return JSONArray.parseArray(printStatus.trim()); + } catch (Exception e) { + return new JSONArray(); + } + } } diff --git a/cash-common/cash-common-service/src/main/java/com/czg/order/vo/OrderInfoVo.java b/cash-common/cash-common-service/src/main/java/com/czg/order/vo/OrderInfoVo.java index 190d13386..9c7a7a8c5 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/order/vo/OrderInfoVo.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/order/vo/OrderInfoVo.java @@ -133,6 +133,11 @@ public class OrderInfoVo implements Serializable { * 备注 */ private String remark; + /** + * 打印状态 Json格式 + * [{"id":"124","name":"111","time":"2025-12-29 11:05:18"},{"id":"111","name":"标签","time":"2025-12-29 11:05:30"}] + */ + private String printStatus; /** * 是否使用了霸王餐 diff --git a/cash-service/order-service/src/main/java/com/czg/service/order/print/PrinterHandler.java b/cash-service/order-service/src/main/java/com/czg/service/order/print/PrinterHandler.java index bd9caf027..32303d319 100644 --- a/cash-service/order-service/src/main/java/com/czg/service/order/print/PrinterHandler.java +++ b/cash-service/order-service/src/main/java/com/czg/service/order/print/PrinterHandler.java @@ -49,9 +49,6 @@ public abstract class PrinterHandler { @Setter protected PrinterHandler nextPrinter; protected String printerBrand; - // 创建 ThreadLocal 变量 - private static final ThreadLocal ERR_MSG = ThreadLocal.withInitial(() -> ""); - @Resource protected OrderDetailService orderDetailService; @@ -148,16 +145,17 @@ public abstract class PrinterHandler { * @param printType 打印类型,JSON数组 refund-确认退款单 handover-交班单 queue-排队取号 * @return 打印机列表 */ - private List getPrintMachine(Long shopId, String subType, String printMethod, String printType) { + private List getPrintMachine(Long shopId, String subType, String printMethod, String printType, Long machineId) { QueryWrapper wrapper = new QueryWrapper() .eq(PrintMachine::getStatus, 1) + .eq(PrintMachine::getId, machineId) .eq(PrintMachine::getShopId, shopId) .eq(PrintMachine::getSubType, subType) .eq(PrintMachine::getConnectionType, "网络"); if (StrUtil.isNotEmpty(printMethod)) { List arrayList = switch (printMethod) { - case "all" ->Arrays.asList("one", "normal", "all"); + case "all" -> Arrays.asList("one", "normal", "all"); case "one" -> Arrays.asList("one", "all"); case "normal" -> Arrays.asList("normal", "all"); default -> new ArrayList<>(); @@ -188,10 +186,11 @@ public abstract class PrinterHandler { /** * 处理打印 - * @param data 传递的数据 + * + * @param data 传递的数据 * @param printTypeEnum order returnOrder preOrder one call handover */ - public void handler(String data, PrintTypeEnum printTypeEnum) { + public void handler(String data, PrintTypeEnum printTypeEnum, Long machineId) { Long shopId; String printMethod = ""; String printType = ""; @@ -262,7 +261,7 @@ public abstract class PrinterHandler { } Object finalObj = obj; - getPrintMachine(shopId, "cash", printMethod, printType).forEach(machine -> { + getPrintMachine(shopId, "cash", printMethod, printType, machineId).forEach(machine -> { handleRequest(machine, finalObj, printTypeEnum); // printPlaceTicket(isReturn, machine, orderInfo, shopInfo); }); @@ -314,7 +313,7 @@ public abstract class PrinterHandler { item.setNum(item.getNum().subtract(printDetailInfo.getPrintNum())); item.setReturnNum(item.getReturnNum().subtract(printDetailInfo.getPrintReturnNum())); orderDetails.add(item); - }else { + } else { orderDetails.add(item); } @@ -334,7 +333,7 @@ public abstract class PrinterHandler { log.info("准备开始打印交班"); if (data instanceof HandoverRecordDTO record) { handoverPrint(machine, record); - }else { + } else { throw new RuntimeException("传递数据类型有误"); } break; @@ -343,7 +342,7 @@ public abstract class PrinterHandler { if (data instanceof OrderInfo orderInfo) { List orderDetailList = orderDetailService.list(new QueryWrapper().eq(OrderDetail::getOrderId, orderInfo.getId())); onlyFrontDesk(machine, false, orderInfo, orderDetailList); - }else { + } else { throw new RuntimeException("传递数据类型有误"); } break; @@ -352,7 +351,7 @@ public abstract class PrinterHandler { if (data instanceof OrderInfo orderInfo) { List orderDetailList = orderDetailService.list(new QueryWrapper().eq(OrderDetail::getOrderId, orderInfo.getId())); onlyFrontDesk(machine, true, orderInfo, orderDetailList); - }else { + } else { throw new RuntimeException("传递数据类型有误"); } break; @@ -361,7 +360,7 @@ public abstract class PrinterHandler { if (data instanceof OrderInfo orderInfo) { List orderDetailList = orderDetailService.list(new QueryWrapper().eq(OrderDetail::getOrderId, orderInfo.getId())); onlyKitchen(machine, orderInfo, orderDetailList); - }else { + } else { throw new RuntimeException("传递数据类型有误"); } break; @@ -369,7 +368,7 @@ public abstract class PrinterHandler { log.info("准备开始打印叫号单"); if (data instanceof CallQueue queue) { onlyCallNumPrint(machine, queue); - }else { + } else { throw new RuntimeException("传递数据类型有误"); } break; @@ -393,7 +392,7 @@ public abstract class PrinterHandler { default: throw new RuntimeException("打印方法有误"); } - }else { + } else { throw new RuntimeException("传递数据类型有误"); } diff --git a/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/OrderInfoCustomServiceImpl.java b/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/OrderInfoCustomServiceImpl.java index 17b70b386..df23df62c 100644 --- a/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/OrderInfoCustomServiceImpl.java +++ b/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/OrderInfoCustomServiceImpl.java @@ -1060,8 +1060,7 @@ public class OrderInfoCustomServiceImpl implements OrderInfoCustomService { distributionUserService.costUpgradeLevelBefore(orderInfo.getUserId(), orderInfo.getShopId()); // 分销奖励 distributionUserService.distribute(orderInfo.getId(), orderInfo.getOrderNo(), payment.getAmount(), orderInfo.getUserId(), orderInfo.getShopId(), "order"); - } - else if (PayTypeConstants.SourceType.MEMBER_IN.equals(payment.getSourceType()) || PayTypeConstants.SourceType.FREE.equals(payment.getSourceType())) { + } else if (PayTypeConstants.SourceType.MEMBER_IN.equals(payment.getSourceType()) || PayTypeConstants.SourceType.FREE.equals(payment.getSourceType())) { boolean isFree = PayTypeConstants.SourceType.FREE.equals(payment.getSourceType()); ShopUser shopUser = shopUserService.getById(payment.getSourceId()); OrderInfo orderInfo = null; @@ -1113,22 +1112,17 @@ public class OrderInfoCustomServiceImpl implements OrderInfoCustomService { payment.getId(), payment.getSourceType(), bizEnum, orderInfo == null); } } - } - else if (PayTypeConstants.SourceType.MEMBER_PAY.equals(payment.getSourceType())) { + } else if (PayTypeConstants.SourceType.MEMBER_PAY.equals(payment.getSourceType())) { //购买会员 ShopUser shopUser = shopUserService.getById(payment.getSourceId()); memberConfigService.joinMember(payment.getShopId(), shopUser.getUserId(), payment.getRelatedId()); - } - else if (PayTypeConstants.SourceType.DISTRIBUTION.equals(payment.getSourceType())) { + } else if (PayTypeConstants.SourceType.DISTRIBUTION.equals(payment.getSourceType())) { distributionUserService.open(payment.getSourceId(), payment.getAmount(), payment.getShopId(), payment.getId()); - } - else if (PayTypeConstants.SourceType.POINT.equals(payment.getSourceType())) { + } else if (PayTypeConstants.SourceType.POINT.equals(payment.getSourceType())) { goodPayService.payCallBack(payment.getSourceId(), payment.getId()); - } - else if (PayTypeConstants.SourceType.WARE.equals(payment.getSourceType())) { + } else if (PayTypeConstants.SourceType.WARE.equals(payment.getSourceType())) { gbOrderService.payCallBack(payment.getSourceId(), payment.getId()); - } - else if (PayTypeConstants.SourceType.PP.equals(payment.getSourceType())) { + } else if (PayTypeConstants.SourceType.PP.equals(payment.getSourceType())) { ppPackageOrderService.paySuccess(payment.getSourceId(), payment.getId()); } } @@ -1529,13 +1523,13 @@ public class OrderInfoCustomServiceImpl implements OrderInfoCustomService { switch (orderInfoPrintDTO.getType()) { case 0: - printerHandler.handler(orderInfo.getId().toString(), PrinterHandler.PrintTypeEnum.ONE_AND_ORDER); + printerHandler.handler(orderInfo.getId().toString(), PrinterHandler.PrintTypeEnum.ONE_AND_ORDER, orderInfoPrintDTO.getMachineId()); break; case 1: - printerHandler.handler(orderInfo.getId().toString(), PrinterHandler.PrintTypeEnum.PRE_ORDER); + printerHandler.handler(orderInfo.getId().toString(), PrinterHandler.PrintTypeEnum.PRE_ORDER, orderInfoPrintDTO.getMachineId()); break; case 2: - printerHandler.handler(orderInfo.getId().toString(), PrinterHandler.PrintTypeEnum.ORDER); + printerHandler.handler(orderInfo.getId().toString(), PrinterHandler.PrintTypeEnum.ORDER, orderInfoPrintDTO.getMachineId()); break; } return true; From ff09e8e92b094b3249eac2f0b4b76837845d2ce9 Mon Sep 17 00:00:00 2001 From: wangw <1594593906@qq.com> Date: Mon, 29 Dec 2025 14:26:51 +0800 Subject: [PATCH 009/133] =?UTF-8?q?=E6=89=93=E5=8D=B0=E7=8A=B6=E6=80=81?= =?UTF-8?q?=E6=A0=87=E8=AF=86=20=E5=85=81=E8=AE=B8=E9=87=8D=E6=96=B0?= =?UTF-8?q?=E6=93=8D=E4=BD=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/czg/mq/PrintMqListener.java | 38 ++----------------- .../impl/PrintMachineLogServiceImpl.java | 27 +++++++------ 2 files changed, 19 insertions(+), 46 deletions(-) diff --git a/cash-api/order-server/src/main/java/com/czg/mq/PrintMqListener.java b/cash-api/order-server/src/main/java/com/czg/mq/PrintMqListener.java index 0657298ac..ef97c341c 100644 --- a/cash-api/order-server/src/main/java/com/czg/mq/PrintMqListener.java +++ b/cash-api/order-server/src/main/java/com/czg/mq/PrintMqListener.java @@ -30,9 +30,6 @@ public class PrintMqListener { @Resource private FunUtil funUtil; - // 注入自定义线程池(建议单独配置,避免使用默认线程池) - @Resource - private ThreadPoolTaskExecutor asyncExecutor; @Lazy @Resource private PrinterHandler printerHandler; @@ -64,37 +61,10 @@ public class PrintMqListener { } Boolean printOrder = jsonObject.getBoolean("printOrder"); funUtil.runFunAndCheckKey(() -> { - printerHandler.handler(orderId, printOrder != null && !printOrder ? PrinterHandler.PrintTypeEnum.ONE : PrinterHandler.PrintTypeEnum.ONE_AND_ORDER); + printerHandler.handler(orderId, printOrder != null && !printOrder ? PrinterHandler.PrintTypeEnum.ONE : PrinterHandler.PrintTypeEnum.ONE_AND_ORDER, null); return null; }, RedisCst.getLockKey("orderPrint", orderId)); }); -// // 使用异步线程池执行延迟任务,不阻塞当前消费者线程 -// CompletableFuture.runAsync(() -> { -// try { -// // 延迟3秒处理 -// TimeUnit.SECONDS.sleep(3); -// // 执行核心打印逻辑 -// invokeFun("orderPrint", "java.order", req, (data) -> { -// JSONObject jsonObject = JSONObject.parseObject(data); -// String orderId = jsonObject.getString("orderId"); -// if (orderId == null) { -// throw new RuntimeException("订单打印失败,未传递orderId"); -// } -// Boolean printOrder = jsonObject.getBoolean("printOrder"); -// funUtil.runFunAndCheckKey(() -> { -// printerHandler.handler(orderId, printOrder != null && !printOrder ? PrinterHandler.PrintTypeEnum.ONE : PrinterHandler.PrintTypeEnum.ONE_AND_ORDER); -// return null; -// }, RedisCst.getLockKey("orderPrint", orderId)); -// }); -// } catch (InterruptedException e) { -// Thread.currentThread().interrupt(); -// // 记录中断日志 -// log.warn("打印任务被中断,req:{}", req, e); -// } catch (Exception e) { -// // 记录业务异常日志 -// log.error("打印任务处理失败,req:{}", req, e); -// } -// }, asyncExecutor); } /** @@ -102,14 +72,14 @@ public class PrintMqListener { */ @RabbitListener(queues = {"${spring.profiles.active}-" + RabbitConstants.Queue.ORDER_HANDOVER_PRINT_QUEUE}) public void handoverPrint(String id) { - invokeFun("handoverPrint", "java.order", id, (data) -> printerHandler.handler(data, PrinterHandler.PrintTypeEnum.HANDOVER)); + invokeFun("handoverPrint", "java.order", id, (data) -> printerHandler.handler(data, PrinterHandler.PrintTypeEnum.HANDOVER, null)); } /** - * 交班打印 + * 叫号打印 */ @RabbitListener(queues = {"${spring.profiles.active}-" + RabbitConstants.Queue.CALL_TABLE_PRINT_QUEUE}) public void callTablePrint(String id) { - invokeFun("handoverPrint", "java.order", id, (data) -> printerHandler.handler(data, PrinterHandler.PrintTypeEnum.CALL)); + invokeFun("handoverPrint", "java.order", id, (data) -> printerHandler.handler(data, PrinterHandler.PrintTypeEnum.CALL, null)); } } diff --git a/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/PrintMachineLogServiceImpl.java b/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/PrintMachineLogServiceImpl.java index 04025d977..0ac76ffb7 100644 --- a/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/PrintMachineLogServiceImpl.java +++ b/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/PrintMachineLogServiceImpl.java @@ -2,7 +2,6 @@ package com.czg.service.order.service.impl; import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.date.DateUtil; -import cn.hutool.core.map.MapProxy; import cn.hutool.core.map.MapUtil; import cn.hutool.core.text.UnicodeUtil; import cn.hutool.core.thread.ThreadUtil; @@ -12,18 +11,15 @@ import cn.hutool.http.HttpUtil; import cn.hutool.json.JSONObject; import cn.hutool.json.JSONUtil; import com.czg.account.entity.PrintMachine; -import com.github.pagehelper.PageHelper; -import com.github.pagehelper.PageInfo; -import com.mybatisflex.core.query.QueryWrapper; -import com.mybatisflex.spring.service.impl.ServiceImpl; +import com.czg.market.service.OrderInfoService; import com.czg.order.entity.PrintMachineLog; import com.czg.order.service.PrintMachineLogService; import com.czg.service.order.mapper.PrintMachineLogMapper; +import com.mybatisflex.spring.service.impl.ServiceImpl; +import jakarta.annotation.Resource; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.codec.digest.DigestUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; @@ -38,7 +34,7 @@ import java.util.*; @Slf4j @Service @RequiredArgsConstructor -public class PrintMachineLogServiceImpl extends ServiceImpl implements PrintMachineLogService{ +public class PrintMachineLogServiceImpl extends ServiceImpl implements PrintMachineLogService { //请求地址 private static final String URL_STR = "https://ioe.car900.com/v1/openApi/dev/customPrint.json"; //APPID @@ -53,6 +49,10 @@ public class PrintMachineLogServiceImpl extends ServiceImpl finalMap = new HashMap<>(); finalMap.put("ENCODE", encode.toString()); - System.out.println("+++++++++++++++" + token + APP_SECRET); finalMap.put("TOKEN", SecureUtil.md5(token + APP_SECRET).toUpperCase()); return finalMap; } + /** * 检查打印状态 * @@ -106,9 +106,11 @@ public class PrintMachineLogServiceImpl extends ServiceImpl Date: Mon, 29 Dec 2025 14:29:10 +0800 Subject: [PATCH 010/133] =?UTF-8?q?=E5=A4=9A=E4=BD=99=E6=89=93=E5=8D=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/czg/config/FilteredNacosRegistry.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cash-common/cash-common-api-config/src/main/java/com/czg/config/FilteredNacosRegistry.java b/cash-common/cash-common-api-config/src/main/java/com/czg/config/FilteredNacosRegistry.java index ff986780d..cacb01360 100644 --- a/cash-common/cash-common-api-config/src/main/java/com/czg/config/FilteredNacosRegistry.java +++ b/cash-common/cash-common-api-config/src/main/java/com/czg/config/FilteredNacosRegistry.java @@ -54,7 +54,7 @@ public class FilteredNacosRegistry extends NacosRegistry { public void register(URL url) { // 1. 获取原始注册的方法列表 String originalMethods = url.getParameter("methods"); - log.info("【过滤提示】服务 {} 注册方法:{}", url.getServiceInterface(), originalMethods); +// log.info("【过滤提示】服务 {} 注册方法:{}", url.getServiceInterface(), originalMethods); if (originalMethods != null && !originalMethods.isEmpty()) { // 2. 过滤黑名单中的方法名 List filteredMethods = Arrays.stream(originalMethods.split(",")) @@ -67,12 +67,12 @@ public class FilteredNacosRegistry extends NacosRegistry { // 3. 处理过滤后的结果 if (filteredMethods.isEmpty()) { // 若所有方法都被过滤,直接终止注册(可选:根据业务决定是否保留服务注册) - log.info("【过滤提示】服务 {} 所有方法均被过滤,终止注册", url.getServiceInterface()); +// log.info("【过滤提示】服务 {} 所有方法均被过滤,终止注册", url.getServiceInterface()); return; } else { // 替换 URL 中的 methods 参数为过滤后的列表 url = url.addParameter("methods", String.join(",", filteredMethods)); - log.info("【过滤提示】服务 {} 注册方法:{}", url.getServiceInterface(), filteredMethods); +// log.info("【过滤提示】服务 {} 注册方法:{}", url.getServiceInterface(), filteredMethods); } } From dc3be2f1d8655b328d5cd242f84ee1db2394d73b Mon Sep 17 00:00:00 2001 From: wangw <1594593906@qq.com> Date: Mon, 29 Dec 2025 14:40:39 +0800 Subject: [PATCH 011/133] =?UTF-8?q?=E6=89=93=E5=8D=B0=E7=8A=B6=E6=80=81?= =?UTF-8?q?=E5=AD=97=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/czg/order/vo/OrderDetailSmallVO.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cash-common/cash-common-service/src/main/java/com/czg/order/vo/OrderDetailSmallVO.java b/cash-common/cash-common-service/src/main/java/com/czg/order/vo/OrderDetailSmallVO.java index 044421de9..bf954e0a3 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/order/vo/OrderDetailSmallVO.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/order/vo/OrderDetailSmallVO.java @@ -42,6 +42,6 @@ public class OrderDetailSmallVO implements Serializable { private LocalDateTime dishOutTime; private LocalDateTime foodServeTime; private Integer isTemporary; - + private String printStatus; } From 057f851dcf2cf9b218923bff09182085a51c4a08 Mon Sep 17 00:00:00 2001 From: wangw <1594593906@qq.com> Date: Mon, 29 Dec 2025 14:51:26 +0800 Subject: [PATCH 012/133] =?UTF-8?q?=E8=BF=94=E5=9B=9E=E6=95=B0=E6=8D=AE=20?= =?UTF-8?q?=E5=B0=9D=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/czg/order/entity/OrderInfo.java | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/cash-common/cash-common-service/src/main/java/com/czg/order/entity/OrderInfo.java b/cash-common/cash-common-service/src/main/java/com/czg/order/entity/OrderInfo.java index 8f55cef62..9c1dae004 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/order/entity/OrderInfo.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/order/entity/OrderInfo.java @@ -347,14 +347,14 @@ public class OrderInfo implements Serializable { } - public JSONArray getPrintStatus() { - if (StrUtil.isBlank(printStatus)) { - return new JSONArray(); - } - try { - return JSONArray.parseArray(printStatus.trim()); - } catch (Exception e) { - return new JSONArray(); - } - } +// public JSONArray getPrintStatus() { +// if (StrUtil.isBlank(printStatus)) { +// return new JSONArray(); +// } +// try { +// return JSONArray.parseArray(printStatus.trim()); +// } catch (Exception e) { +// return new JSONArray(); +// } +// } } From 8a8cef3005abc882e1ff92be2083a67b331eaa8d Mon Sep 17 00:00:00 2001 From: gong <1157756119@qq.com> Date: Mon, 29 Dec 2025 15:30:35 +0800 Subject: [PATCH 013/133] =?UTF-8?q?=E9=83=A8=E5=88=86=E6=94=AF=E4=BB=98?= =?UTF-8?q?=E5=AE=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cash-dependencies/pom.xml | 7 +++ cash-sdk/aggregation-pay/pom.xml | 5 ++ .../com/czg/alipay/AlipayEntryManager.java | 49 +++++++++++++++++++ .../dto/AlipayCreateContactInfoDto.java | 34 +++++++++++++ .../com/czg/alipay/dto/AlipayCreateDto.java | 37 ++++++++++++++ 5 files changed, 132 insertions(+) create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/AlipayEntryManager.java create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/AlipayCreateContactInfoDto.java create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/AlipayCreateDto.java diff --git a/cash-dependencies/pom.xml b/cash-dependencies/pom.xml index cbbd275f7..a598172c8 100644 --- a/cash-dependencies/pom.xml +++ b/cash-dependencies/pom.xml @@ -43,6 +43,7 @@ 2.9.10 4.1.128.Final 0.2.17 + 3.1.65.ALL @@ -275,6 +276,12 @@ wechatpay-java ${wechatpay.version} + + + com.alipay.sdk + alipay-sdk-java-v3 + ${apipay-v3.version} + diff --git a/cash-sdk/aggregation-pay/pom.xml b/cash-sdk/aggregation-pay/pom.xml index 3df1fb396..1955b7850 100644 --- a/cash-sdk/aggregation-pay/pom.xml +++ b/cash-sdk/aggregation-pay/pom.xml @@ -25,6 +25,11 @@ com.github.wechatpay-apiv3 wechatpay-java + + + com.alipay.sdk + alipay-sdk-java-v3 + \ No newline at end of file diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/AlipayEntryManager.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/AlipayEntryManager.java new file mode 100644 index 000000000..db63e8645 --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/AlipayEntryManager.java @@ -0,0 +1,49 @@ +package com.czg.alipay; + +import com.alipay.v3.ApiClient; +import com.alipay.v3.ApiException; +import com.alipay.v3.Configuration; +import com.alipay.v3.api.AlipayOpenAgentApi; +import com.alipay.v3.model.AlipayOpenAgentCreateDefaultResponse; +import com.alipay.v3.model.AlipayOpenAgentCreateModel; +import com.alipay.v3.model.AlipayOpenAgentCreateResponseModel; +import com.alipay.v3.model.ContactModel; +import com.alipay.v3.util.model.AlipayConfig; + +/** + * 支付宝进件管理 + * + * ... + * @author yjjie + * @date 2025/12/29 14:11 + */ +public class AlipayEntryManager { + + public static void main(String[] args) throws ApiException { + ApiClient defaultClient = Configuration.getDefaultApiClient(); + // 初始化alipay参数(全局设置一次) + AlipayConfig alipayConfig = new AlipayConfig(); + alipayConfig.setServerUrl("https://openapi.alipay.com"); + alipayConfig.setAppId("2021004174605036"); + alipayConfig.setAlipayPublicKey("MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAiQkrz+emAuS1mB3KKDOMmAZRd/BlPbh7fAIHAqAj1+QCZNcV3o2BTLIIqnuKpSlFXDG3uDzp2VsBxcizXuBbFyPGylnD9CgCj5abyh3+FIHPAZ2IM3TtpqImZ0TSPGXrMli4Nir7MvZktgccCqQKCC4o6iaDGz+UwWwJUIPna8fm2tiTZ+KH150CZbKVj4ZGNpBh5XSV/1dRgyQIV9D/EwSbkZ0n6VgKQLJBi0C2UE3QB17aL1Ir6+gDXIDbknN8O7GUD3aMGdThYdSRUb5wp9CZ5qfV7vCS/CgaRo38nhH3NOzkTL+7v0m1ZDHPmqEkn9VzZN6sCQdL7PoAOjHOCwIDAQAB"); + alipayConfig.setPrivateKey("MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQD48HaUoV7OH7os+9L01kHgxzwIhJick4OkFq4aHsntsXEJ J3gedhuEZtV8oHKZ30DPW12IJ4S8NXtpr8OWaqrAPFonf4wVaRY1d0yIAea57kfLEn9oOEEy4FzARgMNDkyxC+/3OUdGbLHpTjfVX3gusXsEhUDy1/WewihAkoNYF37+W3W/uVLzeWoPq0EcUbRv/G/t/p6gL69ltsMAiVFG4Q/Yk24YAN6lYgBPNLXUEwQ1Q+T+1omjfavHgvarKOp33z3JOUH+aGOmDsJ5Y9gyGtJzOCipAd8Zcv+T1ygsEzZYO1/gzcbPnfO1ShqStCHzssuw8FBVx2JdfQKXKMMNAgMBAAECggEAVTrO/pg5Q00titU1Jspsh67u6OOs9H605Ws2dI7yB8VmtAGlaJh7V1t14FN2qSP8poHbhhAxq9aLyGV7C3a9u09udnN+3J28EtYjh7VO732bavWMVXxdJjQWzWWrCb9JlpxFrlkYBA6W4w/6ob0sAqCVQ7jzwbEa0R4cde8ztOa5nysKSfr4YTSs0gqvoiC6fmg8eiRJraEQBoYz9VkKFtOhhh/4w5FhVcYQ2gQvZ3kK3QVuD1eJIQKlCtz8qaox9lXKDiZT4SCmnKshdUL0u5TYIcYeBjZmhJz0Q50KHcpZrCs5y7I0+vRBH3hU+TKSQt7ureymwhbwWMHScLV2gQKBgQD+58SHXhr5M8NGagAmTdsgmCnNv2kOYMd4STyPMY10SVwCv1Bk808ZuP+7e558J1b5/OuDLI5dLq6xrZ/1wLv1G++XqxI00hlFuWS5mUGJVcXotT1mw20rVeUILc7Qe3mLvbMGgfyKf4A7Qa5SSZ4bDeDTJYaFxyiQ281hMzDuPQKBgQD6AiL/Na2/uPH4CG6juwpjYvYVUcjK+7gbRwf3wWsWMpk90Z4ju2iUiP5c1J/oK9P+1T3PIr6M4Xjza8JJj+r9KC/PVB0gBv6vVM96cDpKUEy/UMpcn/T81vqj/Z+WEOODU8Ms6NiTTm+u9ldvpCjbu0u8M+9c0JeIyadJvSTFEQKBgQCsxmFyM3nq8YfpgU2qqNjfBeRH3faSVUy+nj1a/YZYjKS+A/i1BCnYUImeBVNN6chNV342ggvY4xxruDiU9Vcw8wd58O09Oi8BEIFSP6upL6cebUI6Fjo3xlegLJRiwV6INkNTJOYM5hD/mSxUACwXQFfkJipBINXBIgraWD1RLQKBgQCj49axWq0F6+WjZVOyPaD3uh37p9trRUxRhWTxw3fB23WdktaKMgbCqHOmwzP4bRLSEVQtf2dOz1gMqu14b8HqJvgAf/F/11YJ9hz09LEhmjZVjE68HZfqT7uK2W5OX8/lfXmK7TFcj6SjG5YB96lZMhTZ0WnufEd6QkdKDZYXIQKBgQD9GDTcIMbFwbEaKHnfZaTD3f876EGRgsgrCxwdEk7LBCRPwWo7yI929M4psIlpNwNeiyjBkBunWIVkpznp6qPtJqagIPUYesU4f5v6/okq5wcpaNKSkWbIvWVLaLGOiA1aeGJtbpMpyClbSr52puHpRRdvAiIEQ74yYh0JX8q96g=="); + defaultClient.setAlipayConfig(alipayConfig); + AlipayOpenAgentApi api = new AlipayOpenAgentApi(); + AlipayOpenAgentCreateModel data = new AlipayOpenAgentCreateModel(); + ContactModel contactInfo = new ContactModel(); + contactInfo.setContactEmail("zhangsan@alipy.com"); + contactInfo.setContactName("张三"); + contactInfo.setContactMobile("18866668888"); + data.setContactInfo(contactInfo); + data.setOrderTicket("00ee2d475f374ad097ee0f1ac223fX00"); + data.setAccount("test@alipay.com"); + try { + AlipayOpenAgentCreateResponseModel response = api.create(data); + System.out.println(response); + } catch (ApiException e) { + AlipayOpenAgentCreateDefaultResponse errorObject = (AlipayOpenAgentCreateDefaultResponse) e.getErrorObject(); + System.out.println("调用失败:" + errorObject); + System.out.println("调用失败:" + e.getMessage()); + } + } +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/AlipayCreateContactInfoDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/AlipayCreateContactInfoDto.java new file mode 100644 index 000000000..313506dcd --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/AlipayCreateContactInfoDto.java @@ -0,0 +1,34 @@ +package com.czg.alipay.dto; + +import com.alibaba.fastjson2.annotation.JSONField; +import lombok.Data; + +/** + * 联系人信息 + * @author yjjie + * @date 2025/12/29 14:21 + */ +@Data +public class AlipayCreateContactInfoDto { + + /** + * 【必填】 + * 联系人名称 + */ + @JSONField(name = "contact_name") + private String contactName; + + /** + * 【必填】 + * 联系人手机号 + */ + @JSONField(name = "contact_mobile") + private String contactMobile; + + /** + * 【选填】 + * 联系人邮箱 + */ + @JSONField(name = "contact_email") + private String contactEmail; +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/AlipayCreateDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/AlipayCreateDto.java new file mode 100644 index 000000000..a9f9edd76 --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/AlipayCreateDto.java @@ -0,0 +1,37 @@ +package com.czg.alipay.dto; + +import com.alibaba.fastjson2.annotation.JSONField; +import lombok.Data; + +/** + * 开启代商户签约、创建应用事务 + * 在 ISV 代商户进行应用创建、产品签约时,用于开启一个操作事务,必须是第一个调用的接口。 + * 场景1:ISV 代商户进行应用创建、产品签约,最后提交事务后需要商户确认才能完成流程; + * 场景2:服务市场订购及授权,使用订单授权凭证order_ticket开启预授权模式,该模式下提交事务后无需商户确认。 + * @author yjjie + * @date 2025/12/29 14:19 + */ +@Data +public class AlipayCreateDto { + + /** + * 【必填】 + * isv代操作的商户账号,可以是支付宝账号,也可以是pid(2088开头) + */ + @JSONField(name = "account") + private String account; + + /** + * 【必填】 + * 商户联系人信息,包含联系人名称、手机、邮箱信息。联系人信息将用于接受签约后的重要通知,如确认协议、到期提醒等。 + */ + @JSONField(name = "contact_info") + private AlipayCreateContactInfoDto contactInfo; + + /** + * 【选填】 + * 订单授权凭证。若传入本参数,则对应事务提交后进入预授权模式。 + */ + @JSONField(name = "order_ticket") + private String orderTicket; +} From 87797e58121f796219a6f92d1b1f68220b42e980 Mon Sep 17 00:00:00 2001 From: gong <1157756119@qq.com> Date: Mon, 29 Dec 2025 15:32:23 +0800 Subject: [PATCH 014/133] =?UTF-8?q?=E5=85=B3=E8=81=94=E5=95=86=E5=93=81?= =?UTF-8?q?=E6=9F=A5=E8=AF=A2=E5=90=8C=E6=AD=A5=E5=95=86=E5=93=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/resources/mapper/ProductMapper.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cash-service/product-service/src/main/resources/mapper/ProductMapper.xml b/cash-service/product-service/src/main/resources/mapper/ProductMapper.xml index dbc19dcd5..828ba4455 100644 --- a/cash-service/product-service/src/main/resources/mapper/ProductMapper.xml +++ b/cash-service/product-service/src/main/resources/mapper/ProductMapper.xml @@ -153,6 +153,10 @@ #{item} + or t1.sync_id in + + #{item} + order by t1.sort desc,t1.id desc From 76f6e7776ebf04beb8e46279695422380c639d78 Mon Sep 17 00:00:00 2001 From: wangw <1594593906@qq.com> Date: Mon, 29 Dec 2025 15:47:02 +0800 Subject: [PATCH 015/133] =?UTF-8?q?=E6=89=93=E5=8D=B0=E6=9C=BA=E7=B1=BB?= =?UTF-8?q?=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/czg/order/vo/OrderDetailSmallVO.java | 1 - .../order/service/impl/PrintMachineLogServiceImpl.java | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/cash-common/cash-common-service/src/main/java/com/czg/order/vo/OrderDetailSmallVO.java b/cash-common/cash-common-service/src/main/java/com/czg/order/vo/OrderDetailSmallVO.java index bf954e0a3..d6158b4c4 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/order/vo/OrderDetailSmallVO.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/order/vo/OrderDetailSmallVO.java @@ -42,6 +42,5 @@ public class OrderDetailSmallVO implements Serializable { private LocalDateTime dishOutTime; private LocalDateTime foodServeTime; private Integer isTemporary; - private String printStatus; } diff --git a/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/PrintMachineLogServiceImpl.java b/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/PrintMachineLogServiceImpl.java index 0ac76ffb7..66c7b7bee 100644 --- a/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/PrintMachineLogServiceImpl.java +++ b/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/PrintMachineLogServiceImpl.java @@ -187,7 +187,7 @@ public class PrintMachineLogServiceImpl extends ServiceImpl yxxStatusMap = MapUtil.builder(0, "离线(设备上线后自动补打)").put(1, "在线").put(2, "获取失败").put(3, "未激活").put(4, "设备已禁用").build(); // 云想印 - if ("云享印".equals(config.getContentType())) { + if ("云想印".equals(config.getContentType())) { cn.hutool.json.JSONObject resp = JSONUtil.parseObj(respJson); int code = resp.getInt("code"); cn.hutool.json.JSONObject data = resp.getJSONObject("data").getJSONObject("data"); @@ -240,7 +240,7 @@ public class PrintMachineLogServiceImpl extends ServiceImpl Date: Mon, 29 Dec 2025 16:28:09 +0800 Subject: [PATCH 016/133] =?UTF-8?q?=E5=BF=AB=E6=8D=B7=E8=8F=9C=E5=8D=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../czg/controller/admin/MenuController.java | 16 +++++ .../controller/admin/QuickMenuController.java | 61 ++++++++++++++++ .../com/czg/account/entity/QuickMenu.java | 69 +++++++++++++++++++ .../czg/account/service/QuickMenuService.java | 14 ++++ .../account/mapper/QuickMenuMapper.java | 14 ++++ .../service/impl/QuickMenuServiceImpl.java | 18 +++++ .../main/resources/mapper/QuickMenuMapper.xml | 7 ++ 7 files changed, 199 insertions(+) create mode 100644 cash-api/account-server/src/main/java/com/czg/controller/admin/QuickMenuController.java create mode 100644 cash-common/cash-common-service/src/main/java/com/czg/account/entity/QuickMenu.java create mode 100644 cash-common/cash-common-service/src/main/java/com/czg/account/service/QuickMenuService.java create mode 100644 cash-service/account-service/src/main/java/com/czg/service/account/mapper/QuickMenuMapper.java create mode 100644 cash-service/account-service/src/main/java/com/czg/service/account/service/impl/QuickMenuServiceImpl.java create mode 100644 cash-service/account-service/src/main/resources/mapper/QuickMenuMapper.xml diff --git a/cash-api/account-server/src/main/java/com/czg/controller/admin/MenuController.java b/cash-api/account-server/src/main/java/com/czg/controller/admin/MenuController.java index 15617009d..45f547efd 100644 --- a/cash-api/account-server/src/main/java/com/czg/controller/admin/MenuController.java +++ b/cash-api/account-server/src/main/java/com/czg/controller/admin/MenuController.java @@ -4,14 +4,18 @@ import com.czg.account.dto.menu.MenuAddDTO; import com.czg.account.dto.menu.MenuDelDTO; import com.czg.account.dto.menu.MenuEditDTO; import com.czg.account.entity.CashMenu; +import com.czg.account.entity.QuickMenu; import com.czg.account.entity.SysMenu; +import com.czg.account.service.QuickMenuService; import com.czg.account.service.SysMenuService; import com.czg.account.vo.MenuVO; import com.czg.annotation.SaAdminCheckPermission; import com.czg.annotation.SaAdminCheckRole; import com.czg.resp.CzgResult; import com.czg.sa.StpKit; +import com.mybatisflex.core.query.QueryWrapper; import jakarta.annotation.Resource; +import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -19,6 +23,7 @@ import java.util.List; /** * 菜单管理 + * * @author zs */ @RestController @@ -27,9 +32,12 @@ public class MenuController { @Resource private SysMenuService menuService; + @Resource + private QuickMenuService quickMenuService; /** * 获取当前用户菜单列表 + * * @return 菜单结构 */ @GetMapping @@ -40,6 +48,7 @@ public class MenuController { /** * 收银机菜单 + * * @return 所有菜单 */ @GetMapping("/list/cash") @@ -49,6 +58,7 @@ public class MenuController { /** * 获取所有菜单 + * * @return 菜单结构 */ @SaAdminCheckPermission(parentName = "菜单管理", value = "menu:list", name = "菜单列表") @@ -62,6 +72,7 @@ public class MenuController { /** * 菜单详情 + * * @return 菜单结构 */ @SaAdminCheckRole("管理员") @@ -73,6 +84,7 @@ public class MenuController { /** * 菜单添加 + * * @return 是否成功 */ @SaAdminCheckRole("管理员") @@ -84,6 +96,7 @@ public class MenuController { /** * 菜单修改 + * * @return 是否成功 */ @SaAdminCheckRole("管理员") @@ -95,12 +108,15 @@ public class MenuController { /** * 菜单删除 + * * @return 是否成功 */ @SaAdminCheckRole("管理员") @SaAdminCheckPermission(parentName = "菜单管理", value = "menu:del", name = "菜单删除") @DeleteMapping() + @Transactional public CzgResult edit(@RequestBody @Validated MenuDelDTO menuDelDTO) { + quickMenuService.remove(QueryWrapper.create().eq(QuickMenu::getMenuId, menuDelDTO.getId())); return CzgResult.success(menuService.removeById(menuDelDTO.getId())); } diff --git a/cash-api/account-server/src/main/java/com/czg/controller/admin/QuickMenuController.java b/cash-api/account-server/src/main/java/com/czg/controller/admin/QuickMenuController.java new file mode 100644 index 000000000..548850db5 --- /dev/null +++ b/cash-api/account-server/src/main/java/com/czg/controller/admin/QuickMenuController.java @@ -0,0 +1,61 @@ +package com.czg.controller.admin; + +import com.czg.account.entity.QuickMenu; +import com.czg.account.service.QuickMenuService; +import com.czg.annotation.SaAdminCheckPermission; +import com.czg.resp.CzgResult; +import com.czg.sa.StpKit; +import com.mybatisflex.core.query.QueryWrapper; +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import java.util.List; +import java.util.Set; + +/** + * 悬浮窗/快捷菜单 + * + * @author ww + * @description + */ +@RestController +@RequestMapping("/admin/quick/") +@Slf4j +public class QuickMenuController { + + @Resource + private QuickMenuService quickMenuService; + + @SaAdminCheckPermission(parentName = "悬浮窗", value = "quick:list", name = "悬浮窗-列表") + @GetMapping + public CzgResult> getQuickList(Integer status) { + return CzgResult.success(quickMenuService.list(QueryWrapper.create() + .eq(QuickMenu::getShopId, StpKit.USER.getShopId()) + .eq(QuickMenu::getStatus, status) + .orderBy(QuickMenu::getSort, true) + ) + ); + } + + @SaAdminCheckPermission(parentName = "悬浮窗", value = "quick:list", name = "悬浮窗-新增") + @PostMapping + public CzgResult getQuickList(@RequestBody @Validated QuickMenu quickMenu) { + quickMenu.setShopId(StpKit.USER.getShopId()); + return CzgResult.success(quickMenuService.save(quickMenu)); + } + + @SaAdminCheckPermission(parentName = "悬浮窗", value = "quick:list", name = "悬浮窗-修改") + @PutMapping + public CzgResult updateQuick(@RequestBody @Validated QuickMenu quickMenu) { + return CzgResult.success(quickMenuService.update(quickMenu, QueryWrapper.create() + .eq(QuickMenu::getId, quickMenu.getId()).eq(QuickMenu::getShopId, StpKit.USER.getShopId()))); + } + + @SaAdminCheckPermission(parentName = "悬浮窗", value = "quick:list", name = "悬浮窗-删除") + @DeleteMapping + public CzgResult deleteQuick(@RequestBody Set ids) { + return CzgResult.success(quickMenuService.remove(QueryWrapper.create().in(QuickMenu::getId, ids).eq(QuickMenu::getShopId, StpKit.USER.getShopId()))); + } +} diff --git a/cash-common/cash-common-service/src/main/java/com/czg/account/entity/QuickMenu.java b/cash-common/cash-common-service/src/main/java/com/czg/account/entity/QuickMenu.java new file mode 100644 index 000000000..5d72f08e5 --- /dev/null +++ b/cash-common/cash-common-service/src/main/java/com/czg/account/entity/QuickMenu.java @@ -0,0 +1,69 @@ +package com.czg.account.entity; + +import com.mybatisflex.annotation.Column; +import com.mybatisflex.annotation.Id; +import com.mybatisflex.annotation.KeyType; +import com.mybatisflex.annotation.Table; +import java.io.Serializable; +import java.time.LocalDateTime; + +import java.io.Serial; + +import jakarta.validation.constraints.NotNull; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 悬浮窗配置 实体类。 + * + * @author ww + * @since 2025-12-29 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Table("tb_quick_menu") +public class QuickMenu implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + @Id(keyType = KeyType.Auto) + private Integer id; + + /** + * 店铺Id + */ + private Long shopId; + /** + * 菜单图标 + */ + private String url; + + + /** + * 菜单Id + */ + @NotNull(message = "关联菜单不能为空") + private Long menuId; + + /** + * 排序 + */ + private Integer sort; + + /** + * 状态 1-启用 0-禁用 + */ + private Integer status; + + @Column(onInsertValue = "now()") + private LocalDateTime createTime; + + @Column(onInsertValue = "now()", onUpdateValue = "now()") + private LocalDateTime updateTime; + +} diff --git a/cash-common/cash-common-service/src/main/java/com/czg/account/service/QuickMenuService.java b/cash-common/cash-common-service/src/main/java/com/czg/account/service/QuickMenuService.java new file mode 100644 index 000000000..ce1a41c9e --- /dev/null +++ b/cash-common/cash-common-service/src/main/java/com/czg/account/service/QuickMenuService.java @@ -0,0 +1,14 @@ +package com.czg.account.service; + +import com.mybatisflex.core.service.IService; +import com.czg.account.entity.QuickMenu; + +/** + * 悬浮窗配置 服务层。 + * + * @author ww + * @since 2025-12-29 + */ +public interface QuickMenuService extends IService { + +} diff --git a/cash-service/account-service/src/main/java/com/czg/service/account/mapper/QuickMenuMapper.java b/cash-service/account-service/src/main/java/com/czg/service/account/mapper/QuickMenuMapper.java new file mode 100644 index 000000000..eedbb8b62 --- /dev/null +++ b/cash-service/account-service/src/main/java/com/czg/service/account/mapper/QuickMenuMapper.java @@ -0,0 +1,14 @@ +package com.czg.service.account.mapper; + +import com.mybatisflex.core.BaseMapper; +import com.czg.account.entity.QuickMenu; + +/** + * 悬浮窗配置 映射层。 + * + * @author ww + * @since 2025-12-29 + */ +public interface QuickMenuMapper extends BaseMapper { + +} diff --git a/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/QuickMenuServiceImpl.java b/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/QuickMenuServiceImpl.java new file mode 100644 index 000000000..d9b76cad7 --- /dev/null +++ b/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/QuickMenuServiceImpl.java @@ -0,0 +1,18 @@ +package com.czg.service.account.service.impl; + +import com.mybatisflex.spring.service.impl.ServiceImpl; +import com.czg.account.entity.QuickMenu; +import com.czg.account.service.QuickMenuService; +import com.czg.service.account.mapper.QuickMenuMapper; +import org.springframework.stereotype.Service; + +/** + * 悬浮窗配置 服务层实现。 + * + * @author ww + * @since 2025-12-29 + */ +@Service +public class QuickMenuServiceImpl extends ServiceImpl implements QuickMenuService{ + +} diff --git a/cash-service/account-service/src/main/resources/mapper/QuickMenuMapper.xml b/cash-service/account-service/src/main/resources/mapper/QuickMenuMapper.xml new file mode 100644 index 000000000..ee950d745 --- /dev/null +++ b/cash-service/account-service/src/main/resources/mapper/QuickMenuMapper.xml @@ -0,0 +1,7 @@ + + + + + From 0ca2a6c7f8cc086b2530321c539b0c304f1e3743 Mon Sep 17 00:00:00 2001 From: wangw <1594593906@qq.com> Date: Mon, 29 Dec 2025 16:30:50 +0800 Subject: [PATCH 017/133] =?UTF-8?q?=E5=BF=AB=E6=8D=B7=E8=8F=9C=E5=8D=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/czg/controller/admin/QuickMenuController.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cash-api/account-server/src/main/java/com/czg/controller/admin/QuickMenuController.java b/cash-api/account-server/src/main/java/com/czg/controller/admin/QuickMenuController.java index 548850db5..63067abaf 100644 --- a/cash-api/account-server/src/main/java/com/czg/controller/admin/QuickMenuController.java +++ b/cash-api/account-server/src/main/java/com/czg/controller/admin/QuickMenuController.java @@ -21,7 +21,7 @@ import java.util.Set; * @description */ @RestController -@RequestMapping("/admin/quick/") +@RequestMapping("/admin/quick") @Slf4j public class QuickMenuController { @@ -41,7 +41,7 @@ public class QuickMenuController { @SaAdminCheckPermission(parentName = "悬浮窗", value = "quick:list", name = "悬浮窗-新增") @PostMapping - public CzgResult getQuickList(@RequestBody @Validated QuickMenu quickMenu) { + public CzgResult saveQuick(@RequestBody @Validated QuickMenu quickMenu) { quickMenu.setShopId(StpKit.USER.getShopId()); return CzgResult.success(quickMenuService.save(quickMenu)); } From 329d9dfb3dc9725637a109baae3b950fb0b01c93 Mon Sep 17 00:00:00 2001 From: wangw <1594593906@qq.com> Date: Mon, 29 Dec 2025 17:59:50 +0800 Subject: [PATCH 018/133] =?UTF-8?q?=E5=BF=AB=E6=8D=B7=E8=8F=9C=E5=8D=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/admin/QuickMenuController.java | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/cash-api/account-server/src/main/java/com/czg/controller/admin/QuickMenuController.java b/cash-api/account-server/src/main/java/com/czg/controller/admin/QuickMenuController.java index 63067abaf..dda983a67 100644 --- a/cash-api/account-server/src/main/java/com/czg/controller/admin/QuickMenuController.java +++ b/cash-api/account-server/src/main/java/com/czg/controller/admin/QuickMenuController.java @@ -1,5 +1,6 @@ package com.czg.controller.admin; +import cn.hutool.core.collection.CollUtil; import com.czg.account.entity.QuickMenu; import com.czg.account.service.QuickMenuService; import com.czg.annotation.SaAdminCheckPermission; @@ -31,12 +32,17 @@ public class QuickMenuController { @SaAdminCheckPermission(parentName = "悬浮窗", value = "quick:list", name = "悬浮窗-列表") @GetMapping public CzgResult> getQuickList(Integer status) { - return CzgResult.success(quickMenuService.list(QueryWrapper.create() - .eq(QuickMenu::getShopId, StpKit.USER.getShopId()) - .eq(QuickMenu::getStatus, status) - .orderBy(QuickMenu::getSort, true) - ) - ); + List list = quickMenuService.list(QueryWrapper.create() + .eq(QuickMenu::getShopId, StpKit.USER.getShopId()) + .eq(QuickMenu::getStatus, status) + .orderBy(QuickMenu::getSort, true)); + if (CollUtil.isEmpty(list)) { + list = quickMenuService.list(QueryWrapper.create() + .eq(QuickMenu::getShopId, 1) + .eq(QuickMenu::getStatus, status) + .orderBy(QuickMenu::getSort, true)); + } + return CzgResult.success(list); } @SaAdminCheckPermission(parentName = "悬浮窗", value = "quick:list", name = "悬浮窗-新增") From 7384b67c5007b55b12ac877742a16d964b9446cd Mon Sep 17 00:00:00 2001 From: wangw <1594593906@qq.com> Date: Tue, 30 Dec 2025 10:23:04 +0800 Subject: [PATCH 019/133] =?UTF-8?q?=E6=89=93=E5=8D=B0=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/czg/mq/PrintMqListener.java | 7 +- .../com/czg/order/dto/OrderInfoPrintDTO.java | 4 - .../order/service/PrintMachineLogService.java | 2 +- .../czg/service/order/print/FeiPrinter.java | 95 +++- .../service/order/print/PrinterHandler.java | 33 +- .../czg/service/order/print/PrinterImpl.java | 10 +- .../czg/service/order/print/YxyPrinter.java | 84 ++-- .../impl/OrderInfoCustomServiceImpl.java | 6 +- .../impl/PrintMachineLogServiceImpl.java | 475 ++++++++++-------- 9 files changed, 415 insertions(+), 301 deletions(-) diff --git a/cash-api/order-server/src/main/java/com/czg/mq/PrintMqListener.java b/cash-api/order-server/src/main/java/com/czg/mq/PrintMqListener.java index ef97c341c..33f610667 100644 --- a/cash-api/order-server/src/main/java/com/czg/mq/PrintMqListener.java +++ b/cash-api/order-server/src/main/java/com/czg/mq/PrintMqListener.java @@ -12,7 +12,6 @@ import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; import org.springframework.amqp.rabbit.annotation.RabbitListener; import org.springframework.context.annotation.Lazy; -import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import org.springframework.stereotype.Component; import java.util.function.Consumer; @@ -61,7 +60,7 @@ public class PrintMqListener { } Boolean printOrder = jsonObject.getBoolean("printOrder"); funUtil.runFunAndCheckKey(() -> { - printerHandler.handler(orderId, printOrder != null && !printOrder ? PrinterHandler.PrintTypeEnum.ONE : PrinterHandler.PrintTypeEnum.ONE_AND_ORDER, null); + printerHandler.handler(orderId, printOrder != null && !printOrder ? PrinterHandler.PrintTypeEnum.ONE : PrinterHandler.PrintTypeEnum.ONE_AND_ORDER); return null; }, RedisCst.getLockKey("orderPrint", orderId)); }); @@ -72,7 +71,7 @@ public class PrintMqListener { */ @RabbitListener(queues = {"${spring.profiles.active}-" + RabbitConstants.Queue.ORDER_HANDOVER_PRINT_QUEUE}) public void handoverPrint(String id) { - invokeFun("handoverPrint", "java.order", id, (data) -> printerHandler.handler(data, PrinterHandler.PrintTypeEnum.HANDOVER, null)); + invokeFun("handoverPrint", "java.order", id, (data) -> printerHandler.handler(data, PrinterHandler.PrintTypeEnum.HANDOVER)); } /** @@ -80,6 +79,6 @@ public class PrintMqListener { */ @RabbitListener(queues = {"${spring.profiles.active}-" + RabbitConstants.Queue.CALL_TABLE_PRINT_QUEUE}) public void callTablePrint(String id) { - invokeFun("handoverPrint", "java.order", id, (data) -> printerHandler.handler(data, PrinterHandler.PrintTypeEnum.CALL, null)); + invokeFun("handoverPrint", "java.order", id, (data) -> printerHandler.handler(data, PrinterHandler.PrintTypeEnum.CALL)); } } diff --git a/cash-common/cash-common-service/src/main/java/com/czg/order/dto/OrderInfoPrintDTO.java b/cash-common/cash-common-service/src/main/java/com/czg/order/dto/OrderInfoPrintDTO.java index bbe02a34c..51afbc2ce 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/order/dto/OrderInfoPrintDTO.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/order/dto/OrderInfoPrintDTO.java @@ -24,9 +24,5 @@ public class OrderInfoPrintDTO implements Serializable { */ @NotNull(message = "打印类型不为空") private Integer type; - /** - * 打印机id - */ - private Long machineId; } diff --git a/cash-common/cash-common-service/src/main/java/com/czg/order/service/PrintMachineLogService.java b/cash-common/cash-common-service/src/main/java/com/czg/order/service/PrintMachineLogService.java index 22d8d77f8..40c77ab7b 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/order/service/PrintMachineLogService.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/order/service/PrintMachineLogService.java @@ -11,6 +11,6 @@ import com.czg.order.entity.PrintMachineLog; * @since 2025-03-11 */ public interface PrintMachineLogService extends IService { - void save(PrintMachine config, String bizType, String printContent, Object respJson); + void save(PrintMachine config, String bizType, String printContent, String respJson); } diff --git a/cash-service/order-service/src/main/java/com/czg/service/order/print/FeiPrinter.java b/cash-service/order-service/src/main/java/com/czg/service/order/print/FeiPrinter.java index 3665d34dd..aa1b6494a 100644 --- a/cash-service/order-service/src/main/java/com/czg/service/order/print/FeiPrinter.java +++ b/cash-service/order-service/src/main/java/com/czg/service/order/print/FeiPrinter.java @@ -1,17 +1,18 @@ package com.czg.service.order.print; import cn.hutool.core.date.DateUtil; +import cn.hutool.core.text.UnicodeUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; +import cn.hutool.http.HttpUtil; +import cn.hutool.json.JSONObject; +import cn.hutool.json.JSONUtil; import com.czg.account.dto.HandoverRecordDTO; -import com.czg.account.entity.HandoverRecord; import com.czg.account.entity.PrintMachine; import com.czg.account.entity.ShopInfo; -import com.czg.account.service.ShopInfoService; import com.czg.order.entity.OrderDetail; import com.czg.order.entity.OrderInfo; import com.czg.service.order.enums.OrderStatusEnums; -import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; import org.apache.commons.codec.digest.DigestUtils; import org.springframework.http.HttpEntity; @@ -20,12 +21,13 @@ import org.springframework.http.MediaType; import org.springframework.stereotype.Component; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; -import org.springframework.web.client.RestTemplate; import java.math.BigDecimal; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; +import java.util.HashMap; import java.util.List; +import java.util.Map; /** * @author Administrator @@ -33,11 +35,6 @@ import java.util.List; @Component @Slf4j public class FeiPrinter extends PrinterHandler implements PrinterImpl { - @Resource - private RestTemplate restTemplate; - - @Resource - private ShopInfoService shopInfoService; // API 地址 private static final String URL = "http://api.feieyun.cn/Api/Open/"; @@ -72,10 +69,8 @@ public class FeiPrinter extends PrinterHandler implements PrinterImpl { String remark = orderDetail.getRemark(); String content = buildDishPrintData(false, getPickupNum(orderInfo), orderInfo.getCreateTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")), orderDetail.getProductName(), orderDetail.getSkuName(), orderDetail.getNum(), remark, orderDetail.getProGroupInfo(), orderDetail.getId(), orderDetail.isUrgent()); - Object o = sendPrintRequest(machine.getAddress(), content, null, "1"); + String o = sendPrintRequest(machine.getAddress(), content, null, "1"); printMachineLogService.save(machine, "新订单", content, o); - -// printMachineLogService.save(machine, "新订单", , ); } @@ -84,7 +79,7 @@ public class FeiPrinter extends PrinterHandler implements PrinterImpl { String remark = orderDetail.getRemark(); String content = buildDishPrintData(true, getPickupNum(orderInfo), orderInfo.getCreateTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")), orderDetail.getProductName(), orderDetail.getSkuName(), orderDetail.getReturnNum(), remark, orderDetail.getProGroupInfo(), orderDetail.getId(), orderDetail.isUrgent()); - Object o = sendPrintRequest(machine.getAddress(), content, null, "1"); + String o = sendPrintRequest(machine.getAddress(), content, null, "1"); printMachineLogService.save(machine, "退款单", content, o); } @@ -106,8 +101,8 @@ public class FeiPrinter extends PrinterHandler implements PrinterImpl { .setRemark(orderInfo.getRemark()) .setDiscountAmount(orderInfo.getOriginAmount().subtract(orderInfo.getPayAmount()).toPlainString()); String string = buildOrderPrintData(printInfoDTO, detailList); - Object o = sendPrintRequest(machine.getAddress(), string, null, printerNum); - printMachineLogService.save(machine, "退款单", string, o); + String o = sendPrintRequest(machine.getAddress(), string, null, printerNum); + printMachineLogService.save(machine, "结算单", string, o); } @@ -134,16 +129,16 @@ public class FeiPrinter extends PrinterHandler implements PrinterImpl { .setRemark(orderInfo.getRemark()) .setDiscountAmount((orderInfo.getOriginAmount().add(orderInfo.getSeatAmount()).add(orderInfo.getPackFee()).subtract(orderInfo.getPayAmount())).toPlainString()); printInfoDTO.setPrintTitle(printInfoDTO.getPrintTitle()); - if(orderInfo.getSeatNum() != null && orderInfo.getSeatAmount().compareTo(BigDecimal.ZERO) > 0){ + if (orderInfo.getSeatNum() != null && orderInfo.getSeatAmount().compareTo(BigDecimal.ZERO) > 0) { printInfoDTO.setSeatNum(orderInfo.getSeatNum().toString()); printInfoDTO.setSeatAmount(orderInfo.getSeatAmount().toPlainString()); } - if(orderInfo.getPackFee().compareTo(BigDecimal.ZERO) > 0){ + if (orderInfo.getPackFee().compareTo(BigDecimal.ZERO) > 0) { printInfoDTO.setPackFee(orderInfo.getPackFee().toPlainString()); } String string = buildOrderPrintData(printInfoDTO, detailList); - Object resp = sendPrintRequest(machine.getAddress(), string, null, printerNum); + String resp = sendPrintRequest(machine.getAddress(), string, null, printerNum); printMachineLogService.save(machine, "结算单", string, resp); } @@ -151,7 +146,7 @@ public class FeiPrinter extends PrinterHandler implements PrinterImpl { protected void callNumPrint(PrintMachine machine, String callNum, String shopName, String tableName, String tableNote, String preNum, String codeUrl, LocalDateTime takeTime, String shopNote) { String voiceJson = "{\"bizType\":\"2\",\"content\":\"您有一条新的排号记录\"}"; String data = buildCallTicketData(shopName, tableName, callNum, preNum, codeUrl, shopNote, takeTime); - Object resp = sendPrintRequest(machine.getAddress(), data, voiceJson, "1"); + String resp = sendPrintRequest(machine.getAddress(), data, voiceJson, "1"); printMachineLogService.save(machine, "叫号单", data, resp); } @@ -170,7 +165,7 @@ public class FeiPrinter extends PrinterHandler implements PrinterImpl { } @Override - public R sendPrintRequest(String address, String metaPrintData, String voiceData, String printerNum) { + public String sendPrintRequest(String address, String metaPrintData, String voiceData, String printerNum) { log.info("飞蛾打印机开始发送打印请求, 设备地址: {}, 元数据: {}", address, metaPrintData); String time = String.valueOf(System.currentTimeMillis() / 1000); MultiValueMap formData = new LinkedMultiValueMap<>(); @@ -189,12 +184,68 @@ public class FeiPrinter extends PrinterHandler implements PrinterImpl { HttpEntity> requestEntity = new HttpEntity<>(formData, headers); String result = restTemplate.postForObject(URL, requestEntity, String.class); - log.info("打印结果: {}", result); - return (R) result; + log.info("飞鹅打印结果: {}", result); + return result; } catch (Exception e) { log.error("打印请求失败: {}", e.getMessage()); throw new RuntimeException("飞蛾打印请求失败", e); } } + /** + * 检查飞鹅打印机 打印任务是否已打印 + * + * @param printOrderId 打印订单编号 + * @return null-未知错误,true-已打印,false-未打印 + */ + public Boolean checkFPrintStatus(String printOrderId) { + String time = String.valueOf(System.currentTimeMillis() / 1000); + Map paramMap = new HashMap<>(); + paramMap.put("user", USER); + paramMap.put("stime", time); + paramMap.put("sig", signature(time)); + paramMap.put("apiname", "Open_queryOrderState"); + paramMap.put("orderid", printOrderId); + Boolean ret; + try { + String resp = HttpUtil.post(URL, paramMap, 1000 * 5); + //成功 {"msg":"ok","ret":0,"data":true,"serverExecutedTime":4} + //失败 {"msg":"ok","ret":0,"data":false,"serverExecutedTime":4} + JSONObject json = JSONUtil.parseObj(UnicodeUtil.toString(resp)); + log.info("飞鹅打印机 打印任务状态响应: {}", json); + ret = json.getBool("data"); + } catch (Exception e) { + ret = null; + } + return ret; + } + + /** + * 检查飞鹅打印机是否在线 + * + * @param sn 设备编号 + * @return 在线,工作状态正常。/离线。/未知错误 + */ + public String checkOnline(String sn) { + String time = String.valueOf(System.currentTimeMillis() / 1000); + Map paramMap = new HashMap<>(); + paramMap.put("user", USER); + paramMap.put("stime", time); + paramMap.put("sig", signature(time)); + paramMap.put("apiname", "Open_queryPrinterStatus"); + paramMap.put("sn", sn); + String msg; + try { + String resp = HttpUtil.post(URL, paramMap, 1000 * 5); + //成功 开机 {"msg":"ok","ret":0,"data":"在线,工作状态正常。","serverExecutedTime":4} + //成功 离线 {"msg":"ok","ret":0,"data":"离线。","serverExecutedTime":7} + JSONObject json = JSONUtil.parseObj(UnicodeUtil.toString(resp)); + log.info("飞鹅打印机状态响应: {}", json); + msg = json.getStr("data"); + } catch (Exception e) { + msg = "未知错误"; + } + return msg; + } + } diff --git a/cash-service/order-service/src/main/java/com/czg/service/order/print/PrinterHandler.java b/cash-service/order-service/src/main/java/com/czg/service/order/print/PrinterHandler.java index 32303d319..6ee130dae 100644 --- a/cash-service/order-service/src/main/java/com/czg/service/order/print/PrinterHandler.java +++ b/cash-service/order-service/src/main/java/com/czg/service/order/print/PrinterHandler.java @@ -34,6 +34,7 @@ import lombok.ToString; import lombok.experimental.Accessors; import lombok.extern.slf4j.Slf4j; import org.apache.dubbo.config.annotation.DubboReference; +import org.springframework.web.client.RestTemplate; import java.math.BigDecimal; import java.time.LocalDateTime; @@ -50,6 +51,8 @@ public abstract class PrinterHandler { protected PrinterHandler nextPrinter; protected String printerBrand; + @Resource + protected RestTemplate restTemplate; @Resource protected OrderDetailService orderDetailService; @Resource @@ -81,7 +84,11 @@ public abstract class PrinterHandler { @Getter public enum PrintTypeEnum { HANDOVER("交班", "handover"), - ORDER("订单", "order"), ONE("菜品", "one"), CALL("叫号", "call"), ONE_AND_ORDER("菜品和结算单同时打印", "oneAndOrder"), PRE_ORDER("预结算单", "preOrder"); + ORDER("订单", "order"), + ONE("菜品", "one"), + CALL("叫号", "call"), + ONE_AND_ORDER("菜品和结算单同时打印", "oneAndOrder"), + PRE_ORDER("预结算单", "preOrder"); private final String name; private final String code; @@ -145,10 +152,9 @@ public abstract class PrinterHandler { * @param printType 打印类型,JSON数组 refund-确认退款单 handover-交班单 queue-排队取号 * @return 打印机列表 */ - private List getPrintMachine(Long shopId, String subType, String printMethod, String printType, Long machineId) { + private List getPrintMachine(Long shopId, String subType, String printMethod, String printType) { QueryWrapper wrapper = new QueryWrapper() .eq(PrintMachine::getStatus, 1) - .eq(PrintMachine::getId, machineId) .eq(PrintMachine::getShopId, shopId) .eq(PrintMachine::getSubType, subType) .eq(PrintMachine::getConnectionType, "网络"); @@ -171,10 +177,6 @@ public abstract class PrinterHandler { wrapper.like(PrintMachine::getPrintType, printType); } List list = printMachineService.list(wrapper); -// for (PrintMachine item : list) { -// //实际打印以传递的参数为准 -// item.setPrintMethod(printMethod); -// } if (list.isEmpty()) { log.error("店铺未配置打印机,店铺id: {}", shopId); return list; @@ -190,7 +192,7 @@ public abstract class PrinterHandler { * @param data 传递的数据 * @param printTypeEnum order returnOrder preOrder one call handover */ - public void handler(String data, PrintTypeEnum printTypeEnum, Long machineId) { + public void handler(String data, PrintTypeEnum printTypeEnum) { Long shopId; String printMethod = ""; String printType = ""; @@ -261,7 +263,7 @@ public abstract class PrinterHandler { } Object finalObj = obj; - getPrintMachine(shopId, "cash", printMethod, printType, machineId).forEach(machine -> { + getPrintMachine(shopId, "cash", printMethod, printType).forEach(machine -> { handleRequest(machine, finalObj, printTypeEnum); // printPlaceTicket(isReturn, machine, orderInfo, shopInfo); }); @@ -447,17 +449,7 @@ public abstract class PrinterHandler { log.info("台位费商品,不打印"); return; } -// ProdSku sku = prodSkuService.getById(item.getSkuId()); -// if (isTemporary == 0 && sku == null) { -// log.error("商品不存在, id: {}", item.getSkuId()); -// return; -// } else if (isTemporary == 1) { -// sku = new ProdSku(); -// } - -// String remark = StrUtil.isNotBlank(sku.getSpecInfo()) ? sku.getSpecInfo() : ""; -// item.setRemark(remark); if (item.getReturnNum().compareTo(BigDecimal.ZERO) > 0) { returnDishesPrint(orderInfo, item, machine); } @@ -468,7 +460,8 @@ public abstract class PrinterHandler { // 保存已打印信息 OrderDetail orderDetail = detailMap.get(item.getId()); - redisService.set(RedisCst.getPrintOrderDetailKey(orderInfo.getId(), item.getId()), JSONObject.toJSONString(new PrintDetailInfo().setPrint(item.getIsPrint() == 1).setDetailId(item.getId()) + redisService.set(RedisCst.getPrintOrderDetailKey(orderInfo.getId(), item.getId()), + JSONObject.toJSONString(new PrintDetailInfo().setPrint(item.getIsPrint() == 1).setDetailId(item.getId()) .setPrintNum(orderDetail.getNum()).setPrintReturnNum(orderDetail.getReturnNum())), 3600 * 24); }); diff --git a/cash-service/order-service/src/main/java/com/czg/service/order/print/PrinterImpl.java b/cash-service/order-service/src/main/java/com/czg/service/order/print/PrinterImpl.java index 3d0f9c125..33024622b 100644 --- a/cash-service/order-service/src/main/java/com/czg/service/order/print/PrinterImpl.java +++ b/cash-service/order-service/src/main/java/com/czg/service/order/print/PrinterImpl.java @@ -9,7 +9,6 @@ import cn.hutool.json.JSONUtil; import com.alibaba.fastjson2.JSONArray; import com.alibaba.fastjson2.JSONObject; import com.czg.account.dto.HandoverRecordDTO; -import com.czg.account.entity.HandoverRecord; import com.czg.order.entity.OrderDetail; import lombok.Data; import lombok.experimental.Accessors; @@ -69,10 +68,9 @@ public interface PrinterImpl { * @param metaPrintData 打印元数据 * @param voiceData 语音信息 * @param printNum 打印联数 - * @param 返回数据类型 * @return 打印结果 */ - R sendPrintRequest(String address, String metaPrintData, String voiceData, String printNum); + String sendPrintRequest(String address, String metaPrintData, String voiceData, String printNum); /** * 获取当前打印机标签信息 @@ -560,12 +558,6 @@ public interface PrinterImpl { return str; } - public static void main(String[] args) { - System.out.println("水煮肉片".length()); - System.out.println(StrUtil.repeat(' ', 8)); - System.out.println(StrUtil.fillAfter("水煮肉片", ' ', 21)); - } - /** * 获取填充字符串, 并且换行 * diff --git a/cash-service/order-service/src/main/java/com/czg/service/order/print/YxyPrinter.java b/cash-service/order-service/src/main/java/com/czg/service/order/print/YxyPrinter.java index 3d9f19c70..3f32358a9 100644 --- a/cash-service/order-service/src/main/java/com/czg/service/order/print/YxyPrinter.java +++ b/cash-service/order-service/src/main/java/com/czg/service/order/print/YxyPrinter.java @@ -4,11 +4,10 @@ import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.crypto.SecureUtil; +import cn.hutool.http.HttpUtil; import com.czg.account.dto.HandoverRecordDTO; -import com.czg.account.entity.HandoverRecord; import com.czg.account.entity.PrintMachine; import com.czg.account.entity.ShopInfo; -import com.czg.account.service.ShopInfoService; import com.czg.order.entity.OrderDetail; import com.czg.order.entity.OrderInfo; import com.czg.service.order.enums.OrderStatusEnums; @@ -20,9 +19,7 @@ import org.springframework.http.MediaType; import org.springframework.stereotype.Component; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; -import org.springframework.web.client.RestTemplate; -import javax.annotation.Resource; import java.math.BigDecimal; import java.time.LocalDateTime; import java.util.*; @@ -45,12 +42,6 @@ public class YxyPrinter extends PrinterHandler implements PrinterImpl { //APPSECRET private static final String APP_SECRET = "2022bsjZF544GAH"; - @Resource - private ShopInfoService shopInfoService; - - @Resource - private RestTemplate restTemplate; - public YxyPrinter() { super("云想印"); } @@ -75,7 +66,7 @@ public class YxyPrinter extends PrinterHandler implements PrinterImpl { @Override - public R sendPrintRequest(String address, String metaPrintData, String voiceData, String printNum) { + public String sendPrintRequest(String address, String metaPrintData, String voiceData, String printNum) { log.info("开始请求云享印,请求数据:{}, {}", voiceData, metaPrintData); //设备名称 //行为方式 1:只打印数据 2:只播放信息 3:打印数据并播放信息 @@ -87,10 +78,9 @@ public class YxyPrinter extends PrinterHandler implements PrinterImpl { String time = String.valueOf(System.currentTimeMillis()); String uuid = UUID.randomUUID().toString(); - Map param = getToken(time, uuid); //参数 MultiValueMap multiValueMap = new LinkedMultiValueMap<>(); - multiValueMap.add("token", param.get("TOKEN")); + multiValueMap.add("token", getToken(time, uuid)); multiValueMap.add("devName", address); multiValueMap.add("actWay", 3); multiValueMap.add("cn", printNum); @@ -108,7 +98,7 @@ public class YxyPrinter extends PrinterHandler implements PrinterImpl { httpEntity, String.class); log.info("请求云享印成功,响应数据: {}", httpResponse); - return (R) httpResponse; + return httpResponse; } @Override @@ -116,9 +106,7 @@ public class YxyPrinter extends PrinterHandler implements PrinterImpl { String buildDishPrintData = buildDishPrintData(false, getPickupNum(orderInfo), DateUtil.format(orderDetail.getCreateTime(), "yyyy-MM-dd HH:mm:ss"), orderDetail.getProductName(), orderDetail.getSkuName(), orderDetail.getNum(), orderDetail.getRemark(), orderDetail.getProGroupInfo(), orderDetail.getId(), orderDetail.isUrgent()); String voiceJson = "{\"bizType\":\"2\",\"content\":\"您有一笔新的订单,请及时处理\"}"; -// String voiceJson = "{\"bizType\":\"2\",\"content\":\"\"}"; - Object resp = sendPrintRequest(machine.getAddress(), buildDishPrintData, voiceJson, "1"); -// sendPrintRequest(voiceJson, 3, 1, machine.getAddress(), data); + String resp = sendPrintRequest(machine.getAddress(), buildDishPrintData, voiceJson, "1"); printMachineLogService.save(machine, "新订单", buildDishPrintData, resp); } @@ -127,9 +115,8 @@ public class YxyPrinter extends PrinterHandler implements PrinterImpl { protected void returnDishesPrint(OrderInfo orderInfo, OrderDetail orderDetail, PrintMachine machine) { String buildDishPrintData = buildDishPrintData(true, getPickupNum(orderInfo), DateUtil.format(orderDetail.getCreateTime(), "yyyy-MM-dd HH:mm:ss"), orderDetail.getProductName(), orderDetail.getSkuName(), orderDetail.getReturnNum(), orderDetail.getRemark(), orderDetail.getProGroupInfo(), orderDetail.getId(), orderDetail.isUrgent()); -// String voiceJson = "{\"bizType\":\"2\",\"content\":\"您有一笔新的订单,请及时处理\"}"; String voiceJson = "{\"bizType\":\"2\",\"content\":\"\"}"; - Object resp = sendPrintRequest(machine.getAddress(), buildDishPrintData, voiceJson, "1"); + String resp = sendPrintRequest(machine.getAddress(), buildDishPrintData, voiceJson, "1"); printMachineLogService.save(machine, "退款单", buildDishPrintData, resp); } @@ -141,18 +128,17 @@ public class YxyPrinter extends PrinterHandler implements PrinterImpl { .setOrderNo(orderInfo.getOrderNo()).setTradeDate(DateUtil.format(orderInfo.getCreateTime(), "yyyy-MM-dd HH:mm:ss")).setOperator("【POS-1】001").setPayAmount(orderInfo.getPayAmount().toPlainString()) .setOriginalAmount(orderInfo.getOriginAmount().toPlainString()).setReturn(isReturn(orderInfo)) .setBalance(balance).setPayType((ObjectUtil.isEmpty(orderInfo.getPayType()) || ObjectUtil.isNull(orderInfo.getPayType()) ? "" : orderInfo.getPayType())).setIntegral("0") - .setOutNumber(orderInfo.getTakeCode()).setPrintTitle("结算单") + .setOutNumber(orderInfo.getTakeCode()).setPrintTitle("退款单") .setRemark(orderInfo.getRemark()).setDiscountAmount(orderInfo.getOriginAmount().subtract(orderInfo.getPayAmount()).toPlainString()); String data = buildOrderPrintData(printInfoDTO, detailList); String voiceJson = "{\"PbizType\":\"2\",\"content\":\"您有一笔新的订单,请及时处理\"}"; -// String voiceJson = "{\"bizType\":\"2\",\"content\":\"\"}"; String printerNum = "1"; if (StrUtil.isNotBlank(machine.getPrintQty())) { printerNum = machine.getPrintQty().split("\\^")[1]; } String resp = sendPrintRequest(machine.getAddress(), data, voiceJson, printerNum); - printMachineLogService.save(machine, "新订单", data, resp); + printMachineLogService.save(machine, "退款单", data, resp); } @@ -173,33 +159,38 @@ public class YxyPrinter extends PrinterHandler implements PrinterImpl { .setRemark(orderInfo.getRemark()) .setDiscountAmount((orderInfo.getOriginAmount().add(orderInfo.getSeatAmount()).add(orderInfo.getPackFee()).subtract(orderInfo.getPayAmount())).toPlainString()); printInfoDTO.setPrintTitle(printInfoDTO.getPrintTitle()); - if(orderInfo.getSeatNum() != null && orderInfo.getSeatAmount().compareTo(BigDecimal.ZERO) > 0){ + if (orderInfo.getSeatNum() != null && orderInfo.getSeatAmount().compareTo(BigDecimal.ZERO) > 0) { printInfoDTO.setSeatNum(orderInfo.getSeatNum().toString()); printInfoDTO.setSeatAmount(orderInfo.getSeatAmount().toPlainString()); } - if(orderInfo.getPackFee().compareTo(BigDecimal.ZERO) > 0){ + if (orderInfo.getPackFee().compareTo(BigDecimal.ZERO) > 0) { printInfoDTO.setPackFee(orderInfo.getPackFee().toPlainString()); } String data = buildOrderPrintData(printInfoDTO, detailList); String voiceJson = "{\"PbizType\":\"2\",\"content\":\"您有一笔新的订单,请及时处理\"}"; -// String voiceJson = "{\"bizType\":\"2\",\"content\":\"\"}"; String printerNum = "1"; if (StrUtil.isNotBlank(machine.getPrintQty())) { printerNum = machine.getPrintQty().split("\\^")[1]; } String resp = sendPrintRequest(machine.getAddress(), data, voiceJson, printerNum); -// printMachineLogService.save(machine, printType, data, resp); - printMachineLogService.save(machine, "新订单", data, resp); + printMachineLogService.save(machine, "结算单", data, resp); } + /** + * 叫号单打印 + */ @Override protected void callNumPrint(PrintMachine machine, String callNum, String shopName, String tableName, String tableNote, String preNum, String codeUrl, LocalDateTime takeTime, String shopNote) { String resp = buildCallTicketData(shopName, tableName, callNum, preNum, codeUrl, shopNote, takeTime); sendPrintRequest(machine.getAddress(), resp, null, "1"); } + + /** + * 交班单打印 + */ @Override protected void handoverPrint(PrintMachine machine, HandoverRecordDTO record) { String string = buildHandoverData(record); @@ -214,9 +205,9 @@ public class YxyPrinter extends PrinterHandler implements PrinterImpl { * @param requestId 请求ID,自定义 * @return token信息 */ - private static Map getToken(String timestamp, String requestId) { + private static String getToken(String timestamp, String requestId) { StringBuilder token = new StringBuilder(); - StringBuilder encode = new StringBuilder(); +// StringBuilder encode = new StringBuilder(); SortedMap map = new TreeMap<>(); map.put("appId", APP_ID); map.put("timestamp", timestamp); @@ -226,13 +217,38 @@ public class YxyPrinter extends PrinterHandler implements PrinterImpl { String key = next.getKey(); Object value = next.getValue(); token.append(key).append(value); - encode.append(key).append("=").append(value).append("&"); +// encode.append(key).append("=").append(value).append("&"); } - Map finalMap = new HashMap<>(); - finalMap.put("ENCODE", encode.toString()); - finalMap.put("TOKEN", SecureUtil.md5(token + APP_SECRET).toUpperCase()); - return finalMap; +// Map finalMap = new HashMap<>(); +// finalMap.put("ENCODE", encode.toString()); +// finalMap.put("TOKEN", SecureUtil.md5(token + APP_SECRET).toUpperCase()); +// return finalMap; + return SecureUtil.md5(token + APP_SECRET).toUpperCase(); } + /** + * 检查打印状态 + * + * @param devName 设备名称,(唯一) 对应配置表中的address字段即(IP地址/打印机编号) + * @param taskId 打印任务id,用于复查打印状态,云想印=orderId + */ + public String checkPrintStatus(String devName, String taskId) { + String time = String.valueOf(System.currentTimeMillis()); + String uuid = UUID.randomUUID().toString(); + + Map paramMap = new HashMap<>(); + + paramMap.put("devName", devName); + paramMap.put("orderId", taskId); + paramMap.put("token", getToken(time, uuid)); + paramMap.put("appId", APP_ID); + paramMap.put("timestamp", time); + paramMap.put("requestId", uuid); + paramMap.put("userCode", USER_CODE); + String s = HttpUtil.get("https://ioe.car900.com/v1/openApi/dev/findOrder.json", paramMap, 1000 * 5); + log.info("云想印打印机:{},任务:{}状态:{}", devName, taskId, s); + return s; + } + } diff --git a/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/OrderInfoCustomServiceImpl.java b/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/OrderInfoCustomServiceImpl.java index df23df62c..887e8fe76 100644 --- a/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/OrderInfoCustomServiceImpl.java +++ b/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/OrderInfoCustomServiceImpl.java @@ -1523,13 +1523,13 @@ public class OrderInfoCustomServiceImpl implements OrderInfoCustomService { switch (orderInfoPrintDTO.getType()) { case 0: - printerHandler.handler(orderInfo.getId().toString(), PrinterHandler.PrintTypeEnum.ONE_AND_ORDER, orderInfoPrintDTO.getMachineId()); + printerHandler.handler(orderInfo.getId().toString(), PrinterHandler.PrintTypeEnum.ONE_AND_ORDER); break; case 1: - printerHandler.handler(orderInfo.getId().toString(), PrinterHandler.PrintTypeEnum.PRE_ORDER, orderInfoPrintDTO.getMachineId()); + printerHandler.handler(orderInfo.getId().toString(), PrinterHandler.PrintTypeEnum.PRE_ORDER); break; case 2: - printerHandler.handler(orderInfo.getId().toString(), PrinterHandler.PrintTypeEnum.ORDER, orderInfoPrintDTO.getMachineId()); + printerHandler.handler(orderInfo.getId().toString(), PrinterHandler.PrintTypeEnum.ORDER); break; } return true; diff --git a/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/PrintMachineLogServiceImpl.java b/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/PrintMachineLogServiceImpl.java index 66c7b7bee..20bd6f3d0 100644 --- a/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/PrintMachineLogServiceImpl.java +++ b/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/PrintMachineLogServiceImpl.java @@ -2,28 +2,31 @@ package com.czg.service.order.service.impl; import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.date.DateUtil; -import cn.hutool.core.map.MapUtil; -import cn.hutool.core.text.UnicodeUtil; import cn.hutool.core.thread.ThreadUtil; import cn.hutool.core.util.StrUtil; -import cn.hutool.crypto.SecureUtil; -import cn.hutool.http.HttpUtil; -import cn.hutool.json.JSONObject; -import cn.hutool.json.JSONUtil; +import com.alibaba.fastjson2.JSONObject; import com.czg.account.entity.PrintMachine; import com.czg.market.service.OrderInfoService; import com.czg.order.entity.PrintMachineLog; import com.czg.order.service.PrintMachineLogService; import com.czg.service.order.mapper.PrintMachineLogMapper; +import com.czg.service.order.print.FeiPrinter; +import com.czg.service.order.print.YxyPrinter; import com.mybatisflex.spring.service.impl.ServiceImpl; import jakarta.annotation.Resource; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.codec.digest.DigestUtils; +import org.springframework.context.annotation.Lazy; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; -import java.util.*; +import java.util.Map; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; /** * 店铺小票打印记录ServiceImpl @@ -35,135 +38,22 @@ import java.util.*; @Service @RequiredArgsConstructor public class PrintMachineLogServiceImpl extends ServiceImpl implements PrintMachineLogService { - //请求地址 - private static final String URL_STR = "https://ioe.car900.com/v1/openApi/dev/customPrint.json"; - //APPID - private static final String APP_ID = "ZF544"; - //USERCODE - private static final String USER_CODE = "ZF544"; - //APPSECRET - private static final String APP_SECRET = "2022bsjZF544GAH"; - - public static final String URL = "http://api.feieyun.cn/Api/Open/";//不需要修改 - - public static final String USER = "chaozhanggui2022@163.com";//*必填*:账号名 - public static final String UKEY = "UfWkhXxSkeSSscsU";//*必填*: 飞鹅云后台注册账号后生成的UKEY 【备注:这不是填打印机的KEY】 - public static final String SN = "960238952";//*必填*:打印机编号,必须要在管理后台里添加打印机或调用API接口添加之后,才能调用API @Resource private OrderInfoService orderInfoService; + @Lazy + @Resource + private YxyPrinter yxyPrinter; + @Lazy + @Resource + private FeiPrinter feiPrinter; - /** - * 获取TOKEN值 - * - * @param timestamp 时间戳,13位 - * @param requestId 请求ID,自定义 - * @return - */ - private static Map getToken(String timestamp, String requestId) { - StringBuilder token = new StringBuilder(); - StringBuilder encode = new StringBuilder(); - SortedMap map = new TreeMap<>(); - map.put("appId", APP_ID); - map.put("timestamp", timestamp); - map.put("requestId", requestId); - map.put("userCode", USER_CODE); - for (Map.Entry next : map.entrySet()) { - String key = next.getKey(); - Object value = next.getValue(); - token.append(key).append(value); - encode.append(key).append("=").append(value).append("&"); - } - System.out.println("token" + token); - Map finalMap = new HashMap<>(); - finalMap.put("ENCODE", encode.toString()); - finalMap.put("TOKEN", SecureUtil.md5(token + APP_SECRET).toUpperCase()); - return finalMap; - } - - /** - * 检查打印状态 - * - * @param devName 设备名称,(唯一) 对应配置表中的address字段即(IP地址/打印机编号) - * @param taskId 打印任务id,用于复查打印状态,云想印=orderId - * @return - */ - public static String checkPrintStatus(String devName, String taskId) { - String time = String.valueOf(System.currentTimeMillis()); - String uuid = UUID.randomUUID().toString(); - - Map param = getToken(time, uuid); - String token = param.get("TOKEN"); - Map paramMap = new HashMap<>(); - - paramMap.put("devName", devName); - paramMap.put("orderId", taskId); - paramMap.put("token", token); - paramMap.put("appId", APP_ID); - paramMap.put("timestamp", time); - paramMap.put("requestId", uuid); - paramMap.put("userCode", USER_CODE); - - return HttpUtil.get("https://ioe.car900.com/v1/openApi/dev/findOrder.json", paramMap, 1000 * 5); - } - - private static String signature(String USER, String UKEY, String STIME) { - return DigestUtils.sha1Hex(USER + UKEY + STIME); - } - - /** - * 检查飞鹅打印机打印任务是否已打印 - * - * @param printOrderId 打印订单编号 - * @return null-未知错误,true-已打印,false-未打印 - */ - public static Boolean checkFPrintStatus(String printOrderId) { - String STIME = String.valueOf(System.currentTimeMillis() / 1000); - Map paramMap = new HashMap<>(); - paramMap.put("user", USER); - paramMap.put("stime", STIME); - paramMap.put("sig", signature(USER, UKEY, STIME)); - paramMap.put("apiname", "Open_queryOrderState"); - paramMap.put("orderid", printOrderId); - Boolean ret; - try { - String resp = HttpUtil.post(URL, paramMap, 1000 * 5); - //成功 {"msg":"ok","ret":0,"data":true,"serverExecutedTime":4} - //失败 {"msg":"ok","ret":0,"data":false,"serverExecutedTime":4} - JSONObject json = JSONUtil.parseObj(UnicodeUtil.toString(resp)); - ret = json.getBool("data"); - } catch (Exception e) { - ret = null; - } - return ret; - } - - /** - * 检查飞鹅打印机是否在线 - * - * @param sn 设备编号 - * @return 在线,工作状态正常。/离线。/未知错误 - */ - public static String checkOnline(String sn) { - String STIME = String.valueOf(System.currentTimeMillis() / 1000); - Map paramMap = new HashMap<>(); - paramMap.put("user", USER); - paramMap.put("stime", STIME); - paramMap.put("sig", signature(USER, UKEY, STIME)); - paramMap.put("apiname", "Open_queryPrinterStatus"); - paramMap.put("sn", sn); - String msg; - try { - String resp = HttpUtil.post(URL, paramMap, 1000 * 5); - //成功 开机 {"msg":"ok","ret":0,"data":"在线,工作状态正常。","serverExecutedTime":4} - //成功 离线 {"msg":"ok","ret":0,"data":"离线。","serverExecutedTime":7} - JSONObject json = JSONUtil.parseObj(UnicodeUtil.toString(resp)); - msg = json.getStr("data"); - } catch (Exception e) { - msg = "未知错误"; - } - return msg; - } + Map yxxStatusMap = Map.of( + 0, "离线(设备上线后自动补打)", + 1, "在线", + 2, "获取失败", + 3, "未激活", + 4, "设备已禁用"); /** * 保存打印记录 @@ -175,7 +65,7 @@ public class PrintMachineLogServiceImpl extends ServiceImpl yxxStatusMap = MapUtil.builder(0, "离线(设备上线后自动补打)").put(1, "在线").put(2, "获取失败").put(3, "未激活").put(4, "设备已禁用").build(); + JSONObject resp = JSONObject.parseObject(respJson); // 云想印 if ("云想印".equals(config.getContentType())) { - cn.hutool.json.JSONObject resp = JSONUtil.parseObj(respJson); - int code = resp.getInt("code"); - cn.hutool.json.JSONObject data = resp.getJSONObject("data").getJSONObject("data"); + int code = resp.getIntValue("code"); + JSONObject respData = resp.getJSONObject("data"); + JSONObject data = respData.getJSONObject("data"); //设备状态,0: 离线, 1: 在线, 2: 获取失败, 3:未激活, 4:设备已禁用 - int status = data.getInt("status"); + int status = data.getIntValue("status"); if (code != 0) { failFlag = 1; respCode = code + ""; - respMsg = resp.getStr("msg"); + respMsg = resp.getString("msg"); } else if (status != 1) { failFlag = 1; respCode = code + ""; - respMsg = status + "_" + yxxStatusMap.get(status); } if (code == 0) { - String taskId = resp.getJSONObject("data").getStr("orderId"); - entity.setTaskId(taskId); + entity.setTaskId(respData.getString("orderId")); } // 飞鹅云打印机暂时没有适配,先return不做打印记录 } else if ("飞鹅".equals(config.getContentType())) { - cn.hutool.json.JSONObject resp = JSONUtil.parseObj(respJson); - int ret = resp.getInt("ret"); + int ret = resp.getIntValue("ret"); if (ret != 0) { failFlag = 1; respCode = ret + ""; - respMsg = resp.getStr("msg"); + respMsg = resp.getString("msg"); } else { - String printOrderId = resp.getStr("data"); - entity.setTaskId(printOrderId); + entity.setTaskId(resp.getString("data")); } } else { // 其他打印机暂时没有适配,先return不做打印记录 return; } entity.setBizType(bizType); -// entity.setCreateUserId(config.getCurrentUserId()); -// entity.setCreateUserName(config.getCurrentUserName()); -// if (StrUtil.isNotBlank(config.getCurrentUserNickName())) { -// entity.setCreateUserName(StrUtil.concat(true, config.getCurrentUserNickName(), " | ", config.getCurrentUserName())); -// } entity.setPrintContent(printContent); entity.setCreateTime(DateUtil.date().toLocalDateTime()); if (failFlag == 0) { @@ -238,64 +118,251 @@ public class PrintMachineLogServiceImpl extends ServiceImpl checkPrintStatus(config, entity)); + } - // 云想印 - if ("云想印".equals(config.getContentType())) { - // 延迟3ms,复查打印状态 (用户可以根据设备信息查询到当前设备的在线情况(注:该接口只能提供参考,设备的离线状态是在设备离线3分钟后才会生效)) - ThreadUtil.safeSleep(1000 * 5); - String jsonStr = checkPrintStatus(config.getAddress(), entity.getTaskId()); - cn.hutool.json.JSONObject resp = JSONUtil.parseObj(jsonStr); - int code = resp.getInt("code"); - if (code == 0) { - cn.hutool.json.JSONObject data = resp.getJSONObject("data"); - boolean status = data.containsKey("status"); - if (!status) { + /** + * 类级别成员变量:基于虚拟线程的固定大小(5)定时线程池 + * // Java 21+ 虚拟线程工厂,支持命名 + */ + private final ScheduledExecutorService virtualThreadScheduler = Executors.newScheduledThreadPool( + 5, + Thread.ofVirtual().name("print-query-vt-", 0).factory() + ); + + /** + * 打印机状态查询(解决 retryFuture 爆红问题 + 虚拟线程 + 轮询重试) + * + * @param config 打印机配置 + * @param entity 打印日志实体 + */ + public void checkPrintStatus(PrintMachine config, PrintMachineLog entity) { + // 最大重试次数 + int maxRetryTimes = 5; + AtomicInteger executedTimes = new AtomicInteger(0); + + // 原子引用包装ScheduledFuture,用于后续取消轮询 + AtomicReference> retryFutureRef = new AtomicReference<>(); + + // 核心查询任务(修正后,逻辑内聚) + Runnable printQueryTask = () -> { + int currentTimes = executedTimes.incrementAndGet(); + boolean isPrintSuccess = false; + boolean isLastTask = false; + + try { + // 1. 云想印打印机状态查询 + if ("云想印".equals(config.getContentType())) { + String jsonStr = yxyPrinter.checkPrintStatus(config.getAddress(), entity.getTaskId()); + log.info("云想印打印状态查询结果(第{}次,虚拟线程:{}):{}", + currentTimes, Thread.currentThread().getName(), jsonStr); + JSONObject resp = JSONObject.parseObject(jsonStr); + int code = resp.getIntValue("code"); + if (code == 0) { + JSONObject data = resp.getJSONObject("data"); + if (data.containsKey("status")) { + isPrintSuccess = data.getBooleanValue("status", false); + updatePrintLogEntity(entity, isPrintSuccess); + } + } + } + // 2. 飞鹅云打印机状态查询 + else if ("飞鹅".equals(config.getContentType())) { + Boolean success = feiPrinter.checkFPrintStatus(entity.getTaskId()); + if (success == null) { + entity.setFailFlag(1); + entity.setRespMsg("打印失败,未知错误"); + entity.setPrintTime(null); + } else if (success) { + isPrintSuccess = true; + updatePrintLogEntity(entity, true); + } else { + String msg = feiPrinter.checkOnline(entity.getAddress()); + if (msg.indexOf("在线,工作状态正常") > 0) { + isPrintSuccess = true; + updatePrintLogEntity(entity, true); + } else { + isPrintSuccess = false; + entity.setFailFlag(1); + entity.setPrintTime(null); + entity.setRespMsg(StrUtil.concat(true, "打印失败,", "_", msg)); + } + } + }else { + log.info("打印类型为其他类型,终止打印状态查询轮询任务"); + ScheduledFuture future = retryFutureRef.get(); + if (future != null && !future.isCancelled()) { + boolean cancelSuccess = future.cancel(false); // 取消后续轮询(不中断当前任务) + log.info("其他打印类型,取消轮询任务:{}", cancelSuccess ? "成功" : "失败"); + } + } + + // 3. 打印成功:取消后续轮询任务 + if (isPrintSuccess) { + isLastTask = true; + ScheduledFuture future = retryFutureRef.get(); + if (future != null && !future.isCancelled()) { + future.cancel(false); // 不中断当前任务,仅取消后续任务 + } return; } - boolean success = data.getBool("status", false); - if (entity.getFailFlag() == 0 && success) { - entity.setFailFlag(0); - entity.setRespMsg("打印成功"); - entity.setPrintTime(entity.getCreateTime()); - } else if (entity.getFailFlag() == 1 && success) { - entity.setFailFlag(0); - entity.setPrintTime(DateUtil.date().toLocalDateTime()); - entity.setRespMsg("打印成功"); - // 如果设备在线 and 休眠5秒后查询结果是未打印,即视为设备已离线,云端3分钟后才会同步到离线信息 - } else if (entity.getFailFlag() == 0 && !success) { - entity.setFailFlag(1); - entity.setPrintTime(null); - entity.setRespMsg("0_离线(设备上线后自动补打)"); - } else { - entity.setFailFlag(1); - entity.setPrintTime(null); - entity.setRespMsg(StrUtil.concat(true, "打印失败,", "_", entity.getRespMsg())); + + // 4. 达到最大重试次数:取消后续轮询任务 + if (currentTimes >= maxRetryTimes) { + isLastTask = true; + ScheduledFuture future = retryFutureRef.get(); + if (future != null && !future.isCancelled()) { + future.cancel(false); + } + } + + } catch (Exception e) { + log.error("第{}次打印机状态查询异常(虚拟线程:{})", + currentTimes, Thread.currentThread().getName(), e); + // 异常时达到最大重试次数,同样取消任务 + if (currentTimes >= maxRetryTimes) { + ScheduledFuture future = retryFutureRef.get(); + if (future != null && !future.isCancelled()) { + boolean cancelSuccess = future.cancel(false); + log.info("查询异常且达到最大重试次数,取消轮询任务:{}", cancelSuccess ? "成功" : "失败"); + } + } + } finally { + //仅当是最后一次任务时,才执行更新操作 + if (isLastTask) { + super.updateById(entity); } } - // 飞鹅云打印机 - } else if ("飞鹅".equals(config.getContentType())) { - ThreadUtil.safeSleep(1000 * 5); - Boolean success = checkFPrintStatus(entity.getTaskId()); - if (success == null) { - entity.setFailFlag(1); - entity.setRespMsg("打印失败,未知错误"); - } else if (success) { - entity.setFailFlag(0); - entity.setPrintTime(DateUtil.date().toLocalDateTime()); - entity.setRespMsg("打印成功"); + }; + + // 修正:统一使用scheduleAtFixedRate,避免任务重复执行 + // 首次延迟10秒执行,后续每隔30秒执行一次(符合原逻辑的首次查询延迟,后续轮询间隔) + ScheduledFuture retryFuture = virtualThreadScheduler.scheduleAtFixedRate( + printQueryTask, + 10, + 30, + TimeUnit.SECONDS + ); + + // 修正:先赋值AtomicReference,再让任务可能执行,避免线程安全隐患 + retryFutureRef.set(retryFuture); + // 修正:关闭钩子仅注册一次(通过静态代码块或类初始化时注册,避免重复注册) + registerShutdownHookOnce(); + } + + /** + * 统一更新打印日志实体 + * + * @param entity 打印日志实体 + * @param isPrintSuccess 是否打印成功 + */ + private void updatePrintLogEntity(PrintMachineLog entity, boolean isPrintSuccess) { + if (isPrintSuccess) { + entity.setFailFlag(0); + entity.setRespMsg("打印成功"); + entity.setPrintTime(entity.getFailFlag() == 0 ? entity.getCreateTime() : DateUtil.date().toLocalDateTime()); + } else { + entity.setFailFlag(1); + entity.setPrintTime(null); + if (entity.getFailFlag() == 0) { + entity.setRespMsg("0_离线(设备上线后自动补打)"); } else { - String msg = checkOnline(entity.getAddress()); - if (msg.indexOf("在线,工作状态正常") > 0) { - entity.setFailFlag(0); - entity.setPrintTime(DateUtil.date().toLocalDateTime()); - entity.setRespMsg("打印成功"); - } else { - entity.setFailFlag(1); - entity.setPrintTime(null); - entity.setRespMsg(StrUtil.concat(true, "打印失败,", "_", msg)); + entity.setRespMsg(StrUtil.concat(true, "打印失败,", "_", entity.getRespMsg())); + } + } + } + + +// public void checkPrintStatus(PrintMachine config, PrintMachineLog entity) { +// // 云想印 +// if ("云想印".equals(config.getContentType())) { +// String jsonStr = yxyPrinter.checkPrintStatus(config.getAddress(), entity.getTaskId()); +// log.info("云想印打印状态查询结果:{}", jsonStr); +// JSONObject resp = JSONObject.parseObject(jsonStr); +// int code = resp.getIntValue("code"); +// if (code == 0) { +// JSONObject data = resp.getJSONObject("data"); +// boolean status = data.containsKey("status"); +// if (!status) { +// return; +// } +// boolean success = data.getBooleanValue("status", false); +// if (entity.getFailFlag() == 0 && success) { +// entity.setFailFlag(0); +// entity.setRespMsg("打印成功"); +// entity.setPrintTime(entity.getCreateTime()); +// } else if (entity.getFailFlag() == 1 && success) { +// entity.setFailFlag(0); +// entity.setPrintTime(DateUtil.date().toLocalDateTime()); +// entity.setRespMsg("打印成功"); +// // 如果设备在线 and 休眠5秒后查询结果是未打印,即视为设备已离线,云端3分钟后才会同步到离线信息 +// } else if (entity.getFailFlag() == 0 && !success) { +// entity.setFailFlag(1); +// entity.setPrintTime(null); +// entity.setRespMsg("0_离线(设备上线后自动补打)"); +// } else { +// entity.setFailFlag(1); +// entity.setPrintTime(null); +// entity.setRespMsg(StrUtil.concat(true, "打印失败,", "_", entity.getRespMsg())); +// } +// } +// // 飞鹅云打印机 +// } else if ("飞鹅".equals(config.getContentType())) { +// Boolean success = feiPrinter.checkFPrintStatus(entity.getTaskId()); +// if (success == null) { +// entity.setFailFlag(1); +// entity.setRespMsg("打印失败,未知错误"); +// } else if (success) { +// entity.setFailFlag(0); +// entity.setPrintTime(DateUtil.date().toLocalDateTime()); +// entity.setRespMsg("打印成功"); +// } else { +// String msg = feiPrinter.checkOnline(entity.getAddress()); +// if (msg.indexOf("在线,工作状态正常") > 0) { +// entity.setFailFlag(0); +// entity.setPrintTime(DateUtil.date().toLocalDateTime()); +// entity.setRespMsg("打印成功"); +// } else { +// entity.setFailFlag(1); +// entity.setPrintTime(null); +// entity.setRespMsg(StrUtil.concat(true, "打印失败,", "_", msg)); +// } +// } +// } +// super.updateById(entity); +// } + + // 静态标识,确保关闭钩子仅注册一次 + private static volatile boolean shutdownHookRegistered = false; + // 锁对象,保证线程安全 + private static final Object HOOK_LOCK = new Object(); + + /** + * 统一注册JVM关闭钩子(仅执行一次) + */ + private void registerShutdownHookOnce() { + if (!shutdownHookRegistered) { + synchronized (HOOK_LOCK) { + // 双重校验锁,避免多线程下重复注册 + if (!shutdownHookRegistered) { + Runtime.getRuntime().addShutdownHook(new Thread(() -> { + if (virtualThreadScheduler != null && !virtualThreadScheduler.isShutdown()) { + virtualThreadScheduler.shutdown(); + try { + if (!virtualThreadScheduler.awaitTermination(10, TimeUnit.SECONDS)) { + log.warn("虚拟线程调度器10秒内未关闭,强制关闭..."); + virtualThreadScheduler.shutdownNow(); + } + } catch (InterruptedException e) { + log.error("等待虚拟线程调度器终止时被中断,强制关闭", e); + virtualThreadScheduler.shutdownNow(); + Thread.currentThread().interrupt(); // 保留中断状态 + } + } + }, "PrinterScheduler-ShutdownHook")); + shutdownHookRegistered = true; } } } - super.updateById(entity); } } From 484c40cdb5c641498c87b689ad66a1295483831b Mon Sep 17 00:00:00 2001 From: gong <1157756119@qq.com> Date: Tue, 30 Dec 2025 10:38:45 +0800 Subject: [PATCH 020/133] =?UTF-8?q?=E8=8E=B7=E5=8F=96=E5=BE=AE=E4=BF=A1?= =?UTF-8?q?=E6=94=AF=E8=A1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/czg/alipay/AlipayEntryManager.java | 6 +- .../com/czg/wechat/WechatEntryManager.java | 23 +++++-- .../java/com/czg/wechat/WechatReqUtils.java | 69 ++++++++++++------- 3 files changed, 64 insertions(+), 34 deletions(-) diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/AlipayEntryManager.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/AlipayEntryManager.java index db63e8645..d33793279 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/AlipayEntryManager.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/AlipayEntryManager.java @@ -13,7 +13,7 @@ import com.alipay.v3.util.model.AlipayConfig; /** * 支付宝进件管理 * - * ... + * ... * @author yjjie * @date 2025/12/29 14:11 */ @@ -24,9 +24,9 @@ public class AlipayEntryManager { // 初始化alipay参数(全局设置一次) AlipayConfig alipayConfig = new AlipayConfig(); alipayConfig.setServerUrl("https://openapi.alipay.com"); - alipayConfig.setAppId("2021004174605036"); + alipayConfig.setAppId("2021006121646825"); alipayConfig.setAlipayPublicKey("MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAiQkrz+emAuS1mB3KKDOMmAZRd/BlPbh7fAIHAqAj1+QCZNcV3o2BTLIIqnuKpSlFXDG3uDzp2VsBxcizXuBbFyPGylnD9CgCj5abyh3+FIHPAZ2IM3TtpqImZ0TSPGXrMli4Nir7MvZktgccCqQKCC4o6iaDGz+UwWwJUIPna8fm2tiTZ+KH150CZbKVj4ZGNpBh5XSV/1dRgyQIV9D/EwSbkZ0n6VgKQLJBi0C2UE3QB17aL1Ir6+gDXIDbknN8O7GUD3aMGdThYdSRUb5wp9CZ5qfV7vCS/CgaRo38nhH3NOzkTL+7v0m1ZDHPmqEkn9VzZN6sCQdL7PoAOjHOCwIDAQAB"); - alipayConfig.setPrivateKey("MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQD48HaUoV7OH7os+9L01kHgxzwIhJick4OkFq4aHsntsXEJ J3gedhuEZtV8oHKZ30DPW12IJ4S8NXtpr8OWaqrAPFonf4wVaRY1d0yIAea57kfLEn9oOEEy4FzARgMNDkyxC+/3OUdGbLHpTjfVX3gusXsEhUDy1/WewihAkoNYF37+W3W/uVLzeWoPq0EcUbRv/G/t/p6gL69ltsMAiVFG4Q/Yk24YAN6lYgBPNLXUEwQ1Q+T+1omjfavHgvarKOp33z3JOUH+aGOmDsJ5Y9gyGtJzOCipAd8Zcv+T1ygsEzZYO1/gzcbPnfO1ShqStCHzssuw8FBVx2JdfQKXKMMNAgMBAAECggEAVTrO/pg5Q00titU1Jspsh67u6OOs9H605Ws2dI7yB8VmtAGlaJh7V1t14FN2qSP8poHbhhAxq9aLyGV7C3a9u09udnN+3J28EtYjh7VO732bavWMVXxdJjQWzWWrCb9JlpxFrlkYBA6W4w/6ob0sAqCVQ7jzwbEa0R4cde8ztOa5nysKSfr4YTSs0gqvoiC6fmg8eiRJraEQBoYz9VkKFtOhhh/4w5FhVcYQ2gQvZ3kK3QVuD1eJIQKlCtz8qaox9lXKDiZT4SCmnKshdUL0u5TYIcYeBjZmhJz0Q50KHcpZrCs5y7I0+vRBH3hU+TKSQt7ureymwhbwWMHScLV2gQKBgQD+58SHXhr5M8NGagAmTdsgmCnNv2kOYMd4STyPMY10SVwCv1Bk808ZuP+7e558J1b5/OuDLI5dLq6xrZ/1wLv1G++XqxI00hlFuWS5mUGJVcXotT1mw20rVeUILc7Qe3mLvbMGgfyKf4A7Qa5SSZ4bDeDTJYaFxyiQ281hMzDuPQKBgQD6AiL/Na2/uPH4CG6juwpjYvYVUcjK+7gbRwf3wWsWMpk90Z4ju2iUiP5c1J/oK9P+1T3PIr6M4Xjza8JJj+r9KC/PVB0gBv6vVM96cDpKUEy/UMpcn/T81vqj/Z+WEOODU8Ms6NiTTm+u9ldvpCjbu0u8M+9c0JeIyadJvSTFEQKBgQCsxmFyM3nq8YfpgU2qqNjfBeRH3faSVUy+nj1a/YZYjKS+A/i1BCnYUImeBVNN6chNV342ggvY4xxruDiU9Vcw8wd58O09Oi8BEIFSP6upL6cebUI6Fjo3xlegLJRiwV6INkNTJOYM5hD/mSxUACwXQFfkJipBINXBIgraWD1RLQKBgQCj49axWq0F6+WjZVOyPaD3uh37p9trRUxRhWTxw3fB23WdktaKMgbCqHOmwzP4bRLSEVQtf2dOz1gMqu14b8HqJvgAf/F/11YJ9hz09LEhmjZVjE68HZfqT7uK2W5OX8/lfXmK7TFcj6SjG5YB96lZMhTZ0WnufEd6QkdKDZYXIQKBgQD9GDTcIMbFwbEaKHnfZaTD3f876EGRgsgrCxwdEk7LBCRPwWo7yI929M4psIlpNwNeiyjBkBunWIVkpznp6qPtJqagIPUYesU4f5v6/okq5wcpaNKSkWbIvWVLaLGOiA1aeGJtbpMpyClbSr52puHpRRdvAiIEQ74yYh0JX8q96g=="); + alipayConfig.setPrivateKey("MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCz3FkdffxZibdwis9W7eOW1dEjGAbSvRDL2ikfeCIW5KZNoIjUqxI0mIoUlLRRKO71QLHZS1Vb2aJp8jeOAqIPa8e76HTneQEzk3FGA8gpraSGvbadHWzvxnmYKsts1TBiEZQL82ySJXhQTJvZ6jyDM7s6wHHUnrH+Qi29QpppQ1sxsoJeCtajUgRg3btD6XbBcyFAX3pzM56Kw9eaIjZoD8WToZOM/Y3sqNL2uo8lLqcIpTrI7Pq5ZOspmBQ+t8v3rS9IdDZZMvd0trzS67AXwHz8rKPBT/lL1A4iHnXCHUvktusX1fPs3/RGY/a7PIddaBLnfY0GcueE16K7QcrXAgMBAAECggEAbSdT2eckp75BWoaTcGEs1tRqeM7TDT/6moyKmnOQ1K3tE31SrSYpBUxxuC3LBNo/sw2RIZtrcTOyMnPyLTgB3DP/4lUf5X51MTTQ8LnI1ypvh+pIki9Sdm3QS33lOOZk149tdpdDk6ozyx/DEcvq74EMpoo2SuAIi5LkKVDrXuehvGA/WeXtpmuPgqRFdIA+JBlA3knHk5XEQY/k2Y31gq5oCwNL9iT9OAZqVkukE6EnvCXE9t2rAV4/snYilaf/UaO+ktgEwSbPBQ8YKlovDAarMBbGtgr6E174A9djlPyR+W/fgx8rlTwSWtieb9MkO8LN3KSxgVs0kY5U8OHg8QKBgQDljJq9kTFHare+W/fAXdUy3tJprfNQCAii6s+GuDfTQiviVQDtWmdtHAN+xU3to7MepvVhwHsqtQnZXKTtZuwwxn82FNl7A5RYD3GVFW+wG6AsGLIdESrWxySoL6Kx8QmNpMEVg8acT/ywzW/RnUXS5vU7GIi8GA0vtyBo24R9KQKBgQDIlf/R9+iNk9oXlbB/k4um9eVvBBS7l5cx4E5Id5Dpp4kGZfPZEa7oDsEUstZZM9mgQLJK/noNWbcf0+BohCR5ux7SC12qIoxwN3k4BzTDqrS8BzFuVVp5PELUsf/uCbRn05iMzpiDUhj3Vde04wvjHYIobfKlZO2HeSWXCpUH/wKBgQC8wSuU6ck90pEY5QMKmZ3wYK1g3PsQOirv3Gmde+nbu7PePsuuYQJfBAQTwCZeXJezgtKP+PjOm2Nn6vhrhpB9YxvD2s0ijET1TG23i5L1myHQYNZFdJJnXgXUjqcX7v5ODMYA7QTqEBPXRnbGRK7fx66rU3dMQ/LD46+wyaFeUQKBgA4QTk53dkuu6SSsLyLSwoDjTsHY5Gc+urAZjQORtoxbXcUgEtfOYJgOqMT9wP+iHgkZYCbX7tDO0IMfxOUvFqueTgvmFhwergAUM6CVCMMLTf689l9JBr3nVrw4+rvC3G5HLLP6rEDQ2cVFtIkPPj8fS4fwJYopKGpOOS9843QbAoGBAMoHH8LqoZ50FLsospx/hJe24Cd8wCgQTXSa/hMqNZ1999JDhftMt7R0ZdB1he2LReACe0K9ntBU4H4u225zZ3wZlyOfoyerAHuLK/ysNlgIIzblZlOxbBJ64Kul8leXzlYy3tOZuZ997KqBcWPCE3LUBBNvM6E3blJUnlmJAVoi"); defaultClient.setAlipayConfig(alipayConfig); AlipayOpenAgentApi api = new AlipayOpenAgentApi(); AlipayOpenAgentCreateModel data = new AlipayOpenAgentCreateModel(); diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatEntryManager.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatEntryManager.java index 7524b156c..676da7552 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatEntryManager.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatEntryManager.java @@ -11,7 +11,6 @@ import com.czg.wechat.dto.req.entry.business.sales.WechatEntrySalesInfoReqDto; import com.czg.wechat.dto.req.entry.business.sales.WechatEntryStoreInfoReqDto; import com.wechat.pay.java.core.Config; import com.wechat.pay.java.core.cipher.PrivacyEncryptor; -import com.wechat.pay.java.core.cipher.Signer; import com.wechat.pay.java.service.file.FileUploadService; import com.wechat.pay.java.service.file.model.FileUploadResponse; import lombok.extern.slf4j.Slf4j; @@ -20,24 +19,34 @@ import java.net.URI; import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; -import java.util.Arrays; import java.util.List; +import java.util.Map; /** * 微信支付进件 管理 - * + * 参考地址 ... * @author yjjie * @date 2025/12/26 10:57 */ @Slf4j public class WechatEntryManager { + public static void queryBankList(WechatPayConfigDto configDto, Integer offset, Integer limit) { + WechatReqUtils.getReq(configDto, "/v3/capital/capitallhh/banks/personal-banking", Map.of("offset", offset, "limit", limit)); + } + + /** + * 商户进件 + * + * @param configDto 配置 + * @param reqDto 请求参数 + */ public static void entryMerchant(WechatPayConfigDto configDto, WechatEntryReqDto reqDto) { String params = JSONObject.toJSONString(reqDto, JSONWriter.Feature.IgnoreEmpty); -// String string = WechatReqUtils.encryptReqParam(configDto, "POST", "/v3/applyment4sub/applyment/", params); +// String string = WechatReqUtils.encryptReqParam(configDto, "/v3/applyment4sub/applyment/", params); - WechatReqUtils.postReq(configDto, "POST", "/v3/applyment4sub/applyment/", params); + WechatReqUtils.postReq(configDto, "/v3/applyment4sub/applyment/", params); } /** @@ -178,6 +187,8 @@ public class WechatEntryManager { .setPublicKeyId("PUB_KEY_ID_0116437794082025111000382377001000") .setDomain("https://api.mch.weixin.qq.com"); + queryBankList(dto, 0, 10); + // String string = uploadImage(dto, "https://czg-qr-order.oss-cn-beijing.aliyuncs.com/indexs/shuangbackground.png"); // log.info("图片上传成功:{}", string); @@ -253,6 +264,6 @@ public class WechatEntryManager { reqDto.setBankAccountInfo(bankAccountInfo); - entryMerchant(dto, reqDto); +// entryMerchant(dto, reqDto); } } diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatReqUtils.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatReqUtils.java index b92fb54fc..7a3a3c7ad 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatReqUtils.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatReqUtils.java @@ -1,15 +1,21 @@ package com.czg.wechat; +import cn.hutool.core.util.StrUtil; import cn.hutool.http.HttpRequest; import cn.hutool.http.HttpUtil; +import com.czg.exception.CzgException; import com.czg.wechat.dto.config.WechatPayConfigDto; import com.wechat.pay.java.core.Config; -import com.wechat.pay.java.core.RSAPublicKeyConfig; -import com.wechat.pay.java.core.cipher.PrivacyEncryptor; import com.wechat.pay.java.core.cipher.Signer; import lombok.extern.slf4j.Slf4j; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.Arrays; +import java.util.Map; +import java.util.Objects; import java.util.UUID; +import java.util.stream.Collectors; /** * 微信请求工具类 @@ -20,38 +26,51 @@ import java.util.UUID; @Slf4j public class WechatReqUtils { - public static String postReq(WechatPayConfigDto configDto, String method, String url, String body) { + public static String postReq(WechatPayConfigDto configDto, String url, String body) { + return req(configDto, url, "POST", body); + } + + public static String getReq(WechatPayConfigDto configDto, String url, Map params) { + url = Arrays.stream(params.entrySet().toArray(new Map.Entry[0])) + .map(entry -> entry.getKey() + "=" + URLEncoder.encode(entry.getValue().toString(), StandardCharsets.UTF_8)) + .collect(Collectors.joining("&", url + "?", "")); + return req(configDto, url, "GET", ""); + } + + private static String req(WechatPayConfigDto configDto, String url, String method, String body) { long timestamp = getTimestamp(); String nonce = getNonceStr(); - String signature = encryptReqParam(configDto, method, url, body, timestamp, nonce); - String authorization = String.format("WECHATPAY2-SHA256-RSA2048 mchid=\"%s\",nonce_str=\"%s\",signature=\"%s\",timestamp=\"%d\",serial_no=\"%s\"", - configDto.getMerchantId(), nonce, signature, timestamp, "4DE9BAC2EA584C3F274F694C9753CA814C4E9BF4"); + configDto.getMerchantId(), nonce, signature, timestamp, configDto.getSerialNumber()); - log.info("authorization = {}", authorization); - - HttpRequest request = HttpUtil.createPost(configDto.getDomain() + url) - .header("Authorization", authorization) - .header("Content-Type", "application/json") - .header("Wechatpay-Serial", configDto.getPublicKeyId()) -// .header("Wechatpay-Serial", "4DE9BAC2EA584C3F274F694C9753CA814C4E9BF4") - .body(body); + HttpRequest request = switch (method) { + case "POST" -> HttpUtil.createPost(configDto.getDomain() + url) + .header("Authorization", authorization) + .header("Content-Type", "application/json") + .header("Wechatpay-Serial", configDto.getPublicKeyId()) + .body(body); + case "GET" -> HttpUtil.createGet(configDto.getDomain() + url) + .header("Authorization", authorization) + .header("Content-Type", "application/json") + .header("Wechatpay-Serial", configDto.getPublicKeyId()); + default -> throw new CzgException("不支持的请求方法"); + }; String s = request.execute().body(); - log.info("s = {}", s); - - return ""; + log.info("微信支付请求:url = {}, method: {}, body: {}, resp: {}", url, method, body, s); + return s; } /** * 加密请求参数 - * @param configDto 配置 - * @param method 请求方法 - * @param url 请求地址 - * @param body 请求报文主体 - * @return 加密后的报文 * + * @param configDto 配置 + * @param method 请求方法 + * @param url 请求地址 + * @param body 请求报文主体 + * @return 加密后的报文 + *

* 签名方法 * HTTP请求方法\n * URL\n @@ -62,12 +81,12 @@ public class WechatReqUtils { public static String encryptReqParam(WechatPayConfigDto configDto, String method, String url, String body, long timestamp, String nonce) { String encryptStr = String.format("%s\n%s\n%d\n%s\n%s\n", method, url, timestamp, nonce, body); - System.out.println("encryptStr = \n" + encryptStr); + log.info("encryptStr = {}", encryptStr); Config config = WechatConfig.getRsaConfig(configDto); Signer signer = config.createSigner(); String signature = signer.sign(encryptStr).getSign(); - System.out.println("signature = " + signature); + log.info("签名 signature:{}", signature); return signature; } @@ -82,6 +101,6 @@ public class WechatReqUtils { * 获取时间戳 */ private static long getTimestamp() { - return System.currentTimeMillis()/1000; + return System.currentTimeMillis() / 1000; } } From befd2942a2e3d74b7c8c2d1350328121cacd43e4 Mon Sep 17 00:00:00 2001 From: wangw <1594593906@qq.com> Date: Tue, 30 Dec 2025 11:49:54 +0800 Subject: [PATCH 021/133] =?UTF-8?q?=E6=89=93=E5=8D=B0=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/resources/application-dev.yml | 25 ++++++++++- .../java/com/czg/order/entity/OrderInfo.java | 44 ++++++++++++++----- .../order/service/PrintMachineLogService.java | 2 + .../czg/service/order/print/FeiPrinter.java | 8 ++-- .../service/order/print/PrinterHandler.java | 6 ++- .../czg/service/order/print/YxyPrinter.java | 8 ++-- .../impl/OrderInfoCustomServiceImpl.java | 3 ++ .../impl/PrintMachineLogServiceImpl.java | 37 +++++++++++++--- 8 files changed, 107 insertions(+), 26 deletions(-) diff --git a/cash-api/order-server/src/main/resources/application-dev.yml b/cash-api/order-server/src/main/resources/application-dev.yml index a2d9fc027..09d53b35a 100644 --- a/cash-api/order-server/src/main/resources/application-dev.yml +++ b/cash-api/order-server/src/main/resources/application-dev.yml @@ -25,7 +25,30 @@ spring: port: 5672 username: chaozg password: chaozg123 - + # 关键优化:解决MissedHeartbeatException 心跳超时问题 + connection-timeout: 10000 # 连接超时时间(10秒,避免连接建立过慢) + requested-heartbeat: 30 # 心跳间隔调整为30秒(原60秒过长,降低超时概率;过短易误触发) + # 高级配置:连接池 & 自动重连(核心优化,避免连接断开后无法恢复) + cache: + connection: + mode: channel # 连接池模式(默认channel,推荐) + size: 10 # 最大连接数,根据业务调整 + channel: + size: 50 # 每个连接的最大通道数 + # 自动重连配置(Spring AMQP 自带,关键兜底) + publisher-returns: true + template: + retry: + enabled: true # 开启消息发送重试 + max-attempts: 3 # 最大重试次数 + initial-interval: 2000 # 首次重试间隔2秒 + multiplier: 1.5 # 重试间隔倍增因子 + listener: + simple: + retry: + enabled: true # 开启消费者重试 + max-attempts: 3 # 消费者最大重试次数 + acknowledge-mode: auto # 确认模式(可根据业务改为manual) dubbo: application: name: order-server diff --git a/cash-common/cash-common-service/src/main/java/com/czg/order/entity/OrderInfo.java b/cash-common/cash-common-service/src/main/java/com/czg/order/entity/OrderInfo.java index 9c1dae004..26049bad4 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/order/entity/OrderInfo.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/order/entity/OrderInfo.java @@ -2,6 +2,7 @@ package com.czg.order.entity; import cn.hutool.core.util.StrUtil; import com.alibaba.fastjson2.JSONArray; +import com.alibaba.fastjson2.JSONObject; import com.czg.order.dto.LimitRateDTO; import com.mybatisflex.annotation.Column; import com.mybatisflex.annotation.Id; @@ -346,15 +347,38 @@ public class OrderInfo implements Serializable { // .add(this.getRoundAmount() != null ? this.getRoundAmount() : BigDecimal.ZERO); } + private JSONArray getPrintStatusAsArray() { + if (StrUtil.isBlank(printStatus)) { + return new JSONArray(); + } + try { + return JSONArray.parseArray(printStatus.trim()); + } catch (Exception e) { + return new JSONArray(); + } + } -// public JSONArray getPrintStatus() { -// if (StrUtil.isBlank(printStatus)) { -// return new JSONArray(); -// } -// try { -// return JSONArray.parseArray(printStatus.trim()); -// } catch (Exception e) { -// return new JSONArray(); -// } -// } + public void upPrintStatus(JSONObject printStatus, boolean isPrintSuccess) { + String currentDeviceId = printStatus.getString("id"); + JSONArray oldPrintStatusArray = getPrintStatusAsArray(); + // 3. 初始化新的打印状态JSON数组(用于存储处理后的结果) + JSONArray newPrintStatusArray = new JSONArray(); + // 场景1:打印成功 - 移除原有数组中与当前设备ID一致的记录,保留其余记录 + if (oldPrintStatusArray != null && !oldPrintStatusArray.isEmpty()) { + for (int i = 0; i < oldPrintStatusArray.size(); i++) { + JSONObject deviceObj = oldPrintStatusArray.getJSONObject(i); + String deviceId = deviceObj.getString("id"); + // 仅保留非当前设备ID的记录 + if (currentDeviceId != null && !currentDeviceId.equals(deviceId)) { + newPrintStatusArray.add(deviceObj); + } + } + } + if (!isPrintSuccess) { + newPrintStatusArray.add(printStatus); + } + if(newPrintStatusArray.isEmpty()){ + this.setPrintStatus(newPrintStatusArray.toJSONString()); + } + } } diff --git a/cash-common/cash-common-service/src/main/java/com/czg/order/service/PrintMachineLogService.java b/cash-common/cash-common-service/src/main/java/com/czg/order/service/PrintMachineLogService.java index 40c77ab7b..5449bec74 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/order/service/PrintMachineLogService.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/order/service/PrintMachineLogService.java @@ -11,6 +11,8 @@ import com.czg.order.entity.PrintMachineLog; * @since 2025-03-11 */ public interface PrintMachineLogService extends IService { + void save(Long orderId, PrintMachine config, String bizType, String printContent, String respJson); + void save(PrintMachine config, String bizType, String printContent, String respJson); } diff --git a/cash-service/order-service/src/main/java/com/czg/service/order/print/FeiPrinter.java b/cash-service/order-service/src/main/java/com/czg/service/order/print/FeiPrinter.java index aa1b6494a..3e79a3efe 100644 --- a/cash-service/order-service/src/main/java/com/czg/service/order/print/FeiPrinter.java +++ b/cash-service/order-service/src/main/java/com/czg/service/order/print/FeiPrinter.java @@ -70,7 +70,7 @@ public class FeiPrinter extends PrinterHandler implements PrinterImpl { String content = buildDishPrintData(false, getPickupNum(orderInfo), orderInfo.getCreateTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")), orderDetail.getProductName(), orderDetail.getSkuName(), orderDetail.getNum(), remark, orderDetail.getProGroupInfo(), orderDetail.getId(), orderDetail.isUrgent()); String o = sendPrintRequest(machine.getAddress(), content, null, "1"); - printMachineLogService.save(machine, "新订单", content, o); + printMachineLogService.save(orderInfo.getId(), machine, "新订单", content, o); } @@ -80,7 +80,7 @@ public class FeiPrinter extends PrinterHandler implements PrinterImpl { String content = buildDishPrintData(true, getPickupNum(orderInfo), orderInfo.getCreateTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")), orderDetail.getProductName(), orderDetail.getSkuName(), orderDetail.getReturnNum(), remark, orderDetail.getProGroupInfo(), orderDetail.getId(), orderDetail.isUrgent()); String o = sendPrintRequest(machine.getAddress(), content, null, "1"); - printMachineLogService.save(machine, "退款单", content, o); + printMachineLogService.save(orderInfo.getId(), machine, "退款单", content, o); } @@ -102,7 +102,7 @@ public class FeiPrinter extends PrinterHandler implements PrinterImpl { .setDiscountAmount(orderInfo.getOriginAmount().subtract(orderInfo.getPayAmount()).toPlainString()); String string = buildOrderPrintData(printInfoDTO, detailList); String o = sendPrintRequest(machine.getAddress(), string, null, printerNum); - printMachineLogService.save(machine, "结算单", string, o); + printMachineLogService.save(orderInfo.getId(), machine, "结算单", string, o); } @@ -139,7 +139,7 @@ public class FeiPrinter extends PrinterHandler implements PrinterImpl { String string = buildOrderPrintData(printInfoDTO, detailList); String resp = sendPrintRequest(machine.getAddress(), string, null, printerNum); - printMachineLogService.save(machine, "结算单", string, resp); + printMachineLogService.save(orderInfo.getId(), machine, "结算单", string, resp); } @Override diff --git a/cash-service/order-service/src/main/java/com/czg/service/order/print/PrinterHandler.java b/cash-service/order-service/src/main/java/com/czg/service/order/print/PrinterHandler.java index 6ee130dae..d3598eed9 100644 --- a/cash-service/order-service/src/main/java/com/czg/service/order/print/PrinterHandler.java +++ b/cash-service/order-service/src/main/java/com/czg/service/order/print/PrinterHandler.java @@ -342,6 +342,7 @@ public abstract class PrinterHandler { case PrintTypeEnum.ORDER: log.info("准备开始打印订单"); if (data instanceof OrderInfo orderInfo) { + redisService.set("order:print:" + orderInfo.getId(),"", 180); List orderDetailList = orderDetailService.list(new QueryWrapper().eq(OrderDetail::getOrderId, orderInfo.getId())); onlyFrontDesk(machine, false, orderInfo, orderDetailList); } else { @@ -351,6 +352,7 @@ public abstract class PrinterHandler { case PrintTypeEnum.PRE_ORDER: log.info("准备开始打印预结算订单"); if (data instanceof OrderInfo orderInfo) { + redisService.set("order:print:" + orderInfo.getId(),"", 180); List orderDetailList = orderDetailService.list(new QueryWrapper().eq(OrderDetail::getOrderId, orderInfo.getId())); onlyFrontDesk(machine, true, orderInfo, orderDetailList); } else { @@ -360,6 +362,7 @@ public abstract class PrinterHandler { case PrintTypeEnum.ONE: log.info("准备开始打印菜品单"); if (data instanceof OrderInfo orderInfo) { + redisService.set("order:print:" + orderInfo.getId(),"", 180); List orderDetailList = orderDetailService.list(new QueryWrapper().eq(OrderDetail::getOrderId, orderInfo.getId())); onlyKitchen(machine, orderInfo, orderDetailList); } else { @@ -377,6 +380,7 @@ public abstract class PrinterHandler { case PrintTypeEnum.ONE_AND_ORDER: log.info("准备开始打印菜品以及结算单"); if (data instanceof OrderInfo orderInfo) { + redisService.set("order:print:" + orderInfo.getId(),"", 180); List orderDetailList = orderDetailService.list(new QueryWrapper().eq(OrderDetail::getOrderId, orderInfo.getId())); switch (machine.getPrintMethod()) { case "all": @@ -462,7 +466,7 @@ public abstract class PrinterHandler { OrderDetail orderDetail = detailMap.get(item.getId()); redisService.set(RedisCst.getPrintOrderDetailKey(orderInfo.getId(), item.getId()), JSONObject.toJSONString(new PrintDetailInfo().setPrint(item.getIsPrint() == 1).setDetailId(item.getId()) - .setPrintNum(orderDetail.getNum()).setPrintReturnNum(orderDetail.getReturnNum())), 3600 * 24); + .setPrintNum(orderDetail.getNum()).setPrintReturnNum(orderDetail.getReturnNum())), 3600 * 24); }); diff --git a/cash-service/order-service/src/main/java/com/czg/service/order/print/YxyPrinter.java b/cash-service/order-service/src/main/java/com/czg/service/order/print/YxyPrinter.java index 3f32358a9..238a07d0f 100644 --- a/cash-service/order-service/src/main/java/com/czg/service/order/print/YxyPrinter.java +++ b/cash-service/order-service/src/main/java/com/czg/service/order/print/YxyPrinter.java @@ -107,7 +107,7 @@ public class YxyPrinter extends PrinterHandler implements PrinterImpl { orderDetail.getNum(), orderDetail.getRemark(), orderDetail.getProGroupInfo(), orderDetail.getId(), orderDetail.isUrgent()); String voiceJson = "{\"bizType\":\"2\",\"content\":\"您有一笔新的订单,请及时处理\"}"; String resp = sendPrintRequest(machine.getAddress(), buildDishPrintData, voiceJson, "1"); - printMachineLogService.save(machine, "新订单", buildDishPrintData, resp); + printMachineLogService.save(orderInfo.getId(), machine, "新订单", buildDishPrintData, resp); } @@ -117,7 +117,7 @@ public class YxyPrinter extends PrinterHandler implements PrinterImpl { orderDetail.getReturnNum(), orderDetail.getRemark(), orderDetail.getProGroupInfo(), orderDetail.getId(), orderDetail.isUrgent()); String voiceJson = "{\"bizType\":\"2\",\"content\":\"\"}"; String resp = sendPrintRequest(machine.getAddress(), buildDishPrintData, voiceJson, "1"); - printMachineLogService.save(machine, "退款单", buildDishPrintData, resp); + printMachineLogService.save(orderInfo.getId(), machine, "退款单", buildDishPrintData, resp); } @@ -138,7 +138,7 @@ public class YxyPrinter extends PrinterHandler implements PrinterImpl { printerNum = machine.getPrintQty().split("\\^")[1]; } String resp = sendPrintRequest(machine.getAddress(), data, voiceJson, printerNum); - printMachineLogService.save(machine, "退款单", data, resp); + printMachineLogService.save(orderInfo.getId(), machine, "退款单", data, resp); } @@ -174,7 +174,7 @@ public class YxyPrinter extends PrinterHandler implements PrinterImpl { printerNum = machine.getPrintQty().split("\\^")[1]; } String resp = sendPrintRequest(machine.getAddress(), data, voiceJson, printerNum); - printMachineLogService.save(machine, "结算单", data, resp); + printMachineLogService.save(orderInfo.getId(), machine, "结算单", data, resp); } diff --git a/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/OrderInfoCustomServiceImpl.java b/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/OrderInfoCustomServiceImpl.java index 887e8fe76..84572cf5c 100644 --- a/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/OrderInfoCustomServiceImpl.java +++ b/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/OrderInfoCustomServiceImpl.java @@ -1516,6 +1516,9 @@ public class OrderInfoCustomServiceImpl implements OrderInfoCustomService { @Override public Boolean printOrder(Long shopId, OrderInfoPrintDTO orderInfoPrintDTO) { + if (redisService.hasKey("order:print:" + orderInfoPrintDTO.getId())) { + throw new CzgException("网络打印机正在尝试打印中。如需重打,请稍后再试!"); + } OrderInfo orderInfo = orderInfoService.getOne(new QueryWrapper().eq(OrderInfo::getShopId, shopId).eq(OrderInfo::getId, orderInfoPrintDTO.getId())); if (orderInfo == null) { throw new CzgException("订单信息不存在"); diff --git a/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/PrintMachineLogServiceImpl.java b/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/PrintMachineLogServiceImpl.java index 20bd6f3d0..ff1011632 100644 --- a/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/PrintMachineLogServiceImpl.java +++ b/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/PrintMachineLogServiceImpl.java @@ -4,11 +4,14 @@ import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.date.DateUtil; import cn.hutool.core.thread.ThreadUtil; import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson2.JSONArray; import com.alibaba.fastjson2.JSONObject; import com.czg.account.entity.PrintMachine; import com.czg.market.service.OrderInfoService; +import com.czg.order.entity.OrderInfo; import com.czg.order.entity.PrintMachineLog; import com.czg.order.service.PrintMachineLogService; +import com.czg.service.RedisService; import com.czg.service.order.mapper.PrintMachineLogMapper; import com.czg.service.order.print.FeiPrinter; import com.czg.service.order.print.YxyPrinter; @@ -20,6 +23,7 @@ import org.springframework.context.annotation.Lazy; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; +import java.time.LocalDateTime; import java.util.Map; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; @@ -47,6 +51,8 @@ public class PrintMachineLogServiceImpl extends ServiceImpl yxxStatusMap = Map.of( 0, "离线(设备上线后自动补打)", @@ -55,9 +61,19 @@ public class PrintMachineLogServiceImpl extends ServiceImpl checkPrintStatus(config, entity)); + ThreadUtil.execAsync(() -> checkPrintStatus(orderId, config, entity)); } /** @@ -133,10 +149,11 @@ public class PrintMachineLogServiceImpl extends ServiceImpl future = retryFutureRef.get(); if (future != null && !future.isCancelled()) { @@ -230,7 +247,15 @@ public class PrintMachineLogServiceImpl extends ServiceImpl Date: Tue, 30 Dec 2025 13:32:16 +0800 Subject: [PATCH 022/133] =?UTF-8?q?MQ=E9=87=8D=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../order-server/src/main/resources/application-dev.yml | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/cash-api/order-server/src/main/resources/application-dev.yml b/cash-api/order-server/src/main/resources/application-dev.yml index 09d53b35a..2ac1a07d7 100644 --- a/cash-api/order-server/src/main/resources/application-dev.yml +++ b/cash-api/order-server/src/main/resources/application-dev.yml @@ -28,20 +28,13 @@ spring: # 关键优化:解决MissedHeartbeatException 心跳超时问题 connection-timeout: 10000 # 连接超时时间(10秒,避免连接建立过慢) requested-heartbeat: 30 # 心跳间隔调整为30秒(原60秒过长,降低超时概率;过短易误触发) - # 高级配置:连接池 & 自动重连(核心优化,避免连接断开后无法恢复) - cache: - connection: - mode: channel # 连接池模式(默认channel,推荐) - size: 10 # 最大连接数,根据业务调整 - channel: - size: 50 # 每个连接的最大通道数 # 自动重连配置(Spring AMQP 自带,关键兜底) publisher-returns: true template: retry: enabled: true # 开启消息发送重试 max-attempts: 3 # 最大重试次数 - initial-interval: 2000 # 首次重试间隔2秒 + initial-interval: 3000 # 首次重试间隔2秒 multiplier: 1.5 # 重试间隔倍增因子 listener: simple: From a4fc02dcc3cb7703ebd80040d0fb21b9a1bc4938 Mon Sep 17 00:00:00 2001 From: wangw <1594593906@qq.com> Date: Tue, 30 Dec 2025 13:55:11 +0800 Subject: [PATCH 023/133] =?UTF-8?q?=E6=96=87=E6=A1=A3=E5=9C=B0=E5=9D=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/czg/service/order/print/FeiPrinter.java | 1 + .../src/main/java/com/czg/service/order/print/YxyPrinter.java | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/cash-service/order-service/src/main/java/com/czg/service/order/print/FeiPrinter.java b/cash-service/order-service/src/main/java/com/czg/service/order/print/FeiPrinter.java index 3e79a3efe..caae46bed 100644 --- a/cash-service/order-service/src/main/java/com/czg/service/order/print/FeiPrinter.java +++ b/cash-service/order-service/src/main/java/com/czg/service/order/print/FeiPrinter.java @@ -31,6 +31,7 @@ import java.util.Map; /** * @author Administrator + * 接口文档 */ @Component @Slf4j diff --git a/cash-service/order-service/src/main/java/com/czg/service/order/print/YxyPrinter.java b/cash-service/order-service/src/main/java/com/czg/service/order/print/YxyPrinter.java index 238a07d0f..cf1f8a2c5 100644 --- a/cash-service/order-service/src/main/java/com/czg/service/order/print/YxyPrinter.java +++ b/cash-service/order-service/src/main/java/com/czg/service/order/print/YxyPrinter.java @@ -25,8 +25,8 @@ import java.time.LocalDateTime; import java.util.*; /** - * 云享印打印机 - * + * 博实结-云享印打印机 + * 接口文档 * @author Administrator */ @Slf4j From 0684e0459f55ea52404ae13972d8104f1609687b Mon Sep 17 00:00:00 2001 From: wangw <1594593906@qq.com> Date: Tue, 30 Dec 2025 14:11:38 +0800 Subject: [PATCH 024/133] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=A0=87=E8=AF=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/czg/order/entity/OrderInfo.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/cash-common/cash-common-service/src/main/java/com/czg/order/entity/OrderInfo.java b/cash-common/cash-common-service/src/main/java/com/czg/order/entity/OrderInfo.java index 26049bad4..1dd24f0af 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/order/entity/OrderInfo.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/order/entity/OrderInfo.java @@ -358,8 +358,8 @@ public class OrderInfo implements Serializable { } } - public void upPrintStatus(JSONObject printStatus, boolean isPrintSuccess) { - String currentDeviceId = printStatus.getString("id"); + public void upPrintStatus(JSONObject printJson, boolean isPrintSuccess) { + String currentDeviceId = printJson.getString("id"); JSONArray oldPrintStatusArray = getPrintStatusAsArray(); // 3. 初始化新的打印状态JSON数组(用于存储处理后的结果) JSONArray newPrintStatusArray = new JSONArray(); @@ -375,10 +375,10 @@ public class OrderInfo implements Serializable { } } if (!isPrintSuccess) { - newPrintStatusArray.add(printStatus); + newPrintStatusArray.add(printJson); } - if(newPrintStatusArray.isEmpty()){ - this.setPrintStatus(newPrintStatusArray.toJSONString()); + if (newPrintStatusArray.isEmpty()) { + printStatus = newPrintStatusArray.toJSONString(); } } } From 93b2309fcdf51545c8d1f48886142454b7983f7b Mon Sep 17 00:00:00 2001 From: wangw <1594593906@qq.com> Date: Tue, 30 Dec 2025 14:25:37 +0800 Subject: [PATCH 025/133] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=A0=87=E8=AF=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/order/service/impl/PrintMachineLogServiceImpl.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/PrintMachineLogServiceImpl.java b/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/PrintMachineLogServiceImpl.java index ff1011632..0f52cc9fb 100644 --- a/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/PrintMachineLogServiceImpl.java +++ b/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/PrintMachineLogServiceImpl.java @@ -250,6 +250,9 @@ public class PrintMachineLogServiceImpl extends ServiceImpl Date: Tue, 30 Dec 2025 15:05:06 +0800 Subject: [PATCH 026/133] =?UTF-8?q?=E8=B5=8B=E5=80=BC=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/czg/task/DistributionTask.java | 5 - .../main/java/com/czg/mq/OrderMqListener.java | 6 +- .../main/java/com/czg/mq/PrintMqListener.java | 6 +- .../java/com/czg/service/RedisService.java | 111 +++++++++++++++- .../java/com/czg/order/entity/OrderInfo.java | 2 +- .../service/impl/CallTableServiceImpl.java | 10 +- .../service/impl/ShopUserServiceImpl.java | 1 - .../com/czg/service/account/util/FunUtil.java | 100 -------------- .../impl/PrintMachineLogServiceImpl.java | 94 +++---------- .../com/czg/service/order/utils/FunUtil.java | 125 ------------------ 10 files changed, 141 insertions(+), 319 deletions(-) delete mode 100644 cash-service/account-service/src/main/java/com/czg/service/account/util/FunUtil.java delete mode 100644 cash-service/order-service/src/main/java/com/czg/service/order/utils/FunUtil.java diff --git a/cash-api/market-server/src/main/java/com/czg/task/DistributionTask.java b/cash-api/market-server/src/main/java/com/czg/task/DistributionTask.java index 5e59af7ec..cdc53aad2 100644 --- a/cash-api/market-server/src/main/java/com/czg/task/DistributionTask.java +++ b/cash-api/market-server/src/main/java/com/czg/task/DistributionTask.java @@ -1,11 +1,8 @@ package com.czg.task; import cn.hutool.core.collection.CollUtil; -import cn.hutool.core.date.DateUtil; import com.czg.account.entity.ShopInfo; -import com.czg.account.entity.ShopUser; import com.czg.account.service.ShopInfoService; -import com.czg.account.service.ShopUserService; import com.czg.constant.TableValueConstant; import com.czg.constants.SystemConstants; import com.czg.exception.CzgException; @@ -15,13 +12,11 @@ import com.czg.market.service.MkDistributionUserService; import com.czg.market.service.OrderInfoService; import com.czg.order.entity.OrderInfo; import com.czg.service.market.enums.OrderStatusEnums; -import com.czg.utils.FunUtils; import com.mybatisflex.core.query.QueryWrapper; import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; import org.apache.dubbo.config.annotation.DubboReference; import org.springframework.stereotype.Component; -import org.springframework.transaction.annotation.Transactional; import java.math.BigDecimal; import java.time.LocalDateTime; diff --git a/cash-api/order-server/src/main/java/com/czg/mq/OrderMqListener.java b/cash-api/order-server/src/main/java/com/czg/mq/OrderMqListener.java index e8054e747..c220d1f3f 100644 --- a/cash-api/order-server/src/main/java/com/czg/mq/OrderMqListener.java +++ b/cash-api/order-server/src/main/java/com/czg/mq/OrderMqListener.java @@ -9,7 +9,7 @@ import com.czg.order.entity.MqLog; import com.czg.order.service.MqLogService; import com.czg.order.service.OrderInfoCustomService; import com.czg.order.service.OrderInfoRpcService; -import com.czg.service.order.utils.FunUtil; +import com.czg.service.RedisService; import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; import org.springframework.amqp.rabbit.annotation.RabbitListener; @@ -31,7 +31,7 @@ public class OrderMqListener { @Resource private OrderInfoCustomService orderInfoCustomService; @Resource - private FunUtil funUtil; + private RedisService redisService; /** * 订单上菜 @@ -44,7 +44,7 @@ public class OrderMqListener { info = info.replace("UP_ORDER_DETAIL:", ""); log.info("接收到修改菜品状态mq, info: {}", info); String finalInfo = info; - funUtil.debounce("UP_ORDER_DETAIL:" + info, 5, () -> { + redisService.debounce("UP_ORDER_DETAIL:" + info, 5, () -> { orderInfoCustomService.updateOrderDetailStatus(Long.valueOf(finalInfo)); }); diff --git a/cash-api/order-server/src/main/java/com/czg/mq/PrintMqListener.java b/cash-api/order-server/src/main/java/com/czg/mq/PrintMqListener.java index 33f610667..31781b987 100644 --- a/cash-api/order-server/src/main/java/com/czg/mq/PrintMqListener.java +++ b/cash-api/order-server/src/main/java/com/czg/mq/PrintMqListener.java @@ -6,8 +6,8 @@ import com.czg.config.RabbitConstants; import com.czg.config.RedisCst; import com.czg.order.entity.MqLog; import com.czg.order.service.MqLogService; +import com.czg.service.RedisService; import com.czg.service.order.print.PrinterHandler; -import com.czg.service.order.utils.FunUtil; import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; import org.springframework.amqp.rabbit.annotation.RabbitListener; @@ -27,7 +27,7 @@ public class PrintMqListener { @Resource private MqLogService mqLogService; @Resource - private FunUtil funUtil; + private RedisService redisService; @Lazy @Resource @@ -59,7 +59,7 @@ public class PrintMqListener { throw new RuntimeException("订单打印失败,未传递orderId"); } Boolean printOrder = jsonObject.getBoolean("printOrder"); - funUtil.runFunAndCheckKey(() -> { + redisService.runFunAndCheckKey(() -> { printerHandler.handler(orderId, printOrder != null && !printOrder ? PrinterHandler.PrintTypeEnum.ONE : PrinterHandler.PrintTypeEnum.ONE_AND_ORDER); return null; }, RedisCst.getLockKey("orderPrint", orderId)); diff --git a/cash-common/cash-common-redis/src/main/java/com/czg/service/RedisService.java b/cash-common/cash-common-redis/src/main/java/com/czg/service/RedisService.java index e84608854..c5d078a80 100644 --- a/cash-common/cash-common-redis/src/main/java/com/czg/service/RedisService.java +++ b/cash-common/cash-common-redis/src/main/java/com/czg/service/RedisService.java @@ -6,14 +6,15 @@ import jakarta.annotation.Resource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.core.script.DefaultRedisScript; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; -import java.util.Collection; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; import java.util.concurrent.TimeUnit; +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.function.Supplier; /** * @author GYJoker @@ -650,4 +651,106 @@ public class RedisService { } return JSON.parseArray(jsonStr, type); } + + + public static int retryCount = 5; + + /** + * 执行任务并保证锁唯一 + * + * @param supplier 业务逻辑 + * @param lockKey Redis锁的Key + * @return 业务逻辑返回值 + */ + public T runFunAndCheckKey(Supplier supplier, String lockKey) { + String lockValue = String.valueOf(System.nanoTime() + Thread.currentThread().threadId()); + try { + // 尝试获取锁,超时时间 5 秒,防止死锁 + boolean lock = Boolean.TRUE.equals(redisTemplate.opsForValue().setIfAbsent(lockKey, lockValue, 5, TimeUnit.SECONDS)); + int count = 0; + // 初始等待 10ms + int retryDelay = 10; + + while (!lock) { + // 最多重试 10 次,大约 10 秒 + if (count++ > 50) { + throw new RuntimeException("系统繁忙, 稍后再试"); + } + Thread.sleep(retryDelay); + // 指数退避,最大等待 200ms + retryDelay = Math.min(retryDelay * 2, 200); + lock = Boolean.TRUE.equals(redisTemplate.opsForValue().setIfAbsent(lockKey, lockValue, 5, TimeUnit.SECONDS)); + } + + // 执行任务 + return supplier.get(); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new RuntimeException("线程被中断", e); + } catch (Exception e) { + log.error("执行出错:{}", e.getMessage(), e); + throw e; + } finally { + // 释放锁(使用 Lua 脚本确保原子性) + unlock(lockKey, lockValue); + } + } + + /** + * 使用 Lua 脚本确保释放锁的原子性 + * + * @param lockKey 锁的 Key + * @param lockValue 当前线程的锁值 + */ + private void unlock(String lockKey, String lockValue) { + String luaScript = + "if redis.call('get', KEYS[1]) == ARGV[1] then " + + "return redis.call('del', KEYS[1]) " + + "else return 0 end"; + redisTemplate.execute(new DefaultRedisScript<>(luaScript, Long.class), + Collections.singletonList(lockKey), lockValue); + } + + public static R runFunAndRetry( + Supplier function, + Function check, Consumer errFun) { + R result = function.get(); + boolean flag = check.apply(result); + + while (flag && retryCount-- > 0) { + result = function.get(); + flag = check.apply(result); + } + + if (flag) { + errFun.accept(result); + } + return result; + } + + + /** + * 防抖函数:在指定秒数内相同 Key 的任务只会执行一次 + * + * @param key 防抖使用的 Redis Key + * @param seconds 防抖时间(秒) + * @param task 要执行的业务逻辑 + * @return true 执行了任务;false 在防抖期内被拦截 + */ + public boolean debounce(String key, long seconds, Runnable task) { + try { + Boolean success = redisTemplate.opsForValue().setIfAbsent( + key, "1", seconds, TimeUnit.SECONDS + ); + + if (Boolean.TRUE.equals(success)) { + task.run(); + return true; + } + return false; + } catch (Exception e) { + log.error("防抖函数执行失败 key={} err={}", key, e.getMessage(), e); + return false; + } + } } diff --git a/cash-common/cash-common-service/src/main/java/com/czg/order/entity/OrderInfo.java b/cash-common/cash-common-service/src/main/java/com/czg/order/entity/OrderInfo.java index 1dd24f0af..40c89fc74 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/order/entity/OrderInfo.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/order/entity/OrderInfo.java @@ -377,7 +377,7 @@ public class OrderInfo implements Serializable { if (!isPrintSuccess) { newPrintStatusArray.add(printJson); } - if (newPrintStatusArray.isEmpty()) { + if (!newPrintStatusArray.isEmpty()) { printStatus = newPrintStatusArray.toJSONString(); } } diff --git a/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/CallTableServiceImpl.java b/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/CallTableServiceImpl.java index 53d467fe9..0ddc5e49e 100644 --- a/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/CallTableServiceImpl.java +++ b/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/CallTableServiceImpl.java @@ -14,9 +14,9 @@ import com.czg.config.RedisCst; import com.czg.constants.ParamCodeCst; import com.czg.exception.CzgException; import com.czg.resp.CzgResult; +import com.czg.service.RedisService; import com.czg.service.account.mapper.CallQueueMapper; import com.czg.service.account.mapper.CallTableMapper; -import com.czg.service.account.util.FunUtil; import com.czg.service.account.util.WechatMiniMsgUtil; import com.czg.system.dto.SysParamsDTO; import com.czg.system.service.SysParamsService; @@ -51,10 +51,10 @@ public class CallTableServiceImpl extends ServiceImpl { + return redisService.runFunAndCheckKey(() -> { String callNumKey = RedisCst.getTableCallNumKey(shopId, callTable.getId()); String value = stringRedisTemplate.opsForValue().get(callNumKey); AtomicReference newVal = new AtomicReference<>(""); // 初始化 if (StrUtil.isBlank(value)) { - Boolean setFlag = FunUtil.runFunAndRetry(() -> stringRedisTemplate.opsForValue().setIfAbsent(callNumKey, callTable.getStart().toString()), flag -> !flag, + Boolean setFlag = RedisService.runFunAndRetry(() -> stringRedisTemplate.opsForValue().setIfAbsent(callNumKey, callTable.getStart().toString()), flag -> !flag, _ -> newVal.set(stringRedisTemplate.opsForValue().get(callNumKey))); if (setFlag) { diff --git a/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/ShopUserServiceImpl.java b/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/ShopUserServiceImpl.java index b7dd81f9c..5669504ce 100644 --- a/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/ShopUserServiceImpl.java +++ b/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/ShopUserServiceImpl.java @@ -22,7 +22,6 @@ import com.czg.market.vo.InviteUserVO; import com.czg.market.vo.MemberConfigVO; import com.czg.order.entity.OrderInfo; import com.czg.service.account.mapper.ShopUserMapper; -import com.czg.service.account.util.FunUtil; import com.czg.utils.FunUtils; import com.czg.utils.PageUtil; import com.github.pagehelper.PageHelper; diff --git a/cash-service/account-service/src/main/java/com/czg/service/account/util/FunUtil.java b/cash-service/account-service/src/main/java/com/czg/service/account/util/FunUtil.java deleted file mode 100644 index c7d7f2d62..000000000 --- a/cash-service/account-service/src/main/java/com/czg/service/account/util/FunUtil.java +++ /dev/null @@ -1,100 +0,0 @@ -package com.czg.service.account.util; - -import jakarta.annotation.Resource; -import lombok.extern.slf4j.Slf4j; -import org.springframework.data.redis.core.RedisTemplate; -import org.springframework.data.redis.core.script.DefaultRedisScript; -import org.springframework.stereotype.Component; - -import java.util.Collections; -import java.util.concurrent.TimeUnit; -import java.util.function.Consumer; -import java.util.function.Function; -import java.util.function.Supplier; - -/** - * @author Administrator - */ -@Slf4j -@Component -public class FunUtil { - @Resource - private RedisTemplate redisTemplate; - public static int retryCount = 5; - - /** - * 执行任务并保证锁唯一 - * @param supplier 业务逻辑 - * @param lockKey Redis锁的Key - * @return 业务逻辑返回值 - */ - public T runFunAndCheckKey(Supplier supplier, String lockKey) { - String lockValue = String.valueOf(System.nanoTime() + Thread.currentThread().threadId()); - try { - // 尝试获取锁,超时时间 5 秒,防止死锁 - boolean lock = Boolean.TRUE.equals(redisTemplate.opsForValue().setIfAbsent(lockKey, lockValue, 5, TimeUnit.SECONDS)); - int count = 0; - // 初始等待 10ms - int retryDelay = 10; - - while (!lock) { - // 最多重试 10 次,大约 10 秒 - if (count++ > 50) { - throw new RuntimeException("系统繁忙, 稍后再试"); - } - Thread.sleep(retryDelay); - // 指数退避,最大等待 200ms - retryDelay = Math.min(retryDelay * 2, 200); - lock = Boolean.TRUE.equals(redisTemplate.opsForValue().setIfAbsent(lockKey, lockValue, 5, TimeUnit.SECONDS)); - } - - // 执行任务 - return supplier.get(); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - throw new RuntimeException("线程被中断", e); - } catch (Exception e) { - log.error("执行出错:{}", e.getMessage(), e); - throw e; - } finally { - // 释放锁(使用 Lua 脚本确保原子性) - unlock(lockKey, lockValue); - } - } - - /** - * 使用 Lua 脚本确保释放锁的原子性 - * @param lockKey 锁的 Key - * @param lockValue 当前线程的锁值 - */ - private void unlock(String lockKey, String lockValue) { - String luaScript = - "if redis.call('get', KEYS[1]) == ARGV[1] then " + - "return redis.call('del', KEYS[1]) " + - "else return 0 end"; - redisTemplate.execute(new DefaultRedisScript<>(luaScript, Long.class), - Collections.singletonList(lockKey), lockValue); - } - - public static R runFunAndRetry( - Supplier function, - Function check, Consumer errFun) { - log.info("工具类开始执行函数"); - R result = function.get(); - boolean flag = check.apply(result); - - log.info("执行结果: {}", result); - - while (flag && retryCount-- > 0) { - log.info("执行函数失败, 剩余尝试次数{}", retryCount); - result = function.get(); - log.info("执行结果: {}", result); - flag = check.apply(result); - } - - if (flag) { - errFun.accept(result); - } - return result; - } -} diff --git a/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/PrintMachineLogServiceImpl.java b/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/PrintMachineLogServiceImpl.java index 0f52cc9fb..f8ea58f83 100644 --- a/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/PrintMachineLogServiceImpl.java +++ b/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/PrintMachineLogServiceImpl.java @@ -4,9 +4,9 @@ import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.date.DateUtil; import cn.hutool.core.thread.ThreadUtil; import cn.hutool.core.util.StrUtil; -import com.alibaba.fastjson2.JSONArray; import com.alibaba.fastjson2.JSONObject; import com.czg.account.entity.PrintMachine; +import com.czg.config.RedisCst; import com.czg.market.service.OrderInfoService; import com.czg.order.entity.OrderInfo; import com.czg.order.entity.PrintMachineLog; @@ -247,18 +247,8 @@ public class PrintMachineLogServiceImpl extends ServiceImpl { + OrderInfo orderInfo = orderInfoService.getOne(query().select(OrderInfo::getPrintStatus).eq(OrderInfo::getId, orderId)); + if (orderInfo == null) { + orderInfo = new OrderInfo(); + } + JSONObject jsonObject = new JSONObject(); + jsonObject.put("id", config.getId()); + jsonObject.put("name", config.getName()); + jsonObject.put("time", LocalDateTime.now()); + orderInfo.upPrintStatus(jsonObject, isPrintSuccess); + orderInfoService.update(orderInfo, query().eq(OrderInfo::getId, orderId)); + return orderInfo; + }, RedisCst.getLockKey("UP_ORDER_PRINT", orderId)); + redisService.del("order:print:" + orderId); + } + /** * 统一更新打印日志实体 * @@ -300,66 +310,6 @@ public class PrintMachineLogServiceImpl extends ServiceImpl 0) { -// entity.setFailFlag(0); -// entity.setPrintTime(DateUtil.date().toLocalDateTime()); -// entity.setRespMsg("打印成功"); -// } else { -// entity.setFailFlag(1); -// entity.setPrintTime(null); -// entity.setRespMsg(StrUtil.concat(true, "打印失败,", "_", msg)); -// } -// } -// } -// super.updateById(entity); -// } - // 静态标识,确保关闭钩子仅注册一次 private static volatile boolean shutdownHookRegistered = false; // 锁对象,保证线程安全 diff --git a/cash-service/order-service/src/main/java/com/czg/service/order/utils/FunUtil.java b/cash-service/order-service/src/main/java/com/czg/service/order/utils/FunUtil.java deleted file mode 100644 index b1dfa4b5d..000000000 --- a/cash-service/order-service/src/main/java/com/czg/service/order/utils/FunUtil.java +++ /dev/null @@ -1,125 +0,0 @@ -package com.czg.service.order.utils; - -import cn.hutool.core.lang.func.Func0; -import jakarta.annotation.Resource; -import lombok.extern.slf4j.Slf4j; -import org.springframework.data.redis.core.RedisTemplate; -import org.springframework.data.redis.core.script.DefaultRedisScript; -import org.springframework.stereotype.Component; - -import java.util.Collections; -import java.util.concurrent.TimeUnit; -import java.util.function.Consumer; -import java.util.function.Function; -import java.util.function.Supplier; - -/** - * @author Administrator - */ -@Slf4j -@Component -public class FunUtil { - @Resource - private RedisTemplate redisTemplate; - public static int retryCount = 5; - - /** - * 执行任务并保证锁唯一 - * @param supplier 业务逻辑 - * @param lockKey Redis锁的Key - * @return 业务逻辑返回值 - */ - public T runFunAndCheckKey(Supplier supplier, String lockKey) { - String lockValue = String.valueOf(System.nanoTime() + Thread.currentThread().threadId()); - try { - // 尝试获取锁,超时时间 5 秒,防止死锁 - boolean lock = Boolean.TRUE.equals(redisTemplate.opsForValue().setIfAbsent(lockKey, lockValue, 5, TimeUnit.SECONDS)); - int count = 0; - // 初始等待 10ms - int retryDelay = 10; - - while (!lock) { - // 最多重试 10 次,大约 10 秒 - if (count++ > 50) { - throw new RuntimeException("系统繁忙, 稍后再试"); - } - Thread.sleep(retryDelay); - // 指数退避,最大等待 200ms - retryDelay = Math.min(retryDelay * 2, 200); - lock = Boolean.TRUE.equals(redisTemplate.opsForValue().setIfAbsent(lockKey, lockValue, 5, TimeUnit.SECONDS)); - } - - // 执行任务 - return supplier.get(); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - throw new RuntimeException("线程被中断", e); - } catch (Exception e) { - log.error("执行出错:{}", e.getMessage(), e); - throw e; - } finally { - // 释放锁(使用 Lua 脚本确保原子性) - unlock(lockKey, lockValue); - } - } - - /** - * 使用 Lua 脚本确保释放锁的原子性 - * @param lockKey 锁的 Key - * @param lockValue 当前线程的锁值 - */ - private void unlock(String lockKey, String lockValue) { - String luaScript = - "if redis.call('get', KEYS[1]) == ARGV[1] then " + - "return redis.call('del', KEYS[1]) " + - "else return 0 end"; - redisTemplate.execute(new DefaultRedisScript<>(luaScript, Long.class), - Collections.singletonList(lockKey), lockValue); - } - - public static R runFunAndRetry( - Supplier function, - Function check, Consumer errFun) { - log.info("工具类开始执行函数"); - R result = function.get(); - boolean flag = check.apply(result); - - log.info("执行结果: {}", result); - - while (flag && retryCount-- > 0) { - log.info("执行函数失败, 剩余尝试次数{}", retryCount); - result = function.get(); - log.info("执行结果: {}", result); - flag = check.apply(result); - } - - if (flag) { - errFun.accept(result); - } - return result; - } - - /** - * 防抖函数:在指定秒数内相同 Key 的任务只会执行一次 - * @param key 防抖使用的 Redis Key - * @param seconds 防抖时间(秒) - * @param task 要执行的业务逻辑 - * @return true 执行了任务;false 在防抖期内被拦截 - */ - public boolean debounce(String key, long seconds, Runnable task) { - try { - Boolean success = redisTemplate.opsForValue().setIfAbsent( - key, "1", seconds, TimeUnit.SECONDS - ); - - if (Boolean.TRUE.equals(success)) { - task.run(); - return true; - } - return false; - } catch (Exception e) { - log.error("防抖函数执行失败 key={} err={}", key, e.getMessage(), e); - return false; - } - } -} From ee635dcc32e1735edd2f80c4b71ed1a2f8f23b6b Mon Sep 17 00:00:00 2001 From: wangw <1594593906@qq.com> Date: Tue, 30 Dec 2025 15:17:52 +0800 Subject: [PATCH 027/133] =?UTF-8?q?=E6=97=A5=E6=9C=9F=E6=A0=BC=E5=BC=8F?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../order/service/impl/PrintMachineLogServiceImpl.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/PrintMachineLogServiceImpl.java b/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/PrintMachineLogServiceImpl.java index f8ea58f83..c13a5395c 100644 --- a/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/PrintMachineLogServiceImpl.java +++ b/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/PrintMachineLogServiceImpl.java @@ -2,6 +2,7 @@ package com.czg.service.order.service.impl; import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.date.DateUtil; +import cn.hutool.core.date.LocalDateTimeUtil; import cn.hutool.core.thread.ThreadUtil; import cn.hutool.core.util.StrUtil; import com.alibaba.fastjson2.JSONObject; @@ -280,7 +281,7 @@ public class PrintMachineLogServiceImpl extends ServiceImpl Date: Tue, 30 Dec 2025 15:21:58 +0800 Subject: [PATCH 028/133] =?UTF-8?q?=E9=87=8D=E6=96=B0=E6=89=93=E5=8D=B0?= =?UTF-8?q?=E9=97=AE=E9=A2=98=20=E5=A4=B1=E8=B4=A5=E6=A0=87=E8=AF=86?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/czg/order/entity/OrderInfo.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cash-common/cash-common-service/src/main/java/com/czg/order/entity/OrderInfo.java b/cash-common/cash-common-service/src/main/java/com/czg/order/entity/OrderInfo.java index 40c89fc74..f8df987f4 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/order/entity/OrderInfo.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/order/entity/OrderInfo.java @@ -379,6 +379,8 @@ public class OrderInfo implements Serializable { } if (!newPrintStatusArray.isEmpty()) { printStatus = newPrintStatusArray.toJSONString(); + } else { + printStatus = ""; } } } From acf04b8534f4f7ef551bc6f2cb7cee59ee7f506f Mon Sep 17 00:00:00 2001 From: wangw <1594593906@qq.com> Date: Wed, 31 Dec 2025 09:24:09 +0800 Subject: [PATCH 029/133] =?UTF-8?q?=E5=BC=80=E5=85=B3=E6=A0=87=E8=AF=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../czg/controller/admin/QuickMenuController.java | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/cash-api/account-server/src/main/java/com/czg/controller/admin/QuickMenuController.java b/cash-api/account-server/src/main/java/com/czg/controller/admin/QuickMenuController.java index dda983a67..44c786733 100644 --- a/cash-api/account-server/src/main/java/com/czg/controller/admin/QuickMenuController.java +++ b/cash-api/account-server/src/main/java/com/czg/controller/admin/QuickMenuController.java @@ -31,16 +31,19 @@ public class QuickMenuController { @SaAdminCheckPermission(parentName = "悬浮窗", value = "quick:list", name = "悬浮窗-列表") @GetMapping - public CzgResult> getQuickList(Integer status) { + public CzgResult> getQuickList(@RequestParam(required = false) Integer status, + @RequestParam(required = false, defaultValue = "0") Integer isEdit) { List list = quickMenuService.list(QueryWrapper.create() .eq(QuickMenu::getShopId, StpKit.USER.getShopId()) .eq(QuickMenu::getStatus, status) .orderBy(QuickMenu::getSort, true)); - if (CollUtil.isEmpty(list)) { - list = quickMenuService.list(QueryWrapper.create() - .eq(QuickMenu::getShopId, 1) - .eq(QuickMenu::getStatus, status) - .orderBy(QuickMenu::getSort, true)); + if (isEdit.equals(0)) { + if (CollUtil.isEmpty(list)) { + list = quickMenuService.list(QueryWrapper.create() + .eq(QuickMenu::getShopId, 1) + .eq(QuickMenu::getStatus, status) + .orderBy(QuickMenu::getSort, true)); + } } return CzgResult.success(list); } From 9a1b5b5cae49baaac28abf36b4f69f92ea29287f Mon Sep 17 00:00:00 2001 From: gong <1157756119@qq.com> Date: Sun, 4 Jan 2026 10:24:35 +0800 Subject: [PATCH 030/133] =?UTF-8?q?=E6=94=AF=E4=BB=98=E5=AE=9D=E5=85=A5?= =?UTF-8?q?=E7=BD=91=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/czg/alipay/AlipayEntryManager.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/AlipayEntryManager.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/AlipayEntryManager.java index d33793279..74fc03406 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/AlipayEntryManager.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/AlipayEntryManager.java @@ -13,12 +13,13 @@ import com.alipay.v3.util.model.AlipayConfig; /** * 支付宝进件管理 * - * ... + * ... * @author yjjie * @date 2025/12/29 14:11 */ public class AlipayEntryManager { + // https://opendocs.alipay.com/solution/0dec7x?pathHash=caec4753 直付通 public static void main(String[] args) throws ApiException { ApiClient defaultClient = Configuration.getDefaultApiClient(); // 初始化alipay参数(全局设置一次) @@ -35,8 +36,8 @@ public class AlipayEntryManager { contactInfo.setContactName("张三"); contactInfo.setContactMobile("18866668888"); data.setContactInfo(contactInfo); - data.setOrderTicket("00ee2d475f374ad097ee0f1ac223fX00"); - data.setAccount("test@alipay.com"); +// data.setOrderTicket("00ee2d475f374ad097ee0f1ac223fX00"); + data.setAccount("1157756119@qq.com"); try { AlipayOpenAgentCreateResponseModel response = api.create(data); System.out.println(response); From 8d9878a316ed26c23306581ab629bd9f9101fc5a Mon Sep 17 00:00:00 2001 From: gong <1157756119@qq.com> Date: Sun, 4 Jan 2026 14:20:24 +0800 Subject: [PATCH 031/133] =?UTF-8?q?=E6=94=AF=E4=BB=98=E5=AE=9D=20=E5=9B=BE?= =?UTF-8?q?=E7=89=87=E4=B8=8A=E4=BC=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/czg/CommonUtil.java | 41 +++ .../java/com/czg/alipay/AlipayClient.java | 31 +++ .../com/czg/alipay/AlipayEntryManager.java | 47 +++- .../dto/AlipayCreateContactInfoDto.java | 34 --- .../com/czg/alipay/dto/AlipayCreateDto.java | 37 --- .../alipay/dto/config/AlipayConfigDto.java | 34 +++ .../alipay/dto/entry/AlipayAddressReqDto.java | 43 +++ .../dto/entry/AlipayBizCardsReqDto.java | 89 +++++++ .../dto/entry/AlipayContactInfoReqDto.java | 50 ++++ .../alipay/dto/entry/AlipayEntryReqDto.java | 249 ++++++++++++++++++ .../dto/entry/AlipayImageUploadReqDto.java | 31 +++ .../dto/entry/AlipayQualificationsReqDto.java | 30 +++ .../dto/entry/AlipaySettleRuleReqDto.java | 29 ++ .../alipay/dto/entry/AlipaySitesReqDto.java | 148 +++++++++++ .../com/czg/wechat/WechatEntryManager.java | 167 ++++++------ 15 files changed, 893 insertions(+), 167 deletions(-) create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/CommonUtil.java create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/AlipayClient.java delete mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/AlipayCreateContactInfoDto.java delete mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/AlipayCreateDto.java create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/config/AlipayConfigDto.java create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/entry/AlipayAddressReqDto.java create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/entry/AlipayBizCardsReqDto.java create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/entry/AlipayContactInfoReqDto.java create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/entry/AlipayEntryReqDto.java create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/entry/AlipayImageUploadReqDto.java create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/entry/AlipayQualificationsReqDto.java create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/entry/AlipaySettleRuleReqDto.java create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/entry/AlipaySitesReqDto.java diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/CommonUtil.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/CommonUtil.java new file mode 100644 index 000000000..19ab6599b --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/CommonUtil.java @@ -0,0 +1,41 @@ +package com.czg; + +import lombok.extern.slf4j.Slf4j; + +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; + +/** + * @author yjjie + * @date 2026/1/4 13:58 + */ +@Slf4j +public class CommonUtil { + /** + * 下载图片 + * @param url 图片地址 + * @return 图片字节数组 + */ + public static byte[] downloadImage(String url) { + HttpClient client = HttpClient.newHttpClient(); + HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(url)) + .GET() + .build(); + + try { + HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofByteArray()); + + if (response.statusCode() != 200) { + throw new RuntimeException("Failed to download image, status code: " + response.statusCode()); + } + + return response.body(); + } catch (Exception e) { + log.error("Failed to download image: {}", e.getMessage()); + return new byte[0]; + } + } +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/AlipayClient.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/AlipayClient.java new file mode 100644 index 000000000..44991f37e --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/AlipayClient.java @@ -0,0 +1,31 @@ +package com.czg.alipay; + +import com.alipay.v3.ApiClient; +import com.alipay.v3.Configuration; +import com.alipay.v3.util.model.AlipayConfig; +import com.czg.alipay.dto.config.AlipayConfigDto; +import lombok.extern.slf4j.Slf4j; + +/** + * @author yjjie + * @date 2026/1/4 13:48 + */ +@Slf4j +public class AlipayClient { + + public static void setupAlipayConfig(AlipayConfigDto configDto) { + try { + ApiClient defaultClient = Configuration.getDefaultApiClient(); + // 初始化alipay参数(全局设置一次) + AlipayConfig alipayConfig = new AlipayConfig(); + alipayConfig.setServerUrl(configDto.getDomain()); + alipayConfig.setAppId(configDto.getAppId()); + alipayConfig.setAlipayPublicKey(configDto.getAlipayPublicKey()); + alipayConfig.setPrivateKey(configDto.getPrivateKey()); + defaultClient.setAlipayConfig(alipayConfig); + } catch (Exception e) { + log.error("初始化alipay参数异常", e); + } + + } +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/AlipayEntryManager.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/AlipayEntryManager.java index 74fc03406..ddce4f17a 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/AlipayEntryManager.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/AlipayEntryManager.java @@ -3,24 +3,61 @@ package com.czg.alipay; import com.alipay.v3.ApiClient; import com.alipay.v3.ApiException; import com.alipay.v3.Configuration; +import com.alipay.v3.api.AlipayMerchantImageApi; import com.alipay.v3.api.AlipayOpenAgentApi; -import com.alipay.v3.model.AlipayOpenAgentCreateDefaultResponse; -import com.alipay.v3.model.AlipayOpenAgentCreateModel; -import com.alipay.v3.model.AlipayOpenAgentCreateResponseModel; -import com.alipay.v3.model.ContactModel; +import com.alipay.v3.model.*; import com.alipay.v3.util.model.AlipayConfig; +import com.czg.CommonUtil; +import com.czg.alipay.dto.config.AlipayConfigDto; +import com.czg.alipay.dto.entry.AlipayImageUploadReqDto; +import lombok.extern.slf4j.Slf4j; + +import java.io.File; /** * 支付宝进件管理 * * ... + * * @author yjjie * @date 2025/12/29 14:11 */ +@Slf4j public class AlipayEntryManager { + public static String uploadImage() { + + byte[] bytes = CommonUtil.downloadImage("https://czg-qr-order.oss-cn-beijing.aliyuncs.com/indexs/shuangbackground.png"); + + File file = new File("/Users/yjjie/Desktop/111222.jpg"); + + AlipayMerchantImageApi api = new AlipayMerchantImageApi(); + + AlipayMerchantImageUploadModel model = new AlipayMerchantImageUploadModel(); + model.setImageType("jpg"); + try { + AlipayMerchantImageUploadResponseModel upload = api.upload(model, file); + return upload.getImageId(); + } catch (ApiException e) { + log.error("支付宝上传图片报错,URL:{},错误信息:{}", "url", e.getMessage(), e); + return ""; + } + } + + public static void main(String[] args) { + AlipayConfigDto configDto = new AlipayConfigDto() + .setDomain("https://openapi.alipay.com") + .setAppId("2021004174605036") + .setPrivateKey("MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQD48HaUoV7OH7os+9L01kHgxzwIhJick4OkFq4aHsntsXEJ J3gedhuEZtV8oHKZ30DPW12IJ4S8NXtpr8OWaqrAPFonf4wVaRY1d0yIAea57kfLEn9oOEEy4FzARgMNDkyxC+/3OUdGbLHpTjfVX3gusXsEhUDy1/WewihAkoNYF37+W3W/uVLzeWoPq0EcUbRv/G/t/p6gL69ltsMAiVFG4Q/Yk24YAN6lYgBPNLXUEwQ1Q+T+1omjfavHgvarKOp33z3JOUH+aGOmDsJ5Y9gyGtJzOCipAd8Zcv+T1ygsEzZYO1/gzcbPnfO1ShqStCHzssuw8FBVx2JdfQKXKMMNAgMBAAECggEAVTrO/pg5Q00titU1Jspsh67u6OOs9H605Ws2dI7yB8VmtAGlaJh7V1t14FN2qSP8poHbhhAxq9aLyGV7C3a9u09udnN+3J28EtYjh7VO732bavWMVXxdJjQWzWWrCb9JlpxFrlkYBA6W4w/6ob0sAqCVQ7jzwbEa0R4cde8ztOa5nysKSfr4YTSs0gqvoiC6fmg8eiRJraEQBoYz9VkKFtOhhh/4w5FhVcYQ2gQvZ3kK3QVuD1eJIQKlCtz8qaox9lXKDiZT4SCmnKshdUL0u5TYIcYeBjZmhJz0Q50KHcpZrCs5y7I0+vRBH3hU+TKSQt7ureymwhbwWMHScLV2gQKBgQD+58SHXhr5M8NGagAmTdsgmCnNv2kOYMd4STyPMY10SVwCv1Bk808ZuP+7e558J1b5/OuDLI5dLq6xrZ/1wLv1G++XqxI00hlFuWS5mUGJVcXotT1mw20rVeUILc7Qe3mLvbMGgfyKf4A7Qa5SSZ4bDeDTJYaFxyiQ281hMzDuPQKBgQD6AiL/Na2/uPH4CG6juwpjYvYVUcjK+7gbRwf3wWsWMpk90Z4ju2iUiP5c1J/oK9P+1T3PIr6M4Xjza8JJj+r9KC/PVB0gBv6vVM96cDpKUEy/UMpcn/T81vqj/Z+WEOODU8Ms6NiTTm+u9ldvpCjbu0u8M+9c0JeIyadJvSTFEQKBgQCsxmFyM3nq8YfpgU2qqNjfBeRH3faSVUy+nj1a/YZYjKS+A/i1BCnYUImeBVNN6chNV342ggvY4xxruDiU9Vcw8wd58O09Oi8BEIFSP6upL6cebUI6Fjo3xlegLJRiwV6INkNTJOYM5hD/mSxUACwXQFfkJipBINXBIgraWD1RLQKBgQCj49axWq0F6+WjZVOyPaD3uh37p9trRUxRhWTxw3fB23WdktaKMgbCqHOmwzP4bRLSEVQtf2dOz1gMqu14b8HqJvgAf/F/11YJ9hz09LEhmjZVjE68HZfqT7uK2W5OX8/lfXmK7TFcj6SjG5YB96lZMhTZ0WnufEd6QkdKDZYXIQKBgQD9GDTcIMbFwbEaKHnfZaTD3f876EGRgsgrCxwdEk7LBCRPwWo7yI929M4psIlpNwNeiyjBkBunWIVkpznp6qPtJqagIPUYesU4f5v6/okq5wcpaNKSkWbIvWVLaLGOiA1aeGJtbpMpyClbSr52puHpRRdvAiIEQ74yYh0JX8q96g==") + .setAlipayPublicKey("MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAiQkrz+emAuS1mB3KKDOMmAZRd/BlPbh7fAIHAqAj1+QCZNcV3o2BTLIIqnuKpSlFXDG3uDzp2VsBxcizXuBbFyPGylnD9CgCj5abyh3+FIHPAZ2IM3TtpqImZ0TSPGXrMli4Nir7MvZktgccCqQKCC4o6iaDGz+UwWwJUIPna8fm2tiTZ+KH150CZbKVj4ZGNpBh5XSV/1dRgyQIV9D/EwSbkZ0n6VgKQLJBi0C2UE3QB17aL1Ir6+gDXIDbknN8O7GUD3aMGdThYdSRUb5wp9CZ5qfV7vCS/CgaRo38nhH3NOzkTL+7v0m1ZDHPmqEkn9VzZN6sCQdL7PoAOjHOCwIDAQAB"); + AlipayClient.setupAlipayConfig(configDto); + + String image = uploadImage(); + System.out.println("image id = " + image); + } + // https://opendocs.alipay.com/solution/0dec7x?pathHash=caec4753 直付通 - public static void main(String[] args) throws ApiException { + public static void test() throws ApiException { ApiClient defaultClient = Configuration.getDefaultApiClient(); // 初始化alipay参数(全局设置一次) AlipayConfig alipayConfig = new AlipayConfig(); diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/AlipayCreateContactInfoDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/AlipayCreateContactInfoDto.java deleted file mode 100644 index 313506dcd..000000000 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/AlipayCreateContactInfoDto.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.czg.alipay.dto; - -import com.alibaba.fastjson2.annotation.JSONField; -import lombok.Data; - -/** - * 联系人信息 - * @author yjjie - * @date 2025/12/29 14:21 - */ -@Data -public class AlipayCreateContactInfoDto { - - /** - * 【必填】 - * 联系人名称 - */ - @JSONField(name = "contact_name") - private String contactName; - - /** - * 【必填】 - * 联系人手机号 - */ - @JSONField(name = "contact_mobile") - private String contactMobile; - - /** - * 【选填】 - * 联系人邮箱 - */ - @JSONField(name = "contact_email") - private String contactEmail; -} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/AlipayCreateDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/AlipayCreateDto.java deleted file mode 100644 index a9f9edd76..000000000 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/AlipayCreateDto.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.czg.alipay.dto; - -import com.alibaba.fastjson2.annotation.JSONField; -import lombok.Data; - -/** - * 开启代商户签约、创建应用事务 - * 在 ISV 代商户进行应用创建、产品签约时,用于开启一个操作事务,必须是第一个调用的接口。 - * 场景1:ISV 代商户进行应用创建、产品签约,最后提交事务后需要商户确认才能完成流程; - * 场景2:服务市场订购及授权,使用订单授权凭证order_ticket开启预授权模式,该模式下提交事务后无需商户确认。 - * @author yjjie - * @date 2025/12/29 14:19 - */ -@Data -public class AlipayCreateDto { - - /** - * 【必填】 - * isv代操作的商户账号,可以是支付宝账号,也可以是pid(2088开头) - */ - @JSONField(name = "account") - private String account; - - /** - * 【必填】 - * 商户联系人信息,包含联系人名称、手机、邮箱信息。联系人信息将用于接受签约后的重要通知,如确认协议、到期提醒等。 - */ - @JSONField(name = "contact_info") - private AlipayCreateContactInfoDto contactInfo; - - /** - * 【选填】 - * 订单授权凭证。若传入本参数,则对应事务提交后进入预授权模式。 - */ - @JSONField(name = "order_ticket") - private String orderTicket; -} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/config/AlipayConfigDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/config/AlipayConfigDto.java new file mode 100644 index 000000000..a39bd5478 --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/config/AlipayConfigDto.java @@ -0,0 +1,34 @@ +package com.czg.alipay.dto.config; + +import lombok.Data; +import lombok.experimental.Accessors; + +/** + * @author yjjie + * @date 2026/1/4 13:49 + */ +@Data +@Accessors(chain = true) +public class AlipayConfigDto { + + /** + * 支付宝 AppId + */ + private String appId; + + /** + * 商户私钥 + */ + private String privateKey; + + /** + * 支付宝公钥 + */ + private String alipayPublicKey; + + /** + * 支付宝支付域名 + * + */ + private String domain; +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/entry/AlipayAddressReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/entry/AlipayAddressReqDto.java new file mode 100644 index 000000000..349d690eb --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/entry/AlipayAddressReqDto.java @@ -0,0 +1,43 @@ +package com.czg.alipay.dto.entry; + +import com.alibaba.fastjson2.annotation.JSONField; +import lombok.Data; + +/** + * 经营地址 + * @author yjjie + * @date 2026/1/4 11:20 + */ +@Data +public class AlipayAddressReqDto { + + /** + * 【必填】 + * 城市编码 + * 蚂蚁店铺请按照蚂蚁店铺地区码 表格中填写。 + * 直付通商户请按照直付通商户地区码 表格中内容填写。 + */ + @JSONField(name = "city_code") + private String cityCode; + + /** + * 【必填】 + * 区县编码 + */ + @JSONField(name = "district_code") + private String districtCode; + + /** + * 【必填】 + * 详细地址 + */ + @JSONField(name = "address") + private String address; + + /** + * 【必填】 + * 省份编码 + */ + @JSONField(name = "province_code") + private String provinceCode; +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/entry/AlipayBizCardsReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/entry/AlipayBizCardsReqDto.java new file mode 100644 index 000000000..319fbdb2a --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/entry/AlipayBizCardsReqDto.java @@ -0,0 +1,89 @@ +package com.czg.alipay.dto.entry; + +import com.alibaba.fastjson2.annotation.JSONField; +import lombok.Data; + +/** + * 结算银行卡信息 + * @author yjjie + * @date 2026/1/4 11:14 + */ +@Data +public class AlipayBizCardsReqDto { + + /** + * 【必填】 + * 开户支行名 + */ + @JSONField(name = "account_branch_name") + private String accountBranchName; + + /** + * 【必填】 + * 卡户名 + */ + @JSONField(name = "account_holder_name") + private String accountHolderName; + + /** + * 【必填】 + * 开户行所在地-省 + */ + @JSONField(name = "account_inst_province") + private String accountInstProvince; + + /** + * 【必填】 + * 开户行所在地-市 + */ + @JSONField(name = "account_inst_city") + private String accountInstCity; + + /** + * 【必填】 + * 开户行简称缩写 + */ + @JSONField(name = "account_inst_id") + private String accountInstId; + + /** + * 【必填】 + * 银行名称 + */ + @JSONField(name = "account_inst_name") + private String accountInstName; + + /** + * 【必填】 + * 银行卡号 + */ + @JSONField(name = "account_no") + private String accountNo; + + /** + * 【必填】 + * 银行卡类型 + * 【枚举值】 + * 借记卡: DC + * 信用卡: CC + */ + @JSONField(name = "account_type") + private String accountType; + + /** + * 【必填】 + * 账号使用类型 + * 【枚举值】 + * 对公: 01 + * 对私: 02 + */ + @JSONField(name = "usage_type") + private String usageType; + + /** + * 【选填】 + * 联行号 + */ + @JSONField(name = "bank_code") + private String bankCode; +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/entry/AlipayContactInfoReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/entry/AlipayContactInfoReqDto.java new file mode 100644 index 000000000..c29dc6ff0 --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/entry/AlipayContactInfoReqDto.java @@ -0,0 +1,50 @@ +package com.czg.alipay.dto.entry; + +import com.alibaba.fastjson2.annotation.JSONField; +import lombok.Data; + +/** + * 商户联系人信息 + * @author yjjie + * @date 2026/1/4 11:02 + */ +@Data +public class AlipayContactInfoReqDto { + /** + * 【必填】 + * 联系人名字 + */ + @JSONField(name = "name") + private String name; + + /** + * 【必填】 + * email | mobile | phone 三选一 + * 电子邮箱 + */ + @JSONField(name = "email") + private String email; + + /** + * 【必填】 + * email | mobile | phone 三选一 + * 手机号码 + */ + @JSONField(name = "mobile") + private String mobile; + + /** + * 【必填】 + * email | mobile | phone 三选一 + * 电话 + */ + @JSONField(name = "phone") + private String phone; + + /** + * 【必填】 + * 身份证号 + */ + @JSONField(name = "id_card_no") + private String idCardNo; +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/entry/AlipayEntryReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/entry/AlipayEntryReqDto.java new file mode 100644 index 000000000..46fded03d --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/entry/AlipayEntryReqDto.java @@ -0,0 +1,249 @@ +package com.czg.alipay.dto.entry; + +import com.alibaba.fastjson2.annotation.JSONField; +import lombok.Data; + +import java.util.List; + +/** + * 平台商提交二级商户资料进行进件,完成二级商户入驻 + * ... + * @author yjjie + * @date 2025/12/29 14:19 + */ +@Data +public class AlipayEntryReqDto { + + /** + * 【必填】 + * 商户编号,由一级商户定义,保证在一级商户下唯一即可 + */ + @JSONField(name = "external_id") + private String externalId; + + /** + * 【必填】 + * 商户别名。支付宝收银台及账单中的商户名称会展示此处设置的别名。如果涉及支付宝APP内的支付,支付结果页也会展示该别名;如果涉及线下当面付场景,请填写线下店铺名称 + */ + @JSONField(name = "alias_name") + private String aliasName; + + /** + * 【必填】 + * 商户联系人信息。在本业务中,ContactInfo对象中联系人姓名、手机号必填,其他选填 + */ + @JSONField(name = "contact_infos") + private AlipayContactInfoReqDto contactInfo; + + /** + * 【必填】 + * 默认结算规则。当调用收单接口,settle_info中设置默认结算规则(defaultSettle)时,交易资金将结算至此处设置的默认结算目标账户中。其详细描述及收单接口传参示例参考功能包文档 + */ + @JSONField(name = "default_settle_rule") + private AlipaySettleRuleReqDto defaultSettleRule; + + /** + * 【必填】 + * 商户使用服务 + * 可选值有:当面付、jsapi支付、app支付、wap支付、电脑支付、预授权支付、商户代扣、小程序支付、订单码支付。其值会影响其他字段必填性,详见其他字段描述 + * 当面付: 当面付 + * jsapi支付: jsapi支付 + * app支付: app支付 + * wap支付: wap支付 + * 电脑支付: 电脑支付 + * 预授权支付: 预授权支付 + * 商户代扣: 商户代扣 + * 小程序支付: 小程序支付 + * 订单码支付: 订单码支付 + */ + @JSONField(name = "service") + private List service; + + /** + * 【必填】 + * 商户证件编号 + * 按商户类型merchant_type的说明提供对应的证件编号 + */ + @JSONField(name = "cert_no") + private String certNo; + + /** + * 【必填】 + * 商户类别码 mcc + * ... + * 可查看 进件MCC与资质要求 202212.xlsx,特殊行业要按照MCC说明中的资质一栏上传辅助资质,辅助资质要在 qualifications 中上传,会有人工审核。 + * 【示例值】B0007 + */ + @JSONField(name = "mcc") + private String mcc; + + /** + * 【选填】 + * 结算支付宝账号 + * 结算账号使用支付宝账号时必填,本字段指定交易资金结算的具体支付宝账号,与binding_alipay_logon_id同主体的支付宝账号即可 + */ + @JSONField(name = "alipay_logon_id") + private String alipayLogonId; + + /** + * 【选填】 + * 法人名称 + * 非个人商户类型必填 + */ + @JSONField(name = "legal_name") + private String legalName; + + /** + * 【选填】 + * 法人证件编号 + * 法人证件编号,非个人商户类型必填 + */ + @JSONField(name = "legal_cert_no") + private String legalCertNo; + + /** + * 【选填】 + * 商户证件图 + * 目前只有当商户类型是个人商户且使用当面付服务时才需填写 + */ + @JSONField(name = "cert_image_back") + private String certImageBack; + + /** + * 【选填】 + * 商户证件图片 + * 本业务接口中,如果是特殊行业必填;使用当面付服务时,非个人必填,个人结算到卡时必填。其值为使用ant.merchant.expand.indirect.image.upload上传图片得到的一串oss key。 + */ + @JSONField(name = "cert_image") + private String certImage; + + /** + * 【选填】 + * 进件的二级商户名称 + * 一般情况下要与证件的名称相同。个体工商户类型可以放宽到法人名称 + */ + @JSONField(name = "name") + private String name; + + /** + * 【选填】 + * 法人证件类型 + * 默认可不填,认为legal_cert_no是大陆身份证。类型包括:100 大陆身份证;105 港澳居民往来内地通行证;106 台湾同胞往来大陆通行证;108 外国人居留证 + * 【枚举值】 + * 大陆身份证: 100 + * 港澳居民往来内地通行证: 105 + * 台湾同胞往来大陆通行证: 106 + * 外国人居留证: 108 + */ + @JSONField(name = "legal_cert_type") + private String legalCertType; + + /** + * 【选填】 + * 商户类型 + * 01:企业;cert_type填写201(营业执照);cert_no填写营业执照号; + * 02:事业单位:cert_type填写218(事业单位法人证书);cert_no填写事业单位法人证书编号; + * 03:民办非企业组织:cert_type填写204(民办非企业登记证书);cert_no填写民办非企业登记证书编号; + * 04:社会团体:cert_type填写206(社会团体法人登记证书);cert_no填写社会团体法人登记证书编号; + * 05:党政及国家机关:cert_type填写219(党政机关批准设立文件/行政执法主体资格证);cert_no填写党政机关批准设立文件/行政执法主体资格证编号; + * 06:个人商户:cert_type填写100(个人身份证);cert_no填写个人身份证号码; + * 07:个体工商户:cert_type填写201(营业执照);cert_no填写营业执照编号; + */ + @JSONField(name = "merchant_type") + private String merchantType; + + /** + * 【选填】 + * 商户证件类型 + * 按商户类型merchant_type的说明提供对应的证件类型。 + * 营业执照: 201 + * 事业单位法人证书: 218 + * 民办非企业登记证书: 204 + * 社会团体法人登记证书: 206 + * 党政机关批准设立文件/行政执法主体资格证: 219 + * 个人身份证: 100 + */ + @JSONField(name = "cert_type") + private String certType; + + /** + * 【选填】 + * 证件名称 + * 目前只有个体工商户商户类型要求填入本字段,填写值为个体工商户营业执照上的名称 + */ + @JSONField(name = "cert_name") + private String certName; + + /** + * 【选填】 + * 结算银行卡信息 + * 结算银行卡信息,结算账号使用银行卡时必填。本业务当前只允许传入一张结算卡。个人类型商户不允许结算到银行卡 + * 【必选条件】结算银行卡信息,结算账号使用银行卡时必填。本业务当前只允许传入一张结算卡。个人类型商户不允许结算到银行卡 + */ + @JSONField(name = "biz_cards") + private AlipayBizCardsReqDto bizCards; + + /** + * 【选填】 + * 经营地址 + * 使用当面付服务时必填。地址对象中省、市、区、地址必填,其余选填 + */ + @JSONField(name = "business_address") + private AlipayAddressReqDto businessAddress; + + /** + * 【选填】 + * 门头照 + * 使用当面付服务时必填。其值为使用ant.merchant.expand.indirect.image.upload上传图片得到的一串oss key + */ + @JSONField(name = "out_door_images") + private String outDoorImages; + + /** + * 【选填】 + * 内景照 + * 使用当面付服务时必填。其值为使用ant.merchant.expand.indirect.image.upload上传图片得到的一串oss key + */ + @JSONField(name = "in_door_images") + private String inDoorImages; + + /** + * 【选填】 + * 授权函 + * 《说明函》模板参考 + * 当商户名与结算卡户名不一致。《说明函》模板参考。涉及外籍法人(这种情况上传任意能证明身份的图片)时必填, + * 其值为使用ant.merchant.expand.indirect.image.upload上传图片得到的一串oss key。(商户类型为个体工商户时,本字段仅需上传营业执照非授权函) + */ + @JSONField(name = "license_auth_letter_image") + private String licenseAuthLetterImage; + + /** + * 【选填】 + * 商户站点信息 + * 包括网站、app、小程序。商户使用服务包含电脑支付、wap支付时,必须填充一个类型为01(网站)的SiteInfo对象,site_type/site_url/site_name必填; + * 当包含app支付时,必须至少填充类型为02(APP)或06(支付宝小程序)中一种类型的SiteInfo对象,site_type/site_name必填;当包含jsapi支付时,必须填充一个类型为06(支付宝小程序)的SiteInfo对象; + */ + @JSONField(name = "sites") + private AlipaySitesReqDto sites; + + /** + * 【选填】 + * 商户行业资质图片 + * 当商户的经营类目选择了特殊行业时该字段必填,需要特殊行业资质文件。每项行业资质信息中,industry_qualification_type和industry_qualification_image均必填。 + */ + @JSONField(name = "qualifications") + private List qualifications; + + /** + * 【选填】 + * 交易场景 + * 【枚举值】 + * 小程序支付场景: TINY_APP + * H5场景: WAP + * 线下当面付场景: OFFLINE + * APP支付场景: APP + * 网站支付场景: PC + */ + @JSONField(name = "trade_scene") + private List tradeScene; +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/entry/AlipayImageUploadReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/entry/AlipayImageUploadReqDto.java new file mode 100644 index 000000000..a2abcc34e --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/entry/AlipayImageUploadReqDto.java @@ -0,0 +1,31 @@ +package com.czg.alipay.dto.entry; + +import com.alibaba.fastjson2.annotation.JSONField; +import lombok.Data; +import lombok.experimental.Accessors; + +/** + * 图片上传 + * @author yjjie + * @date 2026/1/4 13:46 + */ +@Data +@Accessors(chain = true) +public class AlipayImageUploadReqDto { + + /** + * 【必填】 + * 图片格式 + * 支持格式:bmp、jpg、jpeg、png、gif. + */ + @JSONField(name = "image_type") + private String imageType; + + /** + * 【必填】 + * 图片二进制字节流 + * 最大为10M + */ + @JSONField(name = "image_content") + private byte[] imageContent; +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/entry/AlipayQualificationsReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/entry/AlipayQualificationsReqDto.java new file mode 100644 index 000000000..6e4190027 --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/entry/AlipayQualificationsReqDto.java @@ -0,0 +1,30 @@ +package com.czg.alipay.dto.entry; + +import com.alibaba.fastjson2.annotation.JSONField; +import lombok.Data; + +/** + * 商户行业资质 + * @author yjjie + * @date 2026/1/4 11:40 + */ +@Data +public class AlipayQualificationsReqDto { + + /** + * 【必填】 + * 商户行业资质类型 具体选值参见 文档 + * 【枚举值】 + * 金融许可证: 323 + * 【示例值】323 + */ + @JSONField(name = "industry_qualification_type") + private String industryQualificationType; + + /** + * 【必填】 + * 商户行业资质图片 + */ + @JSONField(name = "industry_qualification_image") + private String industryQualificationImage; +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/entry/AlipaySettleRuleReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/entry/AlipaySettleRuleReqDto.java new file mode 100644 index 000000000..75881a854 --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/entry/AlipaySettleRuleReqDto.java @@ -0,0 +1,29 @@ +package com.czg.alipay.dto.entry; + +import com.alibaba.fastjson2.annotation.JSONField; +import lombok.Data; + +/** + * 结算规则 + * @author yjjie + * @date 2026/1/4 11:06 + */ +@Data +public class AlipaySettleRuleReqDto { + + /** + * 【必填】 + * 默认结算类型 + * 可选值有bankCard/alipayAccount。bankCard表示结算到银行卡;alipayAccount表示结算到支付宝账号 + */ + @JSONField(name = "default_settle_type") + private String defaultSettleType; + + /** + * 【必填】 + * 默认结算目标 + * 当默认结算类型为bankCard时填写银行卡卡号,其值需在进件填写的结算银行卡范围内;当默认结算类型为alipayAccount时填写支付宝账号登录号,其值需在进件填写的结算支付宝账号范围内。 + */ + @JSONField(name = "default_settle_target") + private String defaultSettleTarget; +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/entry/AlipaySitesReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/entry/AlipaySitesReqDto.java new file mode 100644 index 000000000..0e88ad25d --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/entry/AlipaySitesReqDto.java @@ -0,0 +1,148 @@ +package com.czg.alipay.dto.entry; + +import com.alibaba.fastjson2.annotation.JSONField; +import lombok.Data; + +/** + * @author yjjie + * @date 2026/1/4 11:31 + */ +@Data +public class AlipaySitesReqDto { + + /** + * 【必填】 + * 网站类型 + * 【枚举值】 + * 网站: 01 + * APP: 02 + * 服务窗: 03 + * 公众号: 04 + * 其他: 05 + * 支付宝小程序: 06 + * 手机网站/H5: 07 + */ + @JSONField(name = "site_type") + private String siteType; + + /** + * 【选填】 + * 站点地址 + * 当传入service,且包含jsapi支付时,sites的site_type=06, site_url必填 + */ + @JSONField(name = "site_url") + private String siteUrl; + + /** + * 【选填】 + * 站点名称 + * 当传入service,且包含jsapi支付、小程序支付时,sites的site_type=06, site_name必填 + */ + @JSONField(name = "site_name") + private String siteName; + + /** + * 【选填】 + * 截图照片 + * 当传入交易场景trade_scene,且当传入trade_scene=WAP、trade_scene=APP、trade_scene=PC时该参数必传 + */ + @JSONField(name = "screenshot_image") + private String screenshotImage; + + /** + * 【选填】 + * 小程序appId + * 当传入service,且包含jsapi支付时,sites的site_type=06, tiny_app_id必填。 + */ + @JSONField(name = "tiny_app_id") + private String tinyAppId; + + /** + * 【选填】 + * 测试账号 + */ + @JSONField(name = "account") + private String account; + + /** + * 【选填】 + * 测试账号密码 + */ + @JSONField(name = "password") + private String password; + + /** + * 【选填】 + * 上架状态 + * 【枚举值】 + * 已上线: ONLINE + * 已上线-内部: ONLINE_INNER + * 未上线: OFFLINE + */ + @JSONField(name = "status") + private String status; + + /** + * 【选填】 + * 授权函照片 + */ + @JSONField(name = "auth_letter_image") + private String authLetterImage; + + /** + * 【选填】 + * 备注说明 + */ + @JSONField(name = "remark") + private String remark; + + /** + * 【选填】 + * 备注说明图片 + */ + @JSONField(name = "remark_image") + private String remarkImage; + + /** + * 【选填】 + * 网站域名 + */ + @JSONField(name = "site_domain") + private String siteDomain; + + /** + * 【选填】 + * ICP备案主体信息服务名称 + */ + @JSONField(name = "icp_service_name") + private String icpServiceName; + + /** + * 【选填】 + * ICP备案/许可证号 + */ + @JSONField(name = "icp_no") + private String icpNo; + + /** + * 【选填】 + * ICP备案主体主办单位名称 + */ + @JSONField(name = "icp_org_name") + private String icpOrgName; + + /** + * 【选填】 + * 下载地址 + */ + @JSONField(name = "download") + private String download; + + /** + * 【选填】 + * 应用市场 + * 【示例值】豌豆荚 + */ + @JSONField(name = "market") + private String market; +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatEntryManager.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatEntryManager.java index 676da7552..43dc5f8f3 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatEntryManager.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatEntryManager.java @@ -2,6 +2,7 @@ package com.czg.wechat; import com.alibaba.fastjson2.JSONObject; import com.alibaba.fastjson2.JSONWriter; +import com.czg.CommonUtil; import com.czg.wechat.dto.config.WechatPayConfigDto; import com.czg.wechat.dto.req.entry.*; import com.czg.wechat.dto.req.entry.business.WechatEntryBusinessReqDto; @@ -67,7 +68,7 @@ public class WechatEntryManager { try { // 获取图片字节数组 - byte[] bytes = downloadImage(url); + byte[] bytes = CommonUtil.downloadImage(url); if (bytes.length == 0) { log.error("下载的图片内容为空,URL:{}", url); return ""; @@ -98,22 +99,6 @@ public class WechatEntryManager { return ""; } - public static byte[] downloadImage(String url) throws Exception { - HttpClient client = HttpClient.newHttpClient(); - HttpRequest request = HttpRequest.newBuilder() - .uri(URI.create(url)) - .GET() - .build(); - - HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofByteArray()); - - if (response.statusCode() != 200) { - throw new RuntimeException("Failed to download image, status code: " + response.statusCode()); - } - - return response.body(); - } - /** * 从URL中提取文件名 * @@ -187,82 +172,82 @@ public class WechatEntryManager { .setPublicKeyId("PUB_KEY_ID_0116437794082025111000382377001000") .setDomain("https://api.mch.weixin.qq.com"); - queryBankList(dto, 0, 10); +// queryBankList(dto, 0, 10); -// String string = uploadImage(dto, "https://czg-qr-order.oss-cn-beijing.aliyuncs.com/indexs/shuangbackground.png"); -// log.info("图片上传成功:{}", string); + String string = uploadImage(dto, "https://czg-qr-order.oss-cn-beijing.aliyuncs.com/indexs/shuangbackground.png"); + log.info("图片上传成功:{}", string); - Config config = WechatConfig.getRsaConfig(dto); - PrivacyEncryptor encryptor = config.createEncryptor(); - - WechatEntryReqDto reqDto = new WechatEntryReqDto() - .setBusinessCode("MER_20231025110010000010000000000001"); - - WechatEntryContactReqDto contactInfo = new WechatEntryContactReqDto() - .setContactType("LEGAL") - .setContactName(encryptor.encrypt("张三")) - .setContactIdType("IDCARD") - .setContactIdNumber(encryptor.encrypt("110101199001011234")) - .setContactIdDocCopy("https://czg-qr-order.oss-cn-beijing.aliyuncs.com/indexs/shuangbackground.png") - .setContactIdDocCopyBack("https://czg-qr-order.oss-cn-beijing.aliyuncs.com/indexs/shuangbackground.png") - .setContactPeriodBegin("2023-10-25") - .setContactPeriodEnd("2024-10-25") - .setMobilePhone(encryptor.encrypt("13888888888")) - .setContactEmail(encryptor.encrypt("123456@qq.com")); - - reqDto.setContactInfo(contactInfo); - - WechatEntrySubjectReqDto subjectInfo = new WechatEntrySubjectReqDto() - .setSubjectType("SUBJECT_TYPE_INDIVIDUAL"); - - WechatEntryLicenseReqDto licenseInfo = new WechatEntryLicenseReqDto() - .setLicenseCopy("https://czg-qr-order.oss-cn-beijing.aliyuncs.com/indexs/shuangbackground.png") - .setLicenseNumber("110101199001011234") - .setMerchantName("张三商行") - .setLegalPerson(encryptor.encrypt("张三")) - .setLicenseAddress("北京") - .setPeriodBegin("2023-10-25") - .setPeriodEnd("2024-10-25"); - subjectInfo.setBusinessLicenseInfo(licenseInfo); - - WechatEntryIdentityReqDto identityInfo = new WechatEntryIdentityReqDto() - .setIdHolderType("LEGAL"); - subjectInfo.setIdentityInfo(identityInfo); - - reqDto.setSubjectInfo(subjectInfo); - - WechatEntryBusinessReqDto businessInfo = new WechatEntryBusinessReqDto() - .setMerchantShortname("张三商行") - .setServicePhone("13888888888"); - WechatEntrySalesInfoReqDto salesInfo = new WechatEntrySalesInfoReqDto() - .setSalesScenesType(List.of("SALES_SCENES_STORE")); - WechatEntryStoreInfoReqDto storeInfo = new WechatEntryStoreInfoReqDto() - .setBizStoreName("张三商行") - .setBizAddressCode("110101") - .setBizStoreAddress("北京") - .setStoreEntrancePic(List.of("https://czg-qr-order.oss-cn-beijing.aliyuncs.com/indexs/shuangbackground.png")) - .setIndoorPic(List.of("https://czg-qr-order.oss-cn-beijing.aliyuncs.com/indexs/shuangbackground.png")); - salesInfo.setBizStoreInfo(storeInfo); - businessInfo.setSalesInfo(salesInfo); - - reqDto.setBusinessInfo(businessInfo); - - WechatEntrySettleReqDto settleInfo = new WechatEntrySettleReqDto() - .setSettlementId("719") - .setQualificationType("IDCARD") - .setQualifications(List.of("110101199001011234")) - .setActivitiesId("20191030111cff5b5e"); - - reqDto.setSettlementInfo(settleInfo); - - WechatEntryBankAccountReqDto bankAccountInfo = new WechatEntryBankAccountReqDto() - .setBankAccountType("BANK_ACCOUNT_TYPE_CORPORATE") - .setAccountBank("ICBC") - .setBankName("中国工商银行") - .setAccountName(encryptor.encrypt("张三")) - .setAccountNumber(encryptor.encrypt("110101199001011234")); - - reqDto.setBankAccountInfo(bankAccountInfo); +// Config config = WechatConfig.getRsaConfig(dto); +// PrivacyEncryptor encryptor = config.createEncryptor(); +// +// WechatEntryReqDto reqDto = new WechatEntryReqDto() +// .setBusinessCode("MER_20231025110010000010000000000001"); +// +// WechatEntryContactReqDto contactInfo = new WechatEntryContactReqDto() +// .setContactType("LEGAL") +// .setContactName(encryptor.encrypt("张三")) +// .setContactIdType("IDCARD") +// .setContactIdNumber(encryptor.encrypt("110101199001011234")) +// .setContactIdDocCopy("https://czg-qr-order.oss-cn-beijing.aliyuncs.com/indexs/shuangbackground.png") +// .setContactIdDocCopyBack("https://czg-qr-order.oss-cn-beijing.aliyuncs.com/indexs/shuangbackground.png") +// .setContactPeriodBegin("2023-10-25") +// .setContactPeriodEnd("2024-10-25") +// .setMobilePhone(encryptor.encrypt("13888888888")) +// .setContactEmail(encryptor.encrypt("123456@qq.com")); +// +// reqDto.setContactInfo(contactInfo); +// +// WechatEntrySubjectReqDto subjectInfo = new WechatEntrySubjectReqDto() +// .setSubjectType("SUBJECT_TYPE_INDIVIDUAL"); +// +// WechatEntryLicenseReqDto licenseInfo = new WechatEntryLicenseReqDto() +// .setLicenseCopy("https://czg-qr-order.oss-cn-beijing.aliyuncs.com/indexs/shuangbackground.png") +// .setLicenseNumber("110101199001011234") +// .setMerchantName("张三商行") +// .setLegalPerson(encryptor.encrypt("张三")) +// .setLicenseAddress("北京") +// .setPeriodBegin("2023-10-25") +// .setPeriodEnd("2024-10-25"); +// subjectInfo.setBusinessLicenseInfo(licenseInfo); +// +// WechatEntryIdentityReqDto identityInfo = new WechatEntryIdentityReqDto() +// .setIdHolderType("LEGAL"); +// subjectInfo.setIdentityInfo(identityInfo); +// +// reqDto.setSubjectInfo(subjectInfo); +// +// WechatEntryBusinessReqDto businessInfo = new WechatEntryBusinessReqDto() +// .setMerchantShortname("张三商行") +// .setServicePhone("13888888888"); +// WechatEntrySalesInfoReqDto salesInfo = new WechatEntrySalesInfoReqDto() +// .setSalesScenesType(List.of("SALES_SCENES_STORE")); +// WechatEntryStoreInfoReqDto storeInfo = new WechatEntryStoreInfoReqDto() +// .setBizStoreName("张三商行") +// .setBizAddressCode("110101") +// .setBizStoreAddress("北京") +// .setStoreEntrancePic(List.of("https://czg-qr-order.oss-cn-beijing.aliyuncs.com/indexs/shuangbackground.png")) +// .setIndoorPic(List.of("https://czg-qr-order.oss-cn-beijing.aliyuncs.com/indexs/shuangbackground.png")); +// salesInfo.setBizStoreInfo(storeInfo); +// businessInfo.setSalesInfo(salesInfo); +// +// reqDto.setBusinessInfo(businessInfo); +// +// WechatEntrySettleReqDto settleInfo = new WechatEntrySettleReqDto() +// .setSettlementId("719") +// .setQualificationType("IDCARD") +// .setQualifications(List.of("110101199001011234")) +// .setActivitiesId("20191030111cff5b5e"); +// +// reqDto.setSettlementInfo(settleInfo); +// +// WechatEntryBankAccountReqDto bankAccountInfo = new WechatEntryBankAccountReqDto() +// .setBankAccountType("BANK_ACCOUNT_TYPE_CORPORATE") +// .setAccountBank("ICBC") +// .setBankName("中国工商银行") +// .setAccountName(encryptor.encrypt("张三")) +// .setAccountNumber(encryptor.encrypt("110101199001011234")); +// +// reqDto.setBankAccountInfo(bankAccountInfo); // entryMerchant(dto, reqDto); } From 0b02f66fb58dda335db14ed4a4474402a2951707 Mon Sep 17 00:00:00 2001 From: wangw <1594593906@qq.com> Date: Mon, 5 Jan 2026 09:37:45 +0800 Subject: [PATCH 032/133] =?UTF-8?q?shop=5Fuser=E6=9F=A5=E8=AF=A2=E5=A4=9A?= =?UTF-8?q?=E4=B8=AA=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/resources/mapper/ShopUserMapper.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cash-service/account-service/src/main/resources/mapper/ShopUserMapper.xml b/cash-service/account-service/src/main/resources/mapper/ShopUserMapper.xml index e7f917f8e..448d425ae 100644 --- a/cash-service/account-service/src/main/resources/mapper/ShopUserMapper.xml +++ b/cash-service/account-service/src/main/resources/mapper/ShopUserMapper.xml @@ -98,7 +98,7 @@ AND a.amount >= #{amount} - + group by a.id ORDER BY a.create_time DESC + select merchant.*,shop.shop_name as shopName + from tb_shop_direct_merchant merchant + left join tb_shop_info shop on merchant.shop_id = shop.id + where + + and merchant.user_type = #{queryParam.userType} + + + and shop.shop_name like concat('%',#{queryParam.shopName},'%') + + + and (merchant.wechat_status = #{queryParam.status} or merchant.alipay_status = #{queryParam.status}) + + + and merchant.alipay_account like concat('%',#{queryParam.alipayAccount},'%') + + From 4e686c9c8e3332faa6413724fa082e854577d6db Mon Sep 17 00:00:00 2001 From: gong <1157756119@qq.com> Date: Fri, 9 Jan 2026 15:53:24 +0800 Subject: [PATCH 058/133] =?UTF-8?q?=E5=BE=AE=E4=BF=A1=E8=BF=9B=E4=BB=B6=20?= =?UTF-8?q?bug=20=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/czg/EntryManager.java | 14 +-- .../src/main/java/com/czg/PayCst.java | 5 + .../src/main/java/com/czg/PayManager.java | 47 ++++++++ .../java/com/czg/dto/req/PayParamsDto.java | 104 ++++++++++++++++++ .../third/alipay/AlipayIsvEntryManager.java | 23 ++-- .../czg/third/alipay/AlipayIsvPayManager.java | 52 ++++++++- .../third/alipay/dto/AlipayAuthInfoDto.java | 63 +++++++++++ .../czg/third/wechat/WechatEntryManager.java | 19 +++- .../czg/third/wechat/WechatPayManager.java | 35 +++++- .../com/czg/third/wechat/WechatReqUtils.java | 2 +- 10 files changed, 338 insertions(+), 26 deletions(-) create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/PayManager.java create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/dto/req/PayParamsDto.java create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/dto/AlipayAuthInfoDto.java diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/EntryManager.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/EntryManager.java index b93cae9f7..d345c25ef 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/EntryManager.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/EntryManager.java @@ -216,10 +216,10 @@ public class EntryManager { String image = WechatEntryManager.uploadImage(null, dto.getUrl()); dto.setWechatId(image); } - if (StrUtil.isBlank(dto.getAlipayId())) { - String image = AlipayEntryManager.uploadImage(null, dto.getUrl()); - dto.setAlipayId(image); - } +// if (StrUtil.isBlank(dto.getAlipayId())) { +// String image = AlipayEntryManager.uploadImage(null, dto.getUrl()); +// dto.setAlipayId(image); +// } } } @@ -370,10 +370,10 @@ public class EntryManager { // uploadParamImage(merchantDto); verifyEntryParam(merchantDto); -// uploadParamImage(merchantDto); + uploadParamImage(merchantDto); // System.out.println(merchantDto); -// entryMerchant(merchantDto, PayCst.Platform.WECHAT); - entryMerchant(merchantDto, PayCst.Platform.ALIPAY); + entryMerchant(merchantDto, PayCst.Platform.WECHAT); +// entryMerchant(merchantDto, PayCst.Platform.ALIPAY); // entryMerchant(merchantDto, PayCst.Platform.WECHAT, PayCst.Platform.ALIPAY); } diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/PayCst.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/PayCst.java index 606d44dae..c2f825e8f 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/PayCst.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/PayCst.java @@ -15,6 +15,11 @@ public interface PayCst { */ String LONG_TERM_DATE = "2099-12-31"; + /** + * 支付宝异常信息获取 key + */ + String ALIPAY_ERROR_MSG_KEY = "message"; + /** * 平台 */ diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/PayManager.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/PayManager.java new file mode 100644 index 000000000..f08d51c21 --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/PayManager.java @@ -0,0 +1,47 @@ +package com.czg; + +import com.czg.dto.req.PayParamsDto; +import com.czg.third.alipay.AlipayIsvPayManager; +import com.czg.third.wechat.WechatPayManager; + +/** + * @author yjjie + * @date 2026/1/9 11:24 + */ +public class PayManager { + + public static void jsapiPay(PayParamsDto paramsDto) { + paramsDto.verifyParams(); + + if (PayCst.Platform.WECHAT.equals(paramsDto.getPlatform())) { + WechatPayManager.jsapiPay(null, paramsDto); + } else if (PayCst.Platform.ALIPAY.equals(paramsDto.getPlatform())) { + AlipayIsvPayManager.jsapiPay(null, paramsDto); + } + } + + public static void main(String[] args) { +// jsapiPay(new PayParamsDto() +// .setPlatform(PayCst.Platform.ALIPAY) +// .setAppId("2021004145625815") +// .setOpenId("123123123") +// .setOrderNo("1111231231213") +// .setTitle("1213") +// .setMerchantId("123312321") +// .setBody("1213") +// .setAmount(1000L) +// .setPayParams("{\"app_auth_token\": \"ssss\"}") +// .setNotifyUrl("https://www.baidu.com")); + jsapiPay(new PayParamsDto() + .setPlatform(PayCst.Platform.WECHAT) + .setAppId("2021004145625815") + .setOpenId("123123123") + .setOrderNo("1111231231213") + .setTitle("1213") + .setMerchantId("123312321") + .setBody("1213") + .setAmount(1000L) + .setPayParams("{\"app_auth_token\": \"ssss\"}") + .setNotifyUrl("https://www.baidu.com")); + } +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/req/PayParamsDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/req/PayParamsDto.java new file mode 100644 index 000000000..114d45ef2 --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/req/PayParamsDto.java @@ -0,0 +1,104 @@ +package com.czg.dto.req; + +import com.alibaba.fastjson2.JSONObject; +import com.czg.PayCst; +import com.czg.exception.CzgException; +import com.czg.third.alipay.dto.AlipayAuthInfoDto; +import com.czg.utils.AssertUtil; +import lombok.Data; +import lombok.experimental.Accessors; + +/** + * 支付参数 + * + * @author yjjie + * @date 2026/1/9 11:12 + */ +@Data +@Accessors(chain = true) +public class PayParamsDto { + + /** + * 【必填】 + * 支付方式 + * {@link com.czg.PayCst.Platform} + */ + private String platform; + + /** + * 【必填】 + * 订单号 + */ + private String orderNo; + + /** + * 【必填】 + * 金额,单位:分 + */ + private Long amount; + + /** + * 【必填】 + * 订单标题 + */ + private String title; + + /** + * 【必填】 + * 回调地址 + */ + private String notifyUrl; + + /** + * 【必填】 + * appId + */ + private String appId; + + /** + * 用户唯一标识 + */ + private String openId; + + /** + * 【微信必填】 + * 商户ID + */ + private String merchantId; + + /** + * 【支付宝必填】 + * 支付参数 + */ + private String payParams; + + /** + * 商品描述 + */ + private String body; + + /** + * 支付宝 授权信息解析,不用传 + */ + private AlipayAuthInfoDto alipayAuthInfo; + + public void verifyParams() { + AssertUtil.isBlank(platform, "请选择支付方式"); + AssertUtil.isBlank(orderNo, "订单号不能为空"); + AssertUtil.isBlank(title, "订单标题不能为空"); + AssertUtil.isBlank(notifyUrl, "回调地址不能为空"); + AssertUtil.isBlank(appId, "appId不能为空"); + AssertUtil.isBlank(openId, "用户唯一标识不能为空"); + + if (PayCst.Platform.WECHAT.equals(platform)) { + AssertUtil.isBlank(merchantId, "商户ID不能为空"); + } else if (PayCst.Platform.ALIPAY.equals(platform)) { + AssertUtil.isBlank(payParams, "支付参数不能为空"); + alipayAuthInfo = JSONObject.parseObject(payParams, AlipayAuthInfoDto.class); + AssertUtil.isNull(alipayAuthInfo, "支付参数错误"); + AssertUtil.isBlank(alipayAuthInfo.getAppAuthToken(), "授权信息错误"); + } else { + throw new CzgException("支付平台错误"); + } + } +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/AlipayIsvEntryManager.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/AlipayIsvEntryManager.java index e3ae2146d..baa87fdba 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/AlipayIsvEntryManager.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/AlipayIsvEntryManager.java @@ -9,6 +9,7 @@ import com.czg.dto.req.*; import com.czg.dto.resp.EntryThirdRespDto; import com.czg.dto.resp.QueryStatusResp; import com.czg.exception.CzgException; +import com.czg.third.alipay.dto.AlipayAuthInfoDto; import com.czg.third.alipay.dto.config.AlipayConfigDto; import com.czg.utils.UploadFileUtil; import lombok.extern.slf4j.Slf4j; @@ -25,8 +26,6 @@ import java.io.IOException; @Slf4j public class AlipayIsvEntryManager { - private static final String ERR_MESSAGE_KEY = "message"; - public static QueryStatusResp queryMerchantBatchStatus(AlipayConfigDto configDto, String batchNo) { QueryStatusResp respDto = new QueryStatusResp() .setPlatform(PayCst.Platform.ALIPAY); @@ -87,7 +86,7 @@ public class AlipayIsvEntryManager { log.error("支付宝查询进件状态异常: {}", body); JSONObject object = JSONObject.parseObject(body); respDto.setStatus(PayCst.EntryStatus.REJECTED); - respDto.setFailReason(object.getString(ERR_MESSAGE_KEY)); + respDto.setFailReason(object.getString(PayCst.ALIPAY_ERROR_MSG_KEY)); return respDto; } } @@ -131,7 +130,7 @@ public class AlipayIsvEntryManager { log.error("支付宝开启代商户签约,创建应用事务异常: {}", body); JSONObject object = JSONObject.parseObject(body); respDto.setStatus(PayCst.EntryStatus.REJECTED); - respDto.setErrorMsg(object.getString(ERR_MESSAGE_KEY)); + respDto.setErrorMsg(object.getString(PayCst.ALIPAY_ERROR_MSG_KEY)); return respDto; } catch (IOException e) { log.error("上传图片出错", e); @@ -174,7 +173,7 @@ public class AlipayIsvEntryManager { String body = e.getResponseBody(); log.error("支付宝开启代商户签约,开启事务异常: {}", body); JSONObject object = JSONObject.parseObject(body); - throw new CzgException("支付宝开启代商户签约,开启事务异常: " + object.getString(ERR_MESSAGE_KEY)); + throw new CzgException("支付宝开启代商户签约,开启事务异常: " + object.getString(PayCst.ALIPAY_ERROR_MSG_KEY)); } } @@ -189,12 +188,22 @@ public class AlipayIsvEntryManager { try { AlipayOpenAgentConfirmResponseModel response = api.confirm(data); log.info("支付宝开启代商户签约,确认事务: 响应={}", response); - return JSONObject.toJSONString(response); + + AlipayAuthInfoDto authInfoDto = new AlipayAuthInfoDto() + .setUserId(response.getUserId()) + .setOpenId(response.getOpenId()) + .setAuthAppId(response.getAuthAppId()) + .setAppAuthToken(response.getAppAuthToken()) + .setExpiresIn(response.getExpiresIn()) + .setAppRefreshToken(response.getAppRefreshToken()) + .setReExpiresIn(response.getReExpiresIn()) + .setOrderNo(response.getOrderNo()); + return JSONObject.toJSONString(authInfoDto); } catch (ApiException e) { String body = e.getResponseBody(); log.error("支付宝开启代商户签约,确认事务异常: {}", body); JSONObject object = JSONObject.parseObject(body); - throw new CzgException(object.getString(ERR_MESSAGE_KEY)); + throw new CzgException(object.getString(PayCst.ALIPAY_ERROR_MSG_KEY)); } } diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/AlipayIsvPayManager.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/AlipayIsvPayManager.java index da44f7f4a..50244a798 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/AlipayIsvPayManager.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/AlipayIsvPayManager.java @@ -1,24 +1,64 @@ package com.czg.third.alipay; +import com.alibaba.fastjson2.JSONObject; import com.alipay.v3.ApiException; import com.alipay.v3.api.AlipayTradeApi; import com.alipay.v3.model.AlipayTradeCreateModel; +import com.alipay.v3.model.AlipayTradeCreateResponseModel; import com.alipay.v3.model.ExtendParams; import com.alipay.v3.util.model.CustomizedParams; +import com.czg.PayCst; +import com.czg.dto.req.PayParamsDto; +import com.czg.exception.CzgException; +import com.czg.third.alipay.dto.config.AlipayConfigDto; +import lombok.extern.slf4j.Slf4j; + +import java.math.BigDecimal; /** * @author yjjie * @date 2026/1/9 09:30 */ +@Slf4j public class AlipayIsvPayManager { - public static void main(String[] args) throws ApiException { - AlipayTradeApi api = new AlipayTradeApi(); - AlipayTradeCreateModel model = new AlipayTradeCreateModel(); + public static String jsapiPay(AlipayConfigDto configDto, PayParamsDto paramsDto) { + try { + AlipayClient.setApiClient(configDto); + AlipayTradeApi api = new AlipayTradeApi(); + AlipayTradeCreateModel model = new AlipayTradeCreateModel(); + model.setOutTradeNo(paramsDto.getOrderNo()); + model.setProductCode("JSAPI_PAY"); + model.setOpAppId(paramsDto.getAppId()); + model.setOpBuyerOpenId(paramsDto.getOpenId()); + model.setTotalAmount(getYuanAmountByFen(paramsDto.getAmount())); + model.setSubject(paramsDto.getTitle()); + model.setBody(paramsDto.getBody()); + model.setNotifyUrl(paramsDto.getNotifyUrl()); - model.setExtendParams(new ExtendParams()); - CustomizedParams customizedParams = new CustomizedParams(); + model.setExtendParams(new ExtendParams()); + CustomizedParams customizedParams = new CustomizedParams(); + customizedParams.setAppAuthToken(paramsDto.getAlipayAuthInfo().getAppAuthToken()); - api.create(model, customizedParams); + AlipayTradeCreateResponseModel responseModel = api.create(model, customizedParams); + return responseModel.getTradeNo(); + } catch (ApiException e) { + String body = e.getResponseBody(); + log.error("支付宝 H5 api 支付异常: {}", body); + JSONObject object = JSONObject.parseObject(body); + throw new CzgException(object.getString(PayCst.ALIPAY_ERROR_MSG_KEY)); + } catch (Exception e) { + log.error("支付宝 H5支付异常: {}", e.getMessage()); + throw new CzgException(e.getMessage()); + } } + + /** + * 金额转换 + */ + private static String getYuanAmountByFen(Long amount) { + BigDecimal yuanAmount = new BigDecimal(amount).divide(new BigDecimal(100)); + return yuanAmount.toString(); + } + } diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/dto/AlipayAuthInfoDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/dto/AlipayAuthInfoDto.java new file mode 100644 index 000000000..873ca6c82 --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/dto/AlipayAuthInfoDto.java @@ -0,0 +1,63 @@ +package com.czg.third.alipay.dto; + +import com.alibaba.fastjson2.annotation.JSONField; +import lombok.Data; +import lombok.experimental.Accessors; + +/** + * 支付宝授权信息 + * @author yjjie + * @date 2026/1/9 11:31 + */ +@Data +@Accessors(chain = true) +public class AlipayAuthInfoDto { + + /** + * 授权商户的user_id + */ + @JSONField(name = "user_id") + private String userId; + + /** + * 授权商户的open_id + */ + @JSONField(name = "open_id") + private String openId; + + /** + * 授权商户的appid + */ + @JSONField(name = "auth_app_id") + private String authAppId; + + /** + * 应用授权令牌 + */ + @JSONField(name = "app_auth_token") + private String appAuthToken; + + /** + * 应用授权令牌有效期 + */ + @JSONField(name = "expires_in") + private String expiresIn; + + /** + * 刷新令牌 + */ + @JSONField(name = "app_refresh_token") + private String appRefreshToken; + + /** + * 刷新令牌的有效时间 + */ + @JSONField(name = "re_expires_in") + private String reExpiresIn; + + /** + * 签约单号 + */ + @JSONField(name = "order_no") + private String orderNo; +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatEntryManager.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatEntryManager.java index a656b42f8..cecb71d38 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatEntryManager.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatEntryManager.java @@ -15,6 +15,7 @@ import com.czg.third.wechat.dto.req.entry.business.WechatEntryLicenseReqDto; import com.czg.third.wechat.dto.req.entry.business.sales.WechatEntryMiniProgramReqDto; import com.czg.third.wechat.dto.req.entry.business.sales.WechatEntrySalesInfoReqDto; import com.czg.third.wechat.dto.req.entry.business.sales.WechatEntryStoreInfoReqDto; +import com.czg.third.wechat.dto.req.entry.id.WechatEntryIdCardReqDto; import com.czg.third.wechat.dto.resp.WechatAuditDetail; import com.czg.third.wechat.dto.resp.WechatQueryStateResp; import com.czg.utils.UploadFileUtil; @@ -102,12 +103,12 @@ public class WechatEntryManager { * @param reqDto 请求信息 */ public static EntryThirdRespDto entryMerchant(WechatPayConfigDto configDto, AggregateMerchantDto reqDto) { - WechatEntryReqDto entryReqDto = buildEntryParams(configDto, reqDto); EntryThirdRespDto respDto = new EntryThirdRespDto() .setPlatform(PayCst.Platform.WECHAT); - - log.info("微信进件参数:{}", JSONObject.toJSONString(entryReqDto)); try { + WechatEntryReqDto entryReqDto = buildEntryParams(configDto, reqDto); + log.info("微信进件参数:{}", JSONObject.toJSONString(entryReqDto)); + String params = JSONObject.toJSONString(entryReqDto, JSONWriter.Feature.IgnoreEmpty); String respBody = WechatReqUtils.postReq(configDto, "/v3/applyment4sub/applyment/", params); JSONObject object = JSONObject.parseObject(respBody); @@ -123,7 +124,7 @@ public class WechatEntryManager { respDto.setErrorMsg(object.getString("message")); } } catch (Exception e) { - log.error("微信进件报错:{}", e.getMessage(), e); + log.error("微信进件报错:{}", e.getMessage()); respDto.setStatus(PayCst.EntryStatus.REJECTED); respDto.setEntryId(""); respDto.setErrorMsg(e.getMessage()); @@ -282,6 +283,16 @@ public class WechatEntryManager { subjectInfo.setBusinessLicenseInfo(licenseReqDto); WechatEntryIdentityReqDto identityInfo = new WechatEntryIdentityReqDto(); identityInfo.setIdHolderType(PayCst.ContactPersonType.LEGAL); + identityInfo.setIdDocType("IDENTIFICATION_TYPE_IDCARD"); + WechatEntryIdCardReqDto idCardInfo = new WechatEntryIdCardReqDto(); + idCardInfo.setIdCardCopy(legalPersonInfo.getIdCardFrontPic().getWechatId()); + idCardInfo.setIdCardNational(legalPersonInfo.getIdCardFrontPic().getWechatId()); + idCardInfo.setIdCardName(encryptor.encrypt(legalPersonInfo.getLegalPersonName())); + idCardInfo.setIdCardNumber(encryptor.encrypt(legalPersonInfo.getLegalPersonId())); + idCardInfo.setIdCardAddress(encryptor.encrypt(legalPersonInfo.getLegalAddress())); + idCardInfo.setCardPeriodBegin(legalPersonInfo.getLegalIdPersonStartDate()); + idCardInfo.setCardPeriodEnd(legalPersonInfo.getLegalPersonIdEndDate()); + identityInfo.setIdCardInfo(idCardInfo); subjectInfo.setIdentityInfo(identityInfo); entryParams.setSubjectInfo(subjectInfo); diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatPayManager.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatPayManager.java index 1b1d914ad..415edd6d4 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatPayManager.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatPayManager.java @@ -1,11 +1,44 @@ package com.czg.third.wechat; +import com.alibaba.fastjson2.JSONObject; +import com.czg.dto.req.PayParamsDto; +import com.czg.third.wechat.dto.config.WechatPayConfigDto; +import lombok.extern.slf4j.Slf4j; + /** * @author yjjie * @date 2025/12/26 09:15 */ +@Slf4j public class WechatPayManager { - public static void main(String[] args) { + /** + * jsapi 小程序支付 + * @param configDto 配置 + * @param paramsDto 参数 + */ + public static String jsapiPay(WechatPayConfigDto configDto, PayParamsDto paramsDto) { + if (configDto == null) { + configDto = WechatPayConfigDto.getDefaultConfig(); + } + JSONObject reqData = new JSONObject(); + reqData.put("sp_appid", paramsDto.getAppId()); + reqData.put("sp_mchid", configDto.getMerchantId()); + reqData.put("sub_mchid", paramsDto.getMerchantId()); + reqData.put("description", paramsDto.getTitle()); + reqData.put("out_trade_no", paramsDto.getOrderNo()); + reqData.put("notify_url", paramsDto.getNotifyUrl()); + + JSONObject amount = new JSONObject(); + amount.put("total", paramsDto.getAmount()); + reqData.put("amount", amount); + + JSONObject payer = new JSONObject(); + payer.put("sp_openid", paramsDto.getOpenId()); + reqData.put("payer", payer); + + String string = WechatReqUtils.postReq(configDto, "/v3/pay/partner/transactions/jsapi", reqData.toJSONString()); + log.info("微信支付请求结果: orderNo = {}, res = {}", paramsDto.getOrderNo(), string); + return ""; } } diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatReqUtils.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatReqUtils.java index 32c95eec2..6c8327684 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatReqUtils.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatReqUtils.java @@ -92,7 +92,7 @@ public class WechatReqUtils { Config config = WechatConfig.getRsaConfig(configDto); Signer signer = config.createSigner(); String signature = signer.sign(encryptStr).getSign(); - log.info("微信签名 encryptStr = {},\nsignature:{}", encryptStr, signature); + log.info("微信签名 encryptStr = \n{} \nsignature:{}", encryptStr, signature); return signature; } From 423423ca0bae3f43b4df73cceb4372456a6562ec Mon Sep 17 00:00:00 2001 From: wangw <1594593906@qq.com> Date: Fri, 9 Jan 2026 15:54:52 +0800 Subject: [PATCH 059/133] =?UTF-8?q?=E5=85=B3=E8=81=94=E4=B8=BB=E9=94=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/czg/controller/admin/EntryManagerController.java | 6 ++---- .../main/java/com/czg/order/entity/ShopDirectMerchant.java | 2 ++ 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cash-api/order-server/src/main/java/com/czg/controller/admin/EntryManagerController.java b/cash-api/order-server/src/main/java/com/czg/controller/admin/EntryManagerController.java index 0b11edac1..500d9bf1e 100644 --- a/cash-api/order-server/src/main/java/com/czg/controller/admin/EntryManagerController.java +++ b/cash-api/order-server/src/main/java/com/czg/controller/admin/EntryManagerController.java @@ -1,17 +1,15 @@ package com.czg.controller.admin; import com.alibaba.fastjson2.JSONObject; -import com.czg.BaseQueryParam; import com.czg.EntryManager; import com.czg.annotation.Debounce; import com.czg.dto.req.AggregateMerchantDto; import com.czg.dto.resp.BankBranchDto; import com.czg.order.entity.ShopDirectMerchant; +import com.czg.resp.CzgResult; import com.czg.service.order.dto.AggregateMerchantVO; import com.czg.service.order.dto.MerchantQueryDTO; import com.czg.service.order.service.ShopDirectMerchantService; -import com.czg.resp.CzgResult; -import com.czg.sa.StpKit; import com.czg.task.EntryManagerTask; import com.mybatisflex.core.paginate.Page; import jakarta.annotation.Resource; @@ -67,7 +65,7 @@ public class EntryManagerController { } /** - * 获取进件信息 + * 获取进件列表 */ @GetMapping("list") public CzgResult> getEntryList(MerchantQueryDTO queryParam) { diff --git a/cash-common/cash-common-service/src/main/java/com/czg/order/entity/ShopDirectMerchant.java b/cash-common/cash-common-service/src/main/java/com/czg/order/entity/ShopDirectMerchant.java index 3f332b18a..504792a74 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/order/entity/ShopDirectMerchant.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/order/entity/ShopDirectMerchant.java @@ -38,11 +38,13 @@ public class ShopDirectMerchant implements Serializable { /** * 店铺名称 */ + @Column(ignore = true) private String shopName; /** * 营业执照编号 */ + @Id private String licenceNo; /** * 支付宝账号 From 7ac540dfa972b7e45332dfef7e0a00824b55ef66 Mon Sep 17 00:00:00 2001 From: wangw <1594593906@qq.com> Date: Fri, 9 Jan 2026 15:59:37 +0800 Subject: [PATCH 060/133] MQ --- .../java/com/czg/mq/EntryManagerMqListener.java | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/cash-api/order-server/src/main/java/com/czg/mq/EntryManagerMqListener.java b/cash-api/order-server/src/main/java/com/czg/mq/EntryManagerMqListener.java index 2c161cfc8..c7b85df9b 100644 --- a/cash-api/order-server/src/main/java/com/czg/mq/EntryManagerMqListener.java +++ b/cash-api/order-server/src/main/java/com/czg/mq/EntryManagerMqListener.java @@ -48,20 +48,24 @@ public class EntryManagerMqListener { ) @RabbitHandler public void handle(Message message, Channel channel, String msg) throws IOException { + log.info("进件1MQ对接开始shopId:{}", msg); String messageId = message.getMessageProperties().getMessageId(); - if (hasMessageId(messageId)) { - return; - } + log.info("进件0MQ对接开始shopId:{}messageId:{}", msg, messageId); +// if (hasMessageId(messageId)) { +// return; +// } try { Long shopId = Long.valueOf(msg); // 将唯一标识添加到日志上下文 - ThreadContext.put("traceId", messageId); +// ThreadContext.put("traceId", messageId); + log.info("进件2MQ对接开始shopId:{}", msg); // 安全转换shopId if (shopId == null) { channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, false); return; } AggregateMerchantVO entry = shopDirectMerchantService.getEntry(Long.valueOf(msg)); + log.info("进件3MQ对接开始shopId:{}", msg); if (entry != null) { EntryManager.uploadParamImage(entry); List platform = new ArrayList<>(); @@ -97,9 +101,9 @@ public class EntryManagerMqListener { channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, false); } finally { - delMessageId(messageId); +// delMessageId(messageId); // 清除日志上下文信息 - ThreadContext.remove("messageId"); +// ThreadContext.remove("messageId"); } } From e3bf70ab9edff58786121e50a0e72a81e1d82a3d Mon Sep 17 00:00:00 2001 From: wangw <1594593906@qq.com> Date: Fri, 9 Jan 2026 16:10:04 +0800 Subject: [PATCH 061/133] MQ --- .../com/czg/controller/admin/EntryManagerController.java | 9 +++++++++ .../service/order/mapper/ShopDirectMerchantMapper.java | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/cash-api/order-server/src/main/java/com/czg/controller/admin/EntryManagerController.java b/cash-api/order-server/src/main/java/com/czg/controller/admin/EntryManagerController.java index 500d9bf1e..53fd4b3ec 100644 --- a/cash-api/order-server/src/main/java/com/czg/controller/admin/EntryManagerController.java +++ b/cash-api/order-server/src/main/java/com/czg/controller/admin/EntryManagerController.java @@ -3,6 +3,7 @@ package com.czg.controller.admin; import com.alibaba.fastjson2.JSONObject; import com.czg.EntryManager; import com.czg.annotation.Debounce; +import com.czg.config.RabbitPublisher; import com.czg.dto.req.AggregateMerchantDto; import com.czg.dto.resp.BankBranchDto; import com.czg.order.entity.ShopDirectMerchant; @@ -33,6 +34,8 @@ public class EntryManagerController { @Resource private EntryManagerTask entryManagerTask; + @Resource + private RabbitPublisher rabbitPublisher; /** * ocr识别填充 * 阿里 ocr识别图片 @@ -64,6 +67,12 @@ public class EntryManagerController { return CzgResult.success(EntryManager.queryBankBranchList(province, city, instId)); } + @GetMapping("test") + public CzgResult test(String shopId) { + rabbitPublisher.sendEntryManagerMsg(shopId); + return CzgResult.success(); + } + /** * 获取进件列表 */ diff --git a/cash-service/order-service/src/main/java/com/czg/service/order/mapper/ShopDirectMerchantMapper.java b/cash-service/order-service/src/main/java/com/czg/service/order/mapper/ShopDirectMerchantMapper.java index 36b91db54..a56042505 100644 --- a/cash-service/order-service/src/main/java/com/czg/service/order/mapper/ShopDirectMerchantMapper.java +++ b/cash-service/order-service/src/main/java/com/czg/service/order/mapper/ShopDirectMerchantMapper.java @@ -3,6 +3,7 @@ package com.czg.service.order.mapper; import com.czg.service.order.dto.MerchantQueryDTO; import com.mybatisflex.core.BaseMapper; import com.czg.order.entity.ShopDirectMerchant; +import org.apache.ibatis.annotations.Param; import java.util.List; @@ -14,5 +15,5 @@ import java.util.List; */ public interface ShopDirectMerchantMapper extends BaseMapper { - List getEntryList(MerchantQueryDTO queryParam); + List getEntryList(@Param("queryParam") MerchantQueryDTO queryParam); } From 16a814568d4ffdfd41ee8101abd93ed9b3ccfd64 Mon Sep 17 00:00:00 2001 From: wangw <1594593906@qq.com> Date: Fri, 9 Jan 2026 16:15:04 +0800 Subject: [PATCH 062/133] =?UTF-8?q?where=20=E6=A0=87=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mapper/ShopDirectMerchantMapper.xml | 27 ++++++++++--------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/cash-service/order-service/src/main/resources/mapper/ShopDirectMerchantMapper.xml b/cash-service/order-service/src/main/resources/mapper/ShopDirectMerchantMapper.xml index 73c34a7cf..8725a4795 100644 --- a/cash-service/order-service/src/main/resources/mapper/ShopDirectMerchantMapper.xml +++ b/cash-service/order-service/src/main/resources/mapper/ShopDirectMerchantMapper.xml @@ -8,18 +8,19 @@ select merchant.*,shop.shop_name as shopName from tb_shop_direct_merchant merchant left join tb_shop_info shop on merchant.shop_id = shop.id - where - - and merchant.user_type = #{queryParam.userType} - - - and shop.shop_name like concat('%',#{queryParam.shopName},'%') - - - and (merchant.wechat_status = #{queryParam.status} or merchant.alipay_status = #{queryParam.status}) - - - and merchant.alipay_account like concat('%',#{queryParam.alipayAccount},'%') - + + + and merchant.user_type = #{queryParam.userType} + + + and shop.shop_name like concat('%',#{queryParam.shopName},'%') + + + and (merchant.wechat_status = #{queryParam.status} or merchant.alipay_status = #{queryParam.status}) + + + and merchant.alipay_account like concat('%',#{queryParam.alipayAccount},'%') + + From ef8eabb06c6fac7b7f24fbb7a63b2df4ba1476dc Mon Sep 17 00:00:00 2001 From: wangw <1594593906@qq.com> Date: Fri, 9 Jan 2026 16:49:22 +0800 Subject: [PATCH 063/133] =?UTF-8?q?mq=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/EntryManagerController.java | 9 ++-- .../com/czg/mq/EntryManagerMqListener.java | 46 +++++++++++-------- .../java/com/czg/task/EntryManagerTask.java | 12 ++--- .../service/ShopDirectMerchantService.java | 2 +- .../impl/ShopDirectMerchantServiceImpl.java | 8 ++-- 5 files changed, 41 insertions(+), 36 deletions(-) diff --git a/cash-api/order-server/src/main/java/com/czg/controller/admin/EntryManagerController.java b/cash-api/order-server/src/main/java/com/czg/controller/admin/EntryManagerController.java index 53fd4b3ec..9610173b8 100644 --- a/cash-api/order-server/src/main/java/com/czg/controller/admin/EntryManagerController.java +++ b/cash-api/order-server/src/main/java/com/czg/controller/admin/EntryManagerController.java @@ -36,6 +36,7 @@ public class EntryManagerController { @Resource private RabbitPublisher rabbitPublisher; + /** * ocr识别填充 * 阿里 ocr识别图片 @@ -86,8 +87,8 @@ public class EntryManagerController { * 获取进件信息 */ @GetMapping - public CzgResult getEntry(Long shopId) { - return CzgResult.success(shopDirectMerchantService.getEntry(shopId)); + public CzgResult getEntry(Long shopId, String licenceNo) { + return CzgResult.success(shopDirectMerchantService.getEntry(shopId, licenceNo)); } /** @@ -97,8 +98,8 @@ public class EntryManagerController { */ @GetMapping("queryEntry") @Debounce(value = "#shopId", interval = 1000 * 60 * 3) - public CzgResult queryEntry(Long shopId) { - entryManagerTask.entryManager(shopId); + public CzgResult queryEntry(Long shopId, String licenceNo) { + entryManagerTask.entryManager(shopId, licenceNo); return CzgResult.success(); } diff --git a/cash-api/order-server/src/main/java/com/czg/mq/EntryManagerMqListener.java b/cash-api/order-server/src/main/java/com/czg/mq/EntryManagerMqListener.java index c7b85df9b..9abd57dcf 100644 --- a/cash-api/order-server/src/main/java/com/czg/mq/EntryManagerMqListener.java +++ b/cash-api/order-server/src/main/java/com/czg/mq/EntryManagerMqListener.java @@ -48,23 +48,32 @@ public class EntryManagerMqListener { ) @RabbitHandler public void handle(Message message, Channel channel, String msg) throws IOException { - log.info("进件1MQ对接开始shopId:{}", msg); - String messageId = message.getMessageProperties().getMessageId(); - log.info("进件0MQ对接开始shopId:{}messageId:{}", msg, messageId); -// if (hasMessageId(messageId)) { -// return; -// } + log.info("进件1MQ对接开始 店铺标识:{}", msg); + long deliveryTag = message.getMessageProperties().getDeliveryTag(); + if (StrUtil.isBlank(msg)) { + channel.basicNack(deliveryTag, false, false); + return; + } + String[] split = msg.split(":"); + if (split.length != 2) { + log.error("进件MQ对接参数异常 店铺标识:{}", msg); + channel.basicNack(deliveryTag, false, false); + return; + } + Long shopId = Long.valueOf(split[0]); + if (shopId == null) { + channel.basicNack(deliveryTag, false, false); + return; + } + if (hasMessageId(String.valueOf(shopId))) { + return; + } try { - Long shopId = Long.valueOf(msg); // 将唯一标识添加到日志上下文 -// ThreadContext.put("traceId", messageId); + ThreadContext.put("traceId", String.valueOf(shopId)); log.info("进件2MQ对接开始shopId:{}", msg); // 安全转换shopId - if (shopId == null) { - channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, false); - return; - } - AggregateMerchantVO entry = shopDirectMerchantService.getEntry(Long.valueOf(msg)); + AggregateMerchantVO entry = shopDirectMerchantService.getEntry(shopId, split[1]); log.info("进件3MQ对接开始shopId:{}", msg); if (entry != null) { EntryManager.uploadParamImage(entry); @@ -89,7 +98,7 @@ public class EntryManagerMqListener { merchant.setAlipayErrorMsg(resp.getAlipayErrorMsg()); shopDirectMerchantService.updateById(merchant); } - channel.basicAck(message.getMessageProperties().getDeliveryTag(), false); + channel.basicAck(deliveryTag, false); } catch (Exception e) { log.error("进件MQ对接业务异常shopId:{}", msg, e); ShopDirectMerchant merchant = new ShopDirectMerchant(); @@ -98,12 +107,11 @@ public class EntryManagerMqListener { merchant.setAlipayStatus(PayCst.EntryStatus.REJECTED); merchant.setErrorMsg("系统错误,请联系管理员后重试。"); shopDirectMerchantService.updateById(merchant); - - channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, false); + channel.basicNack(deliveryTag, false, false); } finally { -// delMessageId(messageId); - // 清除日志上下文信息 -// ThreadContext.remove("messageId"); + delMessageId(String.valueOf(shopId)); +// 清除日志上下文信息 + ThreadContext.remove("messageId"); } } diff --git a/cash-api/order-server/src/main/java/com/czg/task/EntryManagerTask.java b/cash-api/order-server/src/main/java/com/czg/task/EntryManagerTask.java index 39f505b53..69850f661 100644 --- a/cash-api/order-server/src/main/java/com/czg/task/EntryManagerTask.java +++ b/cash-api/order-server/src/main/java/com/czg/task/EntryManagerTask.java @@ -4,14 +4,9 @@ import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.StrUtil; import com.czg.EntryManager; import com.czg.PayCst; -import com.czg.account.entity.ShopInfo; import com.czg.account.service.ShopInfoService; import com.czg.dto.resp.QueryStatusResp; import com.czg.order.entity.ShopDirectMerchant; -import com.czg.order.service.ShopOrderStatisticService; -import com.czg.order.service.ShopProdStatisticService; -import com.czg.order.service.ShopTableOrderStatisticService; -import com.czg.service.RedisService; import com.czg.service.order.service.ShopDirectMerchantService; import com.mybatisflex.core.query.QueryWrapper; import jakarta.annotation.Resource; @@ -20,8 +15,6 @@ import org.apache.dubbo.config.annotation.DubboReference; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; -import java.time.LocalDate; -import java.time.LocalDateTime; import java.util.List; /** @@ -42,16 +35,17 @@ public class EntryManagerTask { public void run() { log.info("进件查询,定时任务执行"); long start = System.currentTimeMillis(); - entryManager(null); + entryManager(null, null); log.info("进件查询,定时任务执行完毕,耗时:{}ms", start - System.currentTimeMillis()); } /** * 查询状态为待处理、待签约、待审核的进件 */ - public void entryManager(Long shopId) { + public void entryManager(Long shopId, String licenceNo) { List list = shopDirectMerchantService.list(QueryWrapper.create() .eq(ShopDirectMerchant::getShopId, shopId) + .eq(ShopDirectMerchant::getLicenceNo, licenceNo) .in(ShopDirectMerchant::getWechatStatus, PayCst.EntryStatus.NEED_QUERY_LIST) .or(ShopDirectMerchant::getAlipayStatus).in(PayCst.EntryStatus.NEED_QUERY_LIST)); if (CollUtil.isEmpty(list)) { diff --git a/cash-service/order-service/src/main/java/com/czg/service/order/service/ShopDirectMerchantService.java b/cash-service/order-service/src/main/java/com/czg/service/order/service/ShopDirectMerchantService.java index 6a9bc72ed..07999fb2e 100644 --- a/cash-service/order-service/src/main/java/com/czg/service/order/service/ShopDirectMerchantService.java +++ b/cash-service/order-service/src/main/java/com/czg/service/order/service/ShopDirectMerchantService.java @@ -29,7 +29,7 @@ public interface ShopDirectMerchantService extends IService /** * 获取进件信息 */ - AggregateMerchantVO getEntry(Long shopId); + AggregateMerchantVO getEntry(Long shopId, String licenceNo); /** * 申请进件 diff --git a/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/ShopDirectMerchantServiceImpl.java b/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/ShopDirectMerchantServiceImpl.java index ac10c3a7f..542864737 100644 --- a/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/ShopDirectMerchantServiceImpl.java +++ b/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/ShopDirectMerchantServiceImpl.java @@ -64,8 +64,10 @@ public class ShopDirectMerchantServiceImpl extends ServiceImpl rabbitPublisher.sendEntryManagerMsg(reqDto.getShopId().toString())); + FunUtils.transactionSafeRun(() -> rabbitPublisher.sendEntryManagerMsg(reqDto.getShopId() + ":" + merchant.getLicenceNo())); return result; } From 504e9b131c09c574da9c4af6745bafe70fea1ae7 Mon Sep 17 00:00:00 2001 From: wangw <1594593906@qq.com> Date: Fri, 9 Jan 2026 16:52:03 +0800 Subject: [PATCH 064/133] =?UTF-8?q?=E8=BF=9B=E4=BB=B6=E6=A0=87=E8=AF=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/czg/controller/admin/EntryManagerController.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cash-api/order-server/src/main/java/com/czg/controller/admin/EntryManagerController.java b/cash-api/order-server/src/main/java/com/czg/controller/admin/EntryManagerController.java index 9610173b8..15e76fbec 100644 --- a/cash-api/order-server/src/main/java/com/czg/controller/admin/EntryManagerController.java +++ b/cash-api/order-server/src/main/java/com/czg/controller/admin/EntryManagerController.java @@ -69,8 +69,8 @@ public class EntryManagerController { } @GetMapping("test") - public CzgResult test(String shopId) { - rabbitPublisher.sendEntryManagerMsg(shopId); + public CzgResult test(String shopId, String licenceNo) { + rabbitPublisher.sendEntryManagerMsg(shopId + ":" + licenceNo); return CzgResult.success(); } From e203d7275aeb5027f045e1dde52f5ec6fc119ea9 Mon Sep 17 00:00:00 2001 From: wangw <1594593906@qq.com> Date: Fri, 9 Jan 2026 16:55:40 +0800 Subject: [PATCH 065/133] =?UTF-8?q?=E8=BF=9B=E4=BB=B6=E6=A0=87=E8=AF=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/czg/mq/EntryManagerMqListener.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cash-api/order-server/src/main/java/com/czg/mq/EntryManagerMqListener.java b/cash-api/order-server/src/main/java/com/czg/mq/EntryManagerMqListener.java index 9abd57dcf..b7c5ae1de 100644 --- a/cash-api/order-server/src/main/java/com/czg/mq/EntryManagerMqListener.java +++ b/cash-api/order-server/src/main/java/com/czg/mq/EntryManagerMqListener.java @@ -65,7 +65,7 @@ public class EntryManagerMqListener { channel.basicNack(deliveryTag, false, false); return; } - if (hasMessageId(String.valueOf(shopId))) { + if (hasMessageId(msg)) { return; } try { @@ -102,14 +102,14 @@ public class EntryManagerMqListener { } catch (Exception e) { log.error("进件MQ对接业务异常shopId:{}", msg, e); ShopDirectMerchant merchant = new ShopDirectMerchant(); - merchant.setShopId(Long.valueOf(msg)); + merchant.setShopId(shopId); merchant.setWechatStatus(PayCst.EntryStatus.REJECTED); merchant.setAlipayStatus(PayCst.EntryStatus.REJECTED); merchant.setErrorMsg("系统错误,请联系管理员后重试。"); shopDirectMerchantService.updateById(merchant); channel.basicNack(deliveryTag, false, false); } finally { - delMessageId(String.valueOf(shopId)); + delMessageId(msg); // 清除日志上下文信息 ThreadContext.remove("messageId"); } From 8cbf20e751f59ecb025497a557f006246320e04c Mon Sep 17 00:00:00 2001 From: gong <1157756119@qq.com> Date: Fri, 9 Jan 2026 16:58:26 +0800 Subject: [PATCH 066/133] =?UTF-8?q?EntryThirdRespDto=20=E4=B8=BA=20null=20?= =?UTF-8?q?=E7=9A=84=E6=83=85=E5=86=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../czg/third/alipay/AlipayIsvEntryManager.java | 6 +++--- .../com/czg/third/wechat/WechatEntryManager.java | 8 ++++---- .../java/com/czg/third/wechat/WechatReqUtils.java | 14 ++++++++------ 3 files changed, 15 insertions(+), 13 deletions(-) diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/AlipayIsvEntryManager.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/AlipayIsvEntryManager.java index baa87fdba..0c01e9a51 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/AlipayIsvEntryManager.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/AlipayIsvEntryManager.java @@ -132,10 +132,10 @@ public class AlipayIsvEntryManager { respDto.setStatus(PayCst.EntryStatus.REJECTED); respDto.setErrorMsg(object.getString(PayCst.ALIPAY_ERROR_MSG_KEY)); return respDto; - } catch (IOException e) { - log.error("上传图片出错", e); + } catch (Exception e) { + log.error("支付宝开启代商户签约,创建应用事务异常2", e); respDto.setStatus(PayCst.EntryStatus.REJECTED); - respDto.setErrorMsg("上传图片出错"); + respDto.setErrorMsg(e.getMessage()); return respDto; } } diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatEntryManager.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatEntryManager.java index cecb71d38..61dd7d808 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatEntryManager.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatEntryManager.java @@ -336,11 +336,11 @@ public class WechatEntryManager { public static void main(String[] args) throws IOException { - queryMerchantEntryStatus(null, "20220106000000000001"); +// queryMerchantEntryStatus(null, "20220106000000000001"); -// int offset = 0; -// Integer limit = 100; -// JSONObject resp = queryBankList(null, offset, limit); + int offset = 0; + Integer limit = 100; + JSONObject resp = queryBankList(null, offset, limit); // queryBankBranchList(dto, "1000009561", "110000", offset, limit); // queryBankBranchList(dto, "1000009561", "29", offset, limit); diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatReqUtils.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatReqUtils.java index 6c8327684..e2d4bf967 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatReqUtils.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatReqUtils.java @@ -50,22 +50,24 @@ public class WechatReqUtils { String authorization = String.format("WECHATPAY2-SHA256-RSA2048 mchid=\"%s\",nonce_str=\"%s\",signature=\"%s\",timestamp=\"%d\",serial_no=\"%s\"", configDto.getMerchantId(), nonce, signature, timestamp, configDto.getSerialNumber()); + HttpRequest request = switch (method) { case "POST" -> HttpUtil.createPost(configDto.getDomain() + url) .header("Authorization", authorization) - .header("Content-Type", "application/json") - .header("Wechatpay-Serial", configDto.getPublicKeyId()) - .body(body); + .charset(StandardCharsets.UTF_8) + .contentType("application/json") + .body(body ); case "GET" -> HttpUtil.createGet(configDto.getDomain() + url) .header("Authorization", authorization) - .header("Content-Type", "application/json") - .header("Wechatpay-Serial", configDto.getPublicKeyId()); + .charset(StandardCharsets.UTF_8) + .contentType("application/json"); default -> throw new CzgException("不支持的请求方法"); }; + log.info("微信支付请求:url = {} \nauthorization: {}", url, authorization); HttpResponse response = request.execute(); String s = response.body(); - log.info("微信支付请求:url = {}, method: {}, body: {}, resp: {}", url, method, body, s); + log.info("微信支付请求:url = {}\n\tmethod: {}\n\tbody: {}\n\tresp: {}", url, method, body, s); return s; } From 0513cd5e65696b95a17b2c83526f4317a45fb812 Mon Sep 17 00:00:00 2001 From: gong <1157756119@qq.com> Date: Fri, 9 Jan 2026 17:06:11 +0800 Subject: [PATCH 067/133] =?UTF-8?q?=E5=BE=AE=E4=BF=A1=E8=AF=B7=E6=B1=82=20?= =?UTF-8?q?header=20=E6=B7=BB=E5=8A=A0=20=20Wechatpay-Serial?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/czg/third/wechat/WechatReqUtils.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatReqUtils.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatReqUtils.java index e2d4bf967..ad52b319b 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatReqUtils.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatReqUtils.java @@ -54,12 +54,14 @@ public class WechatReqUtils { HttpRequest request = switch (method) { case "POST" -> HttpUtil.createPost(configDto.getDomain() + url) .header("Authorization", authorization) + .header("Wechatpay-Serial", configDto.getPublicKeyId()) .charset(StandardCharsets.UTF_8) .contentType("application/json") .body(body ); case "GET" -> HttpUtil.createGet(configDto.getDomain() + url) .header("Authorization", authorization) + .header("Wechatpay-Serial", configDto.getPublicKeyId()) .charset(StandardCharsets.UTF_8) .contentType("application/json"); default -> throw new CzgException("不支持的请求方法"); From 9b74b38799f496090e0926b7957fea94bb18663b Mon Sep 17 00:00:00 2001 From: wangw <1594593906@qq.com> Date: Fri, 9 Jan 2026 17:06:44 +0800 Subject: [PATCH 068/133] =?UTF-8?q?=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/czg/mq/EntryManagerMqListener.java | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/cash-api/order-server/src/main/java/com/czg/mq/EntryManagerMqListener.java b/cash-api/order-server/src/main/java/com/czg/mq/EntryManagerMqListener.java index b7c5ae1de..440802876 100644 --- a/cash-api/order-server/src/main/java/com/czg/mq/EntryManagerMqListener.java +++ b/cash-api/order-server/src/main/java/com/czg/mq/EntryManagerMqListener.java @@ -10,6 +10,7 @@ import com.czg.order.entity.ShopDirectMerchant; import com.czg.service.RedisService; import com.czg.service.order.dto.AggregateMerchantVO; import com.czg.service.order.service.ShopDirectMerchantService; +import com.mybatisflex.core.query.QueryWrapper; import com.rabbitmq.client.Channel; import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; @@ -86,8 +87,6 @@ public class EntryManagerMqListener { } EntryRespDto resp = EntryManager.entryMerchant(entry, platform.toArray(new String[0])); ShopDirectMerchant merchant = new ShopDirectMerchant(); - merchant.setShopId(entry.getShopId()); - merchant.setWechatApplyId(resp.getWechatApplyId()); merchant.setWechatStatus(resp.getWechatStatus()); merchant.setWechatErrorMsg(resp.getWechatErrorMsg()); @@ -96,17 +95,16 @@ public class EntryManagerMqListener { merchant.setAlipayStatus(resp.getAlipayStatus()); merchant.setAlipayAuthInfo(resp.getAlipayAuthInfo()); merchant.setAlipayErrorMsg(resp.getAlipayErrorMsg()); - shopDirectMerchantService.updateById(merchant); + shopDirectMerchantService.update(merchant, new QueryWrapper().eq(ShopDirectMerchant::getShopId, shopId).eq(ShopDirectMerchant::getLicenceNo, split[1])); } channel.basicAck(deliveryTag, false); } catch (Exception e) { log.error("进件MQ对接业务异常shopId:{}", msg, e); ShopDirectMerchant merchant = new ShopDirectMerchant(); - merchant.setShopId(shopId); merchant.setWechatStatus(PayCst.EntryStatus.REJECTED); merchant.setAlipayStatus(PayCst.EntryStatus.REJECTED); merchant.setErrorMsg("系统错误,请联系管理员后重试。"); - shopDirectMerchantService.updateById(merchant); + shopDirectMerchantService.update(merchant, new QueryWrapper().eq(ShopDirectMerchant::getShopId, shopId).eq(ShopDirectMerchant::getLicenceNo, split[1])); channel.basicNack(deliveryTag, false, false); } finally { delMessageId(msg); From dfd2c74c331d656f9f2a77b1cdb7024eb81473b9 Mon Sep 17 00:00:00 2001 From: gong <1157756119@qq.com> Date: Fri, 9 Jan 2026 17:33:32 +0800 Subject: [PATCH 069/133] =?UTF-8?q?=E5=BE=AE=E4=BF=A1=E6=94=AF=E4=BB=98?= =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/czg/PayManager.java | 4 ++-- .../java/com/czg/third/wechat/WechatReqUtils.java | 12 +++++++----- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/PayManager.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/PayManager.java index f08d51c21..06ea794e3 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/PayManager.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/PayManager.java @@ -34,11 +34,11 @@ public class PayManager { // .setNotifyUrl("https://www.baidu.com")); jsapiPay(new PayParamsDto() .setPlatform(PayCst.Platform.WECHAT) - .setAppId("2021004145625815") + .setAppId("wxd88fffa983758a30") .setOpenId("123123123") .setOrderNo("1111231231213") .setTitle("1213") - .setMerchantId("123312321") + .setMerchantId("1665469114") .setBody("1213") .setAmount(1000L) .setPayParams("{\"app_auth_token\": \"ssss\"}") diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatReqUtils.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatReqUtils.java index ad52b319b..662ca11ad 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatReqUtils.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatReqUtils.java @@ -7,6 +7,9 @@ import com.czg.exception.CzgException; import com.czg.third.wechat.dto.config.WechatPayConfigDto; import com.wechat.pay.java.core.Config; import com.wechat.pay.java.core.cipher.Signer; +import com.wechat.pay.java.core.http.HttpClient; +import com.wechat.pay.java.core.http.HttpMethod; +import com.wechat.pay.java.core.util.NonceUtil; import lombok.extern.slf4j.Slf4j; import java.net.URLEncoder; @@ -50,23 +53,22 @@ public class WechatReqUtils { String authorization = String.format("WECHATPAY2-SHA256-RSA2048 mchid=\"%s\",nonce_str=\"%s\",signature=\"%s\",timestamp=\"%d\",serial_no=\"%s\"", configDto.getMerchantId(), nonce, signature, timestamp, configDto.getSerialNumber()); - HttpRequest request = switch (method) { case "POST" -> HttpUtil.createPost(configDto.getDomain() + url) .header("Authorization", authorization) - .header("Wechatpay-Serial", configDto.getPublicKeyId()) + .header("Wechatpay-Serial", configDto.getSerialNumber()) .charset(StandardCharsets.UTF_8) .contentType("application/json") .body(body ); case "GET" -> HttpUtil.createGet(configDto.getDomain() + url) .header("Authorization", authorization) - .header("Wechatpay-Serial", configDto.getPublicKeyId()) + .header("Wechatpay-Serial", configDto.getSerialNumber()) .charset(StandardCharsets.UTF_8) .contentType("application/json"); default -> throw new CzgException("不支持的请求方法"); }; - log.info("微信支付请求:url = {} \nauthorization: {}", url, authorization); + log.info("微信支付请求:url = {} \nauthorization: {}", request.getUrl(), authorization); HttpResponse response = request.execute(); String s = response.body(); log.info("微信支付请求:url = {}\n\tmethod: {}\n\tbody: {}\n\tresp: {}", url, method, body, s); @@ -104,7 +106,7 @@ public class WechatReqUtils { * 获取随机串 */ private static String getNonceStr() { - return UUID.randomUUID().toString().replaceAll("-", "").toUpperCase(); + return NonceUtil.createNonce(32); } /** From 3a5bd9e99450bb86a1fdd2ee4cdd2db1707b42c6 Mon Sep 17 00:00:00 2001 From: gong <1157756119@qq.com> Date: Fri, 9 Jan 2026 18:03:14 +0800 Subject: [PATCH 070/133] =?UTF-8?q?=E6=94=AF=E4=BB=98=E5=AE=9D=20=E7=9B=B4?= =?UTF-8?q?=E4=BB=98=E9=80=9A=E5=8F=82=E6=95=B0=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/czg/EntryManager.java | 6 ++--- .../czg/third/alipay/AlipayEntryManager.java | 4 ++-- .../third/alipay/AlipayIsvEntryManager.java | 23 +++++++++++++++---- .../alipay/dto/config/AlipayConfigDto.java | 20 +++++++++++++++- 4 files changed, 42 insertions(+), 11 deletions(-) diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/EntryManager.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/EntryManager.java index d345c25ef..5743e277b 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/EntryManager.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/EntryManager.java @@ -370,10 +370,10 @@ public class EntryManager { // uploadParamImage(merchantDto); verifyEntryParam(merchantDto); - uploadParamImage(merchantDto); +// uploadParamImage(merchantDto); // System.out.println(merchantDto); - entryMerchant(merchantDto, PayCst.Platform.WECHAT); -// entryMerchant(merchantDto, PayCst.Platform.ALIPAY); +// entryMerchant(merchantDto, PayCst.Platform.WECHAT); + entryMerchant(merchantDto, PayCst.Platform.ALIPAY); // entryMerchant(merchantDto, PayCst.Platform.WECHAT, PayCst.Platform.ALIPAY); } diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/AlipayEntryManager.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/AlipayEntryManager.java index 59198ff39..926d01265 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/AlipayEntryManager.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/AlipayEntryManager.java @@ -347,10 +347,10 @@ public class AlipayEntryManager { public static void main(String[] args) throws ApiException { -// queryBankBranchList("CMB", "陕西省", "西安市"); + queryBankBranchList(null, "CMB", "陕西省", "西安市"); // uploadImage(null, "https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/20240312/31476c871c224389aea0ac4e17c964a3.jpg"); - test(); +// test(); } // https://opendocs.alipay.com/solution/0dec7x?pathHash=caec4753 直付通 diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/AlipayIsvEntryManager.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/AlipayIsvEntryManager.java index 0c01e9a51..1109bcac3 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/AlipayIsvEntryManager.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/AlipayIsvEntryManager.java @@ -27,6 +27,9 @@ import java.io.IOException; public class AlipayIsvEntryManager { public static QueryStatusResp queryMerchantBatchStatus(AlipayConfigDto configDto, String batchNo) { + if (configDto == null) { + configDto = AlipayConfigDto.getThirdDefaultConfig(); + } QueryStatusResp respDto = new QueryStatusResp() .setPlatform(PayCst.Platform.ALIPAY); AlipayClient.setApiClient(configDto); @@ -97,11 +100,14 @@ public class AlipayIsvEntryManager { * @param reqDto 请求信息 */ public static EntryThirdRespDto entryMerchant(AlipayConfigDto configDto, AggregateMerchantDto reqDto) { + if (configDto == null) { + configDto = AlipayConfigDto.getThirdDefaultConfig(); + } AlipayClient.setApiClient(configDto); EntryThirdRespDto respDto = new EntryThirdRespDto() .setPlatform(PayCst.Platform.ALIPAY); try { - String batchNo = createRequest(reqDto); + String batchNo = createRequest(configDto, reqDto); respDto.setEntryId(batchNo); AlipayOpenAgentFacetofaceSignModel signModel = buildFaceToFaceModel(reqDto, batchNo); @@ -115,7 +121,7 @@ public class AlipayIsvEntryManager { log.info("支付宝开启代商户签约: 响应={}", JSONObject.toJSONString(response)); try { - String authInfo = confirmRequest(batchNo); + String authInfo = confirmRequest(configDto, batchNo); respDto.setAlipayAuthInfo(authInfo); respDto.setStatus(PayCst.EntryStatus.INIT); respDto.setErrorMsg(""); @@ -145,7 +151,11 @@ public class AlipayIsvEntryManager { * @param reqDto 请求信息 * @return 请求ID */ - public static String createRequest(AggregateMerchantDto reqDto) { + public static String createRequest(AlipayConfigDto configDto, AggregateMerchantDto reqDto) { + if (configDto == null) { + configDto = AlipayConfigDto.getThirdDefaultConfig(); + } + AlipayClient.setApiClient(configDto); AlipayOpenAgentApi api = new AlipayOpenAgentApi(); AlipayOpenAgentCreateModel openModel = new AlipayOpenAgentCreateModel(); @@ -177,8 +187,11 @@ public class AlipayIsvEntryManager { } } - public static String confirmRequest(String batchNo) { - AlipayClient.setApiClient(null); + public static String confirmRequest(AlipayConfigDto configDto, String batchNo) { + if (configDto == null) { + configDto = AlipayConfigDto.getThirdDefaultConfig(); + } + AlipayClient.setApiClient(configDto); // 构造请求参数以调用接口 AlipayOpenAgentApi api = new AlipayOpenAgentApi(); AlipayOpenAgentConfirmModel data = new AlipayOpenAgentConfirmModel(); diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/dto/config/AlipayConfigDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/dto/config/AlipayConfigDto.java index 3e9e39da2..a0474c4ac 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/dto/config/AlipayConfigDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/dto/config/AlipayConfigDto.java @@ -32,7 +32,7 @@ public class AlipayConfigDto { */ private String domain; - public static AlipayConfigDto getDefaultConfig() { + public static AlipayConfigDto getThirdDefaultConfig() { return new AlipayConfigDto() .setAppId("2021006121646825") .setPrivateKey("MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCz3FkdffxZibdwis9W7eOW1dEjGAbSvRDL2ikfeCIW5KZNoIjUqxI0mIoUlLRRKO71QLHZS1Vb2aJp8jeOAqIPa8e76HTneQEzk3FGA8gpraSGvbadHWzvxnmYKsts1TBiEZQL82ySJXhQTJvZ6jyDM7s6wHHUnrH+Qi29QpppQ1sxsoJeCtajUgRg3btD6XbBcyFAX3pzM56Kw9eaIjZoD8WToZOM/Y3sqNL2uo8lLqcIpTrI7Pq5ZOspmBQ+t8v3rS9IdDZZMvd0trzS67AXwHz8rKPBT/lL1A4iHnXCHUvktusX1fPs3/RGY/a7PIddaBLnfY0GcueE16K7QcrXAgMBAAECggEAbSdT2eckp75BWoaTcGEs1tRqeM7TDT/6moyKmnOQ1K3tE31SrSYpBUxxuC3LBNo/sw2RIZtrcTOyMnPyLTgB3DP/4lUf5X51MTTQ8LnI1ypvh+pIki9Sdm3QS33lOOZk149tdpdDk6ozyx/DEcvq74EMpoo2SuAIi5LkKVDrXuehvGA/WeXtpmuPgqRFdIA+JBlA3knHk5XEQY/k2Y31gq5oCwNL9iT9OAZqVkukE6EnvCXE9t2rAV4/snYilaf/UaO+ktgEwSbPBQ8YKlovDAarMBbGtgr6E174A9djlPyR+W/fgx8rlTwSWtieb9MkO8LN3KSxgVs0kY5U8OHg8QKBgQDljJq9kTFHare+W/fAXdUy3tJprfNQCAii6s+GuDfTQiviVQDtWmdtHAN+xU3to7MepvVhwHsqtQnZXKTtZuwwxn82FNl7A5RYD3GVFW+wG6AsGLIdESrWxySoL6Kx8QmNpMEVg8acT/ywzW/RnUXS5vU7GIi8GA0vtyBo24R9KQKBgQDIlf/R9+iNk9oXlbB/k4um9eVvBBS7l5cx4E5Id5Dpp4kGZfPZEa7oDsEUstZZM9mgQLJK/noNWbcf0+BohCR5ux7SC12qIoxwN3k4BzTDqrS8BzFuVVp5PELUsf/uCbRn05iMzpiDUhj3Vde04wvjHYIobfKlZO2HeSWXCpUH/wKBgQC8wSuU6ck90pEY5QMKmZ3wYK1g3PsQOirv3Gmde+nbu7PePsuuYQJfBAQTwCZeXJezgtKP+PjOm2Nn6vhrhpB9YxvD2s0ijET1TG23i5L1myHQYNZFdJJnXgXUjqcX7v5ODMYA7QTqEBPXRnbGRK7fx66rU3dMQ/LD46+wyaFeUQKBgA4QTk53dkuu6SSsLyLSwoDjTsHY5Gc+urAZjQORtoxbXcUgEtfOYJgOqMT9wP+iHgkZYCbX7tDO0IMfxOUvFqueTgvmFhwergAUM6CVCMMLTf689l9JBr3nVrw4+rvC3G5HLLP6rEDQ2cVFtIkPPj8fS4fwJYopKGpOOS9843QbAoGBAMoHH8LqoZ50FLsospx/hJe24Cd8wCgQTXSa/hMqNZ1999JDhftMt7R0ZdB1he2LReACe0K9ntBU4H4u225zZ3wZlyOfoyerAHuLK/ysNlgIIzblZlOxbBJ64Kul8leXzlYy3tOZuZ997KqBcWPCE3LUBBNvM6E3blJUnlmJAVoi") @@ -47,6 +47,24 @@ public class AlipayConfigDto { // .setAppId("2021004145625815") // .setPrivateKey("MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCAjDBuS8K/IJb9ui+KuNm/sTUdEiaji4BNpZ92avO1N5JpNlGmac6ec4p3tNFT950sBLcQkClcUpQxUHQzAT6DYNNXOKyvfI/EmcqwCw6PaMNLs/8cV//J2WWZBUhLaOsjKurpm9/3W5MnTh4BGxIfBoeBMA8f8K3BgKdmyKtvIEV2h2cyjsMskdn+g6oNZcmWcms0pvpPHyH46mRaGFhpp0v19wX3WsamGldh1L2VntmaDN3C2XbSrXv90XYp5bEUqwTbLwXpMAlzTibF56d/iqv9oYi8cpAKougUFLOymnbutLNs2tLrEDSFwHcmG2/wbZHybZyYcIgFgv4arf+tAgMBAAECggEAf7hKKlw1y6Z6vvAtalxNZUuRZSfyog3p1bwYWxTavZPQcZ7Zs0lvVDmiO1u5m/7q96BbryY9IhCeUv0H5uF2lhwu/3s9AEL3qTPQkeb6eXxyhhX6A9RfPdM1Qbtg4CQHdHKg4qjP9znSVHwmDZ0y/QaEvdPdQzPjv92u9c2tn4N4x6XyBYcU5gzxiJNnIugCmBgcJo/3H2fgV+XXEhORPvy5of9b4oATHEaLS/8dAS2wuOjhzaGS4MXp3VkXn3XaYjwSzaL03qYWA+xm+aO5sJv8bmqZW7sNVck5o3sPo7cQ4VkBFVzyrRdmJcxcSRJ9MsB9JsrhoKI8pgaXrVie4QKBgQDU2vai0lpBIK/0jzRpPNoqdT8lnafnnWni8nU4kfAh+gCLi+HBPhQRT0kv4unQc2q2/gALE7sgZVO00JGY5a3R0orsojPoUSZlpypGW7GGqKy576NHn0nw4o/PdfysT92VWgt1hlfTf6qfCDhfE9APU+RGvlSWXcT8nxVel3iUaQKBgQCamoJN6+4v+chJvL2nqV8NVVRLp0vDIHxs1QOtKwUodx8Qp1D6CJYtavCXn8aNUFVNQJPJ7TQPpJjXP2rI4SN01weDwx+I+wh8PBGHV6/234R+6TvFgY1PrYgCdfNP4i/E7B4uyEhAxdU73PB8qkqRAeJGok05p7oG71KCOBiYpQKBgEZfGflcuDAeAW5GRhqg3rP4zWa/R7qgZVh9tll8jjp9b96y4XFE99d9MgId8BVVgyt6sEL5Q/2C4ni+F9TH4n6jMADp42VkJuCmsqhOOlP9whU67+2G8Sgtj0QUivPg964f9ffl8XVgGOW5DwIIB9p5btggptCLscufQK5kP545AoGADBvf6tR4wl8w9b2HqTMV08iEIqzGvVC1Dh0c/Zop/EJgN4CzUfIMOSBwGaAVAApzs+pD6QPgGP2OTwWTioo/qa4R05sbxDHNN1XJFa2jhZV6HiqMWOrNs5jm1zJ/zRjtHuJTdtyO9CvKiLbESy9XScY4/8lEfSiK5HIoJzTXkFUCgYAkYkvkW6psJpWj05XWq44UN0n6QOU/Igl35Um/iuOMVhsTmIt09STQVTuzJzfH82+sCqoRsD1blE5unKNUC1DK77aNKTv3Z0dxN9R7FAyfZRiYQXTrbBPBqWjay6FCNxn8e8UsJN4Z6FIV2LGlQI114krSap1MALKLVvnld0NaUQ==") // .setAlipayPublicKey("MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAiQkrz+emAuS1mB3KKDOMmAZRd/BlPbh7fAIHAqAj1+QCZNcV3o2BTLIIqnuKpSlFXDG3uDzp2VsBxcizXuBbFyPGylnD9CgCj5abyh3+FIHPAZ2IM3TtpqImZ0TSPGXrMli4Nir7MvZktgccCqQKCC4o6iaDGz+UwWwJUIPna8fm2tiTZ+KH150CZbKVj4ZGNpBh5XSV/1dRgyQIV9D/EwSbkZ0n6VgKQLJBi0C2UE3QB17aL1Ir6+gDXIDbknN8O7GUD3aMGdThYdSRUb5wp9CZ5qfV7vCS/CgaRo38nhH3NOzkTL+7v0m1ZDHPmqEkn9VzZN6sCQdL7PoAOjHOCwIDAQAB") +// .setDomain("https://openapi.alipay.com/gateway.do"); + } + + public static AlipayConfigDto getDefaultConfig() { +// return new AlipayConfigDto() +// .setAppId("2021006121646825") +// .setPrivateKey("MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCz3FkdffxZibdwis9W7eOW1dEjGAbSvRDL2ikfeCIW5KZNoIjUqxI0mIoUlLRRKO71QLHZS1Vb2aJp8jeOAqIPa8e76HTneQEzk3FGA8gpraSGvbadHWzvxnmYKsts1TBiEZQL82ySJXhQTJvZ6jyDM7s6wHHUnrH+Qi29QpppQ1sxsoJeCtajUgRg3btD6XbBcyFAX3pzM56Kw9eaIjZoD8WToZOM/Y3sqNL2uo8lLqcIpTrI7Pq5ZOspmBQ+t8v3rS9IdDZZMvd0trzS67AXwHz8rKPBT/lL1A4iHnXCHUvktusX1fPs3/RGY/a7PIddaBLnfY0GcueE16K7QcrXAgMBAAECggEAbSdT2eckp75BWoaTcGEs1tRqeM7TDT/6moyKmnOQ1K3tE31SrSYpBUxxuC3LBNo/sw2RIZtrcTOyMnPyLTgB3DP/4lUf5X51MTTQ8LnI1ypvh+pIki9Sdm3QS33lOOZk149tdpdDk6ozyx/DEcvq74EMpoo2SuAIi5LkKVDrXuehvGA/WeXtpmuPgqRFdIA+JBlA3knHk5XEQY/k2Y31gq5oCwNL9iT9OAZqVkukE6EnvCXE9t2rAV4/snYilaf/UaO+ktgEwSbPBQ8YKlovDAarMBbGtgr6E174A9djlPyR+W/fgx8rlTwSWtieb9MkO8LN3KSxgVs0kY5U8OHg8QKBgQDljJq9kTFHare+W/fAXdUy3tJprfNQCAii6s+GuDfTQiviVQDtWmdtHAN+xU3to7MepvVhwHsqtQnZXKTtZuwwxn82FNl7A5RYD3GVFW+wG6AsGLIdESrWxySoL6Kx8QmNpMEVg8acT/ywzW/RnUXS5vU7GIi8GA0vtyBo24R9KQKBgQDIlf/R9+iNk9oXlbB/k4um9eVvBBS7l5cx4E5Id5Dpp4kGZfPZEa7oDsEUstZZM9mgQLJK/noNWbcf0+BohCR5ux7SC12qIoxwN3k4BzTDqrS8BzFuVVp5PELUsf/uCbRn05iMzpiDUhj3Vde04wvjHYIobfKlZO2HeSWXCpUH/wKBgQC8wSuU6ck90pEY5QMKmZ3wYK1g3PsQOirv3Gmde+nbu7PePsuuYQJfBAQTwCZeXJezgtKP+PjOm2Nn6vhrhpB9YxvD2s0ijET1TG23i5L1myHQYNZFdJJnXgXUjqcX7v5ODMYA7QTqEBPXRnbGRK7fx66rU3dMQ/LD46+wyaFeUQKBgA4QTk53dkuu6SSsLyLSwoDjTsHY5Gc+urAZjQORtoxbXcUgEtfOYJgOqMT9wP+iHgkZYCbX7tDO0IMfxOUvFqueTgvmFhwergAUM6CVCMMLTf689l9JBr3nVrw4+rvC3G5HLLP6rEDQ2cVFtIkPPj8fS4fwJYopKGpOOS9843QbAoGBAMoHH8LqoZ50FLsospx/hJe24Cd8wCgQTXSa/hMqNZ1999JDhftMt7R0ZdB1he2LReACe0K9ntBU4H4u225zZ3wZlyOfoyerAHuLK/ysNlgIIzblZlOxbBJ64Kul8leXzlYy3tOZuZ997KqBcWPCE3LUBBNvM6E3blJUnlmJAVoi") +// .setAlipayPublicKey("MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAiQkrz+emAuS1mB3KKDOMmAZRd/BlPbh7fAIHAqAj1+QCZNcV3o2BTLIIqnuKpSlFXDG3uDzp2VsBxcizXuBbFyPGylnD9CgCj5abyh3+FIHPAZ2IM3TtpqImZ0TSPGXrMli4Nir7MvZktgccCqQKCC4o6iaDGz+UwWwJUIPna8fm2tiTZ+KH150CZbKVj4ZGNpBh5XSV/1dRgyQIV9D/EwSbkZ0n6VgKQLJBi0C2UE3QB17aL1Ir6+gDXIDbknN8O7GUD3aMGdThYdSRUb5wp9CZ5qfV7vCS/CgaRo38nhH3NOzkTL+7v0m1ZDHPmqEkn9VzZN6sCQdL7PoAOjHOCwIDAQAB") +// .setDomain("https://openapi.alipay.com"); + return new AlipayConfigDto() + .setAppId("2021004174605036") + .setPrivateKey("MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQD48HaUoV7OH7os+9L01kHgxzwIhJick4OkFq4aHsntsXEJ J3gedhuEZtV8oHKZ30DPW12IJ4S8NXtpr8OWaqrAPFonf4wVaRY1d0yIAea57kfLEn9oOEEy4FzARgMNDkyxC+/3OUdGbLHpTjfVX3gusXsEhUDy1/WewihAkoNYF37+W3W/uVLzeWoPq0EcUbRv/G/t/p6gL69ltsMAiVFG4Q/Yk24YAN6lYgBPNLXUEwQ1Q+T+1omjfavHgvarKOp33z3JOUH+aGOmDsJ5Y9gyGtJzOCipAd8Zcv+T1ygsEzZYO1/gzcbPnfO1ShqStCHzssuw8FBVx2JdfQKXKMMNAgMBAAECggEAVTrO/pg5Q00titU1Jspsh67u6OOs9H605Ws2dI7yB8VmtAGlaJh7V1t14FN2qSP8poHbhhAxq9aLyGV7C3a9u09udnN+3J28EtYjh7VO732bavWMVXxdJjQWzWWrCb9JlpxFrlkYBA6W4w/6ob0sAqCVQ7jzwbEa0R4cde8ztOa5nysKSfr4YTSs0gqvoiC6fmg8eiRJraEQBoYz9VkKFtOhhh/4w5FhVcYQ2gQvZ3kK3QVuD1eJIQKlCtz8qaox9lXKDiZT4SCmnKshdUL0u5TYIcYeBjZmhJz0Q50KHcpZrCs5y7I0+vRBH3hU+TKSQt7ureymwhbwWMHScLV2gQKBgQD+58SHXhr5M8NGagAmTdsgmCnNv2kOYMd4STyPMY10SVwCv1Bk808ZuP+7e558J1b5/OuDLI5dLq6xrZ/1wLv1G++XqxI00hlFuWS5mUGJVcXotT1mw20rVeUILc7Qe3mLvbMGgfyKf4A7Qa5SSZ4bDeDTJYaFxyiQ281hMzDuPQKBgQD6AiL/Na2/uPH4CG6juwpjYvYVUcjK+7gbRwf3wWsWMpk90Z4ju2iUiP5c1J/oK9P+1T3PIr6M4Xjza8JJj+r9KC/PVB0gBv6vVM96cDpKUEy/UMpcn/T81vqj/Z+WEOODU8Ms6NiTTm+u9ldvpCjbu0u8M+9c0JeIyadJvSTFEQKBgQCsxmFyM3nq8YfpgU2qqNjfBeRH3faSVUy+nj1a/YZYjKS+A/i1BCnYUImeBVNN6chNV342ggvY4xxruDiU9Vcw8wd58O09Oi8BEIFSP6upL6cebUI6Fjo3xlegLJRiwV6INkNTJOYM5hD/mSxUACwXQFfkJipBINXBIgraWD1RLQKBgQCj49axWq0F6+WjZVOyPaD3uh37p9trRUxRhWTxw3fB23WdktaKMgbCqHOmwzP4bRLSEVQtf2dOz1gMqu14b8HqJvgAf/F/11YJ9hz09LEhmjZVjE68HZfqT7uK2W5OX8/lfXmK7TFcj6SjG5YB96lZMhTZ0WnufEd6QkdKDZYXIQKBgQD9GDTcIMbFwbEaKHnfZaTD3f876EGRgsgrCxwdEk7LBCRPwWo7yI929M4psIlpNwNeiyjBkBunWIVkpznp6qPtJqagIPUYesU4f5v6/okq5wcpaNKSkWbIvWVLaLGOiA1aeGJtbpMpyClbSr52puHpRRdvAiIEQ74yYh0JX8q96g==") + .setAlipayPublicKey("MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAiQkrz+emAuS1mB3KKDOMmAZRd/BlPbh7fAIHAqAj1+QCZNcV3o2BTLIIqnuKpSlFXDG3uDzp2VsBxcizXuBbFyPGylnD9CgCj5abyh3+FIHPAZ2IM3TtpqImZ0TSPGXrMli4Nir7MvZktgccCqQKCC4o6iaDGz+UwWwJUIPna8fm2tiTZ+KH150CZbKVj4ZGNpBh5XSV/1dRgyQIV9D/EwSbkZ0n6VgKQLJBi0C2UE3QB17aL1Ir6+gDXIDbknN8O7GUD3aMGdThYdSRUb5wp9CZ5qfV7vCS/CgaRo38nhH3NOzkTL+7v0m1ZDHPmqEkn9VzZN6sCQdL7PoAOjHOCwIDAQAB") + .setDomain("https://openapi.alipay.com/gateway.do"); +// return new AlipayConfigDto() +// .setAppId("2021004145625815") +// .setPrivateKey("MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCAjDBuS8K/IJb9ui+KuNm/sTUdEiaji4BNpZ92avO1N5JpNlGmac6ec4p3tNFT950sBLcQkClcUpQxUHQzAT6DYNNXOKyvfI/EmcqwCw6PaMNLs/8cV//J2WWZBUhLaOsjKurpm9/3W5MnTh4BGxIfBoeBMA8f8K3BgKdmyKtvIEV2h2cyjsMskdn+g6oNZcmWcms0pvpPHyH46mRaGFhpp0v19wX3WsamGldh1L2VntmaDN3C2XbSrXv90XYp5bEUqwTbLwXpMAlzTibF56d/iqv9oYi8cpAKougUFLOymnbutLNs2tLrEDSFwHcmG2/wbZHybZyYcIgFgv4arf+tAgMBAAECggEAf7hKKlw1y6Z6vvAtalxNZUuRZSfyog3p1bwYWxTavZPQcZ7Zs0lvVDmiO1u5m/7q96BbryY9IhCeUv0H5uF2lhwu/3s9AEL3qTPQkeb6eXxyhhX6A9RfPdM1Qbtg4CQHdHKg4qjP9znSVHwmDZ0y/QaEvdPdQzPjv92u9c2tn4N4x6XyBYcU5gzxiJNnIugCmBgcJo/3H2fgV+XXEhORPvy5of9b4oATHEaLS/8dAS2wuOjhzaGS4MXp3VkXn3XaYjwSzaL03qYWA+xm+aO5sJv8bmqZW7sNVck5o3sPo7cQ4VkBFVzyrRdmJcxcSRJ9MsB9JsrhoKI8pgaXrVie4QKBgQDU2vai0lpBIK/0jzRpPNoqdT8lnafnnWni8nU4kfAh+gCLi+HBPhQRT0kv4unQc2q2/gALE7sgZVO00JGY5a3R0orsojPoUSZlpypGW7GGqKy576NHn0nw4o/PdfysT92VWgt1hlfTf6qfCDhfE9APU+RGvlSWXcT8nxVel3iUaQKBgQCamoJN6+4v+chJvL2nqV8NVVRLp0vDIHxs1QOtKwUodx8Qp1D6CJYtavCXn8aNUFVNQJPJ7TQPpJjXP2rI4SN01weDwx+I+wh8PBGHV6/234R+6TvFgY1PrYgCdfNP4i/E7B4uyEhAxdU73PB8qkqRAeJGok05p7oG71KCOBiYpQKBgEZfGflcuDAeAW5GRhqg3rP4zWa/R7qgZVh9tll8jjp9b96y4XFE99d9MgId8BVVgyt6sEL5Q/2C4ni+F9TH4n6jMADp42VkJuCmsqhOOlP9whU67+2G8Sgtj0QUivPg964f9ffl8XVgGOW5DwIIB9p5btggptCLscufQK5kP545AoGADBvf6tR4wl8w9b2HqTMV08iEIqzGvVC1Dh0c/Zop/EJgN4CzUfIMOSBwGaAVAApzs+pD6QPgGP2OTwWTioo/qa4R05sbxDHNN1XJFa2jhZV6HiqMWOrNs5jm1zJ/zRjtHuJTdtyO9CvKiLbESy9XScY4/8lEfSiK5HIoJzTXkFUCgYAkYkvkW6psJpWj05XWq44UN0n6QOU/Igl35Um/iuOMVhsTmIt09STQVTuzJzfH82+sCqoRsD1blE5unKNUC1DK77aNKTv3Z0dxN9R7FAyfZRiYQXTrbBPBqWjay6FCNxn8e8UsJN4Z6FIV2LGlQI114krSap1MALKLVvnld0NaUQ==") +// .setAlipayPublicKey("MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAiQkrz+emAuS1mB3KKDOMmAZRd/BlPbh7fAIHAqAj1+QCZNcV3o2BTLIIqnuKpSlFXDG3uDzp2VsBxcizXuBbFyPGylnD9CgCj5abyh3+FIHPAZ2IM3TtpqImZ0TSPGXrMli4Nir7MvZktgccCqQKCC4o6iaDGz+UwWwJUIPna8fm2tiTZ+KH150CZbKVj4ZGNpBh5XSV/1dRgyQIV9D/EwSbkZ0n6VgKQLJBi0C2UE3QB17aL1Ir6+gDXIDbknN8O7GUD3aMGdThYdSRUb5wp9CZ5qfV7vCS/CgaRo38nhH3NOzkTL+7v0m1ZDHPmqEkn9VzZN6sCQdL7PoAOjHOCwIDAQAB") // .setDomain("https://openapi.alipay.com/gateway.do"); } } From 021a837c1bd2c38de9c21b1d69569bca411d4b24 Mon Sep 17 00:00:00 2001 From: gong <1157756119@qq.com> Date: Fri, 9 Jan 2026 18:18:53 +0800 Subject: [PATCH 071/133] =?UTF-8?q?=E5=BE=AE=E4=BF=A1=20Wechatpay-Serial?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../aggregation-pay/src/main/java/com/czg/EntryManager.java | 6 +++--- .../com/czg/third/alipay/dto/config/AlipayConfigDto.java | 6 ++++++ .../src/main/java/com/czg/third/wechat/WechatReqUtils.java | 4 ++-- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/EntryManager.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/EntryManager.java index 5743e277b..d345c25ef 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/EntryManager.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/EntryManager.java @@ -370,10 +370,10 @@ public class EntryManager { // uploadParamImage(merchantDto); verifyEntryParam(merchantDto); -// uploadParamImage(merchantDto); + uploadParamImage(merchantDto); // System.out.println(merchantDto); -// entryMerchant(merchantDto, PayCst.Platform.WECHAT); - entryMerchant(merchantDto, PayCst.Platform.ALIPAY); + entryMerchant(merchantDto, PayCst.Platform.WECHAT); +// entryMerchant(merchantDto, PayCst.Platform.ALIPAY); // entryMerchant(merchantDto, PayCst.Platform.WECHAT, PayCst.Platform.ALIPAY); } diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/dto/config/AlipayConfigDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/dto/config/AlipayConfigDto.java index a0474c4ac..bcf7d497b 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/dto/config/AlipayConfigDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/dto/config/AlipayConfigDto.java @@ -32,6 +32,9 @@ public class AlipayConfigDto { */ private String domain; + /** + * 第三方应用 签约当面付 + */ public static AlipayConfigDto getThirdDefaultConfig() { return new AlipayConfigDto() .setAppId("2021006121646825") @@ -50,6 +53,9 @@ public class AlipayConfigDto { // .setDomain("https://openapi.alipay.com/gateway.do"); } + /** + * 直付通商户配置 + */ public static AlipayConfigDto getDefaultConfig() { // return new AlipayConfigDto() // .setAppId("2021006121646825") diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatReqUtils.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatReqUtils.java index 662ca11ad..6bf217918 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatReqUtils.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatReqUtils.java @@ -56,14 +56,14 @@ public class WechatReqUtils { HttpRequest request = switch (method) { case "POST" -> HttpUtil.createPost(configDto.getDomain() + url) .header("Authorization", authorization) - .header("Wechatpay-Serial", configDto.getSerialNumber()) + .header("Wechatpay-Serial", configDto.getPublicKeyId()) .charset(StandardCharsets.UTF_8) .contentType("application/json") .body(body ); case "GET" -> HttpUtil.createGet(configDto.getDomain() + url) .header("Authorization", authorization) - .header("Wechatpay-Serial", configDto.getSerialNumber()) + .header("Wechatpay-Serial", configDto.getPublicKeyId()) .charset(StandardCharsets.UTF_8) .contentType("application/json"); default -> throw new CzgException("不支持的请求方法"); From 38f1dc9d1f658ad991a8be3014b013f758d826f3 Mon Sep 17 00:00:00 2001 From: wangw <1594593906@qq.com> Date: Fri, 9 Jan 2026 18:21:44 +0800 Subject: [PATCH 072/133] =?UTF-8?q?=E5=9B=9E=E5=A1=AB=E4=B8=8A=E4=BC=A0id?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/czg/mq/EntryManagerMqListener.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/cash-api/order-server/src/main/java/com/czg/mq/EntryManagerMqListener.java b/cash-api/order-server/src/main/java/com/czg/mq/EntryManagerMqListener.java index 440802876..000cb527e 100644 --- a/cash-api/order-server/src/main/java/com/czg/mq/EntryManagerMqListener.java +++ b/cash-api/order-server/src/main/java/com/czg/mq/EntryManagerMqListener.java @@ -1,6 +1,7 @@ package com.czg.mq; import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson2.JSONObject; import com.czg.EntryManager; import com.czg.PayCst; import com.czg.config.RabbitConstants; @@ -87,10 +88,16 @@ public class EntryManagerMqListener { } EntryRespDto resp = EntryManager.entryMerchant(entry, platform.toArray(new String[0])); ShopDirectMerchant merchant = new ShopDirectMerchant(); + merchant.setMerchantBaseInfo(JSONObject.toJSONString(entry.getMerchantBaseInfo())); + merchant.setLegalPersonInfo(JSONObject.toJSONString(entry.getLegalPersonInfo())); + merchant.setBusinessLicenceInfo(JSONObject.toJSONString(entry.getBusinessLicenceInfo())); + merchant.setStoreInfo(JSONObject.toJSONString(entry.getStoreInfo())); + merchant.setSettlementInfo(JSONObject.toJSONString(entry.getSettlementInfo())); + + merchant.setWechatApplyId(resp.getWechatApplyId()); merchant.setWechatStatus(resp.getWechatStatus()); merchant.setWechatErrorMsg(resp.getWechatErrorMsg()); - merchant.setAlipayOrderId(resp.getAlipayOrderId()); merchant.setAlipayStatus(resp.getAlipayStatus()); merchant.setAlipayAuthInfo(resp.getAlipayAuthInfo()); From a6991905b8f1c7ac5d79e5caa9e68013f98998ab Mon Sep 17 00:00:00 2001 From: wangw <1594593906@qq.com> Date: Fri, 9 Jan 2026 18:27:06 +0800 Subject: [PATCH 073/133] =?UTF-8?q?=E6=96=87=E4=BB=B6=20=E8=BF=87=E5=A4=A7?= =?UTF-8?q?=20=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/czg/third/wechat/WechatEntryManager.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatEntryManager.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatEntryManager.java index 61dd7d808..57c64e686 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatEntryManager.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatEntryManager.java @@ -21,6 +21,7 @@ import com.czg.third.wechat.dto.resp.WechatQueryStateResp; import com.czg.utils.UploadFileUtil; import com.wechat.pay.java.core.Config; import com.wechat.pay.java.core.cipher.PrivacyEncryptor; +import com.wechat.pay.java.core.exception.MalformedMessageException; import com.wechat.pay.java.service.file.FileUploadService; import com.wechat.pay.java.service.file.model.FileUploadResponse; import lombok.extern.slf4j.Slf4j; @@ -203,6 +204,8 @@ public class WechatEntryManager { ); return uploadResponse.getMediaId(); + } catch (MalformedMessageException e) { + log.error("微信上传图片报错,URL:{}", url); } catch (Exception e) { log.error("微信上传图片报错,URL:{},错误信息:{}", url, e.getMessage(), e); } From 89a98123e7ab3a0732d74c7df981b4de78c03792 Mon Sep 17 00:00:00 2001 From: wangw <1594593906@qq.com> Date: Fri, 9 Jan 2026 18:34:13 +0800 Subject: [PATCH 074/133] =?UTF-8?q?=E6=96=87=E4=BB=B6=20=E8=BF=87=E5=A4=A7?= =?UTF-8?q?=20=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/czg/third/wechat/WechatEntryManager.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatEntryManager.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatEntryManager.java index 57c64e686..190c08d52 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatEntryManager.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatEntryManager.java @@ -205,9 +205,11 @@ public class WechatEntryManager { return uploadResponse.getMediaId(); } catch (MalformedMessageException e) { - log.error("微信上传图片报错,URL:{}", url); + log.error("微信上传图片报错1,URL:{}", url); } catch (Exception e) { - log.error("微信上传图片报错,URL:{},错误信息:{}", url, e.getMessage(), e); +// log.error("微信上传图片报错,URL:{},错误信息:{}", url, e.getMessage()); + log.error("微信上传图片报错,URL:{},错误信息:{}", url, e.getMessage()); + log.error("微信上传图片报错2,URL:{}", url); } return ""; } From 33c6a10d199f4e81c769d8fe9b5f00aa05e3ec62 Mon Sep 17 00:00:00 2001 From: wangw <1594593906@qq.com> Date: Fri, 9 Jan 2026 18:37:12 +0800 Subject: [PATCH 075/133] =?UTF-8?q?=E6=96=87=E4=BB=B6=20=E8=BF=87=E5=A4=A7?= =?UTF-8?q?=20=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/czg/third/wechat/WechatEntryManager.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatEntryManager.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatEntryManager.java index 190c08d52..d0a5604d6 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatEntryManager.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatEntryManager.java @@ -207,8 +207,6 @@ public class WechatEntryManager { } catch (MalformedMessageException e) { log.error("微信上传图片报错1,URL:{}", url); } catch (Exception e) { -// log.error("微信上传图片报错,URL:{},错误信息:{}", url, e.getMessage()); - log.error("微信上传图片报错,URL:{},错误信息:{}", url, e.getMessage()); log.error("微信上传图片报错2,URL:{}", url); } return ""; From 15a631383b29c342c84f6c87312c316c5cd37bda Mon Sep 17 00:00:00 2001 From: gong <1157756119@qq.com> Date: Mon, 12 Jan 2026 09:42:37 +0800 Subject: [PATCH 076/133] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E6=9F=A5=E8=AF=A2?= =?UTF-8?q?=E9=93=B6=E8=A1=8C=E6=94=AF=E8=A1=8C=E5=88=97=E8=A1=A8=E4=BD=BF?= =?UTF-8?q?=E7=94=A8=20=E5=BE=AE=E4=BF=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/czg/EntryManager.java | 31 ++++--- .../java/com/czg/dto/resp/BankBranchDto.java | 12 +++ .../czg/dto/resp/WechatBankBranchRespDto.java | 82 +++++++++++++++++++ .../czg/third/wechat/WechatEntryManager.java | 11 ++- 4 files changed, 122 insertions(+), 14 deletions(-) create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/dto/resp/WechatBankBranchRespDto.java diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/EntryManager.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/EntryManager.java index d345c25ef..f778c2ad9 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/EntryManager.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/EntryManager.java @@ -3,10 +3,7 @@ package com.czg; import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.StrUtil; import com.czg.dto.req.*; -import com.czg.dto.resp.BankBranchDto; -import com.czg.dto.resp.EntryRespDto; -import com.czg.dto.resp.EntryThirdRespDto; -import com.czg.dto.resp.QueryStatusResp; +import com.czg.dto.resp.*; import com.czg.exception.CzgException; import com.czg.third.alipay.AlipayEntryManager; import com.czg.third.alipay.AlipayIsvEntryManager; @@ -38,6 +35,17 @@ public class EntryManager { return AlipayEntryManager.queryBankBranchList(null, instId, province, city); } + /** + * 查询银行支行列表 + * 走微信查询 + * + * @param bankAliceCode 银行代码 + * @param cityCode 城市编码 + */ + public static WechatBankBranchRespDto queryBankBranchList(String bankAliceCode, String cityCode) { + return WechatEntryManager.queryBankBranchList(null, bankAliceCode, cityCode, 0, 200); + } + /** * 查询微信进件状态 * @@ -363,16 +371,19 @@ public class EntryManager { public static void main(String[] args) { + WechatBankBranchRespDto respDto = queryBankBranchList("1000009547", "931"); + System.out.println(respDto); - AggregateMerchantDto merchantDto = getTestMerchantEntryData(); +// AggregateMerchantDto merchantDto = getTestMerchantEntryData(); +// +//// verifyEntryParam(merchantDto); +//// uploadParamImage(merchantDto); +// // verifyEntryParam(merchantDto); // uploadParamImage(merchantDto); - - verifyEntryParam(merchantDto); - uploadParamImage(merchantDto); -// System.out.println(merchantDto); - entryMerchant(merchantDto, PayCst.Platform.WECHAT); +//// System.out.println(merchantDto); +// entryMerchant(merchantDto, PayCst.Platform.WECHAT); // entryMerchant(merchantDto, PayCst.Platform.ALIPAY); // entryMerchant(merchantDto, PayCst.Platform.WECHAT, PayCst.Platform.ALIPAY); } diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/resp/BankBranchDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/resp/BankBranchDto.java index f3c473090..abc878ee3 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/resp/BankBranchDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/resp/BankBranchDto.java @@ -55,4 +55,16 @@ public class BankBranchDto { * 机构全称 */ private String instName; + + /** + * 联行支行边行 + */ + @JSONField(name = "bank_branch_id") + private String bankBranchId; + + /** + * 联行支行名称 + */ + @JSONField(name = "bank_branch_name") + private String bankBranchName; } diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/resp/WechatBankBranchRespDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/resp/WechatBankBranchRespDto.java new file mode 100644 index 000000000..d76089038 --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/resp/WechatBankBranchRespDto.java @@ -0,0 +1,82 @@ +package com.czg.dto.resp; + +import com.alibaba.fastjson2.annotation.JSONField; +import lombok.Data; + +import java.util.List; + +/** + * 微信银行支行列表 + * @author yjjie + * @date 2026/1/12 09:32 + */ +@Data +public class WechatBankBranchRespDto { + + // { + // "total_count" : 107, + // "count" : 1, + // "data" : [ + // { + // "bank_branch_name" : "招商银行股份有限公司北京分行", + // "bank_branch_id" : "308100005019" + // } + // ], + // "offset" : 100, + // "links" : { + // "next" : "/v3/capital/capitallhh/banks/1000009561/branches?offset=101&limit=1", + // "prev" : "/v3/capital/capitallhh/banks/1000009561/branches?offset=99&limit=1", + // "self" : "/v3/capital/capitallhh/banks/1000009561/branches?offset=100&limit=1" + // }, + // "account_bank" : "招商银行", + // "account_bank_code" : 1001, + // "bank_alias" : "招商银行", + // "bank_alias_code" : "1000009561" + //} + + /** + * 开户银行 + */ + @JSONField(name = "account_bank") + private String accountBank; + + /** + * 开户银行编码 + */ + @JSONField(name = "account_bank_code") + private Integer accountBankCode; + + /** + * 银行别名 + */ + @JSONField(name = "bank_alias") + private String bankAlias; + + /** + * 银行别名编码 + */ + @JSONField(name = "bank_alias_code") + private String bankAliasCode; + + /** + * 银行支行列表 + */ + @JSONField(name = "data") + private List data; + + + @Data + public static class WechatBankBranchList { + /** + * 银行支行名称 + */ + @JSONField(name = "bank_branch_name") + private String bankBranchName; + + /** + * 银行支行编号 + */ + @JSONField(name = "bank_branch_id") + private String bankBranchId; + } +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatEntryManager.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatEntryManager.java index d0a5604d6..2f9154d28 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatEntryManager.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatEntryManager.java @@ -6,6 +6,7 @@ import com.czg.PayCst; import com.czg.dto.req.*; import com.czg.dto.resp.EntryThirdRespDto; import com.czg.dto.resp.QueryStatusResp; +import com.czg.dto.resp.WechatBankBranchRespDto; import com.czg.exception.CzgException; import com.czg.third.wechat.dto.config.WechatPayConfigDto; import com.czg.third.wechat.dto.req.entry.*; @@ -140,10 +141,10 @@ public class WechatEntryManager { return JSONObject.parseObject(resp); } - public static JSONObject queryBankBranchList(WechatPayConfigDto configDto, String bankAliceCode, String cityCode, Integer offset, Integer limit) { + public static WechatBankBranchRespDto queryBankBranchList(WechatPayConfigDto configDto, String bankAliceCode, String cityCode, Integer offset, Integer limit) { String resp = WechatReqUtils.getReq(configDto, "/v3/capital/capitallhh/banks/" + bankAliceCode + "/branches", Map.of("city_code", cityCode, "offset", offset, "limit", limit)); log.info("微信查询银行支行列表:{}", resp); - return JSONObject.parseObject(resp); + return JSONObject.parseObject(resp, WechatBankBranchRespDto.class); } public static JSONObject queryProvinceList(WechatPayConfigDto configDto) { @@ -345,8 +346,10 @@ public class WechatEntryManager { Integer limit = 100; JSONObject resp = queryBankList(null, offset, limit); -// queryBankBranchList(dto, "1000009561", "110000", offset, limit); -// queryBankBranchList(dto, "1000009561", "29", offset, limit); +// queryProvinceList(null); +// queryCityList(null, "28"); + queryBankBranchList(null, "1000009547", "931", offset, limit); +// queryBankBranchList(null, "1000009561", "29", offset, limit); // queryProvinceList(dto); // queryCityList(dto, "28"); From 692a504da3c032de7d336bfc08d2f7c261c0fb91 Mon Sep 17 00:00:00 2001 From: wangw <1594593906@qq.com> Date: Mon, 12 Jan 2026 10:35:49 +0800 Subject: [PATCH 077/133] =?UTF-8?q?=E9=93=B6=E8=A1=8C=E6=94=AF=E8=A1=8C=20?= =?UTF-8?q?=E5=8C=BA=E5=9F=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/EntryManagerController.java | 13 +++++------- .../controller/admin/SysCommonController.java | 2 -- .../com/czg/system/entity/SysBankInfo.java | 2 +- .../java/com/czg/system/entity/SysRegion.java | 4 ++++ .../czg/dto/resp/WechatBankBranchRespDto.java | 21 ------------------- 5 files changed, 10 insertions(+), 32 deletions(-) diff --git a/cash-api/order-server/src/main/java/com/czg/controller/admin/EntryManagerController.java b/cash-api/order-server/src/main/java/com/czg/controller/admin/EntryManagerController.java index 15e76fbec..6ba4bb73c 100644 --- a/cash-api/order-server/src/main/java/com/czg/controller/admin/EntryManagerController.java +++ b/cash-api/order-server/src/main/java/com/czg/controller/admin/EntryManagerController.java @@ -5,7 +5,7 @@ import com.czg.EntryManager; import com.czg.annotation.Debounce; import com.czg.config.RabbitPublisher; import com.czg.dto.req.AggregateMerchantDto; -import com.czg.dto.resp.BankBranchDto; +import com.czg.dto.resp.WechatBankBranchRespDto; import com.czg.order.entity.ShopDirectMerchant; import com.czg.resp.CzgResult; import com.czg.service.order.dto.AggregateMerchantVO; @@ -17,8 +17,6 @@ import jakarta.annotation.Resource; import lombok.AllArgsConstructor; import org.springframework.web.bind.annotation.*; -import java.util.List; - /** * 进件管理 * @@ -59,13 +57,12 @@ public class EntryManagerController { /** * 查询银行支行列表 * - * @param province 省份 陕西省 从 /system/admin/common/region获取 - * @param city 城市 西安市 从 /system/admin/common/region获取 - * @param instId 顶级机构ID CMB 从 /system/admin/common/bankInfo 获取 + * @param bankAliceCode 银行别名code bankAliasCode 从 /system/admin/common/bankInfo 获取 + * @param cityCode 市编码 wxProvinceCode 从 /system/admin/common/region 获取 */ @GetMapping("bankBranchList") - public CzgResult> queryBankBranchList(String province, String city, String instId) { - return CzgResult.success(EntryManager.queryBankBranchList(province, city, instId)); + public CzgResult queryBankBranchList(String bankAliceCode, String cityCode) { + return CzgResult.success(EntryManager.queryBankBranchList(bankAliceCode, cityCode)); } @GetMapping("test") diff --git a/cash-api/system-server/src/main/java/com/czg/controller/admin/SysCommonController.java b/cash-api/system-server/src/main/java/com/czg/controller/admin/SysCommonController.java index 2585c6995..d8eecea94 100644 --- a/cash-api/system-server/src/main/java/com/czg/controller/admin/SysCommonController.java +++ b/cash-api/system-server/src/main/java/com/czg/controller/admin/SysCommonController.java @@ -3,7 +3,6 @@ package com.czg.controller.admin; import com.czg.BaseQueryParam; import com.czg.resp.CzgResult; import com.czg.system.entity.SysBankInfo; -import com.czg.system.entity.SysCategoryInfo; import com.czg.system.entity.SysRegion; import com.czg.system.service.SysBankInfoService; import com.czg.system.service.SysCategoryInfoService; @@ -17,7 +16,6 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import java.util.List; -import java.util.Map; /** * 通用 diff --git a/cash-common/cash-common-service/src/main/java/com/czg/system/entity/SysBankInfo.java b/cash-common/cash-common-service/src/main/java/com/czg/system/entity/SysBankInfo.java index bc298d759..de376bb20 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/system/entity/SysBankInfo.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/system/entity/SysBankInfo.java @@ -58,7 +58,7 @@ public class SysBankInfo implements Serializable { private String bankAliasCode; /** - * 不知道干啥的 + * 是否需要支行信息 */ private Boolean needBankBranch; diff --git a/cash-common/cash-common-service/src/main/java/com/czg/system/entity/SysRegion.java b/cash-common/cash-common-service/src/main/java/com/czg/system/entity/SysRegion.java index 1b50b9e9a..2606e1d97 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/system/entity/SysRegion.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/system/entity/SysRegion.java @@ -60,6 +60,10 @@ public class SysRegion implements Serializable { * 全级别名称(如“中国|北京|北京市|东城区) */ private String fullName; + /** + * 微信区域编码 + */ + private String wxProvinceCode; /** * 子级区域 diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/resp/WechatBankBranchRespDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/resp/WechatBankBranchRespDto.java index d76089038..8cca740f0 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/resp/WechatBankBranchRespDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/resp/WechatBankBranchRespDto.java @@ -13,27 +13,6 @@ import java.util.List; @Data public class WechatBankBranchRespDto { - // { - // "total_count" : 107, - // "count" : 1, - // "data" : [ - // { - // "bank_branch_name" : "招商银行股份有限公司北京分行", - // "bank_branch_id" : "308100005019" - // } - // ], - // "offset" : 100, - // "links" : { - // "next" : "/v3/capital/capitallhh/banks/1000009561/branches?offset=101&limit=1", - // "prev" : "/v3/capital/capitallhh/banks/1000009561/branches?offset=99&limit=1", - // "self" : "/v3/capital/capitallhh/banks/1000009561/branches?offset=100&limit=1" - // }, - // "account_bank" : "招商银行", - // "account_bank_code" : 1001, - // "bank_alias" : "招商银行", - // "bank_alias_code" : "1000009561" - //} - /** * 开户银行 */ From deb3d81e0d006d6db38fe77a2f1f741d7db08ce5 Mon Sep 17 00:00:00 2001 From: wangw <1594593906@qq.com> Date: Mon, 12 Jan 2026 11:10:46 +0800 Subject: [PATCH 078/133] =?UTF-8?q?=E9=93=B6=E8=A1=8C=E6=94=AF=E8=A1=8C=20?= =?UTF-8?q?=E7=A9=BA=E5=80=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/czg/controller/admin/EntryManagerController.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cash-api/order-server/src/main/java/com/czg/controller/admin/EntryManagerController.java b/cash-api/order-server/src/main/java/com/czg/controller/admin/EntryManagerController.java index 6ba4bb73c..39e97bb4c 100644 --- a/cash-api/order-server/src/main/java/com/czg/controller/admin/EntryManagerController.java +++ b/cash-api/order-server/src/main/java/com/czg/controller/admin/EntryManagerController.java @@ -12,6 +12,7 @@ import com.czg.service.order.dto.AggregateMerchantVO; import com.czg.service.order.dto.MerchantQueryDTO; import com.czg.service.order.service.ShopDirectMerchantService; import com.czg.task.EntryManagerTask; +import com.czg.utils.AssertUtil; import com.mybatisflex.core.paginate.Page; import jakarta.annotation.Resource; import lombok.AllArgsConstructor; @@ -62,6 +63,8 @@ public class EntryManagerController { */ @GetMapping("bankBranchList") public CzgResult queryBankBranchList(String bankAliceCode, String cityCode) { + AssertUtil.isBlank(bankAliceCode, "请选择银行别名"); + AssertUtil.isBlank(cityCode, "请选择城市"); return CzgResult.success(EntryManager.queryBankBranchList(bankAliceCode, cityCode)); } From cd9eb70283ece5556569b8fcd5799950d4e9751a Mon Sep 17 00:00:00 2001 From: gong <1157756119@qq.com> Date: Mon, 12 Jan 2026 17:01:48 +0800 Subject: [PATCH 079/133] =?UTF-8?q?=E5=BE=AE=E4=BF=A1=E5=93=8D=E5=BA=94?= =?UTF-8?q?=E7=BB=93=E6=9E=9C=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/czg/EntryManager.java | 177 ++++++++++-------- .../czg/third/wechat/WechatEntryManager.java | 19 +- .../entry/WechatEntryBankAccountReqDto.java | 3 + 3 files changed, 113 insertions(+), 86 deletions(-) diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/EntryManager.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/EntryManager.java index f778c2ad9..76d70ecac 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/EntryManager.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/EntryManager.java @@ -2,12 +2,14 @@ package com.czg; import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson2.JSONObject; import com.czg.dto.req.*; import com.czg.dto.resp.*; import com.czg.exception.CzgException; import com.czg.third.alipay.AlipayEntryManager; import com.czg.third.alipay.AlipayIsvEntryManager; import com.czg.third.wechat.WechatEntryManager; +import com.czg.third.wechat.dto.req.entry.business.sales.WechatEntryStoreInfoReqDto; import com.czg.utils.AssertUtil; import com.czg.utils.AsyncTaskExecutor; import org.jetbrains.annotations.NotNull; @@ -371,102 +373,121 @@ public class EntryManager { public static void main(String[] args) { - WechatBankBranchRespDto respDto = queryBankBranchList("1000009547", "931"); - System.out.println(respDto); +// WechatBankBranchRespDto respDto = queryBankBranchList("1000009547", "931"); +// System.out.println(respDto); -// AggregateMerchantDto merchantDto = getTestMerchantEntryData(); + AggregateMerchantDto merchantDto = getTestMerchantEntryData(); // -//// verifyEntryParam(merchantDto); -//// uploadParamImage(merchantDto); + verifyEntryParam(merchantDto); + uploadParamImage(merchantDto); // // verifyEntryParam(merchantDto); // uploadParamImage(merchantDto); //// System.out.println(merchantDto); -// entryMerchant(merchantDto, PayCst.Platform.WECHAT); + EntryRespDto respDto = entryMerchant(merchantDto, PayCst.Platform.WECHAT); // entryMerchant(merchantDto, PayCst.Platform.ALIPAY); // entryMerchant(merchantDto, PayCst.Platform.WECHAT, PayCst.Platform.ALIPAY); + System.out.println(respDto); } private static AggregateMerchantDto getTestMerchantEntryData() { AggregateMerchantDto merchantDto = new AggregateMerchantDto(); - merchantDto.setMerchantCode("20220106000000000001"); + merchantDto.setMerchantCode("CZG20260112151202011"); - MerchantBaseInfoDto baseInfoDto = new MerchantBaseInfoDto(); - baseInfoDto.setUserType("1"); - baseInfoDto.setCompanyChildType("1"); - baseInfoDto.setShortName("测试商户"); - baseInfoDto.setAlipayAccount("1157756119@qq.com"); - baseInfoDto.setMccCode("A0001_B0001"); - baseInfoDto.setContactPersonType(PayCst.ContactPersonType.SUPER); - baseInfoDto.setContactName("张三"); - baseInfoDto.setContactPersonId("110101199001011234"); - baseInfoDto.setContactPersonIdStartDate("2021-01-01"); - baseInfoDto.setContactPersonIdEndDate("2025-01-01"); - baseInfoDto.setContactPhone("13800000000"); - baseInfoDto.setContactEmail("1157756119@qq.com"); - baseInfoDto.setContactAddr("广东省深圳市南山区"); - baseInfoDto.setContactIdCardFrontPic(new ImageDto("https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/20240312/31476c871c224389aea0ac4e17c964a3.jpg")); - baseInfoDto.setContactIdCardBackPic(new ImageDto("https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/20240312/31476c871c224389aea0ac4e17c964a3.jpg")); - merchantDto.setMerchantBaseInfo(baseInfoDto); + String baseInfo = "{\"alipayAccount\":\"18191655977\",\"certType\":\"0\",\"companyChildType\":\"1\",\"contactAddr\":\"西安市沣东新城石化大道西段106号沣东科技园5号楼1层5-037室\",\"contactEmail\":\"892675422@qq.com\",\"contactIdCardBackPic\":{\"alipayId\":\"\",\"url\":\"https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/1/ce731859ee644df8a4a46104b49c7696.png\",\"wechatId\":\"V1_S-iU_YpBpSKoSZFhQw3plh53G4PXHmNlhi1s88_VTk7A943tAxrkIcKErRcpFPkxG7vkMzhkT4ecN3IWxv71JwLJOzY9eQhmv6giwKWUAjk\"},\"contactIdCardFrontPic\":{\"alipayId\":\"\",\"url\":\"https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/1/e0d259f9fbcf4897b7f93f3f7d1b8e9a.png\",\"wechatId\":\"V1_oYXFrsrx4sZqiHXURjDBMB53G4PXHmPB0jH4yl2JSowqJDinBqRYIZmHrRcpFPkxsGFO-6Ci3dGvLAs-X2g2DQLJOzY9eQhmv6giwKWUAjk\"},\"contactName\":\"\",\"contactPersonId\":\"612501199212187875\",\"contactPersonIdEndDate\":\"2039-02-01\",\"contactPersonIdStartDate\":\"2019-02-01\",\"contactPersonType\":\"LEGAL\",\"contactPhone\":\"18191655977\",\"mccCode\":\"A0001_B0001\",\"shortName\":\"菲慕斯博\",\"userType\":\"1\"}"; + merchantDto.setMerchantBaseInfo(JSONObject.parseObject(baseInfo, MerchantBaseInfoDto.class)); - BusinessLicenceInfoDto businessLicenceInfoDto = new BusinessLicenceInfoDto(); - businessLicenceInfoDto.setLicenceName("测试商户"); - businessLicenceInfoDto.setLicenceNo("110101199001011234"); - businessLicenceInfoDto.setLicenceStartDate("2021-01-01"); - businessLicenceInfoDto.setLicenceEndDate("2052-01-01"); - businessLicenceInfoDto.setRegisteredAddress("广东省深圳市南山区"); - businessLicenceInfoDto.setLicensePic(new ImageDto("https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/20240312/31476c871c224389aea0ac4e17c964a3.jpg")); - merchantDto.setBusinessLicenceInfo(businessLicenceInfoDto); + String legalPersonInfo = "{\"idCardBackPic\":{\"alipayId\":\"\",\"url\":\"https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/1/bb0f77b0b3404bbd9975a4f8497494df.png\",\"wechatId\":\"V1_Kt7wB6u_YhTp_V97CU_V_x53G4PXHmOeC1YpTSt8JenBIbhCzXjNIZWHrRcpFPkxHwsAu6WQfWU6BYJ3glMBnALJOzY9eQhmv6giwKWUAjk\"},\"idCardFrontPic\":{\"alipayId\":\"\",\"url\":\"https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/1/196a6f37c5954fc395d621e5b0289cb5.png\",\"wechatId\":\"V1__G9UoJplQHSY_ychzdk7QR53G4PXHmMm845pnkw_19i0CeVtQ34dIbOHrRcpFPkxsIEMvoVq19SdOFHTsw6b3wLJOzY9eQhmv6giwKWUAjk\"},\"idCardHandPic\":{\"alipayId\":\"\",\"url\":\"https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/1/eaa5e0f9352d4e77bbf5fa133ed54564.jpg\",\"wechatId\":\"V1_mWQpc12PTPL7P7kkdUOR6h53G4PXHmPbBEOZTTwh_KJ8RdecGr9kIZuGrRcpFPkx-jdQCaZuUWIQRmxr8pm-7QLJOzY9eQhmv6giwKWUAjk\"},\"legalAddress\":\"西安市沣东新城石化大道西段106号沣东科技园5号楼1层5-037室\",\"legalGender\":\"0\",\"legalIdPersonStartDate\":\"2019-02-01\",\"legalPersonEmail\":\"892675422@qq.com\",\"legalPersonId\":\"612501199212187875\",\"legalPersonIdEndDate\":\"2039-02-01\",\"legalPersonName\":\"蔺佳佳\",\"legalPersonPhone\":\"18191655977\"}"; + merchantDto.setLegalPersonInfo(JSONObject.parseObject(legalPersonInfo, LegalPersonInfoDto.class)); - LegalPersonInfoDto legalPersonInfoDto = new LegalPersonInfoDto(); - legalPersonInfoDto.setLegalPersonName("张三"); - legalPersonInfoDto.setLegalPersonId("110101199001011234"); - legalPersonInfoDto.setLegalIdPersonStartDate("2021-01-01"); - legalPersonInfoDto.setLegalPersonIdEndDate("2055-01-01"); - legalPersonInfoDto.setLegalPersonPhone("13800000000"); - legalPersonInfoDto.setLegalPersonEmail("1157756119@qq.com"); - legalPersonInfoDto.setLegalGender("1"); - legalPersonInfoDto.setLegalAddress("广东省深圳市南山区"); - legalPersonInfoDto.setIdCardHandPic(new ImageDto("https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/20240312/31476c871c224389aea0ac4e17c964a3.jpg")); - legalPersonInfoDto.setIdCardFrontPic(new ImageDto("https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/20240312/31476c871c224389aea0ac4e17c964a3.jpg")); - legalPersonInfoDto.setIdCardBackPic(new ImageDto("https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/20240312/31476c871c224389aea0ac4e17c964a3.jpg")); - merchantDto.setLegalPersonInfo(legalPersonInfoDto); + String businessInfo = "{\"licenceEndDate\":\"2099-12-31\",\"licenceName\":\"西安菲慕斯博市场营销策划有限公司\",\"licenceNo\":\"91610131MA6TXACP28\",\"licenceStartDate\":\"2021-02-25\",\"licensePic\":{\"alipayId\":\"\",\"url\":\"https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/1/81b60f3a25494c8586159a193389aa2d.jpg\",\"wechatId\":\"V1_-Vbealekn9NZb3mT37ggpB53G4PXHmNEw41rkFGHdR1KJkYqgc5QId-HrRcpFPkxJLlN6u4U4s24lzVyTVoxPgLJOzY9eQhmv6giwKWUAjk\"},\"registeredAddress\":\"陕西省西安市高新区科技路37号海星城市广场B座2002-080室\"}"; + merchantDto.setBusinessLicenceInfo(JSONObject.parseObject(businessInfo, BusinessLicenceInfoDto.class)); - StoreInfoDto storeInfoDto = new StoreInfoDto(); - storeInfoDto.setMercProvCode("440000"); - storeInfoDto.setMercCityCode("440300"); - storeInfoDto.setMercAreaCode("440303"); - storeInfoDto.setMercProv("广东省"); - storeInfoDto.setMercCity("深圳市"); - storeInfoDto.setMercArea("南山区"); - storeInfoDto.setBusinessAddress("广东省深圳市南山区"); - storeInfoDto.setInsidePic(new ImageDto("https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/20240312/31476c871c224389aea0ac4e17c964a3.jpg")); - storeInfoDto.setDoorPic(new ImageDto("https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/20240312/31476c871c224389aea0ac4e17c964a3.jpg")); - storeInfoDto.setCashierDeskPic(new ImageDto("https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/20240312/31476c871c224389aea0ac4e17c964a3.jpg")); - merchantDto.setStoreInfo(storeInfoDto); + String storeInfo = "{\"businessAddress\":\"西安市沣东新城石化大道西段106号沣东科技园5号楼1层5-037室\",\"cashierDeskPic\":{\"alipayId\":\"\",\"url\":\"https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/1/4e52859aac754670aaf9be1c923da827.jpg\",\"wechatId\":\"V1_qFmvcdaX1XSUmknkcwKzMh53G4PXHmNYVJzGUiEs-qE-2ERQMr6XIemErRcpFPkxyCyY2DFU5QIBiaW6WamZmwLJOzY9eQhmv6giwKWUAjk\"},\"doorPic\":{\"alipayId\":\"\",\"url\":\"https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/1/2c207c6f4a764ad18e501ed10fbfad59.png\",\"wechatId\":\"V1_JPI6iQUmEXiUL2JogtdaJR53G4PXHmO3QpILvqWkLccmvi-vX4OJIdmBrRcpFPkxwNCa-m1w5XissHoA_ynwKQLJOzY9eQhmv6giwKWUAjk\"},\"insidePic\":{\"alipayId\":\"\",\"url\":\"https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/1/394b4834698a47e9b75419a5fd7f7de7.jpg\",\"wechatId\":\"V1_djcTvjUKESKADtVCmtLqmR53G4PXHmOLw9uEV3te3o7OebPqjdklIdGBrRcpFPkxy6JbIGyYEZT6XatGXNQ2YQLJOzY9eQhmv6giwKWUAjk\"},\"mercArea\":\"雁塔区\",\"mercAreaCode\":\"610113\",\"mercCity\":\"西安市\",\"mercCityCode\":\"610100\",\"mercProv\":\"陕西省\",\"mercProvCode\":\"610000\"}"; + merchantDto.setStoreInfo(JSONObject.parseObject(storeInfo, StoreInfoDto.class)); - SettlementInfoDto settlementInfoDto = new SettlementInfoDto(); - settlementInfoDto.setSettlementType("1"); - settlementInfoDto.setSettlementCardType("21"); - settlementInfoDto.setSettlementName("张三"); - settlementInfoDto.setSettlementCardNo("110101199001011234"); - settlementInfoDto.setBankMobile("13800000000"); - settlementInfoDto.setOpenAccProvinceId("440000"); - settlementInfoDto.setOpenAccCityId("440300"); - settlementInfoDto.setOpenAccAreaId("440303"); - settlementInfoDto.setOpenAccProvince("广东省"); - settlementInfoDto.setOpenAccCity("深圳市"); - settlementInfoDto.setOpenAccArea("南山区"); - settlementInfoDto.setBankName("中国工商银行"); - settlementInfoDto.setBankInstId("ICBC"); - settlementInfoDto.setBankType("1"); - settlementInfoDto.setBankBranchName("广东省深圳市南山区"); - settlementInfoDto.setBankBranchCode("440300"); - settlementInfoDto.setBankCardFrontPic(new ImageDto("https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/20240312/31476c871c224389aea0ac4e17c964a3.jpg")); - settlementInfoDto.setBankCardBackPic(new ImageDto("https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/20240312/31476c871c224389aea0ac4e17c964a3.jpg")); - settlementInfoDto.setOpenAccountLicencePic(new ImageDto("https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/20240312/31476c871c224389aea0ac4e17c964a3.jpg")); - merchantDto.setSettlementInfo(settlementInfoDto); + String settlementInfo = "{\"bankBranchCode\":\"313791000427\",\"bankBranchName\":\"西安银行高新四路支行\",\"bankCardBackPic\":{\"alipayId\":\"\",\"url\":\"https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/1/3f3bb30f89fd4441985808f4a451c9c7.jpg\",\"wechatId\":\"V1_KAo5J49VNaCiC7twEi6NfB53G4PXHmNqgVl38ZojoETk3a9m_ZLvIaeHrRcpFPkxmQ3bRK2ytADSD8Fe8v-mpALJOzY9eQhmv6giwKWUAjk\"},\"bankCardFrontPic\":{\"alipayId\":\"\",\"url\":\"https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/1/413f9170ca1d4f0893e05fd72b5e2b0e.jpg\",\"wechatId\":\"V1_GNhNtE1UYUCeRAuLsxdimR53G4PXHmNn9A4-gDbYgq47MiHxjki-IarByRcpFPkxfqldVa9taQ7W5KtWL35ppwLJOzY9eQhmv6giwKWUAjk\"},\"bankInstId\":\"XAB\",\"bankMobile\":\"18191655977\",\"bankName\":\"其他银行\",\"bankType\":\"\",\"noLegalHandSettleAuthPic\":{\"alipayId\":\"\",\"url\":\"\",\"wechatId\":\"\"},\"noLegalId\":\"\",\"noLegalIdCardBackPic\":{\"alipayId\":\"\",\"url\":\"\",\"wechatId\":\"\"},\"noLegalIdCardFrontPic\":{\"alipayId\":\"\",\"url\":\"\",\"wechatId\":\"\"},\"noLegalName\":\"\",\"noLegalSettleAuthPic\":{\"alipayId\":\"\",\"url\":\"\",\"wechatId\":\"\"},\"openAccArea\":\"雁塔区\",\"openAccAreaId\":\"610113\",\"openAccCity\":\"西安市\",\"openAccCityId\":\"610100\",\"openAccProvince\":\"陕西省\",\"openAccProvinceId\":\"610000\",\"openAccountLicencePic\":{\"alipayId\":\"\",\"url\":\"https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/1/6e5dca0822f742649ecf1666f91ad1b3.jpg\",\"wechatId\":\"V1_1S62SpAFYecG5T-DC9ewHR53G4PXHmMA49fy0uVVk5j35lE5L5njIfSGrRcpFPkxU9Fm6P6bYLY3t010FYkmAQLJOzY9eQhmv6giwKWUAjk\"},\"settlementCardNo\":\"611011580000054186\",\"settlementCardType\":\"21\",\"settlementName\":\"西安菲慕斯博市场营销策划有限公司\",\"settlementType\":\"1\"}"; + merchantDto.setSettlementInfo(JSONObject.parseObject(settlementInfo, SettlementInfoDto.class)); + + +// merchantDto.setMerchantCode("20220106000000000001"); +// +// MerchantBaseInfoDto baseInfoDto = new MerchantBaseInfoDto(); +// baseInfoDto.setUserType("1"); +// baseInfoDto.setCompanyChildType("1"); +// baseInfoDto.setShortName("测试商户"); +// baseInfoDto.setAlipayAccount("1157756119@qq.com"); +// baseInfoDto.setMccCode("A0001_B0001"); +// baseInfoDto.setContactPersonType(PayCst.ContactPersonType.SUPER); +// baseInfoDto.setContactName("张三"); +// baseInfoDto.setContactPersonId("110101199001011234"); +// baseInfoDto.setContactPersonIdStartDate("2021-01-01"); +// baseInfoDto.setContactPersonIdEndDate("2025-01-01"); +// baseInfoDto.setContactPhone("13800000000"); +// baseInfoDto.setContactEmail("1157756119@qq.com"); +// baseInfoDto.setContactAddr("广东省深圳市南山区"); +// baseInfoDto.setContactIdCardFrontPic(new ImageDto("https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/20240312/31476c871c224389aea0ac4e17c964a3.jpg")); +// baseInfoDto.setContactIdCardBackPic(new ImageDto("https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/20240312/31476c871c224389aea0ac4e17c964a3.jpg")); +// merchantDto.setMerchantBaseInfo(baseInfoDto); +// +// BusinessLicenceInfoDto businessLicenceInfoDto = new BusinessLicenceInfoDto(); +// businessLicenceInfoDto.setLicenceName("测试商户"); +// businessLicenceInfoDto.setLicenceNo("110101199001011234"); +// businessLicenceInfoDto.setLicenceStartDate("2021-01-01"); +// businessLicenceInfoDto.setLicenceEndDate("2052-01-01"); +// businessLicenceInfoDto.setRegisteredAddress("广东省深圳市南山区"); +// businessLicenceInfoDto.setLicensePic(new ImageDto("https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/20240312/31476c871c224389aea0ac4e17c964a3.jpg")); +// merchantDto.setBusinessLicenceInfo(businessLicenceInfoDto); +// +// LegalPersonInfoDto legalPersonInfoDto = new LegalPersonInfoDto(); +// legalPersonInfoDto.setLegalPersonName("张三"); +// legalPersonInfoDto.setLegalPersonId("110101199001011234"); +// legalPersonInfoDto.setLegalIdPersonStartDate("2021-01-01"); +// legalPersonInfoDto.setLegalPersonIdEndDate("2055-01-01"); +// legalPersonInfoDto.setLegalPersonPhone("13800000000"); +// legalPersonInfoDto.setLegalPersonEmail("1157756119@qq.com"); +// legalPersonInfoDto.setLegalGender("1"); +// legalPersonInfoDto.setLegalAddress("广东省深圳市南山区"); +// legalPersonInfoDto.setIdCardHandPic(new ImageDto("https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/20240312/31476c871c224389aea0ac4e17c964a3.jpg")); +// legalPersonInfoDto.setIdCardFrontPic(new ImageDto("https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/20240312/31476c871c224389aea0ac4e17c964a3.jpg")); +// legalPersonInfoDto.setIdCardBackPic(new ImageDto("https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/20240312/31476c871c224389aea0ac4e17c964a3.jpg")); +// merchantDto.setLegalPersonInfo(legalPersonInfoDto); +// +// StoreInfoDto storeInfoDto = new StoreInfoDto(); +// storeInfoDto.setMercProvCode("440000"); +// storeInfoDto.setMercCityCode("440300"); +// storeInfoDto.setMercAreaCode("440303"); +// storeInfoDto.setMercProv("广东省"); +// storeInfoDto.setMercCity("深圳市"); +// storeInfoDto.setMercArea("南山区"); +// storeInfoDto.setBusinessAddress("广东省深圳市南山区"); +// storeInfoDto.setInsidePic(new ImageDto("https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/20240312/31476c871c224389aea0ac4e17c964a3.jpg")); +// storeInfoDto.setDoorPic(new ImageDto("https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/20240312/31476c871c224389aea0ac4e17c964a3.jpg")); +// storeInfoDto.setCashierDeskPic(new ImageDto("https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/20240312/31476c871c224389aea0ac4e17c964a3.jpg")); +// merchantDto.setStoreInfo(storeInfoDto); +// +// SettlementInfoDto settlementInfoDto = new SettlementInfoDto(); +// settlementInfoDto.setSettlementType("1"); +// settlementInfoDto.setSettlementCardType("21"); +// settlementInfoDto.setSettlementName("张三"); +// settlementInfoDto.setSettlementCardNo("110101199001011234"); +// settlementInfoDto.setBankMobile("13800000000"); +// settlementInfoDto.setOpenAccProvinceId("440000"); +// settlementInfoDto.setOpenAccCityId("440300"); +// settlementInfoDto.setOpenAccAreaId("440303"); +// settlementInfoDto.setOpenAccProvince("广东省"); +// settlementInfoDto.setOpenAccCity("深圳市"); +// settlementInfoDto.setOpenAccArea("南山区"); +// settlementInfoDto.setBankName("中国工商银行"); +// settlementInfoDto.setBankInstId("ICBC"); +// settlementInfoDto.setBankType("1"); +// settlementInfoDto.setBankBranchName("广东省深圳市南山区"); +// settlementInfoDto.setBankBranchCode("440300"); +// settlementInfoDto.setBankCardFrontPic(new ImageDto("https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/20240312/31476c871c224389aea0ac4e17c964a3.jpg")); +// settlementInfoDto.setBankCardBackPic(new ImageDto("https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/20240312/31476c871c224389aea0ac4e17c964a3.jpg")); +// settlementInfoDto.setOpenAccountLicencePic(new ImageDto("https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/20240312/31476c871c224389aea0ac4e17c964a3.jpg")); +// merchantDto.setSettlementInfo(settlementInfoDto); return merchantDto; } diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatEntryManager.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatEntryManager.java index 2f9154d28..a848a1148 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatEntryManager.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatEntryManager.java @@ -1,5 +1,6 @@ package com.czg.third.wechat; +import com.alibaba.fastjson2.JSONArray; import com.alibaba.fastjson2.JSONObject; import com.alibaba.fastjson2.JSONWriter; import com.czg.PayCst; @@ -55,15 +56,14 @@ public class WechatEntryManager { String resp = WechatReqUtils.getReq(configDto, "/v3/applyment4sub/applyment/applyment_id/" + applyId, Map.of()); JSONObject object = JSONObject.parseObject(resp); - JSONObject data = object.getJSONObject("data"); - if (data == null) { + if (resp.contains("message")) { log.error("微信查询进件状态失败:{}", resp); queryStatusResp.setFailReason(object.getString("message")); queryStatusResp.setStatus(PayCst.EntryStatus.REJECTED); return queryStatusResp; } log.info("微信查询进件状态:{}", resp); - WechatQueryStateResp stateResp = JSONObject.parseObject(data.toJSONString(), WechatQueryStateResp.class); + WechatQueryStateResp stateResp = JSONObject.parseObject(resp, WechatQueryStateResp.class); queryStatusResp.setApplyId(stateResp.getApplyId()); switch (stateResp.getApplyState()) { @@ -114,11 +114,10 @@ public class WechatEntryManager { String params = JSONObject.toJSONString(entryReqDto, JSONWriter.Feature.IgnoreEmpty); String respBody = WechatReqUtils.postReq(configDto, "/v3/applyment4sub/applyment/", params); JSONObject object = JSONObject.parseObject(respBody); - JSONObject data = object.getJSONObject("data"); log.info("微信进件结果:{}", respBody); - if (data != null) { + if (respBody.contains("applyment_id")) { respDto.setStatus(PayCst.EntryStatus.INIT); - respDto.setEntryId(data.getString("applyment_id")); + respDto.setEntryId(object.getString("applyment_id")); respDto.setErrorMsg(""); } else { respDto.setStatus(PayCst.EntryStatus.REJECTED); @@ -328,6 +327,7 @@ public class WechatEntryManager { WechatEntryBankAccountReqDto bankAccountReqInfo = new WechatEntryBankAccountReqDto(); bankAccountReqInfo.setBankAccountType("21".equals(settlementInfo.getSettlementCardType()) ? "BANK_ACCOUNT_TYPE_CORPORATE" : "BANK_ACCOUNT_TYPE_PERSONAL"); bankAccountReqInfo.setAccountName(encryptor.encrypt(settlementInfo.getSettlementName())); + bankAccountReqInfo.setBankAddressCode(settlementInfo.getOpenAccCityId()); bankAccountReqInfo.setAccountBank(settlementInfo.getBankName()); bankAccountReqInfo.setBankBranchId(settlementInfo.getBankBranchCode()); bankAccountReqInfo.setBankName(settlementInfo.getBankBranchName()); @@ -344,12 +344,15 @@ public class WechatEntryManager { int offset = 0; Integer limit = 100; - JSONObject resp = queryBankList(null, offset, limit); +// JSONObject resp = queryBankList(null, offset, limit); // queryProvinceList(null); // queryCityList(null, "28"); - queryBankBranchList(null, "1000009547", "931", offset, limit); +// queryBankBranchList(null, "1000009547", "931", offset, limit); // queryBankBranchList(null, "1000009561", "29", offset, limit); + queryBankBranchList(null, "1000005241", "29", offset, limit); + +// uploadImage(null, "https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/5/ec5bafd00f96466fb3efe545a058f08b.png"); // queryProvinceList(dto); // queryCityList(dto, "28"); diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/dto/req/entry/WechatEntryBankAccountReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/dto/req/entry/WechatEntryBankAccountReqDto.java index 948400189..ab84037a7 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/dto/req/entry/WechatEntryBankAccountReqDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/dto/req/entry/WechatEntryBankAccountReqDto.java @@ -35,6 +35,9 @@ public class WechatEntryBankAccountReqDto { @JSONField(name = "account_name") private String accountName; + @JSONField(name = "bank_address_code") + private String bankAddressCode; + /** * 【必填】 * 开户银行 From ad3454143a8dcf35cceb23e19cd763520f01ae6e Mon Sep 17 00:00:00 2001 From: gong <1157756119@qq.com> Date: Mon, 12 Jan 2026 17:33:02 +0800 Subject: [PATCH 080/133] =?UTF-8?q?=E5=AE=A1=E6=A0=B8=E4=B8=AD=20=E8=8E=B7?= =?UTF-8?q?=E5=8F=96=E7=AD=BE=E7=BA=A6=E5=9C=B0=E5=9D=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/czg/third/wechat/WechatEntryManager.java | 1 + 1 file changed, 1 insertion(+) diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatEntryManager.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatEntryManager.java index a848a1148..a7536dfe6 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatEntryManager.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatEntryManager.java @@ -74,6 +74,7 @@ public class WechatEntryManager { case "APPLYMENT_STATE_AUDITING" -> { queryStatusResp.setStatus(PayCst.EntryStatus.AUDIT); queryStatusResp.setFailReason(""); + queryStatusResp.setSignUrl(stateResp.getSignUrl()); } case "APPLYMENT_STATE_REJECTED" -> { queryStatusResp.setStatus(PayCst.EntryStatus.REJECTED); From 36523143ba84b07a8d6348f9d182b90343e82282 Mon Sep 17 00:00:00 2001 From: gong <1157756119@qq.com> Date: Mon, 12 Jan 2026 17:38:57 +0800 Subject: [PATCH 081/133] =?UTF-8?q?=E5=AE=A1=E6=A0=B8=E4=B8=AD=20=E8=8E=B7?= =?UTF-8?q?=E5=8F=96=E7=AD=BE=E7=BA=A6=E5=9C=B0=E5=9D=80=20=E7=8A=B6?= =?UTF-8?q?=E6=80=81=E6=94=B9=E4=B8=BA=E5=BE=85=E5=AE=A1=E6=A0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/czg/third/wechat/WechatEntryManager.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatEntryManager.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatEntryManager.java index a7536dfe6..9328f3507 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatEntryManager.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatEntryManager.java @@ -1,5 +1,6 @@ package com.czg.third.wechat; +import cn.hutool.core.util.StrUtil; import com.alibaba.fastjson2.JSONArray; import com.alibaba.fastjson2.JSONObject; import com.alibaba.fastjson2.JSONWriter; @@ -75,6 +76,9 @@ public class WechatEntryManager { queryStatusResp.setStatus(PayCst.EntryStatus.AUDIT); queryStatusResp.setFailReason(""); queryStatusResp.setSignUrl(stateResp.getSignUrl()); + if (StrUtil.isNotBlank(queryStatusResp.getSignUrl())) { + queryStatusResp.setStatus(PayCst.EntryStatus.SIGN); + } } case "APPLYMENT_STATE_REJECTED" -> { queryStatusResp.setStatus(PayCst.EntryStatus.REJECTED); From 61f5f1a0bb1d17fed2f0db5f22d80a0990497b7e Mon Sep 17 00:00:00 2001 From: gong <1157756119@qq.com> Date: Tue, 13 Jan 2026 09:21:39 +0800 Subject: [PATCH 082/133] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E8=BF=9B=E4=BB=B6?= =?UTF-8?q?=E7=8A=B6=E6=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../order/service/impl/ShopDirectMerchantServiceImpl.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/ShopDirectMerchantServiceImpl.java b/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/ShopDirectMerchantServiceImpl.java index 542864737..b8c2e5fb5 100644 --- a/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/ShopDirectMerchantServiceImpl.java +++ b/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/ShopDirectMerchantServiceImpl.java @@ -100,8 +100,12 @@ public class ShopDirectMerchantServiceImpl extends ServiceImpl Date: Tue, 13 Jan 2026 14:05:50 +0800 Subject: [PATCH 083/133] =?UTF-8?q?userID=20=E4=B8=BA=E7=A9=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/impl/OrderInfoCustomServiceImpl.java | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/OrderInfoCustomServiceImpl.java b/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/OrderInfoCustomServiceImpl.java index 84572cf5c..7eaada20f 100644 --- a/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/OrderInfoCustomServiceImpl.java +++ b/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/OrderInfoCustomServiceImpl.java @@ -364,7 +364,7 @@ public class OrderInfoCustomServiceImpl implements OrderInfoCustomService { if (param.getOrderAmount().compareTo(BigDecimal.ZERO) < 0) { throw new OrderValidateException("生成订单失败,订单金额不能小于0"); } - log.info("订单信息:{},优惠信息:{}", JSONObject.toJSONString(orderInfo), JSONObject.toJSONString(param)); + log.info("订单信息:{},\r\n 优惠信息:{}", JSONObject.toJSONString(orderInfo), JSONObject.toJSONString(param)); Long shopId = orderInfo.getShopId(); AssertUtil.isNull(shopId, "生成支付订单失败,订单信息异常"); //霸王餐不参与满减 @@ -1056,10 +1056,12 @@ public class OrderInfoCustomServiceImpl implements OrderInfoCustomService { } upOrderInfo(orderInfo, new BigDecimal(czgCallBackDto.getAmount()).divide(new BigDecimal(100), 2, RoundingMode.DOWN), DateUtil.parseLocalDateTime(czgCallBackDto.getPayTime()), payment.getId(), null); - // 分销员升级等级 - distributionUserService.costUpgradeLevelBefore(orderInfo.getUserId(), orderInfo.getShopId()); - // 分销奖励 - distributionUserService.distribute(orderInfo.getId(), orderInfo.getOrderNo(), payment.getAmount(), orderInfo.getUserId(), orderInfo.getShopId(), "order"); + if (orderInfo.getUserId() != null) { + // 分销员升级等级 + distributionUserService.costUpgradeLevelBefore(orderInfo.getUserId(), orderInfo.getShopId()); + // 分销奖励 + distributionUserService.distribute(orderInfo.getId(), orderInfo.getOrderNo(), payment.getAmount(), orderInfo.getUserId(), orderInfo.getShopId(), "order"); + } } else if (PayTypeConstants.SourceType.MEMBER_IN.equals(payment.getSourceType()) || PayTypeConstants.SourceType.FREE.equals(payment.getSourceType())) { boolean isFree = PayTypeConstants.SourceType.FREE.equals(payment.getSourceType()); ShopUser shopUser = shopUserService.getById(payment.getSourceId()); From b0aaf154132c82174d66d0df42af991bb39341e6 Mon Sep 17 00:00:00 2001 From: wangw <1594593906@qq.com> Date: Tue, 13 Jan 2026 14:29:57 +0800 Subject: [PATCH 084/133] =?UTF-8?q?=E6=89=93=E5=8D=B0=20=E8=8F=9C=E5=93=81?= =?UTF-8?q?=20=E5=A3=B0=E9=9F=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/order/print/PrinterHandler.java | 18 ++++++++++++++++++ .../czg/service/order/print/YxyPrinter.java | 4 ++-- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/cash-service/order-service/src/main/java/com/czg/service/order/print/PrinterHandler.java b/cash-service/order-service/src/main/java/com/czg/service/order/print/PrinterHandler.java index d3598eed9..9af2c670a 100644 --- a/cash-service/order-service/src/main/java/com/czg/service/order/print/PrinterHandler.java +++ b/cash-service/order-service/src/main/java/com/czg/service/order/print/PrinterHandler.java @@ -578,17 +578,35 @@ public abstract class PrinterHandler { } + /** + * 菜品打印 + */ protected abstract void normalDishesPrint(OrderInfo orderInfo, OrderDetail orderDetail, PrintMachine machine); + /** + * 菜品 退菜打印 + */ protected abstract void returnDishesPrint(OrderInfo orderInfo, OrderDetail orderDetail, PrintMachine machine); + /** + * 退单打印 + */ protected abstract void returnOrderPrint(OrderInfo orderInfo, PrintMachine machine, String balance, List detailList); + /** + * 订单打印 + */ protected abstract void normalOrderPrint(OrderInfo orderInfo, boolean isPre, PrintMachine machine, String balance, List detailList); + /** + * 叫号打印 + */ protected abstract void callNumPrint(PrintMachine machine, String callNum, String shopName, String tableName, String tableNote, String preNum, String codeUrl, LocalDateTime takeTime, String shopNote); + /** + * 交班打印 + */ protected abstract void handoverPrint(PrintMachine machine, HandoverRecordDTO record); } diff --git a/cash-service/order-service/src/main/java/com/czg/service/order/print/YxyPrinter.java b/cash-service/order-service/src/main/java/com/czg/service/order/print/YxyPrinter.java index cf1f8a2c5..7c19acb16 100644 --- a/cash-service/order-service/src/main/java/com/czg/service/order/print/YxyPrinter.java +++ b/cash-service/order-service/src/main/java/com/czg/service/order/print/YxyPrinter.java @@ -105,8 +105,8 @@ public class YxyPrinter extends PrinterHandler implements PrinterImpl { protected void normalDishesPrint(OrderInfo orderInfo, OrderDetail orderDetail, PrintMachine machine) { String buildDishPrintData = buildDishPrintData(false, getPickupNum(orderInfo), DateUtil.format(orderDetail.getCreateTime(), "yyyy-MM-dd HH:mm:ss"), orderDetail.getProductName(), orderDetail.getSkuName(), orderDetail.getNum(), orderDetail.getRemark(), orderDetail.getProGroupInfo(), orderDetail.getId(), orderDetail.isUrgent()); - String voiceJson = "{\"bizType\":\"2\",\"content\":\"您有一笔新的订单,请及时处理\"}"; - String resp = sendPrintRequest(machine.getAddress(), buildDishPrintData, voiceJson, "1"); +// String voiceJson = "{\"bizType\":\"2\",\"content\":\"您有一笔新的订单,请及时处理\"}"; + String resp = sendPrintRequest(machine.getAddress(), buildDishPrintData, null, "1"); printMachineLogService.save(orderInfo.getId(), machine, "新订单", buildDishPrintData, resp); } From 77de98fd58a88b47357755574ae6d85d29f155c6 Mon Sep 17 00:00:00 2001 From: wangw <1594593906@qq.com> Date: Tue, 13 Jan 2026 14:35:28 +0800 Subject: [PATCH 085/133] =?UTF-8?q?=E6=89=93=E5=8D=B0=20=E8=8F=9C=E5=93=81?= =?UTF-8?q?=20=E5=A3=B0=E9=9F=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/czg/service/order/print/YxyPrinter.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cash-service/order-service/src/main/java/com/czg/service/order/print/YxyPrinter.java b/cash-service/order-service/src/main/java/com/czg/service/order/print/YxyPrinter.java index 7c19acb16..cdab880e7 100644 --- a/cash-service/order-service/src/main/java/com/czg/service/order/print/YxyPrinter.java +++ b/cash-service/order-service/src/main/java/com/czg/service/order/print/YxyPrinter.java @@ -106,7 +106,8 @@ public class YxyPrinter extends PrinterHandler implements PrinterImpl { String buildDishPrintData = buildDishPrintData(false, getPickupNum(orderInfo), DateUtil.format(orderDetail.getCreateTime(), "yyyy-MM-dd HH:mm:ss"), orderDetail.getProductName(), orderDetail.getSkuName(), orderDetail.getNum(), orderDetail.getRemark(), orderDetail.getProGroupInfo(), orderDetail.getId(), orderDetail.isUrgent()); // String voiceJson = "{\"bizType\":\"2\",\"content\":\"您有一笔新的订单,请及时处理\"}"; - String resp = sendPrintRequest(machine.getAddress(), buildDishPrintData, null, "1"); + String voiceJson = "{\"bizType\":\"2\",\"content\":\"\"}"; + String resp = sendPrintRequest(machine.getAddress(), buildDishPrintData, voiceJson, "1"); printMachineLogService.save(orderInfo.getId(), machine, "新订单", buildDishPrintData, resp); } From dbe1305811451450c8bda6fc06c4f985316fb87b Mon Sep 17 00:00:00 2001 From: wangw <1594593906@qq.com> Date: Tue, 13 Jan 2026 15:20:37 +0800 Subject: [PATCH 086/133] =?UTF-8?q?=E8=B5=A0=E9=80=81=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/czg/service/order/print/YxyPrinter.java | 6 ++++-- .../src/main/resources/mapper/OrderDetailMapper.xml | 11 +++++++---- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/cash-service/order-service/src/main/java/com/czg/service/order/print/YxyPrinter.java b/cash-service/order-service/src/main/java/com/czg/service/order/print/YxyPrinter.java index cdab880e7..9513ef90b 100644 --- a/cash-service/order-service/src/main/java/com/czg/service/order/print/YxyPrinter.java +++ b/cash-service/order-service/src/main/java/com/czg/service/order/print/YxyPrinter.java @@ -126,7 +126,8 @@ public class YxyPrinter extends PrinterHandler implements PrinterImpl { protected void returnOrderPrint(OrderInfo orderInfo, PrintMachine machine, String balance, List detailList) { ShopInfo shopInfo = shopInfoService.getById(orderInfo.getShopId()); PrintInfoDTO printInfoDTO = new PrintInfoDTO().setShopName(shopInfo.getShopName()).setPrintType("普通打印").setPickupNum(getPickupNum(orderInfo)) - .setOrderNo(orderInfo.getOrderNo()).setTradeDate(DateUtil.format(orderInfo.getCreateTime(), "yyyy-MM-dd HH:mm:ss")).setOperator("【POS-1】001").setPayAmount(orderInfo.getPayAmount().toPlainString()) + .setOrderNo(orderInfo.getOrderNo()).setTradeDate(DateUtil.format(orderInfo.getCreateTime(), "yyyy-MM-dd HH:mm:ss")) + .setOperator("【POS-1】001").setPayAmount(orderInfo.getPayAmount().toPlainString()) .setOriginalAmount(orderInfo.getOriginAmount().toPlainString()).setReturn(isReturn(orderInfo)) .setBalance(balance).setPayType((ObjectUtil.isEmpty(orderInfo.getPayType()) || ObjectUtil.isNull(orderInfo.getPayType()) ? "" : orderInfo.getPayType())).setIntegral("0") .setOutNumber(orderInfo.getTakeCode()).setPrintTitle("退款单") @@ -152,7 +153,8 @@ public class YxyPrinter extends PrinterHandler implements PrinterImpl { .le(OrderInfo::getCreateTime, orderInfo.getCreateTime())); PrintInfoDTO printInfoDTO = new PrintInfoDTO().setShopName(shopInfo.getShopName()) .setPrintType("普通打印").setPickupNum(getPickupNum(orderInfo)) - .setOrderNo(orderInfo.getOrderNo()).setTradeDate(DateUtil.format(orderInfo.getCreateTime(), "yyyy-MM-dd HH:mm:ss")).setOperator("【POS-1】001").setPayAmount(orderInfo.getPayAmount().toPlainString()) + .setOrderNo(orderInfo.getOrderNo()).setTradeDate(DateUtil.format(orderInfo.getCreateTime(), "yyyy-MM-dd HH:mm:ss")) + .setOperator("【POS-1】001").setPayAmount(orderInfo.getPayAmount().toPlainString()) .setOriginalAmount((orderInfo.getOriginAmount().add(orderInfo.getSeatAmount()).add(orderInfo.getPackFee())).toPlainString()).setReturn(isReturn(orderInfo)) .setBalance(balance).setPayType((ObjectUtil.isEmpty(orderInfo.getPayType()) || ObjectUtil.isNull(orderInfo.getPayType()) ? "" : orderInfo.getPayType())).setIntegral("0") .setOutNumber(orderInfo.getTakeCode()).setPrintTitle(isPre ? "预结算单" : "结算单") diff --git a/cash-service/order-service/src/main/resources/mapper/OrderDetailMapper.xml b/cash-service/order-service/src/main/resources/mapper/OrderDetailMapper.xml index 055fdb31b..c1dee96ba 100644 --- a/cash-service/order-service/src/main/resources/mapper/OrderDetailMapper.xml +++ b/cash-service/order-service/src/main/resources/mapper/OrderDetailMapper.xml @@ -6,20 +6,23 @@ INSERT INTO tb_order_detail(order_id, shop_id, product_id, product_img, product_name, product_type, sku_id, - sku_name, price,member_price,discount_sale_amount,unit_price, discount_amount, pack_amount, pay_amount, + sku_name, price,member_price,discount_sale_amount,unit_price, discount_amount,is_gift, pack_amount, pay_amount, return_amount, num, pack_number, coupon_num, is_time_discount, return_num, refund_num, refund_no, discount_sale_note, status, place_num, is_temporary, is_print, is_wait_call, - pro_group_info, remark, refund_remark, create_time, update_time, is_urgent, sub_status, start_order_time, dish_out_time, food_serve_time, order_time) + pro_group_info, remark, refund_remark, create_time, update_time, is_urgent, sub_status, start_order_time, + dish_out_time, food_serve_time, order_time) VALUES (#{orderId}, #{entity.shopId}, #{entity.productId}, #{entity.productImg}, #{entity.productName}, #{entity.productType}, #{entity.skuId}, #{entity.skuName}, #{entity.price},#{entity.memberPrice}, - #{entity.discountSaleAmount}, #{entity.unitPrice}, #{entity.discountAmount}, + #{entity.discountSaleAmount}, #{entity.unitPrice}, #{entity.discountAmount},#{entity.isGift}, #{entity.packAmount}, #{entity.payAmount}, #{entity.returnAmount}, #{entity.num}, #{entity.packNumber}, #{entity.couponNum}, #{entity.isTimeDiscount}, #{entity.returnNum}, #{entity.refundNum}, #{entity.refundNo}, #{entity.discountSaleNote}, #{entity.status}, #{entity.placeNum}, #{entity.isTemporary}, #{entity.isPrint}, #{entity.isWaitCall}, #{entity.proGroupInfo}, #{entity.remark}, #{entity.refundRemark}, - now(), now(), #{entity.isUrgent}, #{entity.subStatus},#{entity.startOrderTime},#{entity.dishOutTime},#{entity.foodServeTime}, #{entity.orderTime}) + now(), now(), #{entity.isUrgent}, + #{entity.subStatus},#{entity.startOrderTime},#{entity.dishOutTime},#{entity.foodServeTime}, + #{entity.orderTime})