From 08ce525c94bb0ea1a289b4667e172cd53135b048 Mon Sep 17 00:00:00 2001 From: gxwebsoft Date: Tue, 14 May 2024 13:10:42 +0800 Subject: [PATCH] =?UTF-8?q?=E9=87=8D=E6=9E=84=E8=AE=A2=E5=8D=95=E8=A1=A8?= =?UTF-8?q?=E5=89=8D=E5=A4=87=E4=BB=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/gxwebsoft/booking/entity/Field.java | 9 ++ .../gxwebsoft/booking/param/FieldParam.java | 4 + .../service/impl/FieldServiceImpl.java | 38 ++++- .../cms/controller/WebsiteController.java | 8 +- .../com/gxwebsoft/cms/entity/Website.java | 2 +- .../com/gxwebsoft/cms/param/WebsiteParam.java | 2 +- .../common/core/security/SecurityConfig.java | 2 + .../shop/controller/OrderController.java | 42 ++++-- .../shop/controller/OrderInfoController.java | 10 +- .../controller/WxPayNotifyController.java | 132 ++++++++++++++++++ .../java/com/gxwebsoft/shop/entity/Order.java | 9 +- .../com/gxwebsoft/shop/entity/OrderInfo.java | 43 ++++-- .../com/gxwebsoft/shop/entity/Payment.java | 87 ++++++++++++ .../shop/mapper/OrderInfoMapper.java | 2 +- .../gxwebsoft/shop/mapper/OrderMapper.java | 7 + .../shop/mapper/xml/OrderInfoMapper.xml | 16 ++- .../gxwebsoft/shop/mapper/xml/OrderMapper.xml | 10 ++ .../gxwebsoft/shop/param/OrderInfoParam.java | 32 ++--- .../shop/service/OrderInfoService.java | 2 +- .../gxwebsoft/shop/service/OrderService.java | 4 + .../service/impl/OrderInfoServiceImpl.java | 2 +- .../shop/service/impl/OrderServiceImpl.java | 83 +++++++---- .../com/gxwebsoft/generator/CmsGenerator.java | 2 +- .../gxwebsoft/generator/ShopGenerator.java | 4 +- 24 files changed, 460 insertions(+), 92 deletions(-) create mode 100644 src/main/java/com/gxwebsoft/shop/controller/WxPayNotifyController.java create mode 100644 src/main/java/com/gxwebsoft/shop/entity/Payment.java diff --git a/src/main/java/com/gxwebsoft/booking/entity/Field.java b/src/main/java/com/gxwebsoft/booking/entity/Field.java index aa360e3..2b9e46f 100644 --- a/src/main/java/com/gxwebsoft/booking/entity/Field.java +++ b/src/main/java/com/gxwebsoft/booking/entity/Field.java @@ -1,5 +1,6 @@ package com.gxwebsoft.booking.entity; +import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; @@ -70,4 +71,12 @@ public class Field implements Serializable { @ApiModelProperty(value = "创建时间") private Date createTime; + @ApiModelProperty(value = "是否被占用") + @TableField(exist = false) + private Boolean isOccupied; + + @ApiModelProperty(value = "1全场,2半场") + @TableField(exist = false) + private Integer type; + } diff --git a/src/main/java/com/gxwebsoft/booking/param/FieldParam.java b/src/main/java/com/gxwebsoft/booking/param/FieldParam.java index 964186f..9b59182 100644 --- a/src/main/java/com/gxwebsoft/booking/param/FieldParam.java +++ b/src/main/java/com/gxwebsoft/booking/param/FieldParam.java @@ -72,4 +72,8 @@ public class FieldParam extends BaseParam { @QueryField(type = QueryType.EQ) private Integer sortNumber; + @ApiModelProperty(value = "按日期查询") + @QueryField(type = QueryType.EQ) + private String dateTime; + } diff --git a/src/main/java/com/gxwebsoft/booking/service/impl/FieldServiceImpl.java b/src/main/java/com/gxwebsoft/booking/service/impl/FieldServiceImpl.java index ec6b75f..6427f8e 100644 --- a/src/main/java/com/gxwebsoft/booking/service/impl/FieldServiceImpl.java +++ b/src/main/java/com/gxwebsoft/booking/service/impl/FieldServiceImpl.java @@ -1,15 +1,25 @@ package com.gxwebsoft.booking.service.impl; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; -import com.gxwebsoft.booking.mapper.FieldMapper; -import com.gxwebsoft.booking.service.FieldService; import com.gxwebsoft.booking.entity.Field; +import com.gxwebsoft.booking.mapper.FieldMapper; import com.gxwebsoft.booking.param.FieldParam; +import com.gxwebsoft.booking.service.FieldService; import com.gxwebsoft.common.core.web.PageParam; import com.gxwebsoft.common.core.web.PageResult; +import com.gxwebsoft.shop.entity.OrderInfo; +import com.gxwebsoft.shop.service.OrderInfoService; import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; +import javax.annotation.Resource; import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +import static com.gxwebsoft.common.core.constants.OrderConstants.PAY_STATUS_SUCCESS; /** * 场馆场地Service实现 @@ -20,6 +30,9 @@ import java.util.List; @Service public class FieldServiceImpl extends ServiceImpl implements FieldService { + @Resource + private OrderInfoService orderInfoService; + @Override public PageResult pageRel(FieldParam param) { PageParam page = new PageParam<>(param); @@ -34,6 +47,27 @@ public class FieldServiceImpl extends ServiceImpl implements // 排序 PageParam page = new PageParam<>(); page.setDefaultOrder("sort_number desc, create_time desc"); + // 是否已被预定 + if (param.getDateTime() != null) { + System.out.println("是否已被预定 = "); + System.out.println("param = " + param); + final List orderInfoList = orderInfoService.list(new LambdaQueryWrapper().eq(OrderInfo::getOrderTime, param.getDateTime()).eq(OrderInfo::getPayStatus,1).or().eq(OrderInfo::getPayStatus,3)); + System.out.println("orderInfoList = " + orderInfoList); + if (!CollectionUtils.isEmpty(orderInfoList)) { + Map> collect = orderInfoList.stream().collect(Collectors.groupingBy(OrderInfo::getFid)); + System.out.println("collect = " + collect); + for (Field item: list){ + System.out.println("item = " + item); + System.out.println("collect.get(item.getFieldId()) = " + collect.get(item.getFieldId())); + final List orderInfos = collect.get(item.getFieldId()); + if (!CollectionUtils.isEmpty(orderInfos)) { + item.setIsOccupied(true); + OrderInfo orderInfo = orderInfos.get(0); + item.setType(orderInfo.getType()); + } + } + } + } return page.sortRecords(list); } diff --git a/src/main/java/com/gxwebsoft/cms/controller/WebsiteController.java b/src/main/java/com/gxwebsoft/cms/controller/WebsiteController.java index 8736a2a..bee38e1 100644 --- a/src/main/java/com/gxwebsoft/cms/controller/WebsiteController.java +++ b/src/main/java/com/gxwebsoft/cms/controller/WebsiteController.java @@ -85,9 +85,11 @@ public class WebsiteController extends BaseController { final String siteInfo = redisUtil.get(key); String access_token = JwtUtil.getAccessToken(request); System.out.println("access_token = " + access_token); - redisUtil.set("Domain:ffai.cn",10157); - redisUtil.set("Domain:www.xn--15qx69a6lbn8t0tlmve.com",10157); - redisUtil.set("Domain:xn--15qx69a6lbn8t0tlmve.com",10157); +// redisUtil.set("Domain:ffai.cn",10157); +// redisUtil.set("Domain:www.xn--15qx69a6lbn8t0tlmve.com",10157); +// redisUtil.set("Domain:xn--15qx69a6lbn8t0tlmve.com",10157); +// redisUtil.set("Domain:oa.gxwebsoft.com",5); +// redisUtil.set("Domain:gxwebsoft.com",5); // 从缓存读取信息 if(StrUtil.isNotBlank(siteInfo)){ return success(JSONObject.parseObject(siteInfo,Website.class)); diff --git a/src/main/java/com/gxwebsoft/cms/entity/Website.java b/src/main/java/com/gxwebsoft/cms/entity/Website.java index a605d89..9d4a80b 100644 --- a/src/main/java/com/gxwebsoft/cms/entity/Website.java +++ b/src/main/java/com/gxwebsoft/cms/entity/Website.java @@ -112,7 +112,7 @@ public class Website implements Serializable { private Integer recommend; @ApiModelProperty(value = "状态") - private Integer status; + private Boolean status; @ApiModelProperty(value = "排序号") private Integer sortNumber; diff --git a/src/main/java/com/gxwebsoft/cms/param/WebsiteParam.java b/src/main/java/com/gxwebsoft/cms/param/WebsiteParam.java index d579818..8e1e66e 100644 --- a/src/main/java/com/gxwebsoft/cms/param/WebsiteParam.java +++ b/src/main/java/com/gxwebsoft/cms/param/WebsiteParam.java @@ -91,7 +91,7 @@ public class WebsiteParam extends BaseParam { @ApiModelProperty(value = "状态") @QueryField(type = QueryType.EQ) - private Integer status; + private Boolean status; @ApiModelProperty(value = "排序号") @QueryField(type = QueryType.EQ) 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 a81613d..5d42e0d 100644 --- a/src/main/java/com/gxwebsoft/common/core/security/SecurityConfig.java +++ b/src/main/java/com/gxwebsoft/common/core/security/SecurityConfig.java @@ -57,6 +57,8 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter { "/api/shop/payment/mp-alipay/getPhoneNumber", "/api/shop/test/**", "/api/shop/wx-login/**", + "/api/shop/wx-native-pay/**", + "/api/shop/wx-pay/**", "/api/apps/hualala/**", "/api/apps/hualala-cart/**", "/api/apps/test-data/**", diff --git a/src/main/java/com/gxwebsoft/shop/controller/OrderController.java b/src/main/java/com/gxwebsoft/shop/controller/OrderController.java index 50f792b..19acb05 100644 --- a/src/main/java/com/gxwebsoft/shop/controller/OrderController.java +++ b/src/main/java/com/gxwebsoft/shop/controller/OrderController.java @@ -3,6 +3,7 @@ package com.gxwebsoft.shop.controller; import cn.hutool.core.date.DateTime; import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.IdUtil; +import cn.hutool.core.util.StrUtil; import com.alibaba.fastjson.JSONObject; import com.gxwebsoft.common.core.web.BaseController; import com.gxwebsoft.shop.entity.OrderInfo; @@ -30,8 +31,11 @@ import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; import java.math.BigDecimal; +import java.util.Collections; +import java.util.Date; import java.util.HashMap; import java.util.List; +import java.util.stream.Collectors; /** * 预约订单控制器 @@ -71,29 +75,49 @@ public class OrderController extends BaseController { return success(orderService.getByIdRel(id)); } - @ApiOperation("添加预约订单") + @PreAuthorize("hasAuthority('sys:order:save')") + @ApiOperation("下单") @PostMapping() public ApiResult save(@RequestBody Order order) { // 记录当前登录用户id User loginUser = getLoginUser(); + if (loginUser == null) { + return fail("请先登录"); + } + // 微信openid(必填) + if(StrUtil.isBlank(loginUser.getOpenid())){ + return fail("微信openid(必填)"); + } + // 商品描述(必填) + if(StrUtil.isBlank(order.getComments())){ + return fail("商品描述(必填)"); + } + // 微信支付(商品金额不能为0) + if(order.getPayType().equals(1)){ + if (order.getTotalPrice().compareTo(BigDecimal.ZERO) == 0) { + return fail("商品金额不能为0"); + } + } + + // 订单信息 long timeMillis = System.currentTimeMillis(); long orderNo = IdUtil.getSnowflakeNextId(); - if (loginUser != null) { - order.setUserId(loginUser.getUserId()); - order.setOpenid(loginUser.getOpenid()); - } order.setOrderNo(Long.toString(orderNo)); - order.setName(loginUser.getRealName()); - order.setStartTime(timeMillis / 1000); - order.setAddTime(timeMillis / 1000); + order.setUserId(loginUser.getUserId()); + order.setOpenid(loginUser.getOpenid()); + order.setRealName(loginUser.getRealName()); order.setPhone(loginUser.getPhone()); + order.setUserId(loginUser.getUserId()); +// List collect = order.getOrderInfoList().stream().map(OrderInfo::getStartTime).collect(Collectors.toList()); + OrderInfo orderInfo = order.getOrderInfoList().get(0); + order.setStartTime(DateUtil.formatTime(orderInfo.getStartTime())); order.setVersion(10); if (orderService.save(order)) { order.getOrderInfoList().forEach(d -> { d.setOid(order.getOrderId()); d.setTimeFlag(timeMillis); d.setVersion(10); - d.setOrderTime(timeMillis / 1000); + d.setOrderTime(d.getOrderTime()); }); orderInfoService.saveBatch(order.getOrderInfoList()); // 创建微信订单 diff --git a/src/main/java/com/gxwebsoft/shop/controller/OrderInfoController.java b/src/main/java/com/gxwebsoft/shop/controller/OrderInfoController.java index e5007d2..1972e85 100644 --- a/src/main/java/com/gxwebsoft/shop/controller/OrderInfoController.java +++ b/src/main/java/com/gxwebsoft/shop/controller/OrderInfoController.java @@ -22,7 +22,7 @@ import java.util.List; * 控制器 * * @author 科技小王子 - * @since 2024-05-03 11:14:47 + * @since 2024-05-13 19:50:43 */ @Api(tags = "管理") @RestController @@ -57,10 +57,10 @@ public class OrderInfoController extends BaseController { @PostMapping() public ApiResult save(@RequestBody OrderInfo orderInfo) { // 记录当前登录用户id - // User loginUser = getLoginUser(); - // if (loginUser != null) { - // orderInfo.setUserId(loginUser.getUserId()); - // } + User loginUser = getLoginUser(); + if (loginUser != null) { + orderInfo.setUserId(loginUser.getUserId()); + } if (orderInfoService.save(orderInfo)) { return success("添加成功"); } diff --git a/src/main/java/com/gxwebsoft/shop/controller/WxPayNotifyController.java b/src/main/java/com/gxwebsoft/shop/controller/WxPayNotifyController.java new file mode 100644 index 0000000..4af6c67 --- /dev/null +++ b/src/main/java/com/gxwebsoft/shop/controller/WxPayNotifyController.java @@ -0,0 +1,132 @@ +package com.gxwebsoft.shop.controller; + +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.StrUtil; +import com.gxwebsoft.common.core.config.ConfigProperties; +import com.gxwebsoft.common.core.utils.RedisUtil; +import com.gxwebsoft.common.core.web.BaseController; +import com.gxwebsoft.shop.entity.Order; +import com.gxwebsoft.shop.entity.Payment; +import com.gxwebsoft.shop.service.OrderService; +import com.wechat.pay.java.core.notification.NotificationConfig; +import com.wechat.pay.java.core.notification.NotificationParser; +import com.wechat.pay.java.core.notification.RSANotificationConfig; +import com.wechat.pay.java.service.partnerpayments.jsapi.model.Transaction; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiModelProperty; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import java.math.BigDecimal; +import java.text.DecimalFormat; +import java.util.Map; + +import static com.gxwebsoft.common.core.constants.OrderConstants.PAY_STATUS_NO_PAY; +import static com.gxwebsoft.common.core.constants.OrderConstants.PAY_STATUS_SUCCESS; + +/** + * 会员特权购买记录表控制器 + * + * @author 科技小王子 + * @since 2023-06-20 18:07:50 + */ +@Api(tags = "微信支付结果通知") +@RestController +@RequestMapping("/api/shop/wx-pay") +public class WxPayNotifyController extends BaseController { + @Value("${spring.profiles.active}") + String active; + @Resource + private OrderService orderService; + @Resource + private RedisUtil redisUtil; + @Resource + private ConfigProperties conf; + // 本地证书 + public static String wechatpayCertPath = "/Users/gxwebsoft/JAVA/com.gxwebsoft.core/src/main/resources/cert/wechatpay_4A3231584E93B6AE77820074D07EADEACCB7E223.pem"; // 平台证书 + + @ApiModelProperty("异步通知") + @PostMapping("/notify/{tenantId}") + public String wxNotify(@RequestHeader Map header, @RequestBody String body, @PathVariable("tenantId") Integer tenantId) { + System.out.println("异步通知*************** = "); +// System.out.println("request header = " + header); +// System.out.println("request body = " + body); +// System.out.println("tenantId = " + tenantId); + + // 获取支付配置信息用于解密 + String key = "Payment:wxPay:".concat(tenantId.toString()); + final Payment payment = redisUtil.get(key, Payment.class); + String privateKey = payment.getApiKey(); + String apiclientCert = conf.getUploadPath().concat("/file").concat(payment.getApiclientCert()); + // 开发环境配置 + if(active.equals("dev")){ + apiclientCert = wechatpayCertPath; + } + + com.wechat.pay.java.core.notification.RequestParam requestParam = new com.wechat.pay.java.core.notification.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(); + + // 如果已经初始化了 RSAAutoCertificateConfig,可直接使用 + // 没有的话,则构造一个 + NotificationConfig config = new RSANotificationConfig.Builder() + .apiV3Key(privateKey) + .certificatesFromPath(apiclientCert) + .build(); + + + // 初始化 NotificationParser + NotificationParser parser = new NotificationParser(config); + + // 以支付通知回调为例,验签、解密并转换成 Transaction + try { + Transaction transaction = parser.parse(requestParam, Transaction.class); + 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); + + if (StrUtil.equals("支付成功", tradeStateDesc)) { + // 1. 查询要处理的订单 + Order order = orderService.getByOutTradeNo(outTradeNo); + System.out.println("order = " + order); + // 2. 已支付则跳过 + if (order.getPayStatus().equals(PAY_STATUS_SUCCESS)) { + return "SUCCESS"; + } + // 2. 未支付则处理更新订单状态 + if (order.getPayStatus().equals(PAY_STATUS_NO_PAY)) { + // 5. TODO 处理订单状态 + order.setPayTime(DateUtil.date()); + order.setPayStatus(PAY_STATUS_SUCCESS); + order.setTransactionId(transactionId); + // 实际付款金额:Integer除以100后转BigDecimal + DecimalFormat df = new DecimalFormat("0.00"); + final String format = df.format(total / 100); + order.setPayPrice(new BigDecimal(format)); + orderService.updateByOutTradeNo(order); + return "SUCCESS"; + } + } + } catch (Exception $e) { + System.out.println($e.getMessage()); + } + + return "fail"; + } + + +} diff --git a/src/main/java/com/gxwebsoft/shop/entity/Order.java b/src/main/java/com/gxwebsoft/shop/entity/Order.java index a79b3ba..3fb78a3 100644 --- a/src/main/java/com/gxwebsoft/shop/entity/Order.java +++ b/src/main/java/com/gxwebsoft/shop/entity/Order.java @@ -61,7 +61,7 @@ public class Order implements Serializable { private String code; @ApiModelProperty(value = "真实姓名") - private String name; + private String realName; @ApiModelProperty(value = "手机号码") private String phone; @@ -90,6 +90,9 @@ public class Order implements Serializable { @ApiModelProperty(value = "教练id") private Integer coachId; + @ApiModelProperty(value = "支付流水号") + private String transactionId; + @ApiModelProperty(value = "1微信支付,2积分,3支付宝,4现金,5POS机,6VIP月卡,7VIP年卡,8VIP次卡,9IC月卡,10IC年卡,11IC次卡,12免费,13VIP充值卡,14IC充值卡,15积分支付,16VIP季卡,17IC季卡") private Integer payType; @@ -115,7 +118,7 @@ public class Order implements Serializable { private BigDecimal returnMoney; @ApiModelProperty(value = "预约详情开始时间数组") - private Long startTime; + private String startTime; @ApiModelProperty(value = "是否已开具发票:1已开发票,2未开发票,3不能开具发票") private Integer isInvoice; @@ -126,7 +129,7 @@ public class Order implements Serializable { private Integer updateTime; @ApiModelProperty(value = "付款时间") - private Integer payTime; + private Date payTime; @ApiModelProperty(value = "退款时间") private Integer refundTime; diff --git a/src/main/java/com/gxwebsoft/shop/entity/OrderInfo.java b/src/main/java/com/gxwebsoft/shop/entity/OrderInfo.java index e0975f4..2e39707 100644 --- a/src/main/java/com/gxwebsoft/shop/entity/OrderInfo.java +++ b/src/main/java/com/gxwebsoft/shop/entity/OrderInfo.java @@ -1,10 +1,15 @@ package com.gxwebsoft.shop.entity; import java.math.BigDecimal; + +import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; +import java.time.LocalDateTime; import java.io.Serializable; +import java.util.Date; + import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; @@ -14,7 +19,7 @@ import lombok.EqualsAndHashCode; * * * @author 科技小王子 - * @since 2024-05-03 11:14:47 + * @since 2024-05-13 19:50:43 */ @Data @EqualsAndHashCode(callSuper = false) @@ -35,14 +40,11 @@ public class OrderInfo implements Serializable { @ApiModelProperty(value = "关联场地id") private Integer fid; - @ApiModelProperty(value = "场馆") - private String siteName; - @ApiModelProperty(value = "场地") private String fieldName; @ApiModelProperty(value = "预约时间段") - private String dateTime; + private String timePeriod; @ApiModelProperty(value = "单价") private BigDecimal price; @@ -51,39 +53,50 @@ public class OrderInfo implements Serializable { private BigDecimal childrenPrice; @ApiModelProperty(value = "成人人数") - private Boolean adultNum; + private Integer adultNum; @ApiModelProperty(value = "儿童人数") - private Boolean childrenNum; + private Integer childrenNum; @ApiModelProperty(value = "1已付款,2未付款,3无需付款或占用状态") - private Boolean payStatus; + private Integer payStatus; @ApiModelProperty(value = "是否免费:1免费、2收费") - private Boolean isFree; + private Integer isFree; @ApiModelProperty(value = "是否支持儿童票:1支持,2不支持") - private Boolean isChildren; + private Integer isChildren; + + @ApiModelProperty(value = "系统版本号 10新版 0旧版") + private Integer version; @ApiModelProperty(value = "预订类型:1全场,2半场") - private Boolean type; + private Integer type; @ApiModelProperty(value = "组合数据:日期+时间段+场馆id+场地id") private String mergeData; + @ApiModelProperty(value = "备注") + private String comments; + @ApiModelProperty(value = "开场时间") - private Long startTime; + private Date startTime; @ApiModelProperty(value = "下单时间") - private Long orderTime; + private Date orderTime; @ApiModelProperty(value = "毫秒时间戳") private Long timeFlag; - @ApiModelProperty(value = "系统版本") - private Integer version; + @ApiModelProperty(value = "用户id") + private Integer userId; @ApiModelProperty(value = "租户id") private Integer tenantId; + private Date updateTime; + + @ApiModelProperty(value = "创建时间") + private Date createTime; + } diff --git a/src/main/java/com/gxwebsoft/shop/entity/Payment.java b/src/main/java/com/gxwebsoft/shop/entity/Payment.java new file mode 100644 index 0000000..440a84a --- /dev/null +++ b/src/main/java/com/gxwebsoft/shop/entity/Payment.java @@ -0,0 +1,87 @@ +package com.gxwebsoft.shop.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableLogic; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.io.Serializable; +import java.util.Date; + +/** + * 支付方式 + * + * @author 科技小王子 + * @since 2024-05-11 12:39:11 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@ApiModel(value = "Payment对象", description = "支付方式") +@TableName("shop_payment") +public class Payment implements Serializable { + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "ID") + @TableId(value = "id", type = IdType.AUTO) + private Integer id; + + @ApiModelProperty(value = "支付方式") + private String name; + + @ApiModelProperty(value = "标识") + private String code; + + @ApiModelProperty(value = "支付图标") + private String image; + + @ApiModelProperty(value = "微信商户号类型 1普通商户2子商户") + private Integer wechatType; + + @ApiModelProperty(value = "应用ID") + private String appId; + + @ApiModelProperty(value = "商户号") + private String mchId; + + @ApiModelProperty(value = "设置APIv3密钥") + private String apiKey; + + @ApiModelProperty(value = "证书文件 (CERT)") + private String apiclientCert; + + @ApiModelProperty(value = "证书文件 (KEY)") + private String apiclientKey; + + @ApiModelProperty(value = "商户证书序列号") + private String merchantSerialNumber; + + @ApiModelProperty(value = "支付结果通知") + private String notifyUrl; + + @ApiModelProperty(value = "备注") + private String comments; + + @ApiModelProperty(value = "文章排序(数字越小越靠前)") + private Integer sortNumber; + + @ApiModelProperty(value = "状态, 0未启用, 1启用") + private Boolean status; + + @ApiModelProperty(value = "是否删除, 0否, 1是") + @TableLogic + private Integer deleted; + + @ApiModelProperty(value = "租户id") + private Integer tenantId; + + @ApiModelProperty(value = "注册时间") + private Date createTime; + + @ApiModelProperty(value = "修改时间") + private Date updateTime; + +} diff --git a/src/main/java/com/gxwebsoft/shop/mapper/OrderInfoMapper.java b/src/main/java/com/gxwebsoft/shop/mapper/OrderInfoMapper.java index 86c1236..cf1bec2 100644 --- a/src/main/java/com/gxwebsoft/shop/mapper/OrderInfoMapper.java +++ b/src/main/java/com/gxwebsoft/shop/mapper/OrderInfoMapper.java @@ -12,7 +12,7 @@ import java.util.List; * Mapper * * @author 科技小王子 - * @since 2024-05-03 11:14:47 + * @since 2024-05-13 19:50:43 */ public interface OrderInfoMapper extends BaseMapper { diff --git a/src/main/java/com/gxwebsoft/shop/mapper/OrderMapper.java b/src/main/java/com/gxwebsoft/shop/mapper/OrderMapper.java index fbc4c45..bcba09d 100644 --- a/src/main/java/com/gxwebsoft/shop/mapper/OrderMapper.java +++ b/src/main/java/com/gxwebsoft/shop/mapper/OrderMapper.java @@ -1,5 +1,6 @@ package com.gxwebsoft.shop.mapper; +import com.baomidou.mybatisplus.annotation.InterceptorIgnore; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.gxwebsoft.shop.entity.Order; @@ -34,4 +35,10 @@ public interface OrderMapper extends BaseMapper { */ List selectListRel(@Param("param") OrderParam param); + + @InterceptorIgnore(tenantLine = "true") + List getByOutTradeNo(OrderParam param); + + @InterceptorIgnore(tenantLine = "true") + void updateByOutTradeNo(@Param("param") Order outTradeNo); } diff --git a/src/main/java/com/gxwebsoft/shop/mapper/xml/OrderInfoMapper.xml b/src/main/java/com/gxwebsoft/shop/mapper/xml/OrderInfoMapper.xml index 1c8fe83..16f7ef5 100644 --- a/src/main/java/com/gxwebsoft/shop/mapper/xml/OrderInfoMapper.xml +++ b/src/main/java/com/gxwebsoft/shop/mapper/xml/OrderInfoMapper.xml @@ -49,6 +49,9 @@ AND a.is_children = #{param.isChildren} + + AND a.version = #{param.version} + AND a.type = #{param.type} @@ -56,14 +59,23 @@ AND a.merge_data LIKE CONCAT('%', #{param.mergeData}, '%') - AND a.start_time = #{param.startTime} + AND a.start_time LIKE CONCAT('%', #{param.startTime}, '%') - AND a.order_time = #{param.orderTime} + AND a.order_time LIKE CONCAT('%', #{param.orderTime}, '%') AND a.time_flag LIKE CONCAT('%', #{param.timeFlag}, '%') + + AND a.user_id = #{param.userId} + + + AND a.create_time >= #{param.createTimeStart} + + + AND a.create_time <= #{param.createTimeEnd} + AND (a.comments LIKE CONCAT('%', #{param.keywords}, '%') ) diff --git a/src/main/java/com/gxwebsoft/shop/mapper/xml/OrderMapper.xml b/src/main/java/com/gxwebsoft/shop/mapper/xml/OrderMapper.xml index 4dd0798..bcf6de6 100644 --- a/src/main/java/com/gxwebsoft/shop/mapper/xml/OrderMapper.xml +++ b/src/main/java/com/gxwebsoft/shop/mapper/xml/OrderMapper.xml @@ -149,4 +149,14 @@ + + + + + + diff --git a/src/main/java/com/gxwebsoft/shop/param/OrderInfoParam.java b/src/main/java/com/gxwebsoft/shop/param/OrderInfoParam.java index 4dbd9ba..82a7ec2 100644 --- a/src/main/java/com/gxwebsoft/shop/param/OrderInfoParam.java +++ b/src/main/java/com/gxwebsoft/shop/param/OrderInfoParam.java @@ -1,8 +1,6 @@ package com.gxwebsoft.shop.param; import java.math.BigDecimal; -import java.util.Set; - import com.gxwebsoft.common.core.annotation.QueryField; import com.gxwebsoft.common.core.annotation.QueryType; import com.gxwebsoft.common.core.web.BaseParam; @@ -16,7 +14,7 @@ import lombok.EqualsAndHashCode; * 查询参数 * * @author 科技小王子 - * @since 2024-05-03 11:14:47 + * @since 2024-05-13 19:50:43 */ @Data @EqualsAndHashCode(callSuper = false) @@ -59,44 +57,46 @@ public class OrderInfoParam extends BaseParam { @ApiModelProperty(value = "成人人数") @QueryField(type = QueryType.EQ) - private Boolean adultNum; + private Integer adultNum; @ApiModelProperty(value = "儿童人数") @QueryField(type = QueryType.EQ) - private Boolean childrenNum; + private Integer childrenNum; @ApiModelProperty(value = "1已付款,2未付款,3无需付款或占用状态") @QueryField(type = QueryType.EQ) - private Boolean payStatus; + private Integer payStatus; @ApiModelProperty(value = "是否免费:1免费、2收费") @QueryField(type = QueryType.EQ) - private Boolean isFree; + private Integer isFree; @ApiModelProperty(value = "是否支持儿童票:1支持,2不支持") @QueryField(type = QueryType.EQ) - private Boolean isChildren; + private Integer isChildren; + + @ApiModelProperty(value = "系统版本号 10新版 0旧版") + @QueryField(type = QueryType.EQ) + private Integer version; @ApiModelProperty(value = "预订类型:1全场,2半场") @QueryField(type = QueryType.EQ) - private Boolean type; + private Integer type; @ApiModelProperty(value = "组合数据:日期+时间段+场馆id+场地id") private String mergeData; @ApiModelProperty(value = "开场时间") - @QueryField(type = QueryType.EQ) - private Integer startTime; + private String startTime; @ApiModelProperty(value = "下单时间") - @QueryField(type = QueryType.EQ) - private Integer orderTime; + private String orderTime; @ApiModelProperty(value = "毫秒时间戳") private Long timeFlag; - @ApiModelProperty(value = "订单ID集合") - @QueryField(type = QueryType.IN) - private Set orderIds; + @ApiModelProperty(value = "用户id") + @QueryField(type = QueryType.EQ) + private Integer userId; } diff --git a/src/main/java/com/gxwebsoft/shop/service/OrderInfoService.java b/src/main/java/com/gxwebsoft/shop/service/OrderInfoService.java index 799504c..88f13c2 100644 --- a/src/main/java/com/gxwebsoft/shop/service/OrderInfoService.java +++ b/src/main/java/com/gxwebsoft/shop/service/OrderInfoService.java @@ -11,7 +11,7 @@ import java.util.List; * Service * * @author 科技小王子 - * @since 2024-05-03 11:14:47 + * @since 2024-05-13 19:50:43 */ public interface OrderInfoService extends IService { diff --git a/src/main/java/com/gxwebsoft/shop/service/OrderService.java b/src/main/java/com/gxwebsoft/shop/service/OrderService.java index 56d1fb7..1934226 100644 --- a/src/main/java/com/gxwebsoft/shop/service/OrderService.java +++ b/src/main/java/com/gxwebsoft/shop/service/OrderService.java @@ -41,4 +41,8 @@ public interface OrderService extends IService { Order getByIdRel(Integer orderId); HashMap createWxOrder(Order order); + + Order getByOutTradeNo(String outTradeNo); + + void updateByOutTradeNo(Order order); } diff --git a/src/main/java/com/gxwebsoft/shop/service/impl/OrderInfoServiceImpl.java b/src/main/java/com/gxwebsoft/shop/service/impl/OrderInfoServiceImpl.java index d41f778..02675df 100644 --- a/src/main/java/com/gxwebsoft/shop/service/impl/OrderInfoServiceImpl.java +++ b/src/main/java/com/gxwebsoft/shop/service/impl/OrderInfoServiceImpl.java @@ -15,7 +15,7 @@ import java.util.List; * Service实现 * * @author 科技小王子 - * @since 2024-05-03 11:14:47 + * @since 2024-05-13 19:50:43 */ @Service public class OrderInfoServiceImpl extends ServiceImpl implements OrderInfoService { 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 601b17f..9a4dbe1 100644 --- a/src/main/java/com/gxwebsoft/shop/service/impl/OrderServiceImpl.java +++ b/src/main/java/com/gxwebsoft/shop/service/impl/OrderServiceImpl.java @@ -1,13 +1,16 @@ package com.gxwebsoft.shop.service.impl; +import cn.hutool.core.util.StrUtil; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.gxwebsoft.common.core.config.ConfigProperties; +import com.gxwebsoft.common.core.utils.JSONUtil; +import com.gxwebsoft.common.core.utils.RedisUtil; import com.gxwebsoft.common.system.service.SettingService; import com.gxwebsoft.shop.entity.OrderInfo; +import com.gxwebsoft.shop.entity.Payment; import com.gxwebsoft.shop.mapper.OrderMapper; -import com.gxwebsoft.shop.param.OrderInfoParam; import com.gxwebsoft.shop.service.OrderInfoService; import com.gxwebsoft.shop.service.OrderService; import com.gxwebsoft.shop.entity.Order; @@ -21,6 +24,7 @@ import com.wechat.pay.java.service.payments.jsapi.model.Amount; import com.wechat.pay.java.service.payments.jsapi.model.Payer; import com.wechat.pay.java.service.payments.jsapi.model.PrepayRequest; import com.wechat.pay.java.service.payments.jsapi.model.PrepayWithRequestPaymentResponse; +import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; @@ -40,13 +44,20 @@ import java.util.stream.Collectors; */ @Service public class OrderServiceImpl extends ServiceImpl implements OrderService { - + @Value("${spring.profiles.active}") + String active; @Resource private OrderInfoService orderInfoService; @Resource private ConfigProperties config; @Resource private SettingService settingService; + @Resource + private RedisUtil redisUtil; + public static String privateKeyPath = "/Users/gxwebsoft/JAVA/com.gxwebsoft.core/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.core/src/main/resources/cert/wechatpay_4A3231584E93B6AE77820074D07EADEACCB7E223.pem"; // 平台证书 + @Override public PageResult pageRel(OrderParam param) { @@ -96,36 +107,28 @@ public class OrderServiceImpl extends ServiceImpl implements final String uploadPath = config.getUploadPath(); // 服务器本地路径 final HashMap orderInfo = new HashMap<>(); // 微信小程序(微信支付) - final JSONObject mpWx = settingService.getBySettingKey("mp-weixin"); - final JSONObject payment = settingService.getBySettingKey("payment"); + String key = "setting:mp-weixin:".concat(order.getTenantId().toString()); + final String string = redisUtil.get(key); + final JSONObject mpWx = JSONObject.parseObject(string); + final Payment payment = redisUtil.get("Payment:wxPay:".concat(order.getTenantId().toString()), Payment.class); // 计算金额 BigDecimal decimal = order.getTotalPrice(); final BigDecimal multiply = decimal.multiply(new BigDecimal(100)); // 将 BigDecimal 转换为 Integer Integer money = multiply.intValue(); - - final String appId = mpWx.getString("appId"); - final String mchId = payment.getString("mchId"); - final String openid = order.getOpenid(); // openid - final String notifyUrl = config.getServerUrl() + "/love/user-plan-log/wx-pay/notify/" + order.getTenantId(); // 异步通知地址 - final String privateKey = uploadPath.concat("file").concat(payment.getString("apiclientKey")); // 秘钥证书 - final String apiclientCert = uploadPath.concat("file").concat(payment.getString("apiclientCert")); - final String merchantSerialNumber = payment.getString("merchantSerialNumber"); // 证书序列号 - final String apiV3key = payment.getString("wechatApiKey"); - - System.out.println("privateKey = " + privateKey); - System.out.println("apiclientCert = " + apiclientCert); - System.out.println("merchantSerialNumber = " + merchantSerialNumber); - System.out.println("apiV3key = " + apiV3key); - System.out.println("mchId = " + mchId); - System.out.println("appId = " + appId); - + String privateKey = uploadPath.concat("/file").concat(payment.getApiclientKey()); // 秘钥证书 + String apiclientCert = uploadPath.concat("/file").concat(payment.getApiclientCert()); + // 开发环境配置 + if(active.equals("dev")){ + privateKey = privateKeyPath; + apiclientCert = wechatpayCertPath; + } Config config = new RSAConfig.Builder() - .merchantId(mchId) + .merchantId(payment.getMchId()) .privateKeyFromPath(privateKey) - .merchantSerialNumber(merchantSerialNumber) + .merchantSerialNumber(payment.getMerchantSerialNumber()) .wechatPayCertificatesFromPath(apiclientCert) .build(); @@ -137,18 +140,26 @@ public class OrderServiceImpl extends ServiceImpl implements amount.setTotal(money); amount.setCurrency("CNY"); request.setAmount(amount); - request.setAppid(appId); - request.setMchid(mchId); + request.setAppid(mpWx.getString("appId")); + request.setMchid(payment.getMchId()); request.setDescription(order.getComments()); - request.setNotifyUrl(notifyUrl); + request.setNotifyUrl("https://server.gxwebsoft.com/api/system/wx-pay/notify/" + order.getTenantId()); // 默认回调地址 request.setOutTradeNo(order.getOrderNo()); request.setAttach(order.getTenantId().toString()); final Payer payer = new Payer(); - payer.setOpenid(openid); + payer.setOpenid(order.getOpenid()); request.setPayer(payer); - + if (StrUtil.isNotBlank(payment.getNotifyUrl())) { + // 后台配置的回调地址 + request.setNotifyUrl(payment.getNotifyUrl().concat("/").concat(order.getTenantId().toString())); + } + // 测试金额 + if(active.equals("dev")){ + amount.setTotal(1); + request.setAmount(amount); + } + System.out.println("request = " + request); PrepayWithRequestPaymentResponse response = service.prepayWithRequestPayment(request); - System.out.println("response = " + response); orderInfo.put("provider", "wxpay"); orderInfo.put("timeStamp", response.getTimeStamp()); orderInfo.put("nonceStr", response.getNonceStr()); @@ -158,4 +169,18 @@ public class OrderServiceImpl extends ServiceImpl implements return orderInfo; } + + @Override + public Order getByOutTradeNo(String outTradeNo) { + System.out.println("outTradeNo = " + outTradeNo); + OrderParam param = new OrderParam(); + param.setOrderNo(outTradeNo); + return param.getOne(baseMapper.getByOutTradeNo(param)); + } + + @Override + public void updateByOutTradeNo(Order order) { + baseMapper.updateByOutTradeNo(order); + } + } diff --git a/src/test/java/com/gxwebsoft/generator/CmsGenerator.java b/src/test/java/com/gxwebsoft/generator/CmsGenerator.java index e24d965..e43061f 100644 --- a/src/test/java/com/gxwebsoft/generator/CmsGenerator.java +++ b/src/test/java/com/gxwebsoft/generator/CmsGenerator.java @@ -54,7 +54,7 @@ public class CmsGenerator { // "cms_navigation", // "cms_design", // "cms_design_record", -// "cms_website", + "cms_website", // "cms_website_field", // "cms_form", // "cms_form_record", diff --git a/src/test/java/com/gxwebsoft/generator/ShopGenerator.java b/src/test/java/com/gxwebsoft/generator/ShopGenerator.java index 72d4414..cd6b819 100644 --- a/src/test/java/com/gxwebsoft/generator/ShopGenerator.java +++ b/src/test/java/com/gxwebsoft/generator/ShopGenerator.java @@ -68,10 +68,10 @@ public class ShopGenerator { // "shop_chat_conversation" // "shop_user_collection", // "shop_mp_menu" -// "shop_order_info", + "shop_order_info", // "shop_order_info_log", // "shop_wechat_deposit" - "shop_users" +// "shop_users" }; // 需要去除的表前缀 private static final String[] TABLE_PREFIX = new String[]{