From 4742874ad840d7e1e3ac79dc288b38e9a642319d Mon Sep 17 00:00:00 2001
From: 无关风月 <443237572@qq.com>
Date: 星期一, 02 六月 2025 19:11:00 +0800
Subject: [PATCH] bug修改
---
cloud-server-management/src/main/webapp/WEB-INF/view/system/tShop/TShop_add.html | 2
cloud-server-management/src/main/webapp/static/modular/system/tHuiminCard/tHuiminCard.js | 12
cloud-server-activity/src/main/java/com/dsh/activity/util/wx/WXPaySignatureCertificateUtil.java | 594 +++++++-------
cloud-server-management/src/main/webapp/static/modular/system/tHuiminCard/tHuiminCard3.js | 98 ++
cloud-server-management/src/main/webapp/static/modular/system/tHuiminCard/tHuiminCard2.js | 95 ++
cloud-server-activity/src/main/java/com/dsh/activity/util/wx/WxV3PayConfig.java | 112 +-
cloud-server-activity/src/main/java/com/dsh/activity/controller/PointMercharsController.java | 3
cloud-server-activity/src/main/java/com/dsh/activity/controller/HuiminController.java | 7
cloud-server-account/src/main/java/com/dsh/account/controller/StudentController.java | 6
cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/code/THuiminCardController.java | 67 +
cloud-server-management/src/main/webapp/WEB-INF/view/system/tHuiminCard/tHuiminCard.html | 7
cloud-server-management/src/main/webapp/WEB-INF/view/system/tHuiminCard/tHuiminCard_addOrder.html | 150 +++
cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/code/TShopController.java | 4
cloud-server-activity/src/main/java/com/dsh/activity/util/wx/WxPayNotifyController.java | 354 ++++----
cloud-server-activity/src/main/java/com/dsh/activity/controller/THuiminCardController.java | 56 +
cloud-server-account/src/main/java/com/dsh/account/controller/AppUserController.java | 3
cloud-server-activity/src/main/java/com/dsh/activity/entity/TPayHuimin.java | 2
cloud-server-activity/src/main/java/com/dsh/activity/feignclient/account/StudentClient.java | 3
cloud-server-activity/src/main/java/com/dsh/activity/util/wx/WXPayConstants.java | 64
cloud-server-activity/src/main/java/com/dsh/activity/util/wx/WxAppPayService.java | 444 +++++-----
cloud-server-activity/src/main/java/com/dsh/activity/service/impl/PayHuiminServiceImpl.java | 61 +
cloud-server-activity/src/main/java/com/dsh/activity/util/wx/WxPayAesUtil.java | 114 +-
cloud-server-management/src/main/java/com/dsh/course/feignClient/activity/HuiminCardClient.java | 5
23 files changed, 1,398 insertions(+), 865 deletions(-)
diff --git a/cloud-server-account/src/main/java/com/dsh/account/controller/AppUserController.java b/cloud-server-account/src/main/java/com/dsh/account/controller/AppUserController.java
index ab51ce9..4d9fe63 100644
--- a/cloud-server-account/src/main/java/com/dsh/account/controller/AppUserController.java
+++ b/cloud-server-account/src/main/java/com/dsh/account/controller/AppUserController.java
@@ -198,7 +198,8 @@
@ResponseBody
@GetMapping("/base/appUser/getAppUserByPhone/{phone}")
public TAppUser getAppUserByPhone(@PathVariable("phone") String phone) {
- TAppUser appUser = appUserService.getOne(new QueryWrapper<TAppUser>().eq("phone", phone));
+ TAppUser appUser = appUserService.getOne(new QueryWrapper<TAppUser>().eq("phone", phone)
+ .eq("state",1));
return appUser;
}
diff --git a/cloud-server-account/src/main/java/com/dsh/account/controller/StudentController.java b/cloud-server-account/src/main/java/com/dsh/account/controller/StudentController.java
index adf363d..e33eafd 100644
--- a/cloud-server-account/src/main/java/com/dsh/account/controller/StudentController.java
+++ b/cloud-server-account/src/main/java/com/dsh/account/controller/StudentController.java
@@ -108,6 +108,12 @@
return new ArrayList<>();
}
}
+ @PostMapping("/student/getStudentById")
+ @ResponseBody
+ TStudent getStudentById(Integer studentId) {
+ TStudent byId = studentService.getById(studentId);
+ return byId;
+ }
@ResponseBody
diff --git a/cloud-server-activity/src/main/java/com/dsh/activity/controller/HuiminController.java b/cloud-server-activity/src/main/java/com/dsh/activity/controller/HuiminController.java
index 75b3aa0..78f5e2d 100644
--- a/cloud-server-activity/src/main/java/com/dsh/activity/controller/HuiminController.java
+++ b/cloud-server-activity/src/main/java/com/dsh/activity/controller/HuiminController.java
@@ -741,6 +741,12 @@
return ResultUtil.tokenErr();
}
TPayHuimin tPayHuimin = payHuiminService.getById(id);
+ if (tPayHuimin.getPaymentType()==3){
+ // 后台录入直接退款
+ tPayHuimin.setStatus(3);
+ payHuiminService.updateById(tPayHuimin);
+ return ResultUtil.success();
+ }
if (tPayHuimin == null) {
return ResultUtil.error("订单不存在");
}
@@ -752,7 +758,6 @@
// 已过期
return ResultUtil.error("玩湃惠民卡已过期,不可退款");
}
- tPayHuimin.setStatus(4);
payHuiminService.updateById(tPayHuimin);
int count = huiminRecordService.list(new LambdaQueryWrapper<THuiminRecord>()
.eq(THuiminRecord::getPayId, tPayHuimin.getId())).size();
diff --git a/cloud-server-activity/src/main/java/com/dsh/activity/controller/PointMercharsController.java b/cloud-server-activity/src/main/java/com/dsh/activity/controller/PointMercharsController.java
index 59bfd58..a6a67dc 100644
--- a/cloud-server-activity/src/main/java/com/dsh/activity/controller/PointMercharsController.java
+++ b/cloud-server-activity/src/main/java/com/dsh/activity/controller/PointMercharsController.java
@@ -1568,7 +1568,8 @@
if (ToolUtil.isNotEmpty(pointMercharsPayedVo.getStatus())) {
userPointsMerchandiseLambdaQueryWrapper.eq(UserPointsMerchandise::getStatus, pointMercharsPayedVo.getStatus());
}
- List<UserPointsMerchandise> list = upmseService.list(userPointsMerchandiseLambdaQueryWrapper.orderByDesc(UserPointsMerchandise::getPaymentTime));
+ List<UserPointsMerchandise> list = upmseService.list(userPointsMerchandiseLambdaQueryWrapper.orderByDesc(UserPointsMerchandise::getPaymentTime)
+ .isNotNull(UserPointsMerchandise::getPaymentTime));
System.out.println(list);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
if (list.size() > 0) {
diff --git a/cloud-server-activity/src/main/java/com/dsh/activity/controller/THuiminCardController.java b/cloud-server-activity/src/main/java/com/dsh/activity/controller/THuiminCardController.java
index bf65325..7e8c2c2 100644
--- a/cloud-server-activity/src/main/java/com/dsh/activity/controller/THuiminCardController.java
+++ b/cloud-server-activity/src/main/java/com/dsh/activity/controller/THuiminCardController.java
@@ -1,5 +1,6 @@
package com.dsh.activity.controller;
+import cn.hutool.core.collection.CollUtil;
import cn.mb.cloud.common.data.controller.BaseController;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
@@ -7,12 +8,18 @@
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.dsh.activity.entity.THuiminCard;
import com.dsh.activity.entity.TPayHuimin;
+import com.dsh.activity.entity.TStudent;
+import com.dsh.activity.feignclient.account.StudentClient;
import com.dsh.activity.service.HuiminCardService;
import com.dsh.activity.service.PayHuiminService;
+import com.dsh.activity.util.UUIDUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
+import java.text.SimpleDateFormat;
+import java.time.LocalDateTime;
+import java.time.ZoneId;
import java.util.Date;
import java.util.List;
import java.util.Map;
@@ -25,6 +32,8 @@
private HuiminCardService tHuiminCardService;
@Autowired
private PayHuiminService payHuiminService;
+ @Autowired
+ private StudentClient studentClient;
@PostMapping("/queryPage")
@@ -155,4 +164,51 @@
tHuiminCardService.updateById(tHuiminCard);
return "success";
}
+ @GetMapping("/getCards")
+
+ public List<THuiminCard> getCards(@RequestParam("storeId")String storeId){
+ List<THuiminCard> list = tHuiminCardService.lambdaQuery().apply("FIND_IN_SET(" + storeId + ",storeIds)").list();
+ return list;
+ }
+ @GetMapping("/addPayHuiMing")
+ public void addPayHuiMing(@RequestParam("studentId")Integer studentId, @RequestParam("cardId")Integer cardId){
+ TPayHuimin tPayHuimin = new TPayHuimin();
+
+ THuiminCard byId = tHuiminCardService.getById(cardId);
+ List<TStudent> studentByIds = studentClient.getStudentByIds(studentId + "");
+ if (CollUtil.isNotEmpty(studentByIds)){
+ tPayHuimin.setAppUserId(studentByIds.get(0).getAppUserId());
+ }
+ tPayHuimin.setSalesMoney(byId.getSalesMoney());
+ tPayHuimin.setStudentId(studentId+"");
+ switch (byId.getHuiMinType()) {
+ case 1:
+ // 年度卡
+ LocalDateTime localDateTime = LocalDateTime.now().plusDays(365);
+ // 将LocalDateTime转换为Date类型
+ Date date = Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
+ tPayHuimin.setEndTime(date);
+ break;
+ case 2:
+ // 年内卡
+ Date date1 = new Date();
+ date1.setMonth(11);
+ date1.setDate(31);
+ date1.setHours(23);
+ date1.setMinutes(59);
+ date1.setSeconds(57);
+ tPayHuimin.setEndTime(date1);
+ break;
+ }
+ tPayHuimin.setInsertTime(new Date());
+ tPayHuimin.setPaymentType(3);
+ tPayHuimin.setRefundStatus(1);
+ tPayHuimin.setCardId(byId.getId());
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS");
+ tPayHuimin.setCode(sdf.format(new Date()) + UUIDUtil.getNumberRandom(5));
+ System.err.println("支付数据" + tPayHuimin);
+ tPayHuimin.setPaymentTime(new Date());
+ tPayHuimin.setStatus(2);
+ payHuiminService.save(tPayHuimin);
+ }
}
diff --git a/cloud-server-activity/src/main/java/com/dsh/activity/entity/TPayHuimin.java b/cloud-server-activity/src/main/java/com/dsh/activity/entity/TPayHuimin.java
index 619921f..b5febda 100644
--- a/cloud-server-activity/src/main/java/com/dsh/activity/entity/TPayHuimin.java
+++ b/cloud-server-activity/src/main/java/com/dsh/activity/entity/TPayHuimin.java
@@ -80,7 +80,7 @@
@TableField("status")
private Integer status;
/**
- *付款方式1微信2支付宝
+ *付款方式1微信2支付宝 3后台录入
*/
@TableField("paymentType")
private Integer paymentType;
diff --git a/cloud-server-activity/src/main/java/com/dsh/activity/feignclient/account/StudentClient.java b/cloud-server-activity/src/main/java/com/dsh/activity/feignclient/account/StudentClient.java
index cec3eba..bdec4b1 100644
--- a/cloud-server-activity/src/main/java/com/dsh/activity/feignclient/account/StudentClient.java
+++ b/cloud-server-activity/src/main/java/com/dsh/activity/feignclient/account/StudentClient.java
@@ -25,6 +25,9 @@
@PostMapping("/student/queryStudentList")
List<TStudent> queryStudentList(Integer appUserId);
+ @PostMapping("/student/getStudentById")
+ TStudent getStudentById(Integer studentId);
+
/**
* 获取有学员的用户ids
*
diff --git a/cloud-server-activity/src/main/java/com/dsh/activity/service/impl/PayHuiminServiceImpl.java b/cloud-server-activity/src/main/java/com/dsh/activity/service/impl/PayHuiminServiceImpl.java
index 1befab5..f55056e 100644
--- a/cloud-server-activity/src/main/java/com/dsh/activity/service/impl/PayHuiminServiceImpl.java
+++ b/cloud-server-activity/src/main/java/com/dsh/activity/service/impl/PayHuiminServiceImpl.java
@@ -19,8 +19,10 @@
import com.dsh.activity.util.DateUtil;
import com.dsh.activity.util.PayMoneyUtil;
import com.dsh.activity.util.ResultUtil;
+import com.sun.org.apache.bcel.internal.generic.NEW;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
+import org.springframework.util.StringUtils;
import javax.annotation.Resource;
import java.math.BigDecimal;
@@ -53,22 +55,44 @@
.eq(THuiminRecord::getPayId, record.getId()));
record.setUseTimes(list.size());
}
- if (CollUtil.isNotEmpty(records)){
- List<Integer> appUserIdList = records.stream().map(SalesDetailVO::getAppUserId).collect(Collectors.toList());
- List<AppUser> appUserList = appUserClient.queryAppUserBatch(appUserIdList);
- Map<Integer, AppUser> appUserMap = appUserList.stream().collect(Collectors.toMap(AppUser::getId, appUser -> appUser));
- records.forEach(item->{
- AppUser appUser = appUserMap.get(item.getAppUserId());
- if (Objects.nonNull(appUser)){
- item.setUserName(appUser.getName());
- item.setPhone(appUser.getPhone());
+ for (SalesDetailVO record : records) {
+ AppUser appUser = appUserClient.queryAppUser(record.getAppUserId());
+ if (Objects.nonNull(appUser)){
+ record.setUserName(appUser.getName());
+ record.setPhone(appUser.getPhone());
+ }
+ StringBuilder stringBuilder = new StringBuilder();
+ String[] split = record.getStudentId().split(",");
+ for (String s : split) {
+ String replace = s.replace(" ", "");
+ List<TStudent> studentById = studentClient.getStudentByIds(replace);
+ if (!studentById.isEmpty()){
+ stringBuilder.append(studentById.get(0).getName()+",");
}
- List<TStudent> studentList = studentClient.getStudentByIds(item.getStudentId());
- if (CollUtil.isNotEmpty(studentList)){
- item.setStudentName(studentList.stream().map(TStudent::getName).collect(Collectors.joining(",")));
- }
- });
+
+ }
+ String string = stringBuilder.toString();
+ if (StringUtils.hasLength(string)) {
+ String stringWithoutLastCharacter = string.substring(0, string.length() - 1);
+ record.setStudentName(stringWithoutLastCharacter);
+ }
}
+// if (CollUtil.isNotEmpty(records)){
+// List<Integer> appUserIdList = records.stream().map(SalesDetailVO::getAppUserId).collect(Collectors.toList());
+// List<AppUser> appUserList = appUserClient.queryAppUserBatch(appUserIdList);
+// Map<Integer, AppUser> appUserMap = appUserList.stream().collect(Collectors.toMap(AppUser::getId, appUser -> appUser));
+// records.forEach(item->{
+// AppUser appUser = appUserMap.get(item.getAppUserId());
+// if (Objects.nonNull(appUser)){
+// item.setUserName(appUser.getName());
+// item.setPhone(appUser.getPhone());
+// }
+// List<TStudent> studentList = studentClient.getStudentByIds(item.getStudentId());
+// if (CollUtil.isNotEmpty(studentList)){
+// item.setStudentName(studentList.stream().map(TStudent::getName).collect(Collectors.joining(",")));
+// }
+// });
+// }
return salesDetailVOPage;
}
@@ -81,6 +105,15 @@
public ResultUtil<?> refund(Integer id) throws AlipayApiException {
TPayHuimin payHuimin = this.getById(id);
if (Objects.nonNull(payHuimin)) {
+ // 后台录入订单直接修改为已退款
+ if (payHuimin.getPaymentType()==3){
+ payHuimin.setStatus(3);
+ payHuimin.setRefundStatus(3);
+ payHuimin.setRefundNumber(payHuimin.getCode());
+ payHuimin.setRefundTime(new Date());
+ this.updateById(payHuimin);
+ return ResultUtil.success();
+ }
Integer count = huiminRecordService.lambdaQuery()
.eq(THuiminRecord::getPayId, payHuimin.getId())
.count();
diff --git a/cloud-server-activity/src/main/java/com/dsh/activity/util/wx/WXPayConstants.java b/cloud-server-activity/src/main/java/com/dsh/activity/util/wx/WXPayConstants.java
index d08730f..e251eed 100644
--- a/cloud-server-activity/src/main/java/com/dsh/activity/util/wx/WXPayConstants.java
+++ b/cloud-server-activity/src/main/java/com/dsh/activity/util/wx/WXPayConstants.java
@@ -1,32 +1,32 @@
-package com.dsh.activity.util.wx;
-
-/**
- * 常量
- */
-public class WXPayConstants {
-
- public static final String DOMAIN_API = "https://api.mch.weixin.qq.com";
-
- //app下单
- public static final String PAY_TRANSACTIONS_APP = "/v3/pay/partner/transactions/app";
-// public static final String PAY_TRANSACTIONS_APP = "/v3/pay/transactions/app";
-
-
- //微信支付回调
- public static final String WECHAT_PAY_NOTIFY_URL =
- "https://xxx.xxxx.com/deal/api/appPayment/weChatPayNotify";
-
-
- //申请退款
- public static final String REFUND_DOMESTIC_REFUNDS = "/refund/domestic/refunds";
-
- //微信退款回调
- public static final String WECHAT_REFUNDS_NOTIFY_URL = "https://xxx.xxxx.com/api/appPayment/weChatPayRefundsNotify";
-
- //关闭订单
- public static final String PAY_TRANSACTIONS_OUT_TRADE_NO = "/pay/transactions/out-trade-no/{}/close";
-
-
-
-
-}
+//package com.dsh.activity.util.wx;
+//
+///**
+// * 常量
+// */
+//public class WXPayConstants {
+//
+// public static final String DOMAIN_API = "https://api.mch.weixin.qq.com";
+//
+// //app下单
+// public static final String PAY_TRANSACTIONS_APP = "/v3/pay/partner/transactions/app";
+//// public static final String PAY_TRANSACTIONS_APP = "/v3/pay/transactions/app";
+//
+//
+// //微信支付回调
+// public static final String WECHAT_PAY_NOTIFY_URL =
+// "https://xxx.xxxx.com/deal/api/appPayment/weChatPayNotify";
+//
+//
+// //申请退款
+// public static final String REFUND_DOMESTIC_REFUNDS = "/refund/domestic/refunds";
+//
+// //微信退款回调
+// public static final String WECHAT_REFUNDS_NOTIFY_URL = "https://xxx.xxxx.com/api/appPayment/weChatPayRefundsNotify";
+//
+// //关闭订单
+// public static final String PAY_TRANSACTIONS_OUT_TRADE_NO = "/pay/transactions/out-trade-no/{}/close";
+//
+//
+//
+//
+//}
diff --git a/cloud-server-activity/src/main/java/com/dsh/activity/util/wx/WXPaySignatureCertificateUtil.java b/cloud-server-activity/src/main/java/com/dsh/activity/util/wx/WXPaySignatureCertificateUtil.java
index 6be2203..02a18af 100644
--- a/cloud-server-activity/src/main/java/com/dsh/activity/util/wx/WXPaySignatureCertificateUtil.java
+++ b/cloud-server-activity/src/main/java/com/dsh/activity/util/wx/WXPaySignatureCertificateUtil.java
@@ -1,297 +1,297 @@
-package com.dsh.activity.util.wx;
-
-import com.wechat.pay.contrib.apache.httpclient.WechatPayHttpClientBuilder;
-import com.wechat.pay.contrib.apache.httpclient.auth.AutoUpdateCertificatesVerifier;
-import com.wechat.pay.contrib.apache.httpclient.auth.PrivateKeySigner;
-import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Credentials;
-import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Validator;
-import com.wechat.pay.contrib.apache.httpclient.util.PemUtil;
-import lombok.SneakyThrows;
-import org.apache.http.impl.client.CloseableHttpClient;
-
-import javax.servlet.http.HttpServletRequest;
-import java.io.*;
-import java.nio.charset.StandardCharsets;
-import java.nio.file.Files;
-import java.nio.file.Paths;
-import java.security.*;
-import java.security.cert.Certificate;
-import java.security.cert.CertificateException;
-import java.security.cert.CertificateFactory;
-import java.security.cert.X509Certificate;
-import java.security.spec.InvalidKeySpecException;
-import java.security.spec.PKCS8EncodedKeySpec;
-import java.security.spec.X509EncodedKeySpec;
-import java.util.Base64;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-
-/**
- * 微信支付V3 API 签名验证工具类
- */
-public class WXPaySignatureCertificateUtil {
-
- // 保存微信平台证书
- private static final ConcurrentHashMap<String, AutoUpdateCertificatesVerifier> verifierMap = new ConcurrentHashMap<>();
- // 缓存公钥,避免频繁IO操作
- private static PublicKey cachedPublicKey = null;
- // 缓存私钥,避免频繁IO操作
- private static PrivateKey cachedPrivateKey = null;
-
- /**
- * 获取HTTP客户端,用于微信支付API请求
- */
- public static CloseableHttpClient getWechatPayClient() throws IOException {
- PrivateKey merchantPrivateKey = getPrivateKey();
- // 构建支付客户端
- return WechatPayHttpClientBuilder.create()
- .withMerchant(WxV3PayConfig.Mch_ID, WxV3PayConfig.mchSerialNo, merchantPrivateKey)
- .withValidator(new WechatPay2Validator(getVerifier()))
- .build();
- }
-
- /**
- * 获取自动更新的证书验证器
- */
- public static AutoUpdateCertificatesVerifier getVerifier() {
- String mchSerialNo = WxV3PayConfig.mchSerialNo;
- AutoUpdateCertificatesVerifier verifier = verifierMap.get(mchSerialNo);
-
- if (verifier == null) {
- synchronized (WXPaySignatureCertificateUtil.class) {
- verifier = verifierMap.get(mchSerialNo);
- if (verifier == null) {
- try {
- PrivateKey privateKey = getPrivateKey();
- PrivateKeySigner signer = new PrivateKeySigner(mchSerialNo, privateKey);
- WechatPay2Credentials credentials = new WechatPay2Credentials(WxV3PayConfig.Mch_ID, signer);
- verifier = new AutoUpdateCertificatesVerifier(
- credentials, WxV3PayConfig.apiV3Key.getBytes(StandardCharsets.UTF_8));
- verifierMap.put(mchSerialNo, verifier);
- } catch (Exception e) {
- throw new RuntimeException("初始化证书验证器失败", e);
- }
- }
- }
- }
-
- return verifier;
- }
-
- /**
- * 使用商户私钥对数据进行签名
- *
- * @param message 待签名数据
- * @return Base64编码的签名结果
- */
- public static String sign(String message) {
- try {
- PrivateKey privateKey = getPrivateKey();
- Signature signature = Signature.getInstance("SHA256withRSA");
- signature.initSign(privateKey);
- signature.update(message.getBytes(StandardCharsets.UTF_8));
- return Base64.getEncoder().encodeToString(signature.sign());
- } catch (Exception e) {
- throw new RuntimeException("签名失败", e);
- }
- }
-
- /**
- * 使用微信支付平台公钥验证签名
- *
- * @param message 原始消息
- * @param signature Base64编码的签名
- * @return 验证结果
- */
- public static boolean verifySign(String message, String signature) {
- try {
- PublicKey publicKey = getWechatPublicKey();
- Signature sig = Signature.getInstance("SHA256withRSA");
- sig.initVerify(publicKey);
- sig.update(message.getBytes(StandardCharsets.UTF_8));
- return sig.verify(Base64.getDecoder().decode(signature));
- } catch (Exception e) {
- throw new RuntimeException("验签失败", e);
- }
- }
-
- /**
- * 验证微信支付通知消息的签名
- *
- * @param request HTTP请求
- * @param body 请求体内容
- * @return 验证结果
- */
- public static boolean verifyNotify(HttpServletRequest request, String body) {
- try {
- // 获取必要的HTTP头信息
- String timestamp = request.getHeader("Wechatpay-Timestamp");
- String nonce = request.getHeader("Wechatpay-Nonce");
- String serialNo = request.getHeader("Wechatpay-Serial");
- String signature = request.getHeader("Wechatpay-Signature");
-
- // 拼接验签字符串
- String message = Stream.of(timestamp, nonce, body)
- .collect(Collectors.joining("\n", "", "\n"));
-
- // 使用自动更新的证书验证器进行验证
- return getVerifier().verify(serialNo, message.getBytes(StandardCharsets.UTF_8), signature);
- } catch (Exception e) {
- throw new RuntimeException("验证微信支付通知签名失败", e);
- }
- }
-
- /**
- * APP支付签名
- */
- public static String appPaySign(String timestamp, String nonceStr, String prepayId) {
- String message = Stream.of(WxV3PayConfig.APP_ID, timestamp, nonceStr, prepayId)
- .collect(Collectors.joining("\n", "", "\n"));
- return sign(message);
- }
-
- /**
- * JSAPI支付签名
- */
- public static String jsApiPaySign(String timestamp, String nonceStr, String prepayId) {
- String message = Stream.of(WxV3PayConfig.APP_ID, timestamp, nonceStr, "prepay_id="+prepayId)
- .collect(Collectors.joining("\n", "", "\n"));
- return sign(message);
- }
-
- /**
- * 构建App支付参数
- */
- public static Map<String, String> buildAppPayParams(String prepayId) {
- try {
- String timestamp = String.valueOf(System.currentTimeMillis() / 1000);
- String nonceStr = generateNonceStr();
- String sign = appPaySign(timestamp, nonceStr, prepayId);
- Map<String, String> params = new HashMap<>();
- params.put("appid", WxV3PayConfig.APP_ID);
- params.put("partnerid", WxV3PayConfig.Mch_ID);
- params.put("prepayid", prepayId);
- params.put("package", "Sign=WXPay");
- params.put("noncestr", nonceStr);
- params.put("timestamp", timestamp);
- params.put("sign", sign);
-
- return params;
- } catch (Exception e) {
- throw new RuntimeException("构建App支付参数失败", e);
- }
- }
-
- /**
- * 构建JSAPI支付参数
- */
- public static Map<String, String> buildJsApiPayParams(String prepayId) {
- try {
- String timestamp = String.valueOf(System.currentTimeMillis() / 1000);
- String nonceStr = generateNonceStr();
- String sign = jsApiPaySign(timestamp, nonceStr, prepayId);
-
- Map<String, String> params = new HashMap<>();
- params.put("appId", WxV3PayConfig.APP_ID);
- params.put("timeStamp", timestamp);
- params.put("nonceStr", nonceStr);
- params.put("package", "prepay_id=" + prepayId);
- params.put("signType", "RSA");
- params.put("paySign", sign);
-
- return params;
- } catch (Exception e) {
- throw new RuntimeException("构建JSAPI支付参数失败", e);
- }
- }
-
- /**
- * 生成随机字符串
- */
- private static String generateNonceStr() {
- return java.util.UUID.randomUUID().toString().replaceAll("-", "").substring(0, 32);
- }
-
- /**
- * 获取商户私钥
- */
- public static PrivateKey getPrivateKey() {
- if (cachedPrivateKey != null) {
- return cachedPrivateKey;
- }
-
- try {
- String filePath = "D:\\玩湃v3参数\\apiclient_key.pem";
- String content = new String(Files.readAllBytes(Paths.get(filePath)), StandardCharsets.UTF_8);
-
- String privateKey = content.replace("-----BEGIN PRIVATE KEY-----", "")
- .replace("-----END PRIVATE KEY-----", "")
- .replaceAll("\\s+", "");
-
- KeyFactory kf = KeyFactory.getInstance("RSA");
- cachedPrivateKey = kf.generatePrivate(
- new PKCS8EncodedKeySpec(Base64.getDecoder().decode(privateKey)));
- return cachedPrivateKey;
- } catch (IOException e) {
- throw new RuntimeException("读取私钥文件失败", e);
- } catch (NoSuchAlgorithmException e) {
- throw new RuntimeException("当前Java环境不支持RSA", e);
- } catch (InvalidKeySpecException e) {
- throw new RuntimeException("无效的密钥格式", e);
- }
- }
-
- /**
- * 获取微信支付平台公钥
- */
- public static PublicKey getWechatPublicKey() {
- if (cachedPublicKey != null) {
- return cachedPublicKey;
- }
-
- try {
- // 使用验证器获取最新的证书
- X509Certificate certificate = getVerifier().getValidCertificate();
- cachedPublicKey = certificate.getPublicKey();
- return cachedPublicKey;
- } catch (Exception e) {
- throw new RuntimeException("获取微信平台公钥失败", e);
- }
- }
-
- /**
- * 从PEM格式文件加载公钥
- */
- public static PublicKey loadPublicKeyFromFile(String filePath) {
- try {
- String content = new String(Files.readAllBytes(Paths.get(filePath)), StandardCharsets.UTF_8);
-
- String publicKeyPEM = content
- .replace("-----BEGIN PUBLIC KEY-----", "")
- .replace("-----END PUBLIC KEY-----", "")
- .replaceAll("\\s+", "");
-
- byte[] encoded = Base64.getDecoder().decode(publicKeyPEM);
- KeyFactory keyFactory = KeyFactory.getInstance("RSA");
- return keyFactory.generatePublic(new X509EncodedKeySpec(encoded));
- } catch (Exception e) {
- throw new RuntimeException("加载公钥文件失败", e);
- }
- }
-
- /**
- * 从证书文件加载公钥
- */
- public static PublicKey loadPublicKeyFromCert(String filePath) {
- try (FileInputStream inputStream = new FileInputStream(filePath)) {
- CertificateFactory factory = CertificateFactory.getInstance("X.509");
- X509Certificate cert = (X509Certificate) factory.generateCertificate(inputStream);
- return cert.getPublicKey();
- } catch (Exception e) {
- throw new RuntimeException("加载证书文件失败", e);
- }
- }
-}
\ No newline at end of file
+//package com.dsh.activity.util.wx;
+//
+//import com.wechat.pay.contrib.apache.httpclient.WechatPayHttpClientBuilder;
+//import com.wechat.pay.contrib.apache.httpclient.auth.AutoUpdateCertificatesVerifier;
+//import com.wechat.pay.contrib.apache.httpclient.auth.PrivateKeySigner;
+//import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Credentials;
+//import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Validator;
+//import com.wechat.pay.contrib.apache.httpclient.util.PemUtil;
+//import lombok.SneakyThrows;
+//import org.apache.http.impl.client.CloseableHttpClient;
+//
+//import javax.servlet.http.HttpServletRequest;
+//import java.io.*;
+//import java.nio.charset.StandardCharsets;
+//import java.nio.file.Files;
+//import java.nio.file.Paths;
+//import java.security.*;
+//import java.security.cert.Certificate;
+//import java.security.cert.CertificateException;
+//import java.security.cert.CertificateFactory;
+//import java.security.cert.X509Certificate;
+//import java.security.spec.InvalidKeySpecException;
+//import java.security.spec.PKCS8EncodedKeySpec;
+//import java.security.spec.X509EncodedKeySpec;
+//import java.util.Base64;
+//import java.util.HashMap;
+//import java.util.Map;
+//import java.util.concurrent.ConcurrentHashMap;
+//import java.util.stream.Collectors;
+//import java.util.stream.Stream;
+//
+///**
+// * 微信支付V3 API 签名验证工具类
+// */
+//public class WXPaySignatureCertificateUtil {
+//
+// // 保存微信平台证书
+// private static final ConcurrentHashMap<String, AutoUpdateCertificatesVerifier> verifierMap = new ConcurrentHashMap<>();
+// // 缓存公钥,避免频繁IO操作
+// private static PublicKey cachedPublicKey = null;
+// // 缓存私钥,避免频繁IO操作
+// private static PrivateKey cachedPrivateKey = null;
+//
+// /**
+// * 获取HTTP客户端,用于微信支付API请求
+// */
+// public static CloseableHttpClient getWechatPayClient() throws IOException {
+// PrivateKey merchantPrivateKey = getPrivateKey();
+// // 构建支付客户端
+// return WechatPayHttpClientBuilder.create()
+// .withMerchant(WxV3PayConfig.Mch_ID, WxV3PayConfig.mchSerialNo, merchantPrivateKey)
+// .withValidator(new WechatPay2Validator(getVerifier()))
+// .build();
+// }
+//
+// /**
+// * 获取自动更新的证书验证器
+// */
+// public static AutoUpdateCertificatesVerifier getVerifier() {
+// String mchSerialNo = WxV3PayConfig.mchSerialNo;
+// AutoUpdateCertificatesVerifier verifier = verifierMap.get(mchSerialNo);
+//
+// if (verifier == null) {
+// synchronized (WXPaySignatureCertificateUtil.class) {
+// verifier = verifierMap.get(mchSerialNo);
+// if (verifier == null) {
+// try {
+// PrivateKey privateKey = getPrivateKey();
+// PrivateKeySigner signer = new PrivateKeySigner(mchSerialNo, privateKey);
+// WechatPay2Credentials credentials = new WechatPay2Credentials(WxV3PayConfig.Mch_ID, signer);
+// verifier = new AutoUpdateCertificatesVerifier(
+// credentials, WxV3PayConfig.apiV3Key.getBytes(StandardCharsets.UTF_8));
+// verifierMap.put(mchSerialNo, verifier);
+// } catch (Exception e) {
+// throw new RuntimeException("初始化证书验证器失败", e);
+// }
+// }
+// }
+// }
+//
+// return verifier;
+// }
+//
+// /**
+// * 使用商户私钥对数据进行签名
+// *
+// * @param message 待签名数据
+// * @return Base64编码的签名结果
+// */
+// public static String sign(String message) {
+// try {
+// PrivateKey privateKey = getPrivateKey();
+// Signature signature = Signature.getInstance("SHA256withRSA");
+// signature.initSign(privateKey);
+// signature.update(message.getBytes(StandardCharsets.UTF_8));
+// return Base64.getEncoder().encodeToString(signature.sign());
+// } catch (Exception e) {
+// throw new RuntimeException("签名失败", e);
+// }
+// }
+//
+// /**
+// * 使用微信支付平台公钥验证签名
+// *
+// * @param message 原始消息
+// * @param signature Base64编码的签名
+// * @return 验证结果
+// */
+// public static boolean verifySign(String message, String signature) {
+// try {
+// PublicKey publicKey = getWechatPublicKey();
+// Signature sig = Signature.getInstance("SHA256withRSA");
+// sig.initVerify(publicKey);
+// sig.update(message.getBytes(StandardCharsets.UTF_8));
+// return sig.verify(Base64.getDecoder().decode(signature));
+// } catch (Exception e) {
+// throw new RuntimeException("验签失败", e);
+// }
+// }
+//
+// /**
+// * 验证微信支付通知消息的签名
+// *
+// * @param request HTTP请求
+// * @param body 请求体内容
+// * @return 验证结果
+// */
+// public static boolean verifyNotify(HttpServletRequest request, String body) {
+// try {
+// // 获取必要的HTTP头信息
+// String timestamp = request.getHeader("Wechatpay-Timestamp");
+// String nonce = request.getHeader("Wechatpay-Nonce");
+// String serialNo = request.getHeader("Wechatpay-Serial");
+// String signature = request.getHeader("Wechatpay-Signature");
+//
+// // 拼接验签字符串
+// String message = Stream.of(timestamp, nonce, body)
+// .collect(Collectors.joining("\n", "", "\n"));
+//
+// // 使用自动更新的证书验证器进行验证
+// return getVerifier().verify(serialNo, message.getBytes(StandardCharsets.UTF_8), signature);
+// } catch (Exception e) {
+// throw new RuntimeException("验证微信支付通知签名失败", e);
+// }
+// }
+//
+// /**
+// * APP支付签名
+// */
+// public static String appPaySign(String timestamp, String nonceStr, String prepayId) {
+// String message = Stream.of(WxV3PayConfig.APP_ID, timestamp, nonceStr, prepayId)
+// .collect(Collectors.joining("\n", "", "\n"));
+// return sign(message);
+// }
+//
+// /**
+// * JSAPI支付签名
+// */
+// public static String jsApiPaySign(String timestamp, String nonceStr, String prepayId) {
+// String message = Stream.of(WxV3PayConfig.APP_ID, timestamp, nonceStr, "prepay_id="+prepayId)
+// .collect(Collectors.joining("\n", "", "\n"));
+// return sign(message);
+// }
+//
+// /**
+// * 构建App支付参数
+// */
+// public static Map<String, String> buildAppPayParams(String prepayId) {
+// try {
+// String timestamp = String.valueOf(System.currentTimeMillis() / 1000);
+// String nonceStr = generateNonceStr();
+// String sign = appPaySign(timestamp, nonceStr, prepayId);
+// Map<String, String> params = new HashMap<>();
+// params.put("appid", WxV3PayConfig.APP_ID);
+// params.put("partnerid", WxV3PayConfig.Mch_ID);
+// params.put("prepayid", prepayId);
+// params.put("package", "Sign=WXPay");
+// params.put("noncestr", nonceStr);
+// params.put("timestamp", timestamp);
+// params.put("sign", sign);
+//
+// return params;
+// } catch (Exception e) {
+// throw new RuntimeException("构建App支付参数失败", e);
+// }
+// }
+//
+// /**
+// * 构建JSAPI支付参数
+// */
+// public static Map<String, String> buildJsApiPayParams(String prepayId) {
+// try {
+// String timestamp = String.valueOf(System.currentTimeMillis() / 1000);
+// String nonceStr = generateNonceStr();
+// String sign = jsApiPaySign(timestamp, nonceStr, prepayId);
+//
+// Map<String, String> params = new HashMap<>();
+// params.put("appId", WxV3PayConfig.APP_ID);
+// params.put("timeStamp", timestamp);
+// params.put("nonceStr", nonceStr);
+// params.put("package", "prepay_id=" + prepayId);
+// params.put("signType", "RSA");
+// params.put("paySign", sign);
+//
+// return params;
+// } catch (Exception e) {
+// throw new RuntimeException("构建JSAPI支付参数失败", e);
+// }
+// }
+//
+// /**
+// * 生成随机字符串
+// */
+// private static String generateNonceStr() {
+// return java.util.UUID.randomUUID().toString().replaceAll("-", "").substring(0, 32);
+// }
+//
+// /**
+// * 获取商户私钥
+// */
+// public static PrivateKey getPrivateKey() {
+// if (cachedPrivateKey != null) {
+// return cachedPrivateKey;
+// }
+//
+// try {
+// String filePath = "D:\\玩湃v3参数\\apiclient_key.pem";
+// String content = new String(Files.readAllBytes(Paths.get(filePath)), StandardCharsets.UTF_8);
+//
+// String privateKey = content.replace("-----BEGIN PRIVATE KEY-----", "")
+// .replace("-----END PRIVATE KEY-----", "")
+// .replaceAll("\\s+", "");
+//
+// KeyFactory kf = KeyFactory.getInstance("RSA");
+// cachedPrivateKey = kf.generatePrivate(
+// new PKCS8EncodedKeySpec(Base64.getDecoder().decode(privateKey)));
+// return cachedPrivateKey;
+// } catch (IOException e) {
+// throw new RuntimeException("读取私钥文件失败", e);
+// } catch (NoSuchAlgorithmException e) {
+// throw new RuntimeException("当前Java环境不支持RSA", e);
+// } catch (InvalidKeySpecException e) {
+// throw new RuntimeException("无效的密钥格式", e);
+// }
+// }
+//
+// /**
+// * 获取微信支付平台公钥
+// */
+// public static PublicKey getWechatPublicKey() {
+// if (cachedPublicKey != null) {
+// return cachedPublicKey;
+// }
+//
+// try {
+// // 使用验证器获取最新的证书
+// X509Certificate certificate = getVerifier().getValidCertificate();
+// cachedPublicKey = certificate.getPublicKey();
+// return cachedPublicKey;
+// } catch (Exception e) {
+// throw new RuntimeException("获取微信平台公钥失败", e);
+// }
+// }
+//
+// /**
+// * 从PEM格式文件加载公钥
+// */
+// public static PublicKey loadPublicKeyFromFile(String filePath) {
+// try {
+// String content = new String(Files.readAllBytes(Paths.get(filePath)), StandardCharsets.UTF_8);
+//
+// String publicKeyPEM = content
+// .replace("-----BEGIN PUBLIC KEY-----", "")
+// .replace("-----END PUBLIC KEY-----", "")
+// .replaceAll("\\s+", "");
+//
+// byte[] encoded = Base64.getDecoder().decode(publicKeyPEM);
+// KeyFactory keyFactory = KeyFactory.getInstance("RSA");
+// return keyFactory.generatePublic(new X509EncodedKeySpec(encoded));
+// } catch (Exception e) {
+// throw new RuntimeException("加载公钥文件失败", e);
+// }
+// }
+//
+// /**
+// * 从证书文件加载公钥
+// */
+// public static PublicKey loadPublicKeyFromCert(String filePath) {
+// try (FileInputStream inputStream = new FileInputStream(filePath)) {
+// CertificateFactory factory = CertificateFactory.getInstance("X.509");
+// X509Certificate cert = (X509Certificate) factory.generateCertificate(inputStream);
+// return cert.getPublicKey();
+// } catch (Exception e) {
+// throw new RuntimeException("加载证书文件失败", e);
+// }
+// }
+//}
\ No newline at end of file
diff --git a/cloud-server-activity/src/main/java/com/dsh/activity/util/wx/WxAppPayService.java b/cloud-server-activity/src/main/java/com/dsh/activity/util/wx/WxAppPayService.java
index bd24df0..0b243e3 100644
--- a/cloud-server-activity/src/main/java/com/dsh/activity/util/wx/WxAppPayService.java
+++ b/cloud-server-activity/src/main/java/com/dsh/activity/util/wx/WxAppPayService.java
@@ -1,222 +1,222 @@
-package com.dsh.activity.util.wx;
-
-import com.dsh.activity.util.wx.WXPayConstants;
-import com.dsh.activity.util.wx.WXPaySignatureCertificateUtil;
-import com.dsh.activity.util.wx.WxV3PayConfig;
-import com.fasterxml.jackson.databind.JsonNode; // 引入Jackson库处理JSON
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.node.ObjectNode;
-import org.apache.http.client.methods.CloseableHttpResponse;
-import org.apache.http.client.methods.HttpPost;
-import org.apache.http.entity.StringEntity;
-import org.apache.http.impl.client.CloseableHttpClient;
-import org.apache.http.util.EntityUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Component;
-import org.springframework.stereotype.Service;
-
-import java.io.IOException;
-import java.math.BigDecimal;
-import java.nio.charset.StandardCharsets;
-import java.util.HashMap;
-import java.util.Map;
-
-@Component
-public class WxAppPayService {
-
- private static final Logger log = LoggerFactory.getLogger(WxAppPayService.class);
-
- private final ObjectMapper objectMapper; // 用于JSON序列化和反序列化
- private final CloseableHttpClient wechatPayClient; // 注入通过工具类创建的HTTP客户端
-
- @Autowired
- public WxAppPayService(ObjectMapper objectMapper) throws IOException {
- this.objectMapper = objectMapper;
- // 在构造函数中初始化带有签名验证功能的HTTP客户端
- this.wechatPayClient = WXPaySignatureCertificateUtil.getWechatPayClient();
- log.info("微信支付V3 HTTP客户端初始化完成。");
- }
-
- /**
- * 创建APP支付预付单 (统一下单)
- *
- * @param description 商品描述
- * @param outTradeNo 商户订单号 (要求32个字符内,只能是数字、大小写字母_-|* 且在同一个商户号下唯一)
- * @param totalAmount 支付总金额 (单位:元)
- * @return 用于调起APP支付的参数 Map (appid, partnerid, prepayid, package, noncestr, timestamp, sign)
- * @throws IOException 网络或IO异常
- * @throws RuntimeException 支付请求失败或处理异常
- */
- public Map<String, String> createOrder(String description, String outTradeNo, BigDecimal totalAmount)
- throws IOException {
-
- // 1. 构建请求URL
- String url = WXPayConstants.DOMAIN_API + WXPayConstants.PAY_TRANSACTIONS_APP;
- HttpPost httpPost = new HttpPost(url);
- httpPost.addHeader("Accept", "application/json");
- httpPost.addHeader("Content-type", "application/json; charset=utf-8");
-
- // 2. 构建请求体 JSON
- ObjectNode rootNode = objectMapper.createObjectNode();
-// rootNode.put("appid", WxV3PayConfig.APP_ID);//服务商不需要该字段
-// rootNode.put("mchid", WxV3PayConfig.Mch_ID);//服务商不需要该字段
- rootNode.put("description", description);
- rootNode.put("out_trade_no", outTradeNo);
- rootNode.put("notify_url", WXPayConstants.WECHAT_PAY_NOTIFY_URL); // 使用常量中的回调地址
-
- ObjectNode amountNode = objectMapper.createObjectNode();
- // 微信支付金额单位为分,需要转换
- amountNode.put("total", totalAmount.multiply(new BigDecimal("100")).intValue());
- amountNode.put("currency", "CNY"); // 货币类型,默认人民币
- rootNode.set("amount", amountNode);
-
- // 如果你是服务商模式,需要添加子商户信息
- rootNode.put("sp_mchid", WxV3PayConfig.Mch_ID);
- rootNode.put("sub_mchid", "123");
- rootNode.put("sp_appid", "wx41d32f362ba0f911");
- // rootNode.put("sub_appid", "子商户AppID"); // 如果子商户需要用自己的AppID拉起支付
-
- String requestBody = rootNode.toString();
- log.info("微信APP支付下单请求体: {}", requestBody);
- httpPost.setEntity(new StringEntity(requestBody, StandardCharsets.UTF_8));
-
- // 3. 发送请求
- try (CloseableHttpResponse response = wechatPayClient.execute(httpPost)) {
- int statusCode = response.getStatusLine().getStatusCode();
- String responseBody = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
- log.info("微信APP支付下单响应状态码: {}, 响应体: {}", statusCode, responseBody);
-
- if (statusCode == 200) { // HTTP状态码 200 表示成功
- JsonNode responseNode = objectMapper.readTree(responseBody);
- String prepayId = responseNode.get("prepay_id").asText();
- log.info("成功获取预支付交易会话标识 (prepay_id): {}", prepayId);
-
- // 4. 生成调起支付所需的参数
- Map<String, String> payParams = WXPaySignatureCertificateUtil.buildAppPayParams(prepayId);
- log.info("生成APP支付参数: {}", payParams);
- return payParams;
-
- } else {
- // 处理错误情况
- log.error("微信APP支付下单失败,状态码: {}, 响应: {}", statusCode, responseBody);
- // 可以根据 responseBody 中的 code 和 message 进一步分析错误
- throw new RuntimeException("微信APP支付下单失败: " + responseBody);
- }
- } catch (Exception e) {
- log.error("微信APP支付下单请求执行异常", e);
- throw new IOException("微信APP支付下单请求执行异常", e);
- }
- }
-
- /**
- * 关闭订单 (根据商户订单号)
- *
- * @param outTradeNo 商户订单号
- * @return true 如果关闭成功或订单已关闭/不存在 (根据微信文档,成功是204 No Content)
- * @throws IOException 网络或IO异常
- * @throws RuntimeException 关闭请求失败或处理异常
- */
- public boolean closeOrder(String outTradeNo) throws IOException {
- // 1. 构建请求URL, 注意替换占位符
- String url = WXPayConstants.DOMAIN_API
- + WXPayConstants.PAY_TRANSACTIONS_OUT_TRADE_NO.replace("{}", outTradeNo);
-
- HttpPost httpPost = new HttpPost(url);
- httpPost.addHeader("Accept", "application/json");
- httpPost.addHeader("Content-type", "application/json; charset=utf-8");
-
- // 2. 构建请求体 JSON (只需要商户号)
- ObjectNode rootNode = objectMapper.createObjectNode();
- rootNode.put("mchid", WxV3PayConfig.Mch_ID);
- // 如果是服务商模式,则用 sp_mchid
- rootNode.put("sp_mchid", WxV3PayConfig.Mch_ID);
-
- String requestBody = rootNode.toString();
- log.info("微信关单请求 URL: {}, 请求体: {}", url, requestBody);
- httpPost.setEntity(new StringEntity(requestBody, StandardCharsets.UTF_8));
-
- // 3. 发送请求
- try (CloseableHttpResponse response = wechatPayClient.execute(httpPost)) {
- int statusCode = response.getStatusLine().getStatusCode();
- // 关单成功时,微信返回 HTTP 状态码 204 No Content
- log.info("微信关单响应状态码: {}", statusCode);
- if (statusCode == 204) {
- log.info("订单 {} 关闭成功。", outTradeNo);
- return true;
- } else {
- String responseBody = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
- log.error("微信关单失败,商户订单号: {}, 状态码: {}, 响应: {}", outTradeNo, statusCode, responseBody);
- // 根据需要可以解析responseBody获取错误详情
- return false; // 或者抛出异常,根据业务决定
- }
- } catch (Exception e) {
- log.error("微信关单请求执行异常, 商户订单号: {}", outTradeNo, e);
- throw new IOException("微信关单请求执行异常", e);
- }
- }
-
-
- // --- 退款相关方法 (可选) ---
-
- /**
- * 申请退款
- *
- * @param outTradeNo 原商户订单号
- * @param outRefundNo 商户退款单号 (商户系统内部的退款单号,要求唯一)
- * @param reason 退款原因 (可选)
- * @param refundAmount 退款金额 (单位:元)
- * @param totalAmount 原订单总金额 (单位:元)
- * @return 退款处理结果,可以返回微信返回的JSON节点或自定义对象
- * @throws IOException 网络或IO异常
- * @throws RuntimeException 退款请求失败或处理异常
- */
- public JsonNode createRefund(String outTradeNo, String outRefundNo, String reason,
- BigDecimal refundAmount, BigDecimal totalAmount) throws IOException {
-
- String url = WXPayConstants.DOMAIN_API + WXPayConstants.REFUND_DOMESTIC_REFUNDS;
- HttpPost httpPost = new HttpPost(url);
- httpPost.addHeader("Accept", "application/json");
- httpPost.addHeader("Content-type", "application/json; charset=utf-8");
-
- ObjectNode rootNode = objectMapper.createObjectNode();
- // 如果是服务商模式,需要添加子商户号
- // rootNode.put("sub_mchid", "子商户号");
- rootNode.put("out_trade_no", outTradeNo);
- rootNode.put("out_refund_no", outRefundNo);
- if (reason != null && !reason.isEmpty()) {
- rootNode.put("reason", reason);
- }
- // 设置退款回调地址
- rootNode.put("notify_url", WXPayConstants.WECHAT_REFUNDS_NOTIFY_URL);
-
- ObjectNode amountNode = objectMapper.createObjectNode();
- amountNode.put("refund", refundAmount.multiply(new BigDecimal("100")).intValue()); // 退款金额,分
- amountNode.put("total", totalAmount.multiply(new BigDecimal("100")).intValue()); // 原订单金额,分
- amountNode.put("currency", "CNY");
- rootNode.set("amount", amountNode);
-
- String requestBody = rootNode.toString();
- log.info("微信申请退款请求体: {}", requestBody);
- httpPost.setEntity(new StringEntity(requestBody, StandardCharsets.UTF_8));
-
- try (CloseableHttpResponse response = wechatPayClient.execute(httpPost)) {
- int statusCode = response.getStatusLine().getStatusCode();
- String responseBody = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
- log.info("微信申请退款响应状态码: {}, 响应体: {}", statusCode, responseBody);
-
- if (statusCode == 200) { // 成功受理
- log.info("微信退款申请成功受理。");
- return objectMapper.readTree(responseBody);
- } else {
- log.error("微信申请退款失败,状态码: {}, 响应: {}", statusCode, responseBody);
- throw new RuntimeException("微信申请退款失败: " + responseBody);
- }
- } catch (Exception e) {
- log.error("微信申请退款请求执行异常", e);
- throw new IOException("微信申请退款请求执行异常", e);
- }
- }
-
-}
\ No newline at end of file
+//package com.dsh.activity.util.wx;
+//
+//import com.dsh.activity.util.wx.WXPayConstants;
+//import com.dsh.activity.util.wx.WXPaySignatureCertificateUtil;
+//import com.dsh.activity.util.wx.WxV3PayConfig;
+//import com.fasterxml.jackson.databind.JsonNode; // 引入Jackson库处理JSON
+//import com.fasterxml.jackson.databind.ObjectMapper;
+//import com.fasterxml.jackson.databind.node.ObjectNode;
+//import org.apache.http.client.methods.CloseableHttpResponse;
+//import org.apache.http.client.methods.HttpPost;
+//import org.apache.http.entity.StringEntity;
+//import org.apache.http.impl.client.CloseableHttpClient;
+//import org.apache.http.util.EntityUtils;
+//import org.slf4j.Logger;
+//import org.slf4j.LoggerFactory;
+//import org.springframework.beans.factory.annotation.Autowired;
+//import org.springframework.stereotype.Component;
+//import org.springframework.stereotype.Service;
+//
+//import java.io.IOException;
+//import java.math.BigDecimal;
+//import java.nio.charset.StandardCharsets;
+//import java.util.HashMap;
+//import java.util.Map;
+//
+//@Component
+//public class WxAppPayService {
+//
+// private static final Logger log = LoggerFactory.getLogger(WxAppPayService.class);
+//
+// private final ObjectMapper objectMapper; // 用于JSON序列化和反序列化
+// private final CloseableHttpClient wechatPayClient; // 注入通过工具类创建的HTTP客户端
+//
+// @Autowired
+// public WxAppPayService(ObjectMapper objectMapper) throws IOException {
+// this.objectMapper = objectMapper;
+// // 在构造函数中初始化带有签名验证功能的HTTP客户端
+// this.wechatPayClient = WXPaySignatureCertificateUtil.getWechatPayClient();
+// log.info("微信支付V3 HTTP客户端初始化完成。");
+// }
+//
+// /**
+// * 创建APP支付预付单 (统一下单)
+// *
+// * @param description 商品描述
+// * @param outTradeNo 商户订单号 (要求32个字符内,只能是数字、大小写字母_-|* 且在同一个商户号下唯一)
+// * @param totalAmount 支付总金额 (单位:元)
+// * @return 用于调起APP支付的参数 Map (appid, partnerid, prepayid, package, noncestr, timestamp, sign)
+// * @throws IOException 网络或IO异常
+// * @throws RuntimeException 支付请求失败或处理异常
+// */
+// public Map<String, String> createOrder(String description, String outTradeNo, BigDecimal totalAmount)
+// throws IOException {
+//
+// // 1. 构建请求URL
+// String url = WXPayConstants.DOMAIN_API + WXPayConstants.PAY_TRANSACTIONS_APP;
+// HttpPost httpPost = new HttpPost(url);
+// httpPost.addHeader("Accept", "application/json");
+// httpPost.addHeader("Content-type", "application/json; charset=utf-8");
+//
+// // 2. 构建请求体 JSON
+// ObjectNode rootNode = objectMapper.createObjectNode();
+//// rootNode.put("appid", WxV3PayConfig.APP_ID);//服务商不需要该字段
+//// rootNode.put("mchid", WxV3PayConfig.Mch_ID);//服务商不需要该字段
+// rootNode.put("description", description);
+// rootNode.put("out_trade_no", outTradeNo);
+// rootNode.put("notify_url", WXPayConstants.WECHAT_PAY_NOTIFY_URL); // 使用常量中的回调地址
+//
+// ObjectNode amountNode = objectMapper.createObjectNode();
+// // 微信支付金额单位为分,需要转换
+// amountNode.put("total", totalAmount.multiply(new BigDecimal("100")).intValue());
+// amountNode.put("currency", "CNY"); // 货币类型,默认人民币
+// rootNode.set("amount", amountNode);
+//
+// // 如果你是服务商模式,需要添加子商户信息
+// rootNode.put("sp_mchid", WxV3PayConfig.Mch_ID);
+// rootNode.put("sub_mchid", "123");
+// rootNode.put("sp_appid", "wx41d32f362ba0f911");
+// // rootNode.put("sub_appid", "子商户AppID"); // 如果子商户需要用自己的AppID拉起支付
+//
+// String requestBody = rootNode.toString();
+// log.info("微信APP支付下单请求体: {}", requestBody);
+// httpPost.setEntity(new StringEntity(requestBody, StandardCharsets.UTF_8));
+//
+// // 3. 发送请求
+// try (CloseableHttpResponse response = wechatPayClient.execute(httpPost)) {
+// int statusCode = response.getStatusLine().getStatusCode();
+// String responseBody = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
+// log.info("微信APP支付下单响应状态码: {}, 响应体: {}", statusCode, responseBody);
+//
+// if (statusCode == 200) { // HTTP状态码 200 表示成功
+// JsonNode responseNode = objectMapper.readTree(responseBody);
+// String prepayId = responseNode.get("prepay_id").asText();
+// log.info("成功获取预支付交易会话标识 (prepay_id): {}", prepayId);
+//
+// // 4. 生成调起支付所需的参数
+// Map<String, String> payParams = WXPaySignatureCertificateUtil.buildAppPayParams(prepayId);
+// log.info("生成APP支付参数: {}", payParams);
+// return payParams;
+//
+// } else {
+// // 处理错误情况
+// log.error("微信APP支付下单失败,状态码: {}, 响应: {}", statusCode, responseBody);
+// // 可以根据 responseBody 中的 code 和 message 进一步分析错误
+// throw new RuntimeException("微信APP支付下单失败: " + responseBody);
+// }
+// } catch (Exception e) {
+// log.error("微信APP支付下单请求执行异常", e);
+// throw new IOException("微信APP支付下单请求执行异常", e);
+// }
+// }
+//
+// /**
+// * 关闭订单 (根据商户订单号)
+// *
+// * @param outTradeNo 商户订单号
+// * @return true 如果关闭成功或订单已关闭/不存在 (根据微信文档,成功是204 No Content)
+// * @throws IOException 网络或IO异常
+// * @throws RuntimeException 关闭请求失败或处理异常
+// */
+// public boolean closeOrder(String outTradeNo) throws IOException {
+// // 1. 构建请求URL, 注意替换占位符
+// String url = WXPayConstants.DOMAIN_API
+// + WXPayConstants.PAY_TRANSACTIONS_OUT_TRADE_NO.replace("{}", outTradeNo);
+//
+// HttpPost httpPost = new HttpPost(url);
+// httpPost.addHeader("Accept", "application/json");
+// httpPost.addHeader("Content-type", "application/json; charset=utf-8");
+//
+// // 2. 构建请求体 JSON (只需要商户号)
+// ObjectNode rootNode = objectMapper.createObjectNode();
+// rootNode.put("mchid", WxV3PayConfig.Mch_ID);
+// // 如果是服务商模式,则用 sp_mchid
+// rootNode.put("sp_mchid", WxV3PayConfig.Mch_ID);
+//
+// String requestBody = rootNode.toString();
+// log.info("微信关单请求 URL: {}, 请求体: {}", url, requestBody);
+// httpPost.setEntity(new StringEntity(requestBody, StandardCharsets.UTF_8));
+//
+// // 3. 发送请求
+// try (CloseableHttpResponse response = wechatPayClient.execute(httpPost)) {
+// int statusCode = response.getStatusLine().getStatusCode();
+// // 关单成功时,微信返回 HTTP 状态码 204 No Content
+// log.info("微信关单响应状态码: {}", statusCode);
+// if (statusCode == 204) {
+// log.info("订单 {} 关闭成功。", outTradeNo);
+// return true;
+// } else {
+// String responseBody = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
+// log.error("微信关单失败,商户订单号: {}, 状态码: {}, 响应: {}", outTradeNo, statusCode, responseBody);
+// // 根据需要可以解析responseBody获取错误详情
+// return false; // 或者抛出异常,根据业务决定
+// }
+// } catch (Exception e) {
+// log.error("微信关单请求执行异常, 商户订单号: {}", outTradeNo, e);
+// throw new IOException("微信关单请求执行异常", e);
+// }
+// }
+//
+//
+// // --- 退款相关方法 (可选) ---
+//
+// /**
+// * 申请退款
+// *
+// * @param outTradeNo 原商户订单号
+// * @param outRefundNo 商户退款单号 (商户系统内部的退款单号,要求唯一)
+// * @param reason 退款原因 (可选)
+// * @param refundAmount 退款金额 (单位:元)
+// * @param totalAmount 原订单总金额 (单位:元)
+// * @return 退款处理结果,可以返回微信返回的JSON节点或自定义对象
+// * @throws IOException 网络或IO异常
+// * @throws RuntimeException 退款请求失败或处理异常
+// */
+// public JsonNode createRefund(String outTradeNo, String outRefundNo, String reason,
+// BigDecimal refundAmount, BigDecimal totalAmount) throws IOException {
+//
+// String url = WXPayConstants.DOMAIN_API + WXPayConstants.REFUND_DOMESTIC_REFUNDS;
+// HttpPost httpPost = new HttpPost(url);
+// httpPost.addHeader("Accept", "application/json");
+// httpPost.addHeader("Content-type", "application/json; charset=utf-8");
+//
+// ObjectNode rootNode = objectMapper.createObjectNode();
+// // 如果是服务商模式,需要添加子商户号
+// // rootNode.put("sub_mchid", "子商户号");
+// rootNode.put("out_trade_no", outTradeNo);
+// rootNode.put("out_refund_no", outRefundNo);
+// if (reason != null && !reason.isEmpty()) {
+// rootNode.put("reason", reason);
+// }
+// // 设置退款回调地址
+// rootNode.put("notify_url", WXPayConstants.WECHAT_REFUNDS_NOTIFY_URL);
+//
+// ObjectNode amountNode = objectMapper.createObjectNode();
+// amountNode.put("refund", refundAmount.multiply(new BigDecimal("100")).intValue()); // 退款金额,分
+// amountNode.put("total", totalAmount.multiply(new BigDecimal("100")).intValue()); // 原订单金额,分
+// amountNode.put("currency", "CNY");
+// rootNode.set("amount", amountNode);
+//
+// String requestBody = rootNode.toString();
+// log.info("微信申请退款请求体: {}", requestBody);
+// httpPost.setEntity(new StringEntity(requestBody, StandardCharsets.UTF_8));
+//
+// try (CloseableHttpResponse response = wechatPayClient.execute(httpPost)) {
+// int statusCode = response.getStatusLine().getStatusCode();
+// String responseBody = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
+// log.info("微信申请退款响应状态码: {}, 响应体: {}", statusCode, responseBody);
+//
+// if (statusCode == 200) { // 成功受理
+// log.info("微信退款申请成功受理。");
+// return objectMapper.readTree(responseBody);
+// } else {
+// log.error("微信申请退款失败,状态码: {}, 响应: {}", statusCode, responseBody);
+// throw new RuntimeException("微信申请退款失败: " + responseBody);
+// }
+// } catch (Exception e) {
+// log.error("微信申请退款请求执行异常", e);
+// throw new IOException("微信申请退款请求执行异常", e);
+// }
+// }
+//
+//}
\ No newline at end of file
diff --git a/cloud-server-activity/src/main/java/com/dsh/activity/util/wx/WxPayAesUtil.java b/cloud-server-activity/src/main/java/com/dsh/activity/util/wx/WxPayAesUtil.java
index d101c61..5191df4 100644
--- a/cloud-server-activity/src/main/java/com/dsh/activity/util/wx/WxPayAesUtil.java
+++ b/cloud-server-activity/src/main/java/com/dsh/activity/util/wx/WxPayAesUtil.java
@@ -1,57 +1,57 @@
-package com.dsh.activity.util.wx;
-
-import javax.crypto.Cipher;
-import javax.crypto.NoSuchPaddingException;
-import javax.crypto.spec.GCMParameterSpec;
-import javax.crypto.spec.SecretKeySpec;
-import java.nio.charset.StandardCharsets;
-import java.security.GeneralSecurityException;
-import java.security.InvalidAlgorithmParameterException;
-import java.security.InvalidKeyException;
-import java.security.NoSuchAlgorithmException;
-import java.util.Base64;
-
-/**
- * 微信支付V3 AES解密工具类 (AEAD_AES_256_GCM)
- */
-public class WxPayAesUtil {
-
- private static final String ALGORITHM = "AES/GCM/NoPadding";
- private static final int TAG_LENGTH_BIT = 128; // GCM认证标签长度,固定为128位
- private static final int NONCE_LENGTH_BYTE = 12; // GCM随机串长度,固定为12字节
- private static final String TRANSFORMATION = "AES/GCM/NoPadding"; // 算法/模式/填充
-
- /**
- * 解密微信支付回调通知中的加密信息
- *
- * @param apiV3Key APIv3密钥 (来自 WxV3PayConfig)
- * @param associatedData 附加数据 (resource.associated_data)
- * @param nonce 随机串 (resource.nonce)
- * @param ciphertext 密文 (resource.ciphertext),Base64编码
- * @return 解密后的明文字符串
- * @throws GeneralSecurityException 解密失败时抛出异常
- */
- public static String decrypt(String apiV3Key, String associatedData, String nonce, String ciphertext)
- throws GeneralSecurityException {
- try {
- SecretKeySpec key = new SecretKeySpec(apiV3Key.getBytes(StandardCharsets.UTF_8), "AES");
- GCMParameterSpec spec = new GCMParameterSpec(TAG_LENGTH_BIT, nonce.getBytes(StandardCharsets.UTF_8));
-
- Cipher cipher = Cipher.getInstance(TRANSFORMATION);
- cipher.init(Cipher.DECRYPT_MODE, key, spec);
- cipher.updateAAD(associatedData.getBytes(StandardCharsets.UTF_8)); // 设置附加认证数据
-
- byte[] decodedCiphertext = Base64.getDecoder().decode(ciphertext);
- byte[] decryptedBytes = cipher.doFinal(decodedCiphertext);
-
- return new String(decryptedBytes, StandardCharsets.UTF_8);
- } catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
- throw new IllegalStateException("当前JDK环境不支持AEAD_AES_256_GCM", e);
- } catch (InvalidKeyException | InvalidAlgorithmParameterException e) {
- throw new IllegalArgumentException("无效的密钥或GCM参数", e);
- } catch (Exception e) {
- // 包括 BadPaddingException 等解密失败的情况
- throw new GeneralSecurityException("AES/GCM 解密失败", e);
- }
- }
-}
\ No newline at end of file
+//package com.dsh.activity.util.wx;
+//
+//import javax.crypto.Cipher;
+//import javax.crypto.NoSuchPaddingException;
+//import javax.crypto.spec.GCMParameterSpec;
+//import javax.crypto.spec.SecretKeySpec;
+//import java.nio.charset.StandardCharsets;
+//import java.security.GeneralSecurityException;
+//import java.security.InvalidAlgorithmParameterException;
+//import java.security.InvalidKeyException;
+//import java.security.NoSuchAlgorithmException;
+//import java.util.Base64;
+//
+///**
+// * 微信支付V3 AES解密工具类 (AEAD_AES_256_GCM)
+// */
+//public class WxPayAesUtil {
+//
+// private static final String ALGORITHM = "AES/GCM/NoPadding";
+// private static final int TAG_LENGTH_BIT = 128; // GCM认证标签长度,固定为128位
+// private static final int NONCE_LENGTH_BYTE = 12; // GCM随机串长度,固定为12字节
+// private static final String TRANSFORMATION = "AES/GCM/NoPadding"; // 算法/模式/填充
+//
+// /**
+// * 解密微信支付回调通知中的加密信息
+// *
+// * @param apiV3Key APIv3密钥 (来自 WxV3PayConfig)
+// * @param associatedData 附加数据 (resource.associated_data)
+// * @param nonce 随机串 (resource.nonce)
+// * @param ciphertext 密文 (resource.ciphertext),Base64编码
+// * @return 解密后的明文字符串
+// * @throws GeneralSecurityException 解密失败时抛出异常
+// */
+// public static String decrypt(String apiV3Key, String associatedData, String nonce, String ciphertext)
+// throws GeneralSecurityException {
+// try {
+// SecretKeySpec key = new SecretKeySpec(apiV3Key.getBytes(StandardCharsets.UTF_8), "AES");
+// GCMParameterSpec spec = new GCMParameterSpec(TAG_LENGTH_BIT, nonce.getBytes(StandardCharsets.UTF_8));
+//
+// Cipher cipher = Cipher.getInstance(TRANSFORMATION);
+// cipher.init(Cipher.DECRYPT_MODE, key, spec);
+// cipher.updateAAD(associatedData.getBytes(StandardCharsets.UTF_8)); // 设置附加认证数据
+//
+// byte[] decodedCiphertext = Base64.getDecoder().decode(ciphertext);
+// byte[] decryptedBytes = cipher.doFinal(decodedCiphertext);
+//
+// return new String(decryptedBytes, StandardCharsets.UTF_8);
+// } catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
+// throw new IllegalStateException("当前JDK环境不支持AEAD_AES_256_GCM", e);
+// } catch (InvalidKeyException | InvalidAlgorithmParameterException e) {
+// throw new IllegalArgumentException("无效的密钥或GCM参数", e);
+// } catch (Exception e) {
+// // 包括 BadPaddingException 等解密失败的情况
+// throw new GeneralSecurityException("AES/GCM 解密失败", e);
+// }
+// }
+//}
\ No newline at end of file
diff --git a/cloud-server-activity/src/main/java/com/dsh/activity/util/wx/WxPayNotifyController.java b/cloud-server-activity/src/main/java/com/dsh/activity/util/wx/WxPayNotifyController.java
index 4f63fcc..ce1e4be 100644
--- a/cloud-server-activity/src/main/java/com/dsh/activity/util/wx/WxPayNotifyController.java
+++ b/cloud-server-activity/src/main/java/com/dsh/activity/util/wx/WxPayNotifyController.java
@@ -1,177 +1,177 @@
-package com.dsh.activity.util.wx;
-
-import com.dsh.activity.util.wx.WXPaySignatureCertificateUtil;
-import com.dsh.activity.util.wx.WxPayAesUtil;
-import com.dsh.activity.util.wx.WxV3PayConfig;
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-
-import javax.servlet.http.HttpServletRequest;
-import java.nio.charset.StandardCharsets;
-import java.util.HashMap;
-import java.util.Map;
-
-@RestController
-@RequestMapping("/api/appPayment") // 路径前缀,与常量中配置的回调URL匹配
-public class WxPayNotifyController {
-
- private static final Logger log = LoggerFactory.getLogger(WxPayNotifyController.class);
-
- private final ObjectMapper objectMapper;
-
- @Autowired
- public WxPayNotifyController(ObjectMapper objectMapper) {
- this.objectMapper = objectMapper;
- }
-
- /**
- * 接收微信支付结果通知
- * URL需要与 WXPayConstants.WECHAT_PAY_NOTIFY_URL 匹配
- */
- @PostMapping("/weChatPayNotify")
- public ResponseEntity<Map<String, String>> handleWeChatPayNotify(HttpServletRequest request, @RequestBody String requestBody) {
-
- Map<String, String> responseMap = new HashMap<>();
- try {
- // 1. 验证签名 (使用工具类,它会处理证书)
- boolean verifyResult = WXPaySignatureCertificateUtil.verifyNotify(request, requestBody);
- if (!verifyResult) {
- log.error("微信支付通知验签失败!");
- responseMap.put("code", "FAIL");
- responseMap.put("message", "验签失败");
- return new ResponseEntity<>(responseMap, HttpStatus.BAD_REQUEST); // 返回错误状态码
- }
- log.info("微信支付通知验签成功。");
-
- // 2. 解析通知体
- JsonNode notifyData = objectMapper.readTree(requestBody);
- String eventType = notifyData.get("event_type").asText();
-
- // 只处理支付成功的通知类型
- if ("TRANSACTION.SUCCESS".equals(eventType)) {
- log.info("处理支付成功通知...");
- JsonNode resourceNode = notifyData.get("resource");
- String associatedData = resourceNode.get("associated_data").asText();
- String nonce = resourceNode.get("nonce").asText();
- String ciphertext = resourceNode.get("ciphertext").asText();
-
- // 3. 解密关键信息
- String decryptedDataJson = WxPayAesUtil.decrypt(WxV3PayConfig.apiV3Key, associatedData, nonce, ciphertext);
- log.info("解密后的支付通知信息: {}", decryptedDataJson);
- JsonNode decryptedData = objectMapper.readTree(decryptedDataJson);
-
- // 4. 处理业务逻辑
- String outTradeNo = decryptedData.get("out_trade_no").asText();
- String transactionId = decryptedData.get("transaction_id").asText();
- String tradeState = decryptedData.get("trade_state").asText();
- // ... 获取其他需要的信息,例如支付金额、用户openid等
-
- // TODO: 在这里实现你的业务逻辑:
- // 1. 根据 outTradeNo 查询你的数据库订单状态。
- // 2. 判断订单是否已经处理过(防止重复处理通知)。
- // 3. 如果订单未处理且 tradeState 为 SUCCESS,则更新订单状态为支付成功。
- // 4. 记录 transactionId (微信支付订单号)。
- // 5. 执行后续业务流程(如发货、增加积分等)。
- // 6. 如果处理失败,可以考虑记录日志并后续重试,但仍需返回成功给微信,避免微信重复通知。
-
- log.info("业务逻辑处理完成,商户订单号: {}, 微信订单号: {}", outTradeNo, transactionId);
-
- } else {
- log.warn("收到非支付成功类型的通知: {}", eventType);
- // 其他类型的通知,根据需要处理或忽略
- }
-
- // 5. 返回成功响应给微信平台
- responseMap.put("code", "SUCCESS");
- responseMap.put("message", "成功");
- return new ResponseEntity<>(responseMap, HttpStatus.OK);
-
- } catch (Exception e) {
- log.error("处理微信支付通知异常", e);
- responseMap.put("code", "FAIL");
- responseMap.put("message", "处理失败");
- // 即使处理失败,也尽量返回成功给微信,避免重复通知轰炸,然后在后台处理异常。
- // 但如果验签失败,可以返回错误状态码。
- return new ResponseEntity<>(responseMap, HttpStatus.INTERNAL_SERVER_ERROR); // 或者返回OK,根据策略定
- }
- }
-
-
- /**
- * 接收微信退款结果通知
- * URL需要与 WXPayConstants.WECHAT_REFUNDS_NOTIFY_URL 匹配
- */
- @PostMapping("/weChatPayRefundsNotify")
- public ResponseEntity<Map<String, String>> handleWeChatRefundsNotify(HttpServletRequest request, @RequestBody String requestBody) {
-
- Map<String, String> responseMap = new HashMap<>();
- try {
- // 1. 验证签名
- boolean verifyResult = WXPaySignatureCertificateUtil.verifyNotify(request, requestBody);
- if (!verifyResult) {
- log.error("微信退款通知验签失败!");
- responseMap.put("code", "FAIL");
- responseMap.put("message", "验签失败");
- return new ResponseEntity<>(responseMap, HttpStatus.BAD_REQUEST);
- }
- log.info("微信退款通知验签成功。");
-
- // 2. 解析通知体
- JsonNode notifyData = objectMapper.readTree(requestBody);
- String eventType = notifyData.get("event_type").asText();
-
- // 处理退款成功或异常的通知
- if ("REFUND.SUCCESS".equals(eventType) || "REFUND.ABNORMAL".equals(eventType) || "REFUND.CLOSED".equals(eventType)) {
- log.info("处理退款通知,类型: {}", eventType);
- JsonNode resourceNode = notifyData.get("resource");
- String associatedData = resourceNode.get("associated_data").asText();
- String nonce = resourceNode.get("nonce").asText();
- String ciphertext = resourceNode.get("ciphertext").asText();
-
- // 3. 解密关键信息
- String decryptedDataJson = WxPayAesUtil.decrypt(WxV3PayConfig.apiV3Key, associatedData, nonce, ciphertext);
- log.info("解密后的退款通知信息: {}", decryptedDataJson);
- JsonNode decryptedData = objectMapper.readTree(decryptedDataJson);
-
- // 4. 处理业务逻辑
- String outTradeNo = decryptedData.get("out_trade_no").asText();
- String outRefundNo = decryptedData.get("out_refund_no").asText();
- String refundStatus = decryptedData.get("refund_status").asText(); // SUCCESS, CLOSED, ABNORMAL
- // ... 获取其他需要的信息,例如退款金额、微信退款单号 refund_id 等
-
- // TODO: 在这里实现你的退款业务逻辑:
- // 1. 根据 outRefundNo 查询你的数据库退款单状态。
- // 2. 判断退款单是否已经处理过。
- // 3. 根据 refundStatus 更新退款单状态。
- // 4. 如果退款成功 (SUCCESS),可能需要执行一些操作,如返还库存、通知用户等。
- // 5. 如果退款关闭或异常,也需要记录状态。
-
- log.info("退款业务逻辑处理完成,商户订单号: {}, 商户退款单号: {}, 退款状态: {}", outTradeNo, outRefundNo, refundStatus);
-
- } else {
- log.warn("收到非退款类型的通知: {}", eventType);
- }
-
- // 5. 返回成功响应给微信平台
- responseMap.put("code", "SUCCESS");
- responseMap.put("message", "成功");
- return new ResponseEntity<>(responseMap, HttpStatus.OK);
-
- } catch (Exception e) {
- log.error("处理微信退款通知异常", e);
- responseMap.put("code", "FAIL");
- responseMap.put("message", "处理失败");
- return new ResponseEntity<>(responseMap, HttpStatus.INTERNAL_SERVER_ERROR);
- }
- }
-
-}
+//package com.dsh.activity.util.wx;
+//
+//import com.dsh.activity.util.wx.WXPaySignatureCertificateUtil;
+//import com.dsh.activity.util.wx.WxPayAesUtil;
+//import com.dsh.activity.util.wx.WxV3PayConfig;
+//import com.fasterxml.jackson.databind.JsonNode;
+//import com.fasterxml.jackson.databind.ObjectMapper;
+//import org.slf4j.Logger;
+//import org.slf4j.LoggerFactory;
+//import org.springframework.beans.factory.annotation.Autowired;
+//import org.springframework.http.HttpStatus;
+//import org.springframework.http.ResponseEntity;
+//import org.springframework.web.bind.annotation.PostMapping;
+//import org.springframework.web.bind.annotation.RequestBody;
+//import org.springframework.web.bind.annotation.RequestMapping;
+//import org.springframework.web.bind.annotation.RestController;
+//
+//import javax.servlet.http.HttpServletRequest;
+//import java.nio.charset.StandardCharsets;
+//import java.util.HashMap;
+//import java.util.Map;
+//
+//@RestController
+//@RequestMapping("/api/appPayment") // 路径前缀,与常量中配置的回调URL匹配
+//public class WxPayNotifyController {
+//
+// private static final Logger log = LoggerFactory.getLogger(WxPayNotifyController.class);
+//
+// private final ObjectMapper objectMapper;
+//
+// @Autowired
+// public WxPayNotifyController(ObjectMapper objectMapper) {
+// this.objectMapper = objectMapper;
+// }
+//
+// /**
+// * 接收微信支付结果通知
+// * URL需要与 WXPayConstants.WECHAT_PAY_NOTIFY_URL 匹配
+// */
+// @PostMapping("/weChatPayNotify")
+// public ResponseEntity<Map<String, String>> handleWeChatPayNotify(HttpServletRequest request, @RequestBody String requestBody) {
+//
+// Map<String, String> responseMap = new HashMap<>();
+// try {
+// // 1. 验证签名 (使用工具类,它会处理证书)
+// boolean verifyResult = WXPaySignatureCertificateUtil.verifyNotify(request, requestBody);
+// if (!verifyResult) {
+// log.error("微信支付通知验签失败!");
+// responseMap.put("code", "FAIL");
+// responseMap.put("message", "验签失败");
+// return new ResponseEntity<>(responseMap, HttpStatus.BAD_REQUEST); // 返回错误状态码
+// }
+// log.info("微信支付通知验签成功。");
+//
+// // 2. 解析通知体
+// JsonNode notifyData = objectMapper.readTree(requestBody);
+// String eventType = notifyData.get("event_type").asText();
+//
+// // 只处理支付成功的通知类型
+// if ("TRANSACTION.SUCCESS".equals(eventType)) {
+// log.info("处理支付成功通知...");
+// JsonNode resourceNode = notifyData.get("resource");
+// String associatedData = resourceNode.get("associated_data").asText();
+// String nonce = resourceNode.get("nonce").asText();
+// String ciphertext = resourceNode.get("ciphertext").asText();
+//
+// // 3. 解密关键信息
+// String decryptedDataJson = WxPayAesUtil.decrypt(WxV3PayConfig.apiV3Key, associatedData, nonce, ciphertext);
+// log.info("解密后的支付通知信息: {}", decryptedDataJson);
+// JsonNode decryptedData = objectMapper.readTree(decryptedDataJson);
+//
+// // 4. 处理业务逻辑
+// String outTradeNo = decryptedData.get("out_trade_no").asText();
+// String transactionId = decryptedData.get("transaction_id").asText();
+// String tradeState = decryptedData.get("trade_state").asText();
+// // ... 获取其他需要的信息,例如支付金额、用户openid等
+//
+// // TODO: 在这里实现你的业务逻辑:
+// // 1. 根据 outTradeNo 查询你的数据库订单状态。
+// // 2. 判断订单是否已经处理过(防止重复处理通知)。
+// // 3. 如果订单未处理且 tradeState 为 SUCCESS,则更新订单状态为支付成功。
+// // 4. 记录 transactionId (微信支付订单号)。
+// // 5. 执行后续业务流程(如发货、增加积分等)。
+// // 6. 如果处理失败,可以考虑记录日志并后续重试,但仍需返回成功给微信,避免微信重复通知。
+//
+// log.info("业务逻辑处理完成,商户订单号: {}, 微信订单号: {}", outTradeNo, transactionId);
+//
+// } else {
+// log.warn("收到非支付成功类型的通知: {}", eventType);
+// // 其他类型的通知,根据需要处理或忽略
+// }
+//
+// // 5. 返回成功响应给微信平台
+// responseMap.put("code", "SUCCESS");
+// responseMap.put("message", "成功");
+// return new ResponseEntity<>(responseMap, HttpStatus.OK);
+//
+// } catch (Exception e) {
+// log.error("处理微信支付通知异常", e);
+// responseMap.put("code", "FAIL");
+// responseMap.put("message", "处理失败");
+// // 即使处理失败,也尽量返回成功给微信,避免重复通知轰炸,然后在后台处理异常。
+// // 但如果验签失败,可以返回错误状态码。
+// return new ResponseEntity<>(responseMap, HttpStatus.INTERNAL_SERVER_ERROR); // 或者返回OK,根据策略定
+// }
+// }
+//
+//
+// /**
+// * 接收微信退款结果通知
+// * URL需要与 WXPayConstants.WECHAT_REFUNDS_NOTIFY_URL 匹配
+// */
+// @PostMapping("/weChatPayRefundsNotify")
+// public ResponseEntity<Map<String, String>> handleWeChatRefundsNotify(HttpServletRequest request, @RequestBody String requestBody) {
+//
+// Map<String, String> responseMap = new HashMap<>();
+// try {
+// // 1. 验证签名
+// boolean verifyResult = WXPaySignatureCertificateUtil.verifyNotify(request, requestBody);
+// if (!verifyResult) {
+// log.error("微信退款通知验签失败!");
+// responseMap.put("code", "FAIL");
+// responseMap.put("message", "验签失败");
+// return new ResponseEntity<>(responseMap, HttpStatus.BAD_REQUEST);
+// }
+// log.info("微信退款通知验签成功。");
+//
+// // 2. 解析通知体
+// JsonNode notifyData = objectMapper.readTree(requestBody);
+// String eventType = notifyData.get("event_type").asText();
+//
+// // 处理退款成功或异常的通知
+// if ("REFUND.SUCCESS".equals(eventType) || "REFUND.ABNORMAL".equals(eventType) || "REFUND.CLOSED".equals(eventType)) {
+// log.info("处理退款通知,类型: {}", eventType);
+// JsonNode resourceNode = notifyData.get("resource");
+// String associatedData = resourceNode.get("associated_data").asText();
+// String nonce = resourceNode.get("nonce").asText();
+// String ciphertext = resourceNode.get("ciphertext").asText();
+//
+// // 3. 解密关键信息
+// String decryptedDataJson = WxPayAesUtil.decrypt(WxV3PayConfig.apiV3Key, associatedData, nonce, ciphertext);
+// log.info("解密后的退款通知信息: {}", decryptedDataJson);
+// JsonNode decryptedData = objectMapper.readTree(decryptedDataJson);
+//
+// // 4. 处理业务逻辑
+// String outTradeNo = decryptedData.get("out_trade_no").asText();
+// String outRefundNo = decryptedData.get("out_refund_no").asText();
+// String refundStatus = decryptedData.get("refund_status").asText(); // SUCCESS, CLOSED, ABNORMAL
+// // ... 获取其他需要的信息,例如退款金额、微信退款单号 refund_id 等
+//
+// // TODO: 在这里实现你的退款业务逻辑:
+// // 1. 根据 outRefundNo 查询你的数据库退款单状态。
+// // 2. 判断退款单是否已经处理过。
+// // 3. 根据 refundStatus 更新退款单状态。
+// // 4. 如果退款成功 (SUCCESS),可能需要执行一些操作,如返还库存、通知用户等。
+// // 5. 如果退款关闭或异常,也需要记录状态。
+//
+// log.info("退款业务逻辑处理完成,商户订单号: {}, 商户退款单号: {}, 退款状态: {}", outTradeNo, outRefundNo, refundStatus);
+//
+// } else {
+// log.warn("收到非退款类型的通知: {}", eventType);
+// }
+//
+// // 5. 返回成功响应给微信平台
+// responseMap.put("code", "SUCCESS");
+// responseMap.put("message", "成功");
+// return new ResponseEntity<>(responseMap, HttpStatus.OK);
+//
+// } catch (Exception e) {
+// log.error("处理微信退款通知异常", e);
+// responseMap.put("code", "FAIL");
+// responseMap.put("message", "处理失败");
+// return new ResponseEntity<>(responseMap, HttpStatus.INTERNAL_SERVER_ERROR);
+// }
+// }
+//
+//}
diff --git a/cloud-server-activity/src/main/java/com/dsh/activity/util/wx/WxV3PayConfig.java b/cloud-server-activity/src/main/java/com/dsh/activity/util/wx/WxV3PayConfig.java
index 5797619..8c28a22 100644
--- a/cloud-server-activity/src/main/java/com/dsh/activity/util/wx/WxV3PayConfig.java
+++ b/cloud-server-activity/src/main/java/com/dsh/activity/util/wx/WxV3PayConfig.java
@@ -1,56 +1,56 @@
-package com.dsh.activity.util.wx;
-
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.stereotype.Component;
-import javax.annotation.PostConstruct; // 如果需要静态访问
-
-@Component
-public class WxV3PayConfig {
-
- private String appIdValue = "wx41d32f362ba0f911";
- public static String APP_ID= "wx41d32f362ba0f911";
-
- private String mchIdValue= "1681873607";
- public static String Mch_ID= "1681873607";
-
- private String apiV3KeyValue= "1skiujh28376shznxmslwosiusytersq";
- public static String apiV3Key= "1skiujh28376shznxmslwosiusytersq";
-
- private String mchSerialNoValue= "55714944F7A7E52526F708280B176DCC838F371A";
- public static String mchSerialNo= "55714944F7A7E52526F708280B176DCC838F371A";
-
- private String privateKeyPathValue= "D:\\玩湃v3参数\\1681873607_20250424_cert\\apiclient_key.pem";
- public static String privateKeyPath= "D:\\玩湃v3参数\\1681873607_20250424_cert\\apiclient_key.pem";
-
- // 如果需要静态访问,可以使用 @PostConstruct 初始化静态变量
- @PostConstruct
- public void init() {
- APP_ID = this.appIdValue;
- Mch_ID = this.mchIdValue;
- apiV3Key = this.apiV3KeyValue;
- mchSerialNo = this.mchSerialNoValue;
- privateKeyPath = this.privateKeyPathValue; // WXPaySignatureCertificateUtil 会用到这个路径
-
- // 可以在这里加一些非空检查
- if (APP_ID == null || Mch_ID == null || apiV3Key == null || mchSerialNo == null || privateKeyPath == null) {
- System.err.println("微信支付V3配置加载不完整,请检查配置文件!");
- // 在实际应用中,这里可能需要抛出异常或采取其他错误处理措施
- } else {
- System.out.println("微信支付V3配置加载完成。");
- }
- }
-
- // 注意: WXPaySignatureCertificateUtil 中的 getPrivateKey() 方法现在应该使用 WxV3PayConfig.privateKeyPath
- // 你需要稍微修改 WXPaySignatureCertificateUtil.getPrivateKey() 方法:
- /*
- public static PrivateKey getPrivateKey() {
- if (cachedPrivateKey != null) {
- return cachedPrivateKey;
- }
- try {
- String filePath = WxV3PayConfig.privateKeyPath; // 使用配置类中的路径
- // ... rest of the method ...
- } // ... catch blocks ...
- }
- */
-}
\ No newline at end of file
+//package com.dsh.activity.util.wx;
+//
+//import org.springframework.beans.factory.annotation.Value;
+//import org.springframework.stereotype.Component;
+//import javax.annotation.PostConstruct; // 如果需要静态访问
+//
+//@Component
+//public class WxV3PayConfig {
+//
+// private String appIdValue = "wx41d32f362ba0f911";
+// public static String APP_ID= "wx41d32f362ba0f911";
+//
+// private String mchIdValue= "1681873607";
+// public static String Mch_ID= "1681873607";
+//
+// private String apiV3KeyValue= "1skiujh28376shznxmslwosiusytersq";
+// public static String apiV3Key= "1skiujh28376shznxmslwosiusytersq";
+//
+// private String mchSerialNoValue= "55714944F7A7E52526F708280B176DCC838F371A";
+// public static String mchSerialNo= "55714944F7A7E52526F708280B176DCC838F371A";
+//
+// private String privateKeyPathValue= "D:\\玩湃v3参数\\1681873607_20250424_cert\\apiclient_key.pem";
+// public static String privateKeyPath= "D:\\玩湃v3参数\\1681873607_20250424_cert\\apiclient_key.pem";
+//
+// // 如果需要静态访问,可以使用 @PostConstruct 初始化静态变量
+// @PostConstruct
+// public void init() {
+// APP_ID = this.appIdValue;
+// Mch_ID = this.mchIdValue;
+// apiV3Key = this.apiV3KeyValue;
+// mchSerialNo = this.mchSerialNoValue;
+// privateKeyPath = this.privateKeyPathValue; // WXPaySignatureCertificateUtil 会用到这个路径
+//
+// // 可以在这里加一些非空检查
+// if (APP_ID == null || Mch_ID == null || apiV3Key == null || mchSerialNo == null || privateKeyPath == null) {
+// System.err.println("微信支付V3配置加载不完整,请检查配置文件!");
+// // 在实际应用中,这里可能需要抛出异常或采取其他错误处理措施
+// } else {
+// System.out.println("微信支付V3配置加载完成。");
+// }
+// }
+//
+// // 注意: WXPaySignatureCertificateUtil 中的 getPrivateKey() 方法现在应该使用 WxV3PayConfig.privateKeyPath
+// // 你需要稍微修改 WXPaySignatureCertificateUtil.getPrivateKey() 方法:
+// /*
+// public static PrivateKey getPrivateKey() {
+// if (cachedPrivateKey != null) {
+// return cachedPrivateKey;
+// }
+// try {
+// String filePath = WxV3PayConfig.privateKeyPath; // 使用配置类中的路径
+// // ... rest of the method ...
+// } // ... catch blocks ...
+// }
+// */
+//}
\ No newline at end of file
diff --git a/cloud-server-management/src/main/java/com/dsh/course/feignClient/activity/HuiminCardClient.java b/cloud-server-management/src/main/java/com/dsh/course/feignClient/activity/HuiminCardClient.java
index 05b3831..bb9933e 100644
--- a/cloud-server-management/src/main/java/com/dsh/course/feignClient/activity/HuiminCardClient.java
+++ b/cloud-server-management/src/main/java/com/dsh/course/feignClient/activity/HuiminCardClient.java
@@ -38,4 +38,9 @@
@GetMapping("/tHuiminCard/changeState")
String changeState(@RequestParam("id")Integer id, @RequestParam("status") Integer status);
+ @GetMapping("/tHuiminCard/getCards")
+
+ List<THuiminCard> getCards(@RequestParam("storeId")String storeId);
+ @GetMapping("/tHuiminCard/addPayHuiMing")
+ void addPayHuiMing(@RequestParam("studentId")Integer studentId, @RequestParam("cardId")Integer cardId);
}
diff --git a/cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/code/THuiminCardController.java b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/code/THuiminCardController.java
index 398d92d..3e92f2d 100644
--- a/cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/code/THuiminCardController.java
+++ b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/code/THuiminCardController.java
@@ -6,6 +6,9 @@
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.api.R;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.dsh.course.feignClient.account.AppUserClient;
+import com.dsh.course.feignClient.account.StudentClient;
+import com.dsh.course.feignClient.account.model.TAppUser;
import com.dsh.course.feignClient.activity.HuiminCardClient;
import com.dsh.course.feignClient.activity.model.THuiminCard;
import com.dsh.guns.config.UserExt;
@@ -45,6 +48,11 @@
private TOperatorService operatorService;
@Autowired
private ITSiteService tSiteService;
+ @Autowired
+ private AppUserClient appUserClient;
+ @Autowired
+ private StudentClient studentClient;
+
/**
* 跳转到玩湃惠民卡首页
@@ -73,7 +81,66 @@
model.addAttribute("objectType", user.getObjectType());
return PREFIX + "tHuiminCard_detail.html";
}
+ /**
+ * 跳转到订单录入页面
+ */
+ @RequestMapping("/tHuiminCardAddOrder")
+ public String tHuiminCardAddOrder(Model model) {
+ Integer objectType = UserExt.getUser().getObjectType();
+ Integer objectId = UserExt.getUser().getObjectId();
+ model.addAttribute("role", objectType);
+ if (objectType==1){
+ List<TOperator> list = operatorService.list(new LambdaQueryWrapper<TOperator>()
+ .eq(TOperator::getState, 1));
+ model.addAttribute("operators", list);
+ }else if (objectType==2){
+ List<TStore> list = storeService.list(new LambdaQueryWrapper<TStore>()
+ .eq(TStore::getOperatorId, objectId));
+ model.addAttribute("stores", list);
+ }else{
+ List<THuiminCard> cards = huiminCardClient.getCards(objectId + "");
+ model.addAttribute("cards", cards);
+ }
+ return PREFIX + "tHuiminCard_addOrder.html";
+ }
+ @RequestMapping("/addPayHuiMing")
+ @ResponseBody
+ public Object addPayHuiMing(Integer studentId,Integer cardId) {
+
+ huiminCardClient.addPayHuiMing(studentId ,cardId);
+
+ return 200;
+ }
+ @RequestMapping(value = "/checkUser")
+ @ResponseBody
+ public Object checkUser(String phone) {
+ TAppUser appUserByPhone = appUserClient.getAppUserByPhone(phone);
+ if (appUserByPhone==null){
+ return 500;
+ }
+ List<TStudent> tStudents = studentClient.queryStudentList(appUserByPhone.getId());
+ if (tStudents.isEmpty()){
+ return 501;
+ }
+ return tStudents;
+ }
+ @RequestMapping(value = "/getStores")
+ @ResponseBody
+ public Object getStores(String operatorId) {
+ if (operatorId.isEmpty()){
+ return new ArrayList<>();
+ }else{
+ List<TStore> list = storeService.lambdaQuery().eq(TStore::getOperatorId, operatorId).list();
+ return list;
+ }
+ }
+ @RequestMapping(value = "/getCards")
+ @ResponseBody
+ public Object getCards(String storeId) {
+ List<THuiminCard> list = huiminCardClient.getCards(storeId);
+ return list;
+ }
/**
* 获取玩湃惠民卡详情
*/
diff --git a/cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/code/TShopController.java b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/code/TShopController.java
index 0aec1a9..06fc408 100644
--- a/cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/code/TShopController.java
+++ b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/code/TShopController.java
@@ -531,10 +531,10 @@
}
}
}else {
- TCity one = cityService.getOne(new LambdaQueryWrapper<TCity>().eq(TCity::getId, tStore.getProvinceCode()));
+ TCity one = cityService.getOne(new LambdaQueryWrapper<TCity>().eq(TCity::getCode, tStore.getProvinceCode()));
tStore.setProvince(one.getName());
tStore.setProvinceCode(one.getCode());
- TCity one1 = cityService.getOne(new LambdaQueryWrapper<TCity>().eq(TCity::getId, tStore.getCityCode()));
+ TCity one1 = cityService.getOne(new LambdaQueryWrapper<TCity>().eq(TCity::getCode, tStore.getCityCode()));
tStore.setCity(one1.getName());
tStore.setCityCode(one1.getCode());
}
diff --git a/cloud-server-management/src/main/webapp/WEB-INF/view/system/tHuiminCard/tHuiminCard.html b/cloud-server-management/src/main/webapp/WEB-INF/view/system/tHuiminCard/tHuiminCard.html
index c9c181f..bc18404 100644
--- a/cloud-server-management/src/main/webapp/WEB-INF/view/system/tHuiminCard/tHuiminCard.html
+++ b/cloud-server-management/src/main/webapp/WEB-INF/view/system/tHuiminCard/tHuiminCard.html
@@ -73,6 +73,10 @@
<i class="fa fa-remove"></i>
下架
</button>
+ <button type="button" class="btn btn-primary" v-on:click="addOrder()">
+ <i class="fa fa-remove"></i>
+ 订单录入
+ </button>
</div>
</div>
<el-table
@@ -155,8 +159,9 @@
</div>
<script src="${ctxPath}/js/vue/vue.js"></script>
<script src="${ctxPath}/js/elementui/index.js"></script>
-<script src="${ctxPath}/modular/system/tHuiminCard/tHuiminCard2.js"></script>
<link rel="stylesheet" href="${ctxPath}/js/elementui/index.css">
+
+<script src="${ctxPath}/modular/system/tHuiminCard/tHuiminCard2.js"></script>
<script src="${ctxPath}/modular/system/tHuiminCard/tHuiminCard.js"></script>
<script src="${ctxPath}/modular/system/tHuiminAgreement/tHuiminAgreement.js"></script>
<script>
diff --git a/cloud-server-management/src/main/webapp/WEB-INF/view/system/tHuiminCard/tHuiminCard_addOrder.html b/cloud-server-management/src/main/webapp/WEB-INF/view/system/tHuiminCard/tHuiminCard_addOrder.html
new file mode 100644
index 0000000..20afd1f
--- /dev/null
+++ b/cloud-server-management/src/main/webapp/WEB-INF/view/system/tHuiminCard/tHuiminCard_addOrder.html
@@ -0,0 +1,150 @@
+@layout("/common/_container.html"){
+<style>
+ .avatar-uploader .el-upload {
+ border: 1px dashed #d9d9d9;
+ border-radius: 6px;
+ cursor: pointer;
+ position: relative;
+ height: 100px;
+ width: 100px;
+ overflow: hidden;
+ }
+
+ .avatar-uploader .el-upload:hover {
+ border-color: #409EFF;
+ }
+
+ .avatar-uploader-icon {
+ font-size: 28px;
+ color: #8c939d;
+ width: 100px;
+ height: 100px;
+ line-height: 100px;
+ margin-top: 32px;
+ text-align: center;
+ }
+
+ .avatar {
+ width: 100px;
+ height: 100px;
+ display: block;
+ }
+
+ .col-sm-12 {
+ margin-top: 20px;
+ }
+
+ .col-sm-12 select {
+ height: 33px;
+ }
+
+
+</style>
+<script type="text/javascript" src="http://webapi.amap.com/maps?v=1.4.15&key=77b37f0753049c4e712ea79a24e0719c"></script>
+<div class="ibox float-e-margins">
+ <div class="ibox-content">
+ <div class="form-horizontal" id="carInfoForm">
+ <div class="form-group">
+ <input hidden id="role" value="${role}">
+
+ <div style="display:flex">
+ <label class="col-sm-3 control-label">*用户手机号:</label>
+ <input type="number" id="phone" name="type" placeholder="请输入">
+ <button type="button" class="btn btn-primary" onclick="THuiminCardInfo.checkUser()">搜索
+ </button>
+ </div>
+ </div>
+ <div class="form-group" id="users">
+ <label class="col-sm-3 control-label">*绑定人员信息:</label>
+ <div class="col-sm-9">
+ <select class="form-control" id="userList" name="userList">
+
+ </select>
+ </div>
+ </div>
+
+ @if(role==1){
+ <div class="form-group">
+ <label class="col-sm-3 control-label">*所属运营商:</label>
+ <div class="col-sm-9">
+ <select class="form-control" id="account" name="account" onchange="THuiminCardInfo.getStores(this)">
+ <option value="">请选择运营商</option>
+ <option value="0">平台</option>
+ @for(i in operators){
+ <option value="${i.id}">${i.name}</option>
+ @}
+ </select>
+ </div>
+ </div>
+ <div class="form-group">
+ <label class="col-sm-3 control-label">*可用门店:</label>
+ <div class="col-sm-9">
+ <select class="form-control" id="shopId" name="shopId" onchange="THuiminCardInfo.getCards(this)">
+ <option value="">选择门店</option>
+
+ </select>
+ </div>
+ </div>
+ <div class="form-group">
+ <label class="col-sm-3 control-label">选择惠民卡:</label>
+ <div class="col-sm-9">
+ <select class="form-control" id="cards" name="cards" >
+ <option value="">选择惠民卡</option>
+ </select>
+ </div>
+ </div>
+ @}
+
+ @if(role==2){
+ <div class="form-group" id="shop">
+ <label class="col-sm-3 control-label">所属门店:</label>
+ <div class="col-sm-9">
+ <select class="form-control" id="shopId" name="shopId" onchange="THuiminCardInfo.getCards(this)" >
+ <option value="">选择门店</option>
+ @for(i in stores){
+ <option value="${i.id}">${i.name}</option>
+ @}
+ </select>
+ </div>
+ </div>
+ <div class="form-group" id="card">
+ <label class="col-sm-3 control-label">选择惠民卡:</label>
+ <div class="col-sm-9">
+ <select class="form-control" id="cards" name="cards" >
+ <option value="">选择惠民卡</option>
+ </select>
+ </div>
+ </div>
+ @}
+ @if(role==3){
+ <div class="form-group" id="card">
+ <label class="col-sm-3 control-label">选择惠民卡:</label>
+ <div class="col-sm-9">
+ <select class="form-control" id="cards" name="cards" >
+ <option value="">选择惠民卡</option>
+ @for(i in cards){
+ <option value="${i.id}">${i.name}</option>
+ @}
+ </select>
+ </div>
+ </div>
+ @}
+ </div>
+ </div>
+
+ <div class="row btn-group-m-t">
+ <div class="col-sm-10 col-sm-offset-5">
+ <#button btnCss="info" name="提交" id="ensure" icon="fa-check" clickFun="THuiminCardInfo.addSubmit()"/>
+ <#button btnCss="danger" name="关闭" id="cancel" icon="fa-eraser" clickFun="THuiminCardInfo.close()"/>
+ </div>
+ </div>
+
+</div>
+
+
+<script src="${ctxPath}/modular/system/tHuiminCard/tHuiminCard3.js"></script>
+<script src="${ctxPath}/js/vue/vue.js"></script>
+<script src="${ctxPath}/js/elementui/index.js"></script>
+<link rel="stylesheet" href="${ctxPath}/js/elementui/index.css">
+
+@}
diff --git a/cloud-server-management/src/main/webapp/WEB-INF/view/system/tShop/TShop_add.html b/cloud-server-management/src/main/webapp/WEB-INF/view/system/tShop/TShop_add.html
index 8c141cb..ca1483a 100644
--- a/cloud-server-management/src/main/webapp/WEB-INF/view/system/tShop/TShop_add.html
+++ b/cloud-server-management/src/main/webapp/WEB-INF/view/system/tShop/TShop_add.html
@@ -42,8 +42,6 @@
<script type="text/javascript" src="http://webapi.amap.com/maps?v=1.4.15&key=77b37f0753049c4e712ea79a24e0719c"></script>
<div class="ibox float-e-margins">
<div class="ibox-content">
-
-
<div class="form-horizontal" id="carInfoForm">
<input hidden id="role" value="${role}">
<input hidden id="operator" value="${operator}">
diff --git a/cloud-server-management/src/main/webapp/static/modular/system/tHuiminCard/tHuiminCard.js b/cloud-server-management/src/main/webapp/static/modular/system/tHuiminCard/tHuiminCard.js
index 51e1c3f..8bfbda0 100644
--- a/cloud-server-management/src/main/webapp/static/modular/system/tHuiminCard/tHuiminCard.js
+++ b/cloud-server-management/src/main/webapp/static/modular/system/tHuiminCard/tHuiminCard.js
@@ -81,6 +81,18 @@
});
this.layerIndex = index;
};
+THuiminCard.addOrder = function (id, pageType) {
+ console.log(id)
+ let index = layer.open({
+ type: 2,
+ title: '订单录入',
+ area: ['100%', '100%'], //宽高
+ fix: false, //不固定
+ maxmin: true,
+ content: Feng.ctxPath + '/tHuiminCard/tHuiminCardAddOrder'
+ });
+ this.layerIndex = index;
+};
/**
* 删除玩湃惠民卡
diff --git a/cloud-server-management/src/main/webapp/static/modular/system/tHuiminCard/tHuiminCard2.js b/cloud-server-management/src/main/webapp/static/modular/system/tHuiminCard/tHuiminCard2.js
index 19e2d9f..d000307 100644
--- a/cloud-server-management/src/main/webapp/static/modular/system/tHuiminCard/tHuiminCard2.js
+++ b/cloud-server-management/src/main/webapp/static/modular/system/tHuiminCard/tHuiminCard2.js
@@ -143,10 +143,103 @@
id = this.ids[0]
}
THuiminCard.openTHuiminCardDetail(id,'detail')
+ },
+ addOrder() {
+ THuiminCard.addOrder()
}
},
created() {
// 初始化逻辑
this.handleSearch()
}
-});
\ No newline at end of file
+});
+var THuiminCardInfo = {
+ goodsPicArray: [],
+ tCarInfoData : {},
+ validateFields: {
+ }
+};
+THuiminCardInfo.close = function() {
+ parent.layer.close(window.parent.THuiminCard.layerIndex);
+}
+THuiminCardInfo.checkUser = function (e) {
+ console.log("用户手机号")
+ console.log(e)
+ var ajax = new $ax(Feng.ctxPath + "/tHuiminCard/checkUser", function(data){
+ if(data==500){
+ $("#userList").empty()
+ Feng.error("操作失败,当前用户未注册")
+ return;
+ }else if (data==501){
+ $("#userList").empty()
+ Feng.error("操作失败,当前用户未添加人员信息")
+ return;
+ }
+
+ else{
+ var content='<option value="">选择人员</option>';
+ $.each(data, function(k,v) {
+ content += "<option value='"+v.id+"'>"+v.name+"</option>";
+ });
+ $("#userList").empty().append(content);
+ $("#shopId").empty();
+ $("#cards").empty();
+ }
+ });
+ ajax.set("phone",phone);
+ ajax.start();
+}
+THuiminCardInfo.getStores = function (e) {
+ var operatorId=$(e).val();
+ var ajax = new $ax(Feng.ctxPath + "/tHuiminCard/getStores", function(data){
+ if(data!=null){
+ var content='<option value="">选择门店</option>';
+ $.each(data, function(k,v) {
+ content += "<option value='"+v.id+"'>"+v.name+"</option>";
+ });
+ $("#shopId").empty().append(content);
+ $("#cards").empty()
+ }
+ });
+ ajax.set("operatorId",operatorId);
+ ajax.start();
+}
+THuiminCardInfo.getCards = function (e) {
+ var operatorId=$(e).val();
+ var ajax = new $ax(Feng.ctxPath + "/tHuiminCard/getCards", function(data){
+ if(data!=null){
+ var content='<option value="">选择玩湃惠民卡</option>';
+ $.each(data, function(k,v) {
+ content += "<option value='"+v.id+"'>"+v.name+"</option>";
+ });
+ $("#cards").empty().append(content);
+ }
+ });
+ ajax.set("storeId",operatorId);
+ ajax.start();
+}
+THuiminCardInfo.addSubmit = function () {
+ let cardId = $("#cards").val()
+ if(cardId==""){
+ Feng.info("请选择惠民卡")
+ return;
+ }
+ let user = $("#user").val()
+ if(user==""){
+ Feng.info("请选择绑定人员信息")
+ return;
+ }
+ var operatorId=$(e).val();
+ var ajax = new $ax(Feng.ctxPath + "/tHuiminCard/addPayHuiMing", function(data){
+ if(data!=null){
+ var content='<option value="">选择玩湃惠民卡</option>';
+ $.each(data, function(k,v) {
+ content += "<option value='"+v.id+"'>"+v.name+"</option>";
+ });
+ $("#cards").empty().append(content);
+ }
+ });
+ ajax.set("studentId",user);
+ ajax.set("cardId",cardId);
+ ajax.start();
+}
\ No newline at end of file
diff --git a/cloud-server-management/src/main/webapp/static/modular/system/tHuiminCard/tHuiminCard3.js b/cloud-server-management/src/main/webapp/static/modular/system/tHuiminCard/tHuiminCard3.js
new file mode 100644
index 0000000..fb3201a
--- /dev/null
+++ b/cloud-server-management/src/main/webapp/static/modular/system/tHuiminCard/tHuiminCard3.js
@@ -0,0 +1,98 @@
+var THuiminCardInfo = {
+ goodsPicArray: [],
+ tCarInfoData : {},
+ validateFields: {
+ }
+};
+THuiminCardInfo.close = function() {
+ parent.layer.close(window.parent.THuiminCard.layerIndex);
+}
+THuiminCardInfo.checkUser = function () {
+
+ if ($("#phone").val()==""){
+ Feng.error("请输入手机号")
+ return
+ }
+ var ajax = new $ax(Feng.ctxPath + "/tHuiminCard/checkUser", function(data){
+ if(data==500){
+ $("#userList").empty()
+ Feng.error("操作失败,当前用户未注册")
+ return;
+ }else if (data==501){
+ $("#userList").empty()
+ Feng.error("操作失败,当前用户未添加人员信息")
+ return;
+ }
+
+ else{
+ var content='<option value="">选择人员</option>';
+ $.each(data, function(k,v) {
+ content += "<option value='"+v.id+"'>"+v.name+"</option>";
+ });
+ $("#userList").empty().append(content);
+ $("#shopId").empty();
+ $("#cards").empty();
+ }
+ });
+ ajax.set("phone",$("#phone").val());
+ ajax.start();
+}
+THuiminCardInfo.getStores = function (e) {
+ var operatorId=$("#account").val();
+ console.log("运营商id")
+ console.log(operatorId)
+ var ajax = new $ax(Feng.ctxPath + "/tHuiminCard/getStores", function(data){
+ if(data!=null){
+ var content='<option value="">选择门店</option>';
+ $.each(data, function(k,v) {
+ content += "<option value='"+v.id+"'>"+v.name+"</option>";
+ });
+ $("#shopId").empty().append(content);
+ $("#cards").empty()
+ }
+ if (operatorId==""){
+ console.log("置空")
+ $("#shopId").empty()
+ $("#cards").empty()
+ }
+ });
+ ajax.set("operatorId",operatorId);
+ ajax.start();
+}
+THuiminCardInfo.getCards = function (e) {
+ var operatorId=$("#shopId").val();
+ var ajax = new $ax(Feng.ctxPath + "/tHuiminCard/getCards", function(data){
+ if(data!=null){
+ var content='<option value="">选择玩湃惠民卡</option>';
+ $.each(data, function(k,v) {
+ content += "<option value='"+v.id+"'>"+v.huiMinName+"</option>";
+ });
+ $("#cards").empty().append(content);
+ }
+ });
+ ajax.set("storeId",operatorId);
+ ajax.start();
+}
+THuiminCardInfo.addSubmit = function () {
+ let cardId = $("#cards").val()
+ if(cardId==""){
+ Feng.info("请选择惠民卡")
+ return;
+ }
+ let user = $("#userList").val()
+ if(user==""){
+ Feng.info("请选择绑定人员信息")
+ return;
+ }
+ var ajax = new $ax(Feng.ctxPath + "/tHuiminCard/addPayHuiMing", function(data){
+ if (data==200){
+ Feng.success("录入成功")
+ THuiminCardInfo.close()
+ return
+ }
+
+ });
+ ajax.set("studentId",user);
+ ajax.set("cardId",cardId);
+ ajax.start();
+}
\ No newline at end of file
--
Gitblit v1.7.1