diff --git a/src/main/java/com/gxwebsoft/common/core/security/SecurityConfig.java b/src/main/java/com/gxwebsoft/common/core/security/SecurityConfig.java index 99658da..409b20b 100644 --- a/src/main/java/com/gxwebsoft/common/core/security/SecurityConfig.java +++ b/src/main/java/com/gxwebsoft/common/core/security/SecurityConfig.java @@ -73,7 +73,8 @@ public class SecurityConfig { "/api/cms/form-record", "/api/shop/merchant-account/getMerchantAccountByPhone", "/api/hjm/hjm-car/**", - "/api/chat/**" + "/api/chat/**", + "/api/shop/shop-order/test" ) .permitAll() .anyRequest() diff --git a/src/main/java/com/gxwebsoft/common/core/utils/RequestUtil.java b/src/main/java/com/gxwebsoft/common/core/utils/RequestUtil.java index 2b1673e..69d05e7 100644 --- a/src/main/java/com/gxwebsoft/common/core/utils/RequestUtil.java +++ b/src/main/java/com/gxwebsoft/common/core/utils/RequestUtil.java @@ -4,6 +4,7 @@ import cn.hutool.http.HttpRequest; import com.alibaba.fastjson.JSONObject; import com.gxwebsoft.common.core.config.ConfigProperties; import com.gxwebsoft.common.core.web.ApiResult; +import com.gxwebsoft.common.system.entity.DictData; import com.gxwebsoft.common.system.entity.Payment; import com.gxwebsoft.common.system.entity.User; import com.gxwebsoft.common.system.entity.UserRole; @@ -121,6 +122,24 @@ public class RequestUtil { return null; } + public User getByUserIdWithoutLogin(Integer userId) { + String path = "/system/user/getByUserId/" + userId; + try { + // 链式构建请求 + String result = HttpRequest.get(getServerUrl().concat(path)) + .header("Tenantid", TENANT_ID) + .timeout(20000)//超时,毫秒 + .execute().body(); + JSONObject jsonObject = JSONObject.parseObject(result); + System.out.println("jsonObject = " + jsonObject); + final String data = jsonObject.getString("data"); + return JSONObject.parseObject(data, User.class); + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + // 新增用户 public boolean saveUserByPhone(ShopMerchantAccount merchantAccount) { String path = "/system/user/"; @@ -173,7 +192,6 @@ public class RequestUtil { try { // 链式构建请求 final String result = HttpRequest.get(getServerUrl().concat("/system/user-referee/getReferee/" + userId)) - .header("Authorization", ACCESS_TOKEN) .header("Tenantid", TENANT_ID) .timeout(20000) .execute().body(); @@ -202,6 +220,21 @@ public class RequestUtil { } } + // 更新用户信息 + public void updateWithoutLogin(User user) { + String path = "/system/user/updateWithoutLogin"; + try { + // 链式构建请求 + final String body = HttpRequest.put(getServerUrl().concat(path)) + .header("Tenantid", TENANT_ID) + .body(JSONUtil.toJSONString(user)) + .timeout(20000) + .execute().body(); + } catch (Exception e) { + e.printStackTrace(); + } + } + public String getMpOrderQrCode(String orderNo) { String path = "/wx-login/getOrderQRCode/"; try { @@ -271,6 +304,21 @@ public class RequestUtil { } } + public ApiResult pageDictData(Integer dictId) { + String path = "/system/dict-data/page"; + try { + // 链式构建请求 + final String body = HttpRequest.get(getServerUrl().concat(path).concat("?dictId=" + dictId)) + .header("tenantId", TENANT_ID) + .timeout(20000) + .execute().body(); + return JSONUtil.parseObject(body, ApiResult.class); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + // 余额支付通知 public void pushBalancePayNotify(Transaction transaction, Payment payment) { System.out.println("payment = " + payment); diff --git a/src/main/java/com/gxwebsoft/common/core/utils/WechatCertAutoConfig.java b/src/main/java/com/gxwebsoft/common/core/utils/WechatCertAutoConfig.java index 672dee7..0d90c69 100644 --- a/src/main/java/com/gxwebsoft/common/core/utils/WechatCertAutoConfig.java +++ b/src/main/java/com/gxwebsoft/common/core/utils/WechatCertAutoConfig.java @@ -3,16 +3,12 @@ package com.gxwebsoft.common.core.utils; import com.wechat.pay.java.core.Config; import com.wechat.pay.java.core.RSAAutoCertificateConfig; import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; -import com.gxwebsoft.common.core.config.ConfigProperties; - -import javax.annotation.Resource; /** * 微信支付证书自动配置工具类 * 使用RSAAutoCertificateConfig实现证书自动管理 - * + * * @author 科技小王子 * @since 2024-07-26 */ @@ -20,47 +16,38 @@ import javax.annotation.Resource; @Component public class WechatCertAutoConfig { - @Value("${spring.profiles.active:prod}") - private String activeProfile; - - @Resource - private ConfigProperties configProperties; - - @Resource - private ConfigProperties configProperties; - /** * 创建微信支付自动证书配置 - * + * * @param merchantId 商户号 * @param privateKeyPath 私钥文件路径 * @param merchantSerialNumber 商户证书序列号 * @param apiV3Key APIv3密钥 * @return 微信支付配置对象 */ - public Config createAutoConfig(String merchantId, String privateKeyPath, + public Config createAutoConfig(String merchantId, String privateKeyPath, String merchantSerialNumber, String apiV3Key) { try { log.info("创建微信支付自动证书配置..."); log.info("商户号: {}", merchantId); log.info("私钥路径: {}", privateKeyPath); log.info("证书序列号: {}", merchantSerialNumber); - + Config config = new RSAAutoCertificateConfig.Builder() .merchantId(merchantId) .privateKeyFromPath(privateKeyPath) .merchantSerialNumber(merchantSerialNumber) .apiV3Key(apiV3Key) .build(); - + log.info("✅ 微信支付自动证书配置创建成功"); log.info("🔄 系统将自动管理平台证书的下载和更新"); - + return config; - + } catch (Exception e) { log.error("❌ 创建微信支付自动证书配置失败: {}", e.getMessage(), e); - + // 提供详细的错误诊断信息 log.error("🔍 错误诊断:"); log.error("1. 请检查商户平台是否已开启API安全功能"); @@ -68,48 +55,28 @@ public class WechatCertAutoConfig { log.error("3. 请验证APIv3密钥和证书序列号是否正确"); log.error("4. 请检查网络连接是否正常"); log.error("5. 请确认私钥文件路径是否正确: {}", privateKeyPath); - + throw new RuntimeException("微信支付自动证书配置失败: " + e.getMessage(), e); } } - + /** * 使用默认开发环境配置创建自动证书配置 - * 根据当前环境自动选择证书路径 - * 开发环境拼接规则:配置文件upload-path + dev/wechat/ + 租户ID - * + * * @return 微信支付配置对象 */ public Config createDefaultDevConfig() { String merchantId = "1723321338"; - String privateKeyPath; + String privateKeyPath = "src/main/resources/certs/dev/wechat/apiclient_key.pem"; String merchantSerialNumber = "2B933F7C35014A1C363642623E4A62364B34C4EB"; String apiV3Key = "0kF5OlPr482EZwtn9zGufUcqa7ovgxRL"; - - // 根据环境选择证书路径 - if ("dev".equals(activeProfile)) { - // 开发环境:使用配置文件upload-path拼接证书路径 - String uploadPath = configProperties.getUploadPath(); // 配置文件路径 - String tenantId = "10550"; // 租户ID - String certPath = uploadPath + "dev/wechat/" + tenantId + "/"; - privateKeyPath = certPath + "apiclient_key.pem"; - - log.info("开发环境:使用配置文件upload-path拼接证书路径"); - log.info("配置文件upload-path: {}", uploadPath); - log.info("证书基础路径: {}", certPath); - log.info("私钥文件路径: {}", privateKeyPath); - } else { - // 生产环境:使用相对路径,由系统动态解析 - privateKeyPath = "src/main/resources/certs/dev/wechat/apiclient_key.pem"; - log.info("生产环境:使用相对证书路径 - {}", privateKeyPath); - } - + return createAutoConfig(merchantId, privateKeyPath, merchantSerialNumber, apiV3Key); } - + /** * 测试证书配置是否正常 - * + * * @param config 微信支付配置 * @return 是否配置成功 */ @@ -117,56 +84,56 @@ public class WechatCertAutoConfig { try { // 这里可以添加一些基本的配置验证逻辑 log.info("🧪 测试微信支付证书配置..."); - + if (config == null) { log.error("配置对象为空"); return false; } - + log.info("✅ 证书配置测试通过"); return true; - + } catch (Exception e) { log.error("❌ 证书配置测试失败: {}", e.getMessage(), e); return false; } } - + /** * 获取配置使用说明 - * + * * @return 使用说明 */ public String getUsageInstructions() { return """ 🚀 微信支付自动证书配置使用说明 ================================ - + ✅ 优势: 1. 自动下载微信支付平台证书 2. 证书过期时自动更新 3. 无需手动管理 wechatpay_cert.pem 文件 4. 符合微信支付官方最佳实践 - + 📝 使用方法: - + // 方法1: 使用默认开发环境配置 Config config = wechatCertAutoConfig.createDefaultDevConfig(); - + // 方法2: 自定义配置 Config config = wechatCertAutoConfig.createAutoConfig( - "商户号", - "私钥路径", - "证书序列号", + "商户号", + "私钥路径", + "证书序列号", "APIv3密钥" ); - + 🔧 前置条件: 1. 微信商户平台已开启API安全功能 2. 已申请使用微信支付公钥 3. 私钥文件存在且路径正确 4. 网络连接正常 - + 📚 更多信息: https://pay.weixin.qq.com/doc/v3/merchant/4012153196 """; diff --git a/src/main/java/com/gxwebsoft/common/system/entity/User.java b/src/main/java/com/gxwebsoft/common/system/entity/User.java index 66d25cc..aa4833a 100644 --- a/src/main/java/com/gxwebsoft/common/system/entity/User.java +++ b/src/main/java/com/gxwebsoft/common/system/entity/User.java @@ -119,7 +119,7 @@ public class User implements UserDetails { private String payMoney; @Schema(description = "实际消费的金额(不含退款)") - private String expendMoney; + private BigDecimal expendMoney; @Schema(description = "会员等级ID") private Integer gradeId; diff --git a/src/main/java/com/gxwebsoft/shop/controller/ShopOrderController.java b/src/main/java/com/gxwebsoft/shop/controller/ShopOrderController.java index 4b2b3bf..9de9caa 100644 --- a/src/main/java/com/gxwebsoft/shop/controller/ShopOrderController.java +++ b/src/main/java/com/gxwebsoft/shop/controller/ShopOrderController.java @@ -6,14 +6,15 @@ import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.NumberUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson.JSONObject; import com.gxwebsoft.common.core.config.ConfigProperties; import com.gxwebsoft.common.core.config.CertificateProperties; -import com.gxwebsoft.common.core.utils.RedisUtil; -import com.gxwebsoft.common.core.utils.CertificateLoader; -import com.gxwebsoft.common.core.utils.WechatCertAutoConfig; -import com.gxwebsoft.common.core.utils.WechatPayConfigValidator; +import com.gxwebsoft.common.core.utils.*; import com.gxwebsoft.common.core.web.BaseController; +import com.gxwebsoft.common.system.entity.DictData; import com.gxwebsoft.common.system.entity.Payment; +import com.gxwebsoft.shop.entity.ShopGoods; +import com.gxwebsoft.shop.service.ShopGoodsService; import com.gxwebsoft.shop.service.ShopOrderGoodsService; import com.gxwebsoft.shop.service.ShopOrderService; import com.gxwebsoft.shop.service.OrderBusinessService; @@ -39,7 +40,9 @@ import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; +import javax.validation.Valid; import java.math.BigDecimal; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -53,329 +56,354 @@ import java.util.Map; @RestController @RequestMapping("/api/shop/shop-order") public class ShopOrderController extends BaseController { - private static final Logger logger = LoggerFactory.getLogger(ShopOrderController.class); - @Resource - private ShopOrderService shopOrderService; - @Resource - private ShopOrderGoodsService shopOrderGoodsService; - @Resource - private OrderBusinessService orderBusinessService; - @Resource - private RedisUtil redisUtil; - @Resource - private ConfigProperties conf; - @Resource - private CertificateProperties certConfig; - @Resource - private CertificateLoader certificateLoader; - @Resource - private WechatCertAutoConfig wechatCertAutoConfig; - @Resource - private WechatPayConfigValidator wechatPayConfigValidator; - @Value("${spring.profiles.active}") - String active; - - @Operation(summary = "分页查询订单") - @GetMapping("/page") - public ApiResult> page(ShopOrderParam param) { - // 使用关联查询 - return success(shopOrderService.pageRel(param)); - } - - @Operation(summary = "查询全部订单") - @GetMapping() - public ApiResult> list(ShopOrderParam param) { - // 使用关联查询 - return success(shopOrderService.listRel(param)); - } - - @PreAuthorize("hasAuthority('shop:shopOrder:list')") - @Operation(summary = "根据id查询订单") - @GetMapping("/{id}") - public ApiResult get(@PathVariable("id") Integer id) { - // 使用关联查询 - return success(shopOrderService.getByIdRel(id)); - } - - @Operation(summary = "添加订单") - @PostMapping() - public ApiResult save(@RequestBody OrderCreateRequest request) { - User loginUser = getLoginUser(); - if (loginUser == null) { - return fail("用户未登录"); + private static final Logger logger = LoggerFactory.getLogger(ShopOrderController.class); + @Resource + private ShopOrderService shopOrderService; + @Resource + private ShopOrderGoodsService shopOrderGoodsService; + @Resource + private OrderBusinessService orderBusinessService; + @Resource + private RedisUtil redisUtil; + @Resource + private ConfigProperties conf; + @Resource + private CertificateProperties certConfig; + @Resource + private CertificateLoader certificateLoader; + @Resource + private WechatCertAutoConfig wechatCertAutoConfig; + @Resource + private WechatPayConfigValidator wechatPayConfigValidator; + @Resource + private ShopGoodsService shopGoodsService; + @Value("${spring.profiles.active}") + String active; + @Resource + private RequestUtil requestUtil; + + @Operation(summary = "分页查询订单") + @GetMapping("/test") + public ApiResult test() { + requestUtil.setTenantId("10550"); + User user = requestUtil.getByUserIdWithoutLogin(33035); + return success(user); } - try { - Map wxOrderInfo = orderBusinessService.createOrder(request, loginUser); - return success("下单成功", wxOrderInfo); - } catch (Exception e) { - logger.error("创建订单失败 - 用户ID:{},请求:{}", loginUser.getUserId(), request, e); - return fail(e.getMessage()); + @Operation(summary = "分页查询订单") + @GetMapping("/page") + public ApiResult> page(ShopOrderParam param) { + // 使用关联查询 + return success(shopOrderService.pageRel(param)); } - } - @Operation(summary = "添加订单(兼容旧版本)") - @PostMapping("/legacy") - public ApiResult saveLegacy(@RequestBody ShopOrder shopOrder) { - // 记录当前登录用户id - User loginUser = getLoginUser(); - if (loginUser != null) { - shopOrder.setUserId(loginUser.getUserId()); - shopOrder.setOpenid(loginUser.getOpenid()); - shopOrder.setPayUserId(loginUser.getUserId()); - if (shopOrder.getOrderNo() == null) { - shopOrder.setOrderNo(Long.toString(IdUtil.getSnowflakeNextId())); - } - if (shopOrder.getComments() == null) { - shopOrder.setComments("暂无"); - } - // 微信支付(商品金额不能为0) - if (shopOrder.getTotalPrice().compareTo(BigDecimal.ZERO) == 0) { - return fail("商品金额不能为0"); - } - // 百色中学项目捐赠金额不能低于20元 - if (shopOrder.getTenantId().equals(10324) && shopOrder.getTotalPrice().compareTo(new BigDecimal("10")) < 0) { - return fail("捐款金额最低不能少于10元,感谢您的爱心捐赠^_^"); - } - // 测试支付 - if (loginUser.getPhone().equals("13737128880")) { - shopOrder.setPrice(new BigDecimal("0.01")); - shopOrder.setTotalPrice(new BigDecimal("0.01")); - } - if (shopOrderService.save(shopOrder)) { - return success("下单成功", shopOrderService.createWxOrder(shopOrder)); - } + @Operation(summary = "查询全部订单") + @GetMapping() + public ApiResult> list(ShopOrderParam param) { + // 使用关联查询 + return success(shopOrderService.listRel(param)); } - return fail("添加失败"); - } - @PreAuthorize("hasAuthority('shop:shopOrder:update')") - @Operation(summary = "修改订单") - @PutMapping() - public ApiResult update(@RequestBody ShopOrder shopOrder) { - if (shopOrderService.updateById(shopOrder)) { - return success("修改成功"); + @PreAuthorize("hasAuthority('shop:shopOrder:list')") + @Operation(summary = "根据id查询订单") + @GetMapping("/{id}") + public ApiResult get(@PathVariable("id") Integer id) { + // 使用关联查询 + return success(shopOrderService.getByIdRel(id)); } - return fail("修改失败"); - } - @Operation(summary = "删除订单") - @DeleteMapping("/{id}") - public ApiResult remove(@PathVariable("id") Integer id) { - if (shopOrderService.removeById(id)) { - return success("删除成功"); + @Operation(summary = "添加订单") + @PostMapping() + public ApiResult save(@Valid @RequestBody OrderCreateRequest request) { + User loginUser = getLoginUser(); + if (loginUser == null) { + return fail("用户未登录"); + } + if (request.getTotalPrice() == null || request.getTotalPrice().compareTo(BigDecimal.ZERO) <= 0) { + if (request.getGoodsItems() != null && !request.getGoodsItems().isEmpty()) { + BigDecimal totalPrice = BigDecimal.ZERO; + int totalNum = 0; + for (OrderCreateRequest.OrderGoodsItem item : request.getGoodsItems()) { + ShopGoods goods = shopGoodsService.getById(item.getGoodsId().toString()); + if (goods != null) { + BigDecimal price = goods.getPrice().multiply(new BigDecimal(item.getQuantity().toString())); + totalPrice = totalPrice.add(price); + totalNum += Integer.parseInt(item.getQuantity().toString()); + } + } + request.setTotalPrice(totalPrice); + request.setPayPrice(totalPrice); + request.setTotalNum(totalNum); + request.setFormId(Integer.parseInt(request.getGoodsItems().get(0).getQuantity().toString())); + } + } + if (request.getTenantId() == null) { + request.setTenantId(getTenantId()); + } + try { + Map wxOrderInfo = orderBusinessService.createOrder(request, loginUser); + return success("下单成功", wxOrderInfo); + } catch (Exception e) { + logger.error("创建订单失败", e); + return fail(e.getMessage()); + } } - return fail("删除失败"); - } - @Operation(summary = "批量添加订单") - @PostMapping("/batch") - public ApiResult saveBatch(@RequestBody List list) { - if (shopOrderService.saveBatch(list)) { - return success("添加成功"); + @Operation(summary = "添加订单(兼容旧版本)") + @PostMapping("/legacy") + public ApiResult saveLegacy(@RequestBody ShopOrder shopOrder) { + // 记录当前登录用户id + User loginUser = getLoginUser(); + if (loginUser != null) { + shopOrder.setUserId(loginUser.getUserId()); + shopOrder.setOpenid(loginUser.getOpenid()); + shopOrder.setPayUserId(loginUser.getUserId()); + if (shopOrder.getOrderNo() == null) { + shopOrder.setOrderNo(Long.toString(IdUtil.getSnowflakeNextId())); + } + if (shopOrder.getComments() == null) { + shopOrder.setComments("暂无"); + } + // 微信支付(商品金额不能为0) + if (shopOrder.getTotalPrice().compareTo(BigDecimal.ZERO) == 0) { + return fail("商品金额不能为0"); + } + // 百色中学项目捐赠金额不能低于20元 + if (shopOrder.getTenantId().equals(10324) && shopOrder.getTotalPrice().compareTo(new BigDecimal("10")) < 0) { + return fail("捐款金额最低不能少于10元,感谢您的爱心捐赠^_^"); + } + // 测试支付 + if (loginUser.getPhone().equals("13737128880")) { + shopOrder.setPrice(new BigDecimal("0.01")); + shopOrder.setTotalPrice(new BigDecimal("0.01")); + } + if (shopOrderService.save(shopOrder)) { + return success("下单成功", shopOrderService.createWxOrder(shopOrder)); + } + } + return fail("添加失败"); } - return fail("添加失败"); - } - @Operation(summary = "批量修改订单") - @PutMapping("/batch") - public ApiResult removeBatch(@RequestBody BatchParam batchParam) { - if (batchParam.update(shopOrderService, "order_id")) { - return success("修改成功"); + @PreAuthorize("hasAuthority('shop:shopOrder:update')") + @Operation(summary = "修改订单") + @PutMapping() + public ApiResult update(@RequestBody ShopOrder shopOrder) { + if (shopOrderService.updateById(shopOrder)) { + return success("修改成功"); + } + return fail("修改失败"); } - return fail("修改失败"); - } - @Operation(summary = "批量删除订单") - @DeleteMapping("/batch") - public ApiResult removeBatch(@RequestBody List ids) { - if (shopOrderService.removeByIds(ids)) { - return success("删除成功"); + @Operation(summary = "删除订单") + @DeleteMapping("/{id}") + public ApiResult remove(@PathVariable("id") Integer id) { + if (shopOrderService.removeById(id)) { + return success("删除成功"); + } + return fail("删除失败"); } - return fail("删除失败"); - } - @Operation(summary = "修复订单") - @PutMapping("/repair") - public ApiResult repair(@RequestBody ShopOrder shopOrder) { - final ShopOrder order = shopOrderService.getByOutTradeNo(shopOrder.getOrderNo()); - if(order != null){ - shopOrderService.queryOrderByOutTradeNo(order); - return success("修复成功"); + @Operation(summary = "批量添加订单") + @PostMapping("/batch") + public ApiResult saveBatch(@RequestBody List list) { + if (shopOrderService.saveBatch(list)) { + return success("添加成功"); + } + return fail("添加失败"); } - return fail("修复失败"); - } - - @Operation(summary = "统计订单总金额") - @GetMapping("/total") - public ApiResult total() { - return success(shopOrderService.total()); - } - @Schema(description = "异步通知") - @PostMapping("/notify/{tenantId}") - public String wxNotify(@RequestHeader Map header, @RequestBody String body, @PathVariable("tenantId") Integer tenantId) { - logger.info("异步通知*************** = " + tenantId); - - // 获取支付配置信息用于解密 - String key = "Payment:1:".concat(tenantId.toString()); - Payment payment = redisUtil.get(key, Payment.class); - - // 检查支付配置 - if (ObjectUtil.isEmpty(payment)) { - throw new RuntimeException("未找到租户支付配置信息,租户ID: " + tenantId); + @Operation(summary = "批量修改订单") + @PutMapping("/batch") + public ApiResult removeBatch(@RequestBody BatchParam batchParam) { + if (batchParam.update(shopOrderService, "order_id")) { + return success("修改成功"); + } + return fail("修改失败"); } - logger.info("开始处理微信支付异步通知 - 租户ID: {}", tenantId); - logger.info("支付配置信息 - 商户号: {}, 应用ID: {}", payment.getMchId(), payment.getAppId()); - - // 验证微信支付配置 - WechatPayConfigValidator.ValidationResult validation = wechatPayConfigValidator.validateWechatPayConfig(payment, tenantId); - if (!validation.isValid()) { - logger.error("❌ 微信支付配置验证失败: {}", validation.getErrors()); - logger.info("📋 配置诊断报告:\n{}", wechatPayConfigValidator.generateDiagnosticReport(payment, tenantId)); - throw new RuntimeException("微信支付配置验证失败: " + validation.getErrors()); + @Operation(summary = "批量删除订单") + @DeleteMapping("/batch") + public ApiResult removeBatch(@RequestBody List ids) { + if (shopOrderService.removeByIds(ids)) { + return success("删除成功"); + } + return fail("删除失败"); } - logger.info("✅ 微信支付配置验证通过"); - - RequestParam requestParam = new RequestParam.Builder() - .serialNumber(header.get("wechatpay-serial")) - .nonce(header.get("wechatpay-nonce")) - .signature(header.get("wechatpay-signature")) - .timestamp(header.get("wechatpay-timestamp")) - .body(body) - .build(); - - // 创建通知配置 - 使用与下单方法相同的证书配置逻辑 - NotificationConfig config; - try { - if (active.equals("dev")) { - // 开发环境 - 使用配置文件的upload-path构建证书路径 - String uploadPath = conf.getUploadPath(); - String tenantCertPath = uploadPath + "dev/wechat/" + tenantId; - String privateKeyPath = tenantCertPath + "/" + certConfig.getWechatPay().getDev().getPrivateKeyFile(); - - logger.info("开发环境异步通知证书路径: {}", privateKeyPath); - logger.info("租户ID: {}, 证书目录: {}", tenantId, tenantCertPath); - // 检查证书文件是否存在 - if (!certificateLoader.certificateExists(privateKeyPath)) { - logger.error("证书文件不存在: {}", privateKeyPath); - throw new RuntimeException("证书文件不存在: " + privateKeyPath); + @Operation(summary = "修复订单") + @PutMapping("/repair") + public ApiResult repair(@RequestBody ShopOrder shopOrder) { + final ShopOrder order = shopOrderService.getByOutTradeNo(shopOrder.getOrderNo()); + if (order != null) { + shopOrderService.queryOrderByOutTradeNo(order); + return success("修复成功"); } + return fail("修复失败"); + } - String privateKey = certificateLoader.loadCertificatePath(privateKeyPath); - - // 使用验证器获取有效的 APIv3 密钥 - String apiV3Key = wechatPayConfigValidator.getValidApiV3Key(payment); - - logger.info("私钥文件加载成功: {}", privateKey); - logger.info("使用APIv3密钥来源: {}", payment.getApiKey() != null && !payment.getApiKey().trim().isEmpty() ? "数据库配置" : "配置文件默认"); - logger.info("APIv3密钥长度: {}", apiV3Key != null ? apiV3Key.length() : 0); - logger.info("商户证书序列号: {}", payment.getMerchantSerialNumber()); - - // 使用自动证书配置 - config = new RSAAutoCertificateConfig.Builder() - .merchantId(payment.getMchId()) - .privateKeyFromPath(privateKey) - .merchantSerialNumber(payment.getMerchantSerialNumber()) - .apiV3Key(apiV3Key) - .build(); - - logger.info("✅ 开发环境使用自动证书配置创建通知解析器成功"); - } else { - // 生产环境 - 使用自动证书配置 - final String certRootPath = certConfig.getCertRootPath(); - final String certBasePath = certRootPath + "/file"; - - String privateKeyRelativePath = payment.getApiclientKey(); - String privateKeyFullPath = privateKeyRelativePath.startsWith("/") - ? certBasePath + privateKeyRelativePath - : certBasePath + "/" + privateKeyRelativePath; - String privateKey = certificateLoader.loadCertificatePath(privateKeyFullPath); - String apiV3Key = payment.getApiKey(); - - // 使用自动证书配置 - config = new RSAAutoCertificateConfig.Builder() - .merchantId(payment.getMchId()) - .privateKeyFromPath(privateKey) - .merchantSerialNumber(payment.getMerchantSerialNumber()) - .apiV3Key(apiV3Key) - .build(); + @Schema(description = "异步通知") + @PostMapping("/notify/{tenantId}") + public String wxNotify(@RequestHeader Map header, @RequestBody String body, @PathVariable("tenantId") Integer tenantId) { + logger.info("异步通知*************** = " + tenantId); - logger.info("✅ 生产环境使用自动证书配置创建通知解析器成功"); - } - } catch (Exception e) { - logger.error("❌ 创建通知配置失败 - 租户ID: {}, 商户号: {}", tenantId, payment.getMchId(), e); - logger.error("🔍 错误详情: {}", e.getMessage()); - logger.error("💡 请检查:"); - logger.error("1. 证书文件是否存在且路径正确"); - logger.error("2. APIv3密钥是否配置正确"); - logger.error("3. 商户证书序列号是否正确"); - logger.error("4. 网络连接是否正常"); - throw new RuntimeException("微信支付通知配置失败: " + e.getMessage(), e); - } + // 获取支付配置信息用于解密 + String key = "Payment:1:".concat(tenantId.toString()); + Payment payment = redisUtil.get(key, Payment.class); - // 初始化 NotificationParser - NotificationParser parser = new NotificationParser(config); - logger.info("✅ 通知解析器创建成功,准备解析异步通知"); + // 检查支付配置 + if (ObjectUtil.isEmpty(payment)) { + throw new RuntimeException("未找到租户支付配置信息,租户ID: " + tenantId); + } - // 以支付通知回调为例,验签、解密并转换成 Transaction - try { - logger.info("开始解析微信支付异步通知..."); - Transaction transaction = parser.parse(requestParam, Transaction.class); - logger.info("✅ 异步通知解析成功 - 交易状态: {}, 商户订单号: {}", - transaction.getTradeStateDesc(), transaction.getOutTradeNo()); + logger.info("开始处理微信支付异步通知 - 租户ID: {}", tenantId); + logger.info("支付配置信息 - 商户号: {}, 应用ID: {}", payment.getMchId(), payment.getAppId()); - if (StrUtil.equals("支付成功", transaction.getTradeStateDesc())) { - final String outTradeNo = transaction.getOutTradeNo(); - final String transactionId = transaction.getTransactionId(); - final Integer total = transaction.getAmount().getTotal(); - final String tradeStateDesc = transaction.getTradeStateDesc(); - final Transaction.TradeStateEnum tradeState = transaction.getTradeState(); - final Transaction.TradeTypeEnum tradeType = transaction.getTradeType(); - System.out.println("transaction = " + transaction); - System.out.println("tradeStateDesc = " + tradeStateDesc); - System.out.println("tradeType = " + tradeType); - System.out.println("tradeState = " + tradeState); - System.out.println("outTradeNo = " + outTradeNo); - System.out.println("amount = " + total); - // 1. 查询要处理的订单 - ShopOrder order = shopOrderService.getByOutTradeNo(outTradeNo); - logger.info("order = " + order); - // 2. 已支付则跳过 - if (order.getPayStatus().equals(true)) { - return "SUCCESS"; + // 验证微信支付配置 + WechatPayConfigValidator.ValidationResult validation = wechatPayConfigValidator.validateWechatPayConfig(payment, tenantId); + if (!validation.isValid()) { + logger.error("❌ 微信支付配置验证失败: {}", validation.getErrors()); + logger.info("📋 配置诊断报告:\n{}", wechatPayConfigValidator.generateDiagnosticReport(payment, tenantId)); + throw new RuntimeException("微信支付配置验证失败: " + validation.getErrors()); } - // 2. 未支付则处理更新订单状态 - if (order.getPayStatus().equals(false)) { - // 5. TODO 处理订单状态 - order.setPayTime(DateUtil.date()); - order.setExpirationTime(order.getCreateTime()); - order.setPayStatus(true); - order.setTransactionId(transactionId); - order.setPayPrice(new BigDecimal(NumberUtil.decimalFormat("0.00", total * 0.01))); - order.setExpirationTime(DateUtil.offset(DateUtil.date(), DateField.YEAR, 10)); - System.out.println("实际付款金额 = " + order.getPayPrice()); - shopOrderService.updateByOutTradeNo(order); - return "SUCCESS"; + logger.info("✅ 微信支付配置验证通过"); + + RequestParam requestParam = new RequestParam.Builder() + .serialNumber(header.get("wechatpay-serial")) + .nonce(header.get("wechatpay-nonce")) + .signature(header.get("wechatpay-signature")) + .timestamp(header.get("wechatpay-timestamp")) + .body(body) + .build(); + + // 创建通知配置 - 使用与下单方法相同的证书配置逻辑 + NotificationConfig config; + try { +// if (active.equals("dev")) { +// // 开发环境 - 构建包含租户号的私钥路径 +// String tenantCertPath = "dev/wechat/" + tenantId; +// String privateKeyPath = tenantCertPath + "/" + certConfig.getWechatPay().getDev().getPrivateKeyFile(); +// +// logger.info("开发环境异步通知证书路径: {}", privateKeyPath); +// logger.info("租户ID: {}, 证书目录: {}", tenantId, tenantCertPath); +// +// // 检查证书文件是否存在 +// if (!certificateLoader.certificateExists(privateKeyPath)) { +// logger.error("证书文件不存在: {}", privateKeyPath); +// throw new RuntimeException("证书文件不存在: " + privateKeyPath); +// } +// +// String privateKey = certificateLoader.loadCertificatePath(privateKeyPath); +// +// // 使用验证器获取有效的 APIv3 密钥 +// String apiV3Key = wechatPayConfigValidator.getValidApiV3Key(payment); +// +// logger.info("私钥文件加载成功: {}", privateKey); +// logger.info("使用APIv3密钥来源: {}", payment.getApiKey() != null && !payment.getApiKey().trim().isEmpty() ? "数据库配置" : "配置文件默认"); +// logger.info("APIv3密钥长度: {}", apiV3Key != null ? apiV3Key.length() : 0); +// logger.info("商户证书序列号: {}", payment.getMerchantSerialNumber()); +// +// // 使用自动证书配置 +// config = new RSAAutoCertificateConfig.Builder() +// .merchantId(payment.getMchId()) +// .privateKeyFromPath(privateKey) +// .merchantSerialNumber(payment.getMerchantSerialNumber()) +// .apiV3Key(apiV3Key) +// .build(); +// +// logger.info("✅ 开发环境使用自动证书配置创建通知解析器成功"); +// } else { + // 生产环境 - 使用自动证书配置 + final String certRootPath = certConfig.getCertRootPath(); + final String certBasePath = certRootPath + "/file"; + + String privateKeyRelativePath = payment.getApiclientKey(); + String privateKeyFullPath = privateKeyRelativePath.startsWith("/") + ? certBasePath + privateKeyRelativePath + : certBasePath + "/" + privateKeyRelativePath; + String privateKey = certificateLoader.loadCertificatePath(privateKeyFullPath); + String apiV3Key = payment.getApiKey(); + + // 使用自动证书配置 + config = new RSAAutoCertificateConfig.Builder() + .merchantId(payment.getMchId()) + .privateKeyFromPath(privateKey) + .merchantSerialNumber(payment.getMerchantSerialNumber()) + .apiV3Key(apiV3Key) + .build(); + + logger.info("✅ 生产环境使用自动证书配置创建通知解析器成功"); +// } + } catch (Exception e) { + logger.error("❌ 创建通知配置失败 - 租户ID: {}, 商户号: {}", tenantId, payment.getMchId(), e); + logger.error("🔍 错误详情: {}", e.getMessage()); + logger.error("💡 请检查:"); + logger.error("1. 证书文件是否存在且路径正确"); + logger.error("2. APIv3密钥是否配置正确"); + logger.error("3. 商户证书序列号是否正确"); + logger.error("4. 网络连接是否正常"); + throw new RuntimeException("微信支付通知配置失败: " + e.getMessage(), e); } - } - } catch (Exception e) { - logger.error("❌ 处理微信支付异步通知失败 - 租户ID: {}, 商户号: {}", tenantId, payment.getMchId(), e); - logger.error("🔍 异常详情: {}", e.getMessage()); - logger.error("💡 可能的原因:"); - logger.error("1. 证书配置错误或证书文件损坏"); - logger.error("2. 微信支付平台证书已过期"); - logger.error("3. 签名验证失败"); - logger.error("4. 请求参数格式错误"); - // 返回失败,微信会重试 - return "fail"; - } + // 初始化 NotificationParser + NotificationParser parser = new NotificationParser(config); + logger.info("✅ 通知解析器创建成功,准备解析异步通知"); + + // 以支付通知回调为例,验签、解密并转换成 Transaction + try { + logger.info("开始解析微信支付异步通知..."); + Transaction transaction = parser.parse(requestParam, Transaction.class); + logger.info("✅ 异步通知解析成功 - 交易状态: {}, 商户订单号: {}", + transaction.getTradeStateDesc(), transaction.getOutTradeNo()); + + if (StrUtil.equals("支付成功", transaction.getTradeStateDesc())) { + final String outTradeNo = transaction.getOutTradeNo(); + final String transactionId = transaction.getTransactionId(); + final Integer total = transaction.getAmount().getTotal(); + final String tradeStateDesc = transaction.getTradeStateDesc(); + final Transaction.TradeStateEnum tradeState = transaction.getTradeState(); + final Transaction.TradeTypeEnum tradeType = transaction.getTradeType(); + System.out.println("transaction = " + transaction); + System.out.println("tradeStateDesc = " + tradeStateDesc); + System.out.println("tradeType = " + tradeType); + System.out.println("tradeState = " + tradeState); + System.out.println("outTradeNo = " + outTradeNo); + System.out.println("amount = " + total); + // 1. 查询要处理的订单 + ShopOrder order = shopOrderService.getByOutTradeNo(outTradeNo); + logger.info("order = " + order); + // 2. 已支付则跳过 + if (order.getPayStatus().equals(true)) { + return "SUCCESS"; + } + // 2. 未支付则处理更新订单状态 + if (order.getPayStatus().equals(false)) { + // 5. TODO 处理订单状态 + order.setPayTime(DateUtil.date()); + order.setExpirationTime(order.getCreateTime()); + order.setPayStatus(true); + order.setTransactionId(transactionId); + order.setPayPrice(new BigDecimal(NumberUtil.decimalFormat("0.00", total * 0.01))); + order.setExpirationTime(DateUtil.offset(DateUtil.date(), DateField.YEAR, 10)); + System.out.println("实际付款金额 = " + order.getPayPrice()); + shopOrderService.updateByOutTradeNo(order); + return "SUCCESS"; + } + } + } catch (Exception e) { + logger.error("❌ 处理微信支付异步通知失败 - 租户ID: {}, 商户号: {}", tenantId, payment.getMchId(), e); + logger.error("🔍 异常详情: {}", e.getMessage()); + logger.error("💡 可能的原因:"); + logger.error("1. 证书配置错误或证书文件损坏"); + logger.error("2. 微信支付平台证书已过期"); + logger.error("3. 签名验证失败"); + logger.error("4. 请求参数格式错误"); + + // 返回失败,微信会重试 + return "fail"; + } - logger.warn("⚠️ 异步通知处理完成但未找到匹配的支付成功状态"); - return "fail"; - } + logger.warn("⚠️ 异步通知处理完成但未找到匹配的支付成功状态"); + return "fail"; + } } diff --git a/src/main/java/com/gxwebsoft/shop/entity/ShopDealerOrder.java b/src/main/java/com/gxwebsoft/shop/entity/ShopDealerOrder.java index 51e2955..b5aada4 100644 --- a/src/main/java/com/gxwebsoft/shop/entity/ShopDealerOrder.java +++ b/src/main/java/com/gxwebsoft/shop/entity/ShopDealerOrder.java @@ -60,7 +60,7 @@ public class ShopDealerOrder implements Serializable { private Integer isSettled; @Schema(description = "结算时间") - private Integer settleTime; + private Long settleTime; @Schema(description = "商城ID") private Integer tenantId; diff --git a/src/main/java/com/gxwebsoft/shop/entity/ShopGoods.java b/src/main/java/com/gxwebsoft/shop/entity/ShopGoods.java index c474996..c2cadb9 100644 --- a/src/main/java/com/gxwebsoft/shop/entity/ShopGoods.java +++ b/src/main/java/com/gxwebsoft/shop/entity/ShopGoods.java @@ -69,6 +69,9 @@ public class ShopGoods implements Serializable { @Schema(description = "经销商价格") private BigDecimal dealerPrice; + @Schema(description = "佣金") + private BigDecimal commission; + @Schema(description = "库存计算方式(10下单减库存 20付款减库存)") private Integer deductStockType; diff --git a/src/main/java/com/gxwebsoft/shop/service/ShopOrderGoodsService.java b/src/main/java/com/gxwebsoft/shop/service/ShopOrderGoodsService.java index d4e932c..f7cd59c 100644 --- a/src/main/java/com/gxwebsoft/shop/service/ShopOrderGoodsService.java +++ b/src/main/java/com/gxwebsoft/shop/service/ShopOrderGoodsService.java @@ -39,4 +39,5 @@ public interface ShopOrderGoodsService extends IService { */ ShopOrderGoods getByIdRel(Integer id); + List getListByOrderId(Integer orderId); } diff --git a/src/main/java/com/gxwebsoft/shop/service/impl/ShopOrderGoodsServiceImpl.java b/src/main/java/com/gxwebsoft/shop/service/impl/ShopOrderGoodsServiceImpl.java index a622c16..db20dff 100644 --- a/src/main/java/com/gxwebsoft/shop/service/impl/ShopOrderGoodsServiceImpl.java +++ b/src/main/java/com/gxwebsoft/shop/service/impl/ShopOrderGoodsServiceImpl.java @@ -1,5 +1,6 @@ package com.gxwebsoft.shop.service.impl; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.gxwebsoft.shop.mapper.ShopOrderGoodsMapper; import com.gxwebsoft.shop.service.ShopOrderGoodsService; @@ -44,4 +45,12 @@ public class ShopOrderGoodsServiceImpl extends ServiceImpl getListByOrderId(Integer orderId) { + return list( + new LambdaQueryWrapper() + .eq(ShopOrderGoods::getOrderId, orderId) + ); + } + } diff --git a/src/main/java/com/gxwebsoft/shop/service/impl/ShopOrderServiceImpl.java b/src/main/java/com/gxwebsoft/shop/service/impl/ShopOrderServiceImpl.java index fb062e1..2c0828f 100644 --- a/src/main/java/com/gxwebsoft/shop/service/impl/ShopOrderServiceImpl.java +++ b/src/main/java/com/gxwebsoft/shop/service/impl/ShopOrderServiceImpl.java @@ -4,30 +4,25 @@ import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; - import org.springframework.util.CollectionUtils; import com.gxwebsoft.common.core.config.ConfigProperties; import com.gxwebsoft.common.core.config.CertificateProperties; - import com.gxwebsoft.common.core.utils.RedisUtil; - import com.gxwebsoft.common.core.utils.CertificateLoader; -import com.gxwebsoft.common.core.service.PaymentCacheService; - import com.gxwebsoft.common.core.utils.WechatPayDiagnostic; - import com.gxwebsoft.common.core.utils.WechatPayCertificateDiagnostic; + import com.gxwebsoft.common.core.utils.*; + import com.gxwebsoft.common.core.service.PaymentCacheService; + import com.gxwebsoft.common.core.web.ApiResult; import com.gxwebsoft.common.system.entity.Payment; + import com.gxwebsoft.common.system.entity.User; + import com.gxwebsoft.shop.entity.*; + import com.gxwebsoft.shop.service.*; import lombok.extern.slf4j.Slf4j; import com.gxwebsoft.common.system.service.PaymentService; import com.gxwebsoft.common.system.service.SettingService; - import com.gxwebsoft.shop.entity.ShopOrderGoods; import com.gxwebsoft.shop.mapper.ShopOrderMapper; - import com.gxwebsoft.shop.service.ShopOrderGoodsService; - import com.gxwebsoft.shop.service.ShopOrderService; - import com.gxwebsoft.shop.entity.ShopOrder; import com.gxwebsoft.shop.param.ShopOrderParam; import com.gxwebsoft.common.core.web.PageParam; import com.gxwebsoft.common.core.web.PageResult; import com.wechat.pay.java.core.Config; import com.wechat.pay.java.core.RSAConfig; import com.wechat.pay.java.core.RSAPublicKeyConfig; - import com.gxwebsoft.common.core.utils.WechatCertAutoConfig; import com.wechat.pay.java.core.exception.ServiceException; import com.wechat.pay.java.service.payments.jsapi.JsapiServiceExtension; import com.wechat.pay.java.service.payments.jsapi.model.*; @@ -38,10 +33,8 @@ import com.gxwebsoft.common.core.service.PaymentCacheService; import javax.annotation.Resource; import java.math.BigDecimal; - import java.util.HashMap; - import java.util.List; - import java.util.Map; - import java.util.Set; + import java.sql.Date; + import java.util.*; import java.util.stream.Collectors; /** @@ -62,6 +55,8 @@ import com.gxwebsoft.common.core.service.PaymentCacheService; @Resource private ShopOrderGoodsService shopOrderGoodsService; @Resource + private ShopGoodsService shopGoodsService; + @Resource private PaymentService paymentService; @Resource private SettingService settingService; @@ -77,6 +72,12 @@ import com.gxwebsoft.common.core.service.PaymentCacheService; private WechatPayDiagnostic wechatPayDiagnostic; @Resource private WechatPayCertificateDiagnostic certificateDiagnostic; + @Resource + private RequestUtil requestUtil; + @Resource + private ShopDealerOrderService shopDealerOrderService; + @Resource + private ShopDealerCapitalService shopDealerCapitalService; @Override public PageResult pageRel(ShopOrderParam param) { @@ -243,6 +244,61 @@ import com.gxwebsoft.common.core.service.PaymentCacheService; @Override public void updateByOutTradeNo(ShopOrder order) { baseMapper.updateByOutTradeNo(order); + if (order.getTenantId().equals(10550)) { + requestUtil.setTenantId(order.getTenantId().toString()); + ApiResult partnerConditionReq = requestUtil.pageDictData(1460); + if (partnerConditionReq.getCode().equals(0) && partnerConditionReq.getData() != null) { + LinkedHashMap dictDataMap = (LinkedHashMap) partnerConditionReq.getData(); + List dictDataList = (List) dictDataMap.get("list"); + String dictDataCode = (String) dictDataList.get(0).get("dictDataCode"); + BigDecimal partnerCondition = new BigDecimal(dictDataCode); + + User user = requestUtil.getByUserIdWithoutLogin(order.getUserId()); + if (user != null) { + user.setExpendMoney(user.getExpendMoney().add(order.getPayPrice())); + if (user.getExpendMoney().compareTo(partnerCondition) >= 0) { + user.setGradeId(3); + } + requestUtil.updateWithoutLogin(user); + + // 上级 + User parent = requestUtil.getParent(order.getUserId()); + if (parent != null) { + + List shopOrderGoodsList = shopOrderGoodsService.getListByOrderId(order.getOrderId()); + List goodsIds = shopOrderGoodsList.stream().map(ShopOrderGoods::getGoodsId).toList(); + List shopGoodsList = shopGoodsService.listByIds(goodsIds); + BigDecimal commission = BigDecimal.ZERO; + for (ShopOrderGoods shopOrderGoods : shopOrderGoodsList) { + ShopGoods shopGoods = shopGoodsList.stream().filter(sG -> sG.getGoodsId().equals(shopOrderGoods.getGoodsId())).findFirst().orElse(null); + if (shopGoods != null) { + commission = commission.add(shopGoods.getCommission().multiply(BigDecimal.valueOf(shopOrderGoods.getTotalNum()))); + } + } + parent.setBalance(parent.getBalance().add(commission)); + requestUtil.updateWithoutLogin(user); + + // 分销订单 + ShopDealerOrder shopDealerOrder = new ShopDealerOrder(); + shopDealerOrder.setUserId(parent.getUserId()); + shopDealerOrder.setOrderId(order.getOrderId()); + shopDealerOrder.setOrderPrice(order.getTotalPrice()); + shopDealerOrder.setFirstUserId(order.getUserId()); + shopDealerOrder.setFirstMoney(commission); + shopDealerOrder.setIsSettled(1); + shopDealerOrder.setSettleTime(DateUtil.currentSeconds()); + shopDealerOrderService.save(shopDealerOrder); + + // 分销资明细 + ShopDealerCapital shopDealerCapital = new ShopDealerCapital(); + shopDealerCapital.setUserId(parent.getUserId()); + shopDealerCapital.setOrderId(order.getOrderId()); + shopDealerCapital.setFlowType(10); + shopDealerCapitalService.save(shopDealerCapital); + } + } + } + } } /** @@ -304,9 +360,8 @@ import com.gxwebsoft.common.core.service.PaymentCacheService; // 开发环境配置 - 使用自动证书配置 if (active.equals("dev")) { - // 开发环境 - 使用配置文件的upload-path构建证书路径 - String uploadPath = config.getUploadPath(); - String tenantCertPath = uploadPath + "dev/wechat/" + order.getTenantId(); + // 构建包含租户号的证书路径: dev/wechat/{tenantId}/ + String tenantCertPath = "dev/wechat/" + order.getTenantId(); String privateKeyPath = tenantCertPath + "/" + certConfig.getWechatPay().getDev().getPrivateKeyFile(); System.out.println("开发环境证书路径 - 租户ID: " + order.getTenantId()); @@ -396,9 +451,8 @@ import com.gxwebsoft.common.core.service.PaymentCacheService; payment.getPubKeyId() != null && !payment.getPubKeyId().isEmpty()) { try { - // 开发环境使用配置文件的upload-path构建公钥路径 - String uploadPath = config.getUploadPath(); - String tenantCertPath = uploadPath + "dev/wechat/" + order.getTenantId(); + // 开发环境固定使用 wechatpay_public_key.pem + String tenantCertPath = "dev/wechat/" + order.getTenantId(); String pubKeyPath = tenantCertPath + "/wechatpay_public_key.pem"; System.out.println("开发环境公钥文件路径: " + pubKeyPath); @@ -472,8 +526,7 @@ import com.gxwebsoft.common.core.service.PaymentCacheService; System.err.println("⚠️ 开发环境回退到基础RSA配置..."); try { // 方案1:尝试使用RSA证书配置(需要商户证书文件) - String uploadPath = config.getUploadPath(); - String tenantCertPath = uploadPath + "dev/wechat/" + order.getTenantId(); + String tenantCertPath = "dev/wechat/" + order.getTenantId(); String apiclientCertPath = tenantCertPath + "/" + certConfig.getWechatPay().getDev().getApiclientCertFile(); if (certificateLoader.certificateExists(apiclientCertPath)) { @@ -651,23 +704,23 @@ import com.gxwebsoft.common.core.service.PaymentCacheService; } } - @Override - public BigDecimal total() { - try { - // 使用数据库聚合查询统计订单总金额,性能更高 - BigDecimal total = baseMapper.selectTotalAmount(); + @Override + public BigDecimal total() { + try { + // 使用数据库聚合查询统计订单总金额,性能更高 + BigDecimal total = baseMapper.selectTotalAmount(); - if (total == null) { - total = BigDecimal.ZERO; - } + if (total == null) { + total = BigDecimal.ZERO; + } - log.info("统计订单总金额完成,总金额:{}", total); - return total; + log.info("统计订单总金额完成,总金额:{}", total); + return total; - } catch (Exception e) { - log.error("统计订单总金额失败", e); - return BigDecimal.ZERO; + } catch (Exception e) { + log.error("统计订单总金额失败", e); + return BigDecimal.ZERO; + } } - } } diff --git a/src/main/resources/application-prod.yml b/src/main/resources/application-prod.yml index 03ec3b1..57406f0 100644 --- a/src/main/resources/application-prod.yml +++ b/src/main/resources/application-prod.yml @@ -3,7 +3,7 @@ # 数据源配置 spring: datasource: - url: jdbc:mysql://1Panel-mysql-Bqdt:3306/website?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8 + url: jdbc:mysql://1Panel-mysql-Bqdt:3306/modules?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8 username: modules password: 8YdLnk7KsPAyDXGA driver-class-name: com.mysql.cj.jdbc.Driver @@ -45,7 +45,7 @@ mqtt: config: # 生产环境接口 server-url: https://server.websoft.top/api - upload-path: /www/wwwroot/file.ws + upload-path: /www/wwwroot/file.ws/ # 阿里云OSS云存储 endpoint: https://oss-cn-shenzhen.aliyuncs.com diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index ad15671..8ced4b2 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -4,7 +4,7 @@ server: # 多环境配置 spring: profiles: - active: dev + active: prod application: name: server