From e38489e5674067fe0ee17a65ac29925f33e86adf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B5=B5=E5=BF=A0=E6=9E=97?= <170083662@qq.com> Date: Wed, 31 Jul 2024 03:02:57 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=EF=BC=9A=E7=89=9B=E5=85=AB?= =?UTF-8?q?=E5=93=A5=E4=B8=93=E7=94=A8=E6=94=AF=E4=BB=98=E5=9B=9E=E8=B0=83?= =?UTF-8?q?=E9=A1=B5=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../booking/controller/FieldController.java | 2 +- .../common/core/config/MybatisPlusConfig.java | 3 + .../common/core/utils/RequestUtil.java | 22 ++++ .../shop/controller/OrderController.java | 3 +- .../controller/WxPayNotifyController.java | 3 + .../controller/WxPayNotifyNbgController.java | 103 ++++++++++++++++++ .../gxwebsoft/shop/service/OrderService.java | 2 +- .../shop/service/impl/OrderServiceImpl.java | 25 +++-- .../gxwebsoft/shop/task/OrderInfoTask.java | 75 ------------- .../com/gxwebsoft/shop/task/OrderTask.java | 72 +++++++++++- 10 files changed, 218 insertions(+), 92 deletions(-) create mode 100644 src/main/java/com/gxwebsoft/shop/controller/WxPayNotifyNbgController.java delete mode 100644 src/main/java/com/gxwebsoft/shop/task/OrderInfoTask.java diff --git a/src/main/java/com/gxwebsoft/booking/controller/FieldController.java b/src/main/java/com/gxwebsoft/booking/controller/FieldController.java index 410e0d8..c7dc0ef 100644 --- a/src/main/java/com/gxwebsoft/booking/controller/FieldController.java +++ b/src/main/java/com/gxwebsoft/booking/controller/FieldController.java @@ -133,7 +133,7 @@ public class FieldController extends BaseController { // 订单信息 final Order order = orderService.getByOutTradeNo(orderNo); order.setOrderInfo(orderInfoService.list(new LambdaQueryWrapper().eq(OrderInfo::getOrderId,order.getOrderId()))); - System.out.println("order = " + order); +// System.out.println("order = " + order); if (order.getPayStatus().equals(0)) { return fail("该订单未支付"); } diff --git a/src/main/java/com/gxwebsoft/common/core/config/MybatisPlusConfig.java b/src/main/java/com/gxwebsoft/common/core/config/MybatisPlusConfig.java index 8073135..9164286 100644 --- a/src/main/java/com/gxwebsoft/common/core/config/MybatisPlusConfig.java +++ b/src/main/java/com/gxwebsoft/common/core/config/MybatisPlusConfig.java @@ -64,6 +64,8 @@ public class MybatisPlusConfig { "sys_dictionary", "sys_dictionary_data", "apps_test_data" +// "shop_order_goods", +// "shop_goods" // "shop_users", // "shop_order", // "shop_order_info", @@ -76,6 +78,7 @@ public class MybatisPlusConfig { // 分页插件配置 PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor(DbType.MYSQL); + paginationInnerInterceptor.setMaxLimit(2000L); interceptor.addInnerInterceptor(paginationInnerInterceptor); return interceptor; 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 69db705..25f0605 100644 --- a/src/main/java/com/gxwebsoft/common/core/utils/RequestUtil.java +++ b/src/main/java/com/gxwebsoft/common/core/utils/RequestUtil.java @@ -4,12 +4,14 @@ import cn.hutool.http.HttpRequest; import com.alibaba.fastjson.JSONObject; import com.gxwebsoft.common.core.security.JwtUtil; import com.gxwebsoft.common.core.web.ApiResult; +import com.gxwebsoft.common.system.entity.Payment; import com.gxwebsoft.common.system.entity.Role; import com.gxwebsoft.common.system.entity.User; import com.gxwebsoft.common.system.entity.UserRole; import com.gxwebsoft.common.system.param.RoleParam; import com.gxwebsoft.shop.entity.MerchantAccount; import com.gxwebsoft.shop.entity.Order; +import com.wechat.pay.java.service.partnerpayments.jsapi.model.Transaction; import org.springframework.http.*; import org.springframework.stereotype.Component; import org.springframework.web.client.RestClientException; @@ -34,6 +36,26 @@ public class RequestUtil { ACCESS_TOKEN = token; } + // 微信支付通知 + public void pushWxPayNotify(Transaction transaction){ + System.out.println("transaction = " + transaction); + // 设置租户ID +// setTenantId(payment.getTenantId().toString()); + // 推送支付通知地址 +// String path = payment.getNotifyUrl(); + try { + // 链式构建请求 + String result = HttpRequest.post("http://pxf4av.natappfree.cc/api/shop/wx-pay/nbg/paySuccess") + .header("Tenantid", "10158") + .body(JSONUtil.toJSONString(transaction))//表单内容 + .timeout(20000)//超时,毫秒 + .execute().body(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public User getUserByPhone(String phone) { String path = "/system/user/getByPhone/" + phone; try { diff --git a/src/main/java/com/gxwebsoft/shop/controller/OrderController.java b/src/main/java/com/gxwebsoft/shop/controller/OrderController.java index 713d9bf..f652882 100644 --- a/src/main/java/com/gxwebsoft/shop/controller/OrderController.java +++ b/src/main/java/com/gxwebsoft/shop/controller/OrderController.java @@ -153,7 +153,6 @@ public class OrderController extends BaseController { @ApiOperation("下单") @PostMapping() public ApiResult save(@RequestBody Order order, HttpServletRequest request) { - System.out.println("order = " + order); String access_token = JwtUtil.getAccessToken(request); // 记录当前登录用户id User loginUser = getLoginUser(); @@ -253,7 +252,7 @@ public class OrderController extends BaseController { goods.setExpirationTime(order.getExpirationTime()); orderGoods.add(goods); }); - System.out.println("carts = " + carts); +// System.out.println("carts = " + carts); order.setGoodsList(orderGoods); } orderGoodsService.saveBatch(order.getGoodsList()); diff --git a/src/main/java/com/gxwebsoft/shop/controller/WxPayNotifyController.java b/src/main/java/com/gxwebsoft/shop/controller/WxPayNotifyController.java index f58c064..950dd31 100644 --- a/src/main/java/com/gxwebsoft/shop/controller/WxPayNotifyController.java +++ b/src/main/java/com/gxwebsoft/shop/controller/WxPayNotifyController.java @@ -82,6 +82,9 @@ public class WxPayNotifyController extends BaseController { .body(body) .build(); + System.out.println("payment = " + payment); + System.out.println("requestParam = " + requestParam); + // 如果已经初始化了 RSAAutoCertificateConfig,可直接使用 // 没有的话,则构造一个 NotificationConfig config = new RSANotificationConfig.Builder() diff --git a/src/main/java/com/gxwebsoft/shop/controller/WxPayNotifyNbgController.java b/src/main/java/com/gxwebsoft/shop/controller/WxPayNotifyNbgController.java new file mode 100644 index 0000000..4687021 --- /dev/null +++ b/src/main/java/com/gxwebsoft/shop/controller/WxPayNotifyNbgController.java @@ -0,0 +1,103 @@ +package com.gxwebsoft.shop.controller; + +import cn.hutool.core.date.DateField; +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.NumberUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import com.gxwebsoft.common.core.utils.RedisUtil; +import com.gxwebsoft.common.core.web.BaseController; +import com.gxwebsoft.shop.entity.Goods; +import com.gxwebsoft.shop.entity.Order; +import com.gxwebsoft.shop.entity.OrderGoods; +import com.gxwebsoft.shop.entity.OrderInfo; +import com.gxwebsoft.shop.service.*; +import com.wechat.pay.java.service.partnerpayments.jsapi.model.Transaction; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiModelProperty; +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.annotation.Resource; +import java.math.BigDecimal; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +/** + * 会员特权购买记录表控制器 + * + * @author 科技小王子 + * @since 2023-06-20 18:07:50 + */ +@Api(tags = "微信支付结果通知") +@RestController +@RequestMapping("/api/shop/wx-pay/nbg") +public class WxPayNotifyNbgController extends BaseController { + @Resource + private OrderService orderService; + @Resource + private OrderInfoService orderInfoService; + @Resource + private OrderGoodsService orderGoodsService; + @Resource + private GoodsService goodsService; + @Resource + private UsersService usersService; + + @Resource + private RedisUtil redisUtil; + + @ApiModelProperty("微信支付通知") + @PostMapping("/notify") + public String demo(@RequestBody Transaction transaction){ + + System.out.println("支付通知 >>>>> "); + System.out.println("transaction = " + transaction); + + // TODO 1.查询订单信息 + final Order order = orderService.getByOutTradeNo(transaction.getOutTradeNo()); + // TODO 2.更新订单支付状态 + order.setPayStatus(1); + order.setTransactionId(transaction.getTransactionId()); + order.setPayPrice(new BigDecimal(NumberUtil.decimalFormat("0.00", transaction.getAmount().getTotal() * 0.01))); + order.setPayTime(DateUtil.date()); + order.setExpirationTime(DateUtil.offset(DateUtil.date(), DateField.YEAR, 10)); + orderService.updateById(order); + // TODO 3.更新订单商品的支付状态 + if (order.getType().equals(0)) { + final boolean update = orderGoodsService.update(new LambdaUpdateWrapper().eq(OrderGoods::getOrderId, order.getOrderId()).set(OrderGoods::getPayStatus, 1)); + System.out.println("update1 = " + update); + // TODO 3.1 更新商品销量、库存数量 + final List orderGoods = orderGoodsService.list(new LambdaQueryWrapper().eq(OrderGoods::getOrderId, order.getOrderId())); + final Set goodsIds = orderGoods.stream().map(OrderGoods::getGoodsId).collect(Collectors.toSet()); + final Map> collectGoods = orderGoods.stream().collect(Collectors.groupingBy(OrderGoods::getGoodsId)); + final List goods = goodsService.list(new LambdaQueryWrapper().in(Goods::getGoodsId, goodsIds)); + for (Goods g : goods) { + final List goods1 = collectGoods.get(g.getGoodsId()); + final OrderGoods goods2 = goods1.get(0); + g.setSales(g.getSales() + goods2.getTotalNum()); + if (g.getStock().compareTo(0) >= 0) { + g.setStock(g.getStock() - goods2.getTotalNum()); + } + + } + final boolean batchById = goodsService.updateBatchById(goods); + System.out.println("batchById = " + batchById); + } + if (order.getType().equals(1)) { + final boolean update = orderInfoService.update(new LambdaUpdateWrapper().eq(OrderInfo::getOrderId, order.getOrderId()).set(OrderInfo::getPayStatus, 1)); + System.out.println("update2 = " + update); + // TODO 3.2 更新订单类型为预定的关联订单信息 + } + + + // TODO 5.累计会员积分 + + return "订单已支付"; + } + +} diff --git a/src/main/java/com/gxwebsoft/shop/service/OrderService.java b/src/main/java/com/gxwebsoft/shop/service/OrderService.java index c14ad32..ee8ba89 100644 --- a/src/main/java/com/gxwebsoft/shop/service/OrderService.java +++ b/src/main/java/com/gxwebsoft/shop/service/OrderService.java @@ -45,7 +45,7 @@ public interface OrderService extends IService { Order getByOutTradeNo(String outTradeNo); - void updateByOutTradeNo(Order order); + Boolean updateByOutTradeNo(Order order); Boolean payByBalance(Order order); diff --git a/src/main/java/com/gxwebsoft/shop/service/impl/OrderServiceImpl.java b/src/main/java/com/gxwebsoft/shop/service/impl/OrderServiceImpl.java index 2883a32..7d239f0 100644 --- a/src/main/java/com/gxwebsoft/shop/service/impl/OrderServiceImpl.java +++ b/src/main/java/com/gxwebsoft/shop/service/impl/OrderServiceImpl.java @@ -79,9 +79,13 @@ public class OrderServiceImpl extends ServiceImpl implements private SettingService settingService; @Resource private RedisUtil redisUtil; - public static String privateKeyPath = "/Users/gxwebsoft/JAVA/com.gxwebsoft.modules/src/main/resources/cert/apiclient_key.pem"; +// public static String privateKeyPath = "/Users/gxwebsoft/JAVA/com.gxwebsoft.modules/src/main/resources/cert/apiclient_key.pem"; +// public static String privateCertPath = "/Users/gxwebsoft/JAVA/com.gxwebsoft.core/src/main/resources/cert/apiclient_cert.pem"; +// public static String wechatpayCertPath = "/Users/gxwebsoft/JAVA/com.gxwebsoft.modules/src/main/resources/cert/wechatpay_2DD5A0669263BAE55E52BF3F35BF4A4006A2DAA6.pem"; // 平台证书 + + public static String privateKeyPath = "/Users/gxwebsoft/Downloads/ef7f7e0430cb47019d06b93f885bf95f/apiclient_key.pem"; public static String privateCertPath = "/Users/gxwebsoft/JAVA/com.gxwebsoft.core/src/main/resources/cert/apiclient_cert.pem"; - public static String wechatpayCertPath = "/Users/gxwebsoft/JAVA/com.gxwebsoft.modules/src/main/resources/cert/wechatpay_2DD5A0669263BAE55E52BF3F35BF4A4006A2DAA6.pem"; // 平台证书 + public static String wechatpayCertPath = "/Users/gxwebsoft/Downloads/ef7f7e0430cb47019d06b93f885bf95f/wechatpay_55729BDEC2502C301BA02CDC28E4CEE4DE4D1DB9.pem"; // 平台证书 @Override @@ -178,12 +182,12 @@ public class OrderServiceImpl extends ServiceImpl implements // 微信小程序(微信支付) String key = "mp-weixin:".concat(order.getTenantId().toString()); final String string = redisUtil.get(key); - System.out.println("string = " + string); +// System.out.println("string = " + string); final JSONObject mpWx = JSONObject.parseObject(string); - System.out.println("mpWx = " + mpWx); +// System.out.println("mpWx = " + mpWx); String key2 = "Payment:".concat(order.getPayType().toString()).concat(":").concat(order.getTenantId().toString()); final Payment payment = redisUtil.get(key2, Payment.class); - System.out.println("payment = " + payment); +// System.out.println("payment = " + payment); // 计算金额 BigDecimal decimal = order.getTotalPrice(); @@ -231,12 +235,12 @@ public class OrderServiceImpl extends ServiceImpl implements if (active.equals("prod")) { amount.setTotal(2); request.setAmount(amount); - request.setNotifyUrl("https://modules.gxwebsoft.com/api/shop/wx-pay/notify/" + order.getTenantId()); // 默认回调地址 + request.setNotifyUrl("https://server.gxwebsoft.com/api/system/wx-pay/notify/" + order.getTenantId()); // 默认回调地址 } - if (StrUtil.isNotBlank(payment.getNotifyUrl())) { +// if (StrUtil.isNotBlank(payment.getNotifyUrl())) { // 后台配置的回调地址 - request.setNotifyUrl(payment.getNotifyUrl().concat("/").concat(order.getTenantId().toString())); - } +// request.setNotifyUrl(payment.getNotifyUrl().concat("/").concat(order.getTenantId().toString())); +// } System.out.println("request = " + request); PrepayWithRequestPaymentResponse response = service.prepayWithRequestPayment(request); orderInfo.put("provider", "wxpay"); @@ -258,8 +262,9 @@ public class OrderServiceImpl extends ServiceImpl implements } @Override - public void updateByOutTradeNo(Order order) { + public Boolean updateByOutTradeNo(Order order) { baseMapper.updateByOutTradeNo(order); + return true; } @Override diff --git a/src/main/java/com/gxwebsoft/shop/task/OrderInfoTask.java b/src/main/java/com/gxwebsoft/shop/task/OrderInfoTask.java deleted file mode 100644 index 02983b6..0000000 --- a/src/main/java/com/gxwebsoft/shop/task/OrderInfoTask.java +++ /dev/null @@ -1,75 +0,0 @@ -package com.gxwebsoft.shop.task; - -import cn.hutool.core.date.DateUtil; -import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; -import com.gxwebsoft.common.core.web.BaseController; -import com.gxwebsoft.shop.entity.Order; -import com.gxwebsoft.shop.entity.OrderInfo; -import com.gxwebsoft.shop.service.OrderInfoService; -import com.gxwebsoft.shop.service.OrderService; -import io.swagger.annotations.Api; -import org.springframework.scheduling.annotation.Scheduled; -import org.springframework.transaction.annotation.Transactional; -import org.springframework.util.CollectionUtils; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -import javax.annotation.Resource; -import java.util.List; - -/** - * 订单结算任务 - * - * @author 科技小王子 - * @since 2024-05-14 13:20:04 - */ -@Api(tags = "订单结算任务") -@RestController -@RequestMapping("/api/shop/order-info") -public class OrderInfoTask extends BaseController { - @Resource - private OrderService orderService; - @Resource - private OrderInfoService orderInfoService; - /** - * 自动处理过期订单任务 - */ -// @Scheduled(cron="*/10 * * * * *") - @Transactional(rollbackFor = {Exception.class}) - public void settledExpirationOrder() { - final Order order = new Order(); - final int hour = DateUtil.hour(DateUtil.date(), true); - final int minute = DateUtil.minute(DateUtil.date()); - final int second = DateUtil.second(DateUtil.date()); - final String startTime = String.format("%02d", hour).concat(":").concat(String.format("%02d", minute)).concat(":").concat(String.format("%02d", second)); - final List list = orderInfoService.list(new LambdaQueryWrapper().eq(OrderInfo::getOrderStatus, 0).ne(OrderInfo::getMerchantId,3028).eq(OrderInfo::getDateTime,DateUtil.today()).lt(OrderInfo::getStartTime,startTime)); - list.forEach(d -> { - d.setOrderStatus(1); - order.setOrderId(d.getOrderId()); - }); - orderInfoService.updateBatchById(list); - order.setOrderStatus(1); - orderService.updateById(order); - System.out.println("自动核销订单 = " + list.size()); - } - - /** - * 自动处理过期订单任务(游泳馆专用) - * Scheduled(cron="0 30 21 * * ?") - */ -// @Scheduled(cron="*/30 * * * * *") - @Transactional(rollbackFor = {Exception.class}) - public void settledExpirationOrderBy3028() { - final Order order = new Order(); - final List list = orderInfoService.list(new LambdaQueryWrapper().eq(OrderInfo::getTenantId,10150).eq(OrderInfo::getOrderStatus, 0).eq(OrderInfo::getMerchantId,3028).eq(OrderInfo::getDateTime,DateUtil.today()).lt(OrderInfo::getStartTime,"21:30:00")); - list.forEach(d -> { - d.setOrderStatus(1); - order.setOrderId(d.getOrderId()); - }); - orderInfoService.updateBatchById(list); - if(!CollectionUtils.isEmpty(list)){ - orderService.updateById(order); - } - System.out.println("自动核销订单(游泳馆) = " + list.size()); - } -} diff --git a/src/main/java/com/gxwebsoft/shop/task/OrderTask.java b/src/main/java/com/gxwebsoft/shop/task/OrderTask.java index 941c64e..65bc33d 100644 --- a/src/main/java/com/gxwebsoft/shop/task/OrderTask.java +++ b/src/main/java/com/gxwebsoft/shop/task/OrderTask.java @@ -1,12 +1,16 @@ package com.gxwebsoft.shop.task; import cn.hutool.core.date.DateUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.gxwebsoft.common.core.web.BaseController; import com.gxwebsoft.shop.entity.Order; +import com.gxwebsoft.shop.entity.OrderInfo; import com.gxwebsoft.shop.mapper.OrderMapper; import com.gxwebsoft.shop.param.OrderParam; +import com.gxwebsoft.shop.service.OrderInfoService; import com.gxwebsoft.shop.service.OrderService; import io.swagger.annotations.Api; +import org.springframework.beans.factory.annotation.Value; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.CollectionUtils; @@ -26,16 +30,39 @@ import java.util.List; @RestController @RequestMapping("/api/shop/order") public class OrderTask extends BaseController { + @Value("${spring.profiles.active}") + String active; @Resource private OrderService orderService; @Resource private OrderMapper orderMapper; + @Resource + private OrderInfoService orderInfoService; + + /** - * 自动处理过期订单任务 + * 订单任务列表 */ - @Scheduled(fixedDelay = 2000, initialDelay = 2000) - @Transactional(rollbackFor = {Exception.class}) + @Scheduled(cron = "*/10 * * * * *") + public void orderTask() { + // 自动处理过期的预定订单 +// this.settledExpirationOrder(); + } + + /** + * 自动核销订单 + */ + @Scheduled(cron = "*/30 * * * * *") + public void writeOff() { + // 自动核销订单 +// this.orderWriteOff(); + } + + // 自动处理过期订单任务 public void settledExpirationOrder() { + if (active.equals("dev")) { + return; + } final OrderParam p = new OrderParam(); p.setOrderStatus(0); p.setExpirationTime(DateUtil.date()); @@ -49,4 +76,43 @@ public class OrderTask extends BaseController { System.out.println("自动处理过期订单 = " + list.size()); } } + + public void settledExpirationOrderBy3028() { + if (active.equals("dev")) { + return; + } + final Order order = new Order(); + final List list = orderInfoService.list(new LambdaQueryWrapper().eq(OrderInfo::getTenantId, 10150).eq(OrderInfo::getOrderStatus, 0).eq(OrderInfo::getMerchantId, 3028).eq(OrderInfo::getDateTime, DateUtil.today()).lt(OrderInfo::getStartTime, "21:30:00")); + list.forEach(d -> { + d.setOrderStatus(1); + order.setOrderId(d.getOrderId()); + }); + orderInfoService.updateBatchById(list); + if (!CollectionUtils.isEmpty(list)) { + orderService.updateById(order); + } + System.out.println("自动核销订单(游泳馆) = " + list.size()); + } + + // 自动核销订单 + public void orderWriteOff() { + if (active.equals("dev")) { + return; + } + final Order order = new Order(); + final int hour = DateUtil.hour(DateUtil.date(), true); + final int minute = DateUtil.minute(DateUtil.date()); + final int second = DateUtil.second(DateUtil.date()); + final String startTime = String.format("%02d", hour).concat(":").concat(String.format("%02d", minute)).concat(":").concat(String.format("%02d", second)); + final List list = orderInfoService.list(new LambdaQueryWrapper().eq(OrderInfo::getOrderStatus, 0).ne(OrderInfo::getMerchantId, 3028).eq(OrderInfo::getDateTime, DateUtil.today()).lt(OrderInfo::getStartTime, startTime)); + list.forEach(d -> { + d.setOrderStatus(1); + order.setOrderId(d.getOrderId()); + }); + orderInfoService.updateBatchById(list); + order.setOrderStatus(1); + orderService.updateById(order); + System.out.println("自动核销订单 = " + list.size()); + } + }