重构订单表前备份

This commit is contained in:
gxwebsoft
2024-05-14 13:10:42 +08:00
parent 65397ff001
commit 08ce525c94
24 changed files with 460 additions and 92 deletions
@@ -1,5 +1,6 @@
package com.gxwebsoft.booking.entity; package com.gxwebsoft.booking.entity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
@@ -70,4 +71,12 @@ public class Field implements Serializable {
@ApiModelProperty(value = "创建时间") @ApiModelProperty(value = "创建时间")
private Date createTime; private Date createTime;
@ApiModelProperty(value = "是否被占用")
@TableField(exist = false)
private Boolean isOccupied;
@ApiModelProperty(value = "1全场,2半场")
@TableField(exist = false)
private Integer type;
} }
@@ -72,4 +72,8 @@ public class FieldParam extends BaseParam {
@QueryField(type = QueryType.EQ) @QueryField(type = QueryType.EQ)
private Integer sortNumber; private Integer sortNumber;
@ApiModelProperty(value = "按日期查询")
@QueryField(type = QueryType.EQ)
private String dateTime;
} }
@@ -1,15 +1,25 @@
package com.gxwebsoft.booking.service.impl; package com.gxwebsoft.booking.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 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.entity.Field;
import com.gxwebsoft.booking.mapper.FieldMapper;
import com.gxwebsoft.booking.param.FieldParam; 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.PageParam;
import com.gxwebsoft.common.core.web.PageResult; 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.stereotype.Service;
import org.springframework.util.CollectionUtils;
import javax.annotation.Resource;
import java.util.List; 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实现 * 场馆场地Service实现
@@ -20,6 +30,9 @@ import java.util.List;
@Service @Service
public class FieldServiceImpl extends ServiceImpl<FieldMapper, Field> implements FieldService { public class FieldServiceImpl extends ServiceImpl<FieldMapper, Field> implements FieldService {
@Resource
private OrderInfoService orderInfoService;
@Override @Override
public PageResult<Field> pageRel(FieldParam param) { public PageResult<Field> pageRel(FieldParam param) {
PageParam<Field, FieldParam> page = new PageParam<>(param); PageParam<Field, FieldParam> page = new PageParam<>(param);
@@ -34,6 +47,27 @@ public class FieldServiceImpl extends ServiceImpl<FieldMapper, Field> implements
// 排序 // 排序
PageParam<Field, FieldParam> page = new PageParam<>(); PageParam<Field, FieldParam> page = new PageParam<>();
page.setDefaultOrder("sort_number desc, create_time desc"); page.setDefaultOrder("sort_number desc, create_time desc");
// 是否已被预定
if (param.getDateTime() != null) {
System.out.println("是否已被预定 = ");
System.out.println("param = " + param);
final List<OrderInfo> orderInfoList = orderInfoService.list(new LambdaQueryWrapper<OrderInfo>().eq(OrderInfo::getOrderTime, param.getDateTime()).eq(OrderInfo::getPayStatus,1).or().eq(OrderInfo::getPayStatus,3));
System.out.println("orderInfoList = " + orderInfoList);
if (!CollectionUtils.isEmpty(orderInfoList)) {
Map<Integer, List<OrderInfo>> 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<OrderInfo> 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); return page.sortRecords(list);
} }
@@ -85,9 +85,11 @@ public class WebsiteController extends BaseController {
final String siteInfo = redisUtil.get(key); final String siteInfo = redisUtil.get(key);
String access_token = JwtUtil.getAccessToken(request); String access_token = JwtUtil.getAccessToken(request);
System.out.println("access_token = " + access_token); System.out.println("access_token = " + access_token);
redisUtil.set("Domain:ffai.cn",10157); // redisUtil.set("Domain:ffai.cn",10157);
redisUtil.set("Domain:www.xn--15qx69a6lbn8t0tlmve.com",10157); // redisUtil.set("Domain:www.xn--15qx69a6lbn8t0tlmve.com",10157);
redisUtil.set("Domain: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)){ if(StrUtil.isNotBlank(siteInfo)){
return success(JSONObject.parseObject(siteInfo,Website.class)); return success(JSONObject.parseObject(siteInfo,Website.class));
@@ -112,7 +112,7 @@ public class Website implements Serializable {
private Integer recommend; private Integer recommend;
@ApiModelProperty(value = "状态") @ApiModelProperty(value = "状态")
private Integer status; private Boolean status;
@ApiModelProperty(value = "排序号") @ApiModelProperty(value = "排序号")
private Integer sortNumber; private Integer sortNumber;
@@ -91,7 +91,7 @@ public class WebsiteParam extends BaseParam {
@ApiModelProperty(value = "状态") @ApiModelProperty(value = "状态")
@QueryField(type = QueryType.EQ) @QueryField(type = QueryType.EQ)
private Integer status; private Boolean status;
@ApiModelProperty(value = "排序号") @ApiModelProperty(value = "排序号")
@QueryField(type = QueryType.EQ) @QueryField(type = QueryType.EQ)
@@ -57,6 +57,8 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
"/api/shop/payment/mp-alipay/getPhoneNumber", "/api/shop/payment/mp-alipay/getPhoneNumber",
"/api/shop/test/**", "/api/shop/test/**",
"/api/shop/wx-login/**", "/api/shop/wx-login/**",
"/api/shop/wx-native-pay/**",
"/api/shop/wx-pay/**",
"/api/apps/hualala/**", "/api/apps/hualala/**",
"/api/apps/hualala-cart/**", "/api/apps/hualala-cart/**",
"/api/apps/test-data/**", "/api/apps/test-data/**",
@@ -3,6 +3,7 @@ package com.gxwebsoft.shop.controller;
import cn.hutool.core.date.DateTime; import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil; import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.gxwebsoft.common.core.web.BaseController; import com.gxwebsoft.common.core.web.BaseController;
import com.gxwebsoft.shop.entity.OrderInfo; import com.gxwebsoft.shop.entity.OrderInfo;
@@ -30,8 +31,11 @@ import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.stream.Collectors;
/** /**
* 预约订单控制器 * 预约订单控制器
@@ -71,29 +75,49 @@ public class OrderController extends BaseController {
return success(orderService.getByIdRel(id)); return success(orderService.getByIdRel(id));
} }
@ApiOperation("添加预约订单") @PreAuthorize("hasAuthority('sys:order:save')")
@ApiOperation("下单")
@PostMapping() @PostMapping()
public ApiResult<?> save(@RequestBody Order order) { public ApiResult<?> save(@RequestBody Order order) {
// 记录当前登录用户id // 记录当前登录用户id
User loginUser = getLoginUser(); 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 timeMillis = System.currentTimeMillis();
long orderNo = IdUtil.getSnowflakeNextId(); long orderNo = IdUtil.getSnowflakeNextId();
if (loginUser != null) { order.setOrderNo(Long.toString(orderNo));
order.setUserId(loginUser.getUserId()); order.setUserId(loginUser.getUserId());
order.setOpenid(loginUser.getOpenid()); order.setOpenid(loginUser.getOpenid());
} order.setRealName(loginUser.getRealName());
order.setOrderNo(Long.toString(orderNo));
order.setName(loginUser.getRealName());
order.setStartTime(timeMillis / 1000);
order.setAddTime(timeMillis / 1000);
order.setPhone(loginUser.getPhone()); order.setPhone(loginUser.getPhone());
order.setUserId(loginUser.getUserId());
// List<Date> 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); order.setVersion(10);
if (orderService.save(order)) { if (orderService.save(order)) {
order.getOrderInfoList().forEach(d -> { order.getOrderInfoList().forEach(d -> {
d.setOid(order.getOrderId()); d.setOid(order.getOrderId());
d.setTimeFlag(timeMillis); d.setTimeFlag(timeMillis);
d.setVersion(10); d.setVersion(10);
d.setOrderTime(timeMillis / 1000); d.setOrderTime(d.getOrderTime());
}); });
orderInfoService.saveBatch(order.getOrderInfoList()); orderInfoService.saveBatch(order.getOrderInfoList());
// 创建微信订单 // 创建微信订单
@@ -22,7 +22,7 @@ import java.util.List;
* 控制器 * 控制器
* *
* @author 科技小王子 * @author 科技小王子
* @since 2024-05-03 11:14:47 * @since 2024-05-13 19:50:43
*/ */
@Api(tags = "管理") @Api(tags = "管理")
@RestController @RestController
@@ -57,10 +57,10 @@ public class OrderInfoController extends BaseController {
@PostMapping() @PostMapping()
public ApiResult<?> save(@RequestBody OrderInfo orderInfo) { public ApiResult<?> save(@RequestBody OrderInfo orderInfo) {
// 记录当前登录用户id // 记录当前登录用户id
// User loginUser = getLoginUser(); User loginUser = getLoginUser();
// if (loginUser != null) { if (loginUser != null) {
// orderInfo.setUserId(loginUser.getUserId()); orderInfo.setUserId(loginUser.getUserId());
// } }
if (orderInfoService.save(orderInfo)) { if (orderInfoService.save(orderInfo)) {
return success("添加成功"); return success("添加成功");
} }
@@ -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<String, String> 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";
}
}
@@ -61,7 +61,7 @@ public class Order implements Serializable {
private String code; private String code;
@ApiModelProperty(value = "真实姓名") @ApiModelProperty(value = "真实姓名")
private String name; private String realName;
@ApiModelProperty(value = "手机号码") @ApiModelProperty(value = "手机号码")
private String phone; private String phone;
@@ -90,6 +90,9 @@ public class Order implements Serializable {
@ApiModelProperty(value = "教练id") @ApiModelProperty(value = "教练id")
private Integer coachId; 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季卡") @ApiModelProperty(value = "1微信支付,2积分,3支付宝,4现金,5POS机,6VIP月卡,7VIP年卡,8VIP次卡,9IC月卡,10IC年卡,11IC次卡,12免费,13VIP充值卡,14IC充值卡,15积分支付,16VIP季卡,17IC季卡")
private Integer payType; private Integer payType;
@@ -115,7 +118,7 @@ public class Order implements Serializable {
private BigDecimal returnMoney; private BigDecimal returnMoney;
@ApiModelProperty(value = "预约详情开始时间数组") @ApiModelProperty(value = "预约详情开始时间数组")
private Long startTime; private String startTime;
@ApiModelProperty(value = "是否已开具发票:1已开发票,2未开发票,3不能开具发票") @ApiModelProperty(value = "是否已开具发票:1已开发票,2未开发票,3不能开具发票")
private Integer isInvoice; private Integer isInvoice;
@@ -126,7 +129,7 @@ public class Order implements Serializable {
private Integer updateTime; private Integer updateTime;
@ApiModelProperty(value = "付款时间") @ApiModelProperty(value = "付款时间")
private Integer payTime; private Date payTime;
@ApiModelProperty(value = "退款时间") @ApiModelProperty(value = "退款时间")
private Integer refundTime; private Integer refundTime;
@@ -1,10 +1,15 @@
package com.gxwebsoft.shop.entity; package com.gxwebsoft.shop.entity;
import java.math.BigDecimal; import java.math.BigDecimal;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
import java.time.LocalDateTime;
import java.io.Serializable; import java.io.Serializable;
import java.util.Date;
import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
@@ -14,7 +19,7 @@ import lombok.EqualsAndHashCode;
* *
* *
* @author 科技小王子 * @author 科技小王子
* @since 2024-05-03 11:14:47 * @since 2024-05-13 19:50:43
*/ */
@Data @Data
@EqualsAndHashCode(callSuper = false) @EqualsAndHashCode(callSuper = false)
@@ -35,14 +40,11 @@ public class OrderInfo implements Serializable {
@ApiModelProperty(value = "关联场地id") @ApiModelProperty(value = "关联场地id")
private Integer fid; private Integer fid;
@ApiModelProperty(value = "场馆")
private String siteName;
@ApiModelProperty(value = "场地") @ApiModelProperty(value = "场地")
private String fieldName; private String fieldName;
@ApiModelProperty(value = "预约时间段") @ApiModelProperty(value = "预约时间段")
private String dateTime; private String timePeriod;
@ApiModelProperty(value = "单价") @ApiModelProperty(value = "单价")
private BigDecimal price; private BigDecimal price;
@@ -51,39 +53,50 @@ public class OrderInfo implements Serializable {
private BigDecimal childrenPrice; private BigDecimal childrenPrice;
@ApiModelProperty(value = "成人人数") @ApiModelProperty(value = "成人人数")
private Boolean adultNum; private Integer adultNum;
@ApiModelProperty(value = "儿童人数") @ApiModelProperty(value = "儿童人数")
private Boolean childrenNum; private Integer childrenNum;
@ApiModelProperty(value = "1已付款,2未付款,3无需付款或占用状态") @ApiModelProperty(value = "1已付款,2未付款,3无需付款或占用状态")
private Boolean payStatus; private Integer payStatus;
@ApiModelProperty(value = "是否免费:1免费、2收费") @ApiModelProperty(value = "是否免费:1免费、2收费")
private Boolean isFree; private Integer isFree;
@ApiModelProperty(value = "是否支持儿童票:1支持,2不支持") @ApiModelProperty(value = "是否支持儿童票:1支持,2不支持")
private Boolean isChildren; private Integer isChildren;
@ApiModelProperty(value = "系统版本号 10新版 0旧版")
private Integer version;
@ApiModelProperty(value = "预订类型:1全场,2半场") @ApiModelProperty(value = "预订类型:1全场,2半场")
private Boolean type; private Integer type;
@ApiModelProperty(value = "组合数据:日期+时间段+场馆id+场地id") @ApiModelProperty(value = "组合数据:日期+时间段+场馆id+场地id")
private String mergeData; private String mergeData;
@ApiModelProperty(value = "备注")
private String comments;
@ApiModelProperty(value = "开场时间") @ApiModelProperty(value = "开场时间")
private Long startTime; private Date startTime;
@ApiModelProperty(value = "下单时间") @ApiModelProperty(value = "下单时间")
private Long orderTime; private Date orderTime;
@ApiModelProperty(value = "毫秒时间戳") @ApiModelProperty(value = "毫秒时间戳")
private Long timeFlag; private Long timeFlag;
@ApiModelProperty(value = "系统版本") @ApiModelProperty(value = "用户id")
private Integer version; private Integer userId;
@ApiModelProperty(value = "租户id") @ApiModelProperty(value = "租户id")
private Integer tenantId; private Integer tenantId;
private Date updateTime;
@ApiModelProperty(value = "创建时间")
private Date createTime;
} }
@@ -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;
}
@@ -12,7 +12,7 @@ import java.util.List;
* Mapper * Mapper
* *
* @author 科技小王子 * @author 科技小王子
* @since 2024-05-03 11:14:47 * @since 2024-05-13 19:50:43
*/ */
public interface OrderInfoMapper extends BaseMapper<OrderInfo> { public interface OrderInfoMapper extends BaseMapper<OrderInfo> {
@@ -1,5 +1,6 @@
package com.gxwebsoft.shop.mapper; package com.gxwebsoft.shop.mapper;
import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import com.gxwebsoft.shop.entity.Order; import com.gxwebsoft.shop.entity.Order;
@@ -34,4 +35,10 @@ public interface OrderMapper extends BaseMapper<Order> {
*/ */
List<Order> selectListRel(@Param("param") OrderParam param); List<Order> selectListRel(@Param("param") OrderParam param);
@InterceptorIgnore(tenantLine = "true")
List<Order> getByOutTradeNo(OrderParam param);
@InterceptorIgnore(tenantLine = "true")
void updateByOutTradeNo(@Param("param") Order outTradeNo);
} }
@@ -49,6 +49,9 @@
<if test="param.isChildren != null"> <if test="param.isChildren != null">
AND a.is_children = #{param.isChildren} AND a.is_children = #{param.isChildren}
</if> </if>
<if test="param.version != null">
AND a.version = #{param.version}
</if>
<if test="param.type != null"> <if test="param.type != null">
AND a.type = #{param.type} AND a.type = #{param.type}
</if> </if>
@@ -56,14 +59,23 @@
AND a.merge_data LIKE CONCAT('%', #{param.mergeData}, '%') AND a.merge_data LIKE CONCAT('%', #{param.mergeData}, '%')
</if> </if>
<if test="param.startTime != null"> <if test="param.startTime != null">
AND a.start_time = #{param.startTime} AND a.start_time LIKE CONCAT('%', #{param.startTime}, '%')
</if> </if>
<if test="param.orderTime != null"> <if test="param.orderTime != null">
AND a.order_time = #{param.orderTime} AND a.order_time LIKE CONCAT('%', #{param.orderTime}, '%')
</if> </if>
<if test="param.timeFlag != null"> <if test="param.timeFlag != null">
AND a.time_flag LIKE CONCAT('%', #{param.timeFlag}, '%') AND a.time_flag LIKE CONCAT('%', #{param.timeFlag}, '%')
</if> </if>
<if test="param.userId != null">
AND a.user_id = #{param.userId}
</if>
<if test="param.createTimeStart != null">
AND a.create_time &gt;= #{param.createTimeStart}
</if>
<if test="param.createTimeEnd != null">
AND a.create_time &lt;= #{param.createTimeEnd}
</if>
<if test="param.keywords != null"> <if test="param.keywords != null">
AND (a.comments LIKE CONCAT('%', #{param.keywords}, '%') AND (a.comments LIKE CONCAT('%', #{param.keywords}, '%')
) )
@@ -149,4 +149,14 @@
<include refid="selectSql"></include> <include refid="selectSql"></include>
</select> </select>
<!-- 按OutTradeNo查询 -->
<select id="getByOutTradeNo" resultType="com.gxwebsoft.shop.entity.Order">
<include refid="selectSql"></include>
</select>
<!-- 更新订单状态 -->
<select id="updateByOutTradeNo" resultType="com.gxwebsoft.shop.entity.Order">
UPDATE sys_order SET pay_status = #{param.payStatus},pay_time = #{param.payTime},pay_price = #{param.payPrice},transaction_id = #{param.transactionId} WHERE order_no = #{param.orderNo}
</select>
</mapper> </mapper>
@@ -1,8 +1,6 @@
package com.gxwebsoft.shop.param; package com.gxwebsoft.shop.param;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.Set;
import com.gxwebsoft.common.core.annotation.QueryField; import com.gxwebsoft.common.core.annotation.QueryField;
import com.gxwebsoft.common.core.annotation.QueryType; import com.gxwebsoft.common.core.annotation.QueryType;
import com.gxwebsoft.common.core.web.BaseParam; import com.gxwebsoft.common.core.web.BaseParam;
@@ -16,7 +14,7 @@ import lombok.EqualsAndHashCode;
* 查询参数 * 查询参数
* *
* @author 科技小王子 * @author 科技小王子
* @since 2024-05-03 11:14:47 * @since 2024-05-13 19:50:43
*/ */
@Data @Data
@EqualsAndHashCode(callSuper = false) @EqualsAndHashCode(callSuper = false)
@@ -59,44 +57,46 @@ public class OrderInfoParam extends BaseParam {
@ApiModelProperty(value = "成人人数") @ApiModelProperty(value = "成人人数")
@QueryField(type = QueryType.EQ) @QueryField(type = QueryType.EQ)
private Boolean adultNum; private Integer adultNum;
@ApiModelProperty(value = "儿童人数") @ApiModelProperty(value = "儿童人数")
@QueryField(type = QueryType.EQ) @QueryField(type = QueryType.EQ)
private Boolean childrenNum; private Integer childrenNum;
@ApiModelProperty(value = "1已付款,2未付款,3无需付款或占用状态") @ApiModelProperty(value = "1已付款,2未付款,3无需付款或占用状态")
@QueryField(type = QueryType.EQ) @QueryField(type = QueryType.EQ)
private Boolean payStatus; private Integer payStatus;
@ApiModelProperty(value = "是否免费:1免费、2收费") @ApiModelProperty(value = "是否免费:1免费、2收费")
@QueryField(type = QueryType.EQ) @QueryField(type = QueryType.EQ)
private Boolean isFree; private Integer isFree;
@ApiModelProperty(value = "是否支持儿童票:1支持,2不支持") @ApiModelProperty(value = "是否支持儿童票:1支持,2不支持")
@QueryField(type = QueryType.EQ) @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半场") @ApiModelProperty(value = "预订类型:1全场,2半场")
@QueryField(type = QueryType.EQ) @QueryField(type = QueryType.EQ)
private Boolean type; private Integer type;
@ApiModelProperty(value = "组合数据:日期+时间段+场馆id+场地id") @ApiModelProperty(value = "组合数据:日期+时间段+场馆id+场地id")
private String mergeData; private String mergeData;
@ApiModelProperty(value = "开场时间") @ApiModelProperty(value = "开场时间")
@QueryField(type = QueryType.EQ) private String startTime;
private Integer startTime;
@ApiModelProperty(value = "下单时间") @ApiModelProperty(value = "下单时间")
@QueryField(type = QueryType.EQ) private String orderTime;
private Integer orderTime;
@ApiModelProperty(value = "毫秒时间戳") @ApiModelProperty(value = "毫秒时间戳")
private Long timeFlag; private Long timeFlag;
@ApiModelProperty(value = "订单ID集合") @ApiModelProperty(value = "用户id")
@QueryField(type = QueryType.IN) @QueryField(type = QueryType.EQ)
private Set<Integer> orderIds; private Integer userId;
} }
@@ -11,7 +11,7 @@ import java.util.List;
* Service * Service
* *
* @author 科技小王子 * @author 科技小王子
* @since 2024-05-03 11:14:47 * @since 2024-05-13 19:50:43
*/ */
public interface OrderInfoService extends IService<OrderInfo> { public interface OrderInfoService extends IService<OrderInfo> {
@@ -41,4 +41,8 @@ public interface OrderService extends IService<Order> {
Order getByIdRel(Integer orderId); Order getByIdRel(Integer orderId);
HashMap<String, String> createWxOrder(Order order); HashMap<String, String> createWxOrder(Order order);
Order getByOutTradeNo(String outTradeNo);
void updateByOutTradeNo(Order order);
} }
@@ -15,7 +15,7 @@ import java.util.List;
* Service实现 * Service实现
* *
* @author 科技小王子 * @author 科技小王子
* @since 2024-05-03 11:14:47 * @since 2024-05-13 19:50:43
*/ */
@Service @Service
public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo> implements OrderInfoService { public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo> implements OrderInfoService {
@@ -1,13 +1,16 @@
package com.gxwebsoft.shop.service.impl; package com.gxwebsoft.shop.service.impl;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gxwebsoft.common.core.config.ConfigProperties; 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.common.system.service.SettingService;
import com.gxwebsoft.shop.entity.OrderInfo; import com.gxwebsoft.shop.entity.OrderInfo;
import com.gxwebsoft.shop.entity.Payment;
import com.gxwebsoft.shop.mapper.OrderMapper; import com.gxwebsoft.shop.mapper.OrderMapper;
import com.gxwebsoft.shop.param.OrderInfoParam;
import com.gxwebsoft.shop.service.OrderInfoService; import com.gxwebsoft.shop.service.OrderInfoService;
import com.gxwebsoft.shop.service.OrderService; import com.gxwebsoft.shop.service.OrderService;
import com.gxwebsoft.shop.entity.Order; 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.Payer;
import com.wechat.pay.java.service.payments.jsapi.model.PrepayRequest; import com.wechat.pay.java.service.payments.jsapi.model.PrepayRequest;
import com.wechat.pay.java.service.payments.jsapi.model.PrepayWithRequestPaymentResponse; 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.stereotype.Service;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
@@ -40,13 +44,20 @@ import java.util.stream.Collectors;
*/ */
@Service @Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService { public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {
@Value("${spring.profiles.active}")
String active;
@Resource @Resource
private OrderInfoService orderInfoService; private OrderInfoService orderInfoService;
@Resource @Resource
private ConfigProperties config; private ConfigProperties config;
@Resource @Resource
private SettingService settingService; 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 @Override
public PageResult<Order> pageRel(OrderParam param) { public PageResult<Order> pageRel(OrderParam param) {
@@ -96,36 +107,28 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
final String uploadPath = config.getUploadPath(); // 服务器本地路径 final String uploadPath = config.getUploadPath(); // 服务器本地路径
final HashMap<String, String> orderInfo = new HashMap<>(); final HashMap<String, String> orderInfo = new HashMap<>();
// 微信小程序(微信支付) // 微信小程序(微信支付)
final JSONObject mpWx = settingService.getBySettingKey("mp-weixin"); String key = "setting:mp-weixin:".concat(order.getTenantId().toString());
final JSONObject payment = settingService.getBySettingKey("payment"); 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(); BigDecimal decimal = order.getTotalPrice();
final BigDecimal multiply = decimal.multiply(new BigDecimal(100)); final BigDecimal multiply = decimal.multiply(new BigDecimal(100));
// 将 BigDecimal 转换为 Integer // 将 BigDecimal 转换为 Integer
Integer money = multiply.intValue(); Integer money = multiply.intValue();
String privateKey = uploadPath.concat("/file").concat(payment.getApiclientKey()); // 秘钥证书
final String appId = mpWx.getString("appId"); String apiclientCert = uploadPath.concat("/file").concat(payment.getApiclientCert());
final String mchId = payment.getString("mchId"); // 开发环境配置
final String openid = order.getOpenid(); // openid if(active.equals("dev")){
final String notifyUrl = config.getServerUrl() + "/love/user-plan-log/wx-pay/notify/" + order.getTenantId(); // 异步通知地址 privateKey = privateKeyPath;
final String privateKey = uploadPath.concat("file").concat(payment.getString("apiclientKey")); // 秘钥证书 apiclientCert = wechatpayCertPath;
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);
Config config = Config config =
new RSAConfig.Builder() new RSAConfig.Builder()
.merchantId(mchId) .merchantId(payment.getMchId())
.privateKeyFromPath(privateKey) .privateKeyFromPath(privateKey)
.merchantSerialNumber(merchantSerialNumber) .merchantSerialNumber(payment.getMerchantSerialNumber())
.wechatPayCertificatesFromPath(apiclientCert) .wechatPayCertificatesFromPath(apiclientCert)
.build(); .build();
@@ -137,18 +140,26 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
amount.setTotal(money); amount.setTotal(money);
amount.setCurrency("CNY"); amount.setCurrency("CNY");
request.setAmount(amount); request.setAmount(amount);
request.setAppid(appId); request.setAppid(mpWx.getString("appId"));
request.setMchid(mchId); request.setMchid(payment.getMchId());
request.setDescription(order.getComments()); 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.setOutTradeNo(order.getOrderNo());
request.setAttach(order.getTenantId().toString()); request.setAttach(order.getTenantId().toString());
final Payer payer = new Payer(); final Payer payer = new Payer();
payer.setOpenid(openid); payer.setOpenid(order.getOpenid());
request.setPayer(payer); 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); PrepayWithRequestPaymentResponse response = service.prepayWithRequestPayment(request);
System.out.println("response = " + response);
orderInfo.put("provider", "wxpay"); orderInfo.put("provider", "wxpay");
orderInfo.put("timeStamp", response.getTimeStamp()); orderInfo.put("timeStamp", response.getTimeStamp());
orderInfo.put("nonceStr", response.getNonceStr()); orderInfo.put("nonceStr", response.getNonceStr());
@@ -158,4 +169,18 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
return orderInfo; 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);
}
} }
@@ -54,7 +54,7 @@ public class CmsGenerator {
// "cms_navigation", // "cms_navigation",
// "cms_design", // "cms_design",
// "cms_design_record", // "cms_design_record",
// "cms_website", "cms_website",
// "cms_website_field", // "cms_website_field",
// "cms_form", // "cms_form",
// "cms_form_record", // "cms_form_record",
@@ -68,10 +68,10 @@ public class ShopGenerator {
// "shop_chat_conversation" // "shop_chat_conversation"
// "shop_user_collection", // "shop_user_collection",
// "shop_mp_menu" // "shop_mp_menu"
// "shop_order_info", "shop_order_info",
// "shop_order_info_log", // "shop_order_info_log",
// "shop_wechat_deposit" // "shop_wechat_deposit"
"shop_users" // "shop_users"
}; };
// 需要去除的表前缀 // 需要去除的表前缀
private static final String[] TABLE_PREFIX = new String[]{ private static final String[] TABLE_PREFIX = new String[]{