fix - 用户可能会有多个订单的情况优化。保持订单幂等。
This commit is contained in:
@@ -3,6 +3,7 @@ package com.sv.api.controller;
|
|||||||
import com.enums.EnterEnum;
|
import com.enums.EnterEnum;
|
||||||
import com.enums.PayTypeEnum;
|
import com.enums.PayTypeEnum;
|
||||||
import com.sv.dto.BasketEnterResult;
|
import com.sv.dto.BasketEnterResult;
|
||||||
|
import com.sv.dto.api.BasketballPayResult;
|
||||||
import com.sv.entity.Device;
|
import com.sv.entity.Device;
|
||||||
import com.sv.entity.Order;
|
import com.sv.entity.Order;
|
||||||
import com.sv.entity.Venue;
|
import com.sv.entity.Venue;
|
||||||
@@ -204,7 +205,7 @@ public class VenueController extends BaseApiController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 篮球入场下订单
|
* 篮球入场下订单(防重复下单)
|
||||||
*/
|
*/
|
||||||
@RequestMapping(value = "/venue/basketball/pay", method = RequestMethod.POST)
|
@RequestMapping(value = "/venue/basketball/pay", method = RequestMethod.POST)
|
||||||
@AccessToken
|
@AccessToken
|
||||||
@@ -219,8 +220,14 @@ public class VenueController extends BaseApiController {
|
|||||||
throw new ServiceException("有人正在使用门禁,请稍后再试");
|
throw new ServiceException("有人正在使用门禁,请稍后再试");
|
||||||
}
|
}
|
||||||
Integer memberId = getMemberIdByAccessToken();
|
Integer memberId = getMemberIdByAccessToken();
|
||||||
|
BasketballPayResult result = orderService.createEnterVenueOrder(venueId, memberId, enterFlag, PayTypeEnum.WEI_XIN, new BigDecimal(payMoney));
|
||||||
|
if (result.getPaidFlag()) {
|
||||||
|
return ResponseDTO.ok().addAttribute("paid_flag", true).addAttribute("order_sn", result.getOrderSn());
|
||||||
|
}
|
||||||
return ResponseDTO.ok().
|
return ResponseDTO.ok().
|
||||||
addAttribute("pay",orderService.createEnterVenueOrder(venueId, memberId, enterFlag, PayTypeEnum.WEI_XIN, new BigDecimal(payMoney)));
|
addAttribute("paid_flag", false).
|
||||||
|
addAttribute("order_sn", result.getOrderSn()).
|
||||||
|
addAttribute("pay", result.getWechatPayParam());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import com.sv.service.api.MemberService;
|
|||||||
import com.sv.service.api.MemberTokenService;
|
import com.sv.service.api.MemberTokenService;
|
||||||
import com.sv.service.common.ApiConstants;
|
import com.sv.service.common.ApiConstants;
|
||||||
import com.sv.service.common.CaptchaCacheServiceImpl;
|
import com.sv.service.common.CaptchaCacheServiceImpl;
|
||||||
|
import com.sv.service.common.MemberKeyLock;
|
||||||
import com.sv.service.common.OSSClientUtil;
|
import com.sv.service.common.OSSClientUtil;
|
||||||
import com.ydd.framework.core.common.utils.ValidationUtils;
|
import com.ydd.framework.core.common.utils.ValidationUtils;
|
||||||
import com.ydd.framework.core.entity.enums.DeletedEnum;
|
import com.ydd.framework.core.entity.enums.DeletedEnum;
|
||||||
@@ -64,6 +65,8 @@ public class LoginRegisterServiceImpl extends BaseServiceImpl {
|
|||||||
private OSSClientUtil ossClientUtil;
|
private OSSClientUtil ossClientUtil;
|
||||||
@Resource
|
@Resource
|
||||||
private WechatService wechatService;
|
private WechatService wechatService;
|
||||||
|
@Resource
|
||||||
|
private MemberKeyLock memberKeyLock;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 手机号注册
|
* 手机号注册
|
||||||
@@ -137,7 +140,7 @@ public class LoginRegisterServiceImpl extends BaseServiceImpl {
|
|||||||
public MemberTokenDTO loginWithXcx(String openId){
|
public MemberTokenDTO loginWithXcx(String openId){
|
||||||
MemberTokenDTO memberTokenDTO = null;
|
MemberTokenDTO memberTokenDTO = null;
|
||||||
Integer platformId = PlatformContext.getPlatFormValue();
|
Integer platformId = PlatformContext.getPlatFormValue();
|
||||||
synchronized (openId.intern()){
|
synchronized (memberKeyLock.getLock(openId)){
|
||||||
// 判断用户是否注册过,用微信登录过
|
// 判断用户是否注册过,用微信登录过
|
||||||
MemberAuth memberAuth = memberAuthService.findByAuthId(openId);
|
MemberAuth memberAuth = memberAuthService.findByAuthId(openId);
|
||||||
// 登录过,则直接登录成功
|
// 登录过,则直接登录成功
|
||||||
@@ -166,7 +169,7 @@ public class LoginRegisterServiceImpl extends BaseServiceImpl {
|
|||||||
throw new ServiceException("token过期");
|
throw new ServiceException("token过期");
|
||||||
}
|
}
|
||||||
MemberTokenDTO memberTokenDTO = null;
|
MemberTokenDTO memberTokenDTO = null;
|
||||||
synchronized (openId){
|
synchronized (memberKeyLock.getLock(memberId)){
|
||||||
// 1.根据openId,查找登录表,是否有记录,无,直接登录,插入信息到登录表
|
// 1.根据openId,查找登录表,是否有记录,无,直接登录,插入信息到登录表
|
||||||
Member member = memberService.findById(memberId);
|
Member member = memberService.findById(memberId);
|
||||||
// memberService.verify(member);
|
// memberService.verify(member);
|
||||||
@@ -364,7 +367,7 @@ public class LoginRegisterServiceImpl extends BaseServiceImpl {
|
|||||||
String mobile = wechatResult.getPhoneNumber();
|
String mobile = wechatResult.getPhoneNumber();
|
||||||
|
|
||||||
MemberTokenDTO memberTokenDTO = null;
|
MemberTokenDTO memberTokenDTO = null;
|
||||||
synchronized (openId.intern()){
|
synchronized (memberKeyLock.getLock(openId)){
|
||||||
Member member = memberService.findByMobile(mobile);
|
Member member = memberService.findByMobile(mobile);
|
||||||
if (member == null) {
|
if (member == null) {
|
||||||
MemberAuth memberAuth = memberAuthService.findByAuthId(openId);
|
MemberAuth memberAuth = memberAuthService.findByAuthId(openId);
|
||||||
|
|||||||
39
api/src/test/java/com/sv/wx/MakeBarcodeTest.java
Normal file
39
api/src/test/java/com/sv/wx/MakeBarcodeTest.java
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
package com.sv.wx;
|
||||||
|
|
||||||
|
import com.WeiXinApplication;
|
||||||
|
import com.enums.EnterEnum;
|
||||||
|
import com.enums.VenueTypeEnum;
|
||||||
|
import com.sv.entity.Constants;
|
||||||
|
import com.sv.entity.Venue;
|
||||||
|
import com.sv.entity.VenueLesson;
|
||||||
|
import com.sv.mapper.WxConfigMapper;
|
||||||
|
import com.sv.service.api.VenueLessonService;
|
||||||
|
import com.sv.service.api.VenueService;
|
||||||
|
import com.sv.service.api.util.DateUtilCard;
|
||||||
|
import com.sv.service.common.BarcodeService;
|
||||||
|
import com.sv.service.message.SendMsg;
|
||||||
|
import com.sv.service.message.WeiXinSendUtils;
|
||||||
|
import com.ydd.oms.entity.sys.WxConfig;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
import org.springframework.test.context.junit4.SpringRunner;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@RunWith(SpringRunner.class)
|
||||||
|
@SpringBootTest(classes={WeiXinApplication.class})
|
||||||
|
public class MakeBarcodeTest {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
BarcodeService barcodeService;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testTask(){
|
||||||
|
barcodeService.newBarcode("123123","2312313123", EnterEnum.ENTER, 1, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -32,8 +32,8 @@ public class WxServiceTest {
|
|||||||
public void refund(){
|
public void refund(){
|
||||||
// wechatPayService.createUnifiedOrder("testlmq20231224",new BigDecimal(0.02),"127.0.0.1","JSAPI", 535);
|
// wechatPayService.createUnifiedOrder("testlmq20231224",new BigDecimal(0.02),"127.0.0.1","JSAPI", 535);
|
||||||
// 根据orderSn查出对应订单信息
|
// 根据orderSn查出对应订单信息
|
||||||
String orderSn = "231231014749545739";
|
String orderSn = "260603140301802382";
|
||||||
Integer memberId = 535;
|
Integer memberId = 1;
|
||||||
Order order = orderService.findOrderSn(orderSn,memberId);
|
Order order = orderService.findOrderSn(orderSn,memberId);
|
||||||
if (order == null){
|
if (order == null){
|
||||||
throw new ServiceException(com.sv.exception.api.ExceptionCodeTemplate.ORDER_ERROR);
|
throw new ServiceException(com.sv.exception.api.ExceptionCodeTemplate.ORDER_ERROR);
|
||||||
@@ -49,7 +49,7 @@ public class WxServiceTest {
|
|||||||
memberRefund.setOutRefundNo(orderService.createSn());//商户退款单号
|
memberRefund.setOutRefundNo(orderService.createSn());//商户退款单号
|
||||||
memberRefund.setPlatformId(1);
|
memberRefund.setPlatformId(1);
|
||||||
memberRefundMapper.insert(memberRefund);
|
memberRefundMapper.insert(memberRefund);
|
||||||
wechatPayService.refundInputMoney(memberRefund, order.getPrice(), new BigDecimal(0.01));
|
wechatPayService.refundInputMoney(memberRefund, order.getPrice(), new BigDecimal(0.02));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
package com.sv.dto;
|
package com.sv.dto;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
@@ -13,6 +15,17 @@ public class BasketEnterResult implements Serializable {
|
|||||||
|
|
||||||
private BigDecimal money;
|
private BigDecimal money;
|
||||||
|
|
||||||
|
private String orderSn;
|
||||||
|
|
||||||
|
@JsonProperty("order_sn")
|
||||||
|
public String getOrderSn() {
|
||||||
|
return orderSn;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOrderSn(String orderSn) {
|
||||||
|
this.orderSn = orderSn;
|
||||||
|
}
|
||||||
|
|
||||||
public BigDecimal getMoney() {
|
public BigDecimal getMoney() {
|
||||||
return money;
|
return money;
|
||||||
}
|
}
|
||||||
|
|||||||
42
entity/src/main/java/com/sv/dto/api/BasketballPayResult.java
Normal file
42
entity/src/main/java/com/sv/dto/api/BasketballPayResult.java
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
package com.sv.dto.api;
|
||||||
|
|
||||||
|
import com.sv.dto.api.wechat.OrderPaySignResponse;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
public class BasketballPayResult implements Serializable {
|
||||||
|
|
||||||
|
private Boolean paidFlag;
|
||||||
|
|
||||||
|
private String orderSn;
|
||||||
|
|
||||||
|
private OrderPaySignResponse.WechatPayParam wechatPayParam;
|
||||||
|
|
||||||
|
@JsonProperty("paid_flag")
|
||||||
|
public Boolean getPaidFlag() {
|
||||||
|
return paidFlag;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPaidFlag(Boolean paidFlag) {
|
||||||
|
this.paidFlag = paidFlag;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonProperty("order_sn")
|
||||||
|
public String getOrderSn() {
|
||||||
|
return orderSn;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOrderSn(String orderSn) {
|
||||||
|
this.orderSn = orderSn;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonProperty("wechatpay")
|
||||||
|
public OrderPaySignResponse.WechatPayParam getWechatPayParam() {
|
||||||
|
return wechatPayParam;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setWechatPayParam(OrderPaySignResponse.WechatPayParam wechatPayParam) {
|
||||||
|
this.wechatPayParam = wechatPayParam;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -12,7 +12,7 @@ import org.springframework.scheduling.annotation.EnableScheduling;
|
|||||||
* @since 2017-06-19
|
* @since 2017-06-19
|
||||||
*/
|
*/
|
||||||
@SpringBootApplication
|
@SpringBootApplication
|
||||||
@EnableScheduling
|
//@EnableScheduling
|
||||||
@MapperScan(value = {"com.ydd.oms.mapper","com.sv.mapper"})
|
@MapperScan(value = {"com.ydd.oms.mapper","com.sv.mapper"})
|
||||||
public class OmsApplication {
|
public class OmsApplication {
|
||||||
|
|
||||||
|
|||||||
@@ -92,6 +92,11 @@ public interface OrderMapper {
|
|||||||
|
|
||||||
Order findLastOrder(@Param("memberId") Integer memberId);
|
Order findLastOrder(@Param("memberId") Integer memberId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* api 查询用户在当前场馆的待支付篮球订单(近10分钟内)
|
||||||
|
*/
|
||||||
|
Order findPendingBasketballOrder(@Param("memberId") Integer memberId, @Param("venueId") Integer venueId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* api 根据订单编号查询总价钱
|
* api 根据订单编号查询总价钱
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import com.sv.dto.api.wechat.OrderPaySignResponse;
|
|||||||
import com.sv.entity.*;
|
import com.sv.entity.*;
|
||||||
import com.sv.mapper.MemberCardOrderMapper;
|
import com.sv.mapper.MemberCardOrderMapper;
|
||||||
import com.sv.service.api.config.WechatPayService;
|
import com.sv.service.api.config.WechatPayService;
|
||||||
|
import com.sv.service.common.MemberKeyLock;
|
||||||
import com.ydd.framework.core.common.Pagination;
|
import com.ydd.framework.core.common.Pagination;
|
||||||
import com.ydd.framework.core.common.utils.ValidationUtils;
|
import com.ydd.framework.core.common.utils.ValidationUtils;
|
||||||
import com.ydd.framework.core.exception.ExceptionCodeTemplate;
|
import com.ydd.framework.core.exception.ExceptionCodeTemplate;
|
||||||
@@ -51,6 +52,8 @@ public class MemberCardOrderService extends BaseServiceImpl {
|
|||||||
private MemberService memberService;
|
private MemberService memberService;
|
||||||
@Resource
|
@Resource
|
||||||
private MemberCardService memberCardService;
|
private MemberCardService memberCardService;
|
||||||
|
@Resource
|
||||||
|
private MemberKeyLock memberKeyLock;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建用户会员卡订单
|
* 创建用户会员卡订单
|
||||||
@@ -138,8 +141,9 @@ public class MemberCardOrderService extends BaseServiceImpl {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@Transactional
|
@Transactional
|
||||||
public synchronized OrderPaySignResponse.WechatPayParam createCardOrder(Integer memberId,Integer cardType,
|
public OrderPaySignResponse.WechatPayParam createCardOrder(Integer memberId,Integer cardType,
|
||||||
Integer type,Integer venueId,Integer num,Integer platformId,String ip){
|
Integer type,Integer venueId,Integer num,Integer platformId,String ip){
|
||||||
|
synchronized (memberKeyLock.getLock(memberId)) {
|
||||||
// 判断用户是否登录
|
// 判断用户是否登录
|
||||||
if (memberId == null){
|
if (memberId == null){
|
||||||
throw new ServiceException(ExceptionCodeTemplate.NEED_LOGIN);
|
throw new ServiceException(ExceptionCodeTemplate.NEED_LOGIN);
|
||||||
@@ -183,6 +187,7 @@ public class MemberCardOrderService extends BaseServiceImpl {
|
|||||||
// 4.调支付
|
// 4.调支付
|
||||||
OrderPaySignResponse.WechatPayParam wechatPayParam = createUnifiedOrder(order.getOrderSn(), memberId,ip,"购买商品");
|
OrderPaySignResponse.WechatPayParam wechatPayParam = createUnifiedOrder(order.getOrderSn(), memberId,ip,"购买商品");
|
||||||
return wechatPayParam;
|
return wechatPayParam;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import com.sv.entity.*;
|
|||||||
import com.sv.exception.api.ExceptionCodeTemplate;
|
import com.sv.exception.api.ExceptionCodeTemplate;
|
||||||
import com.sv.mapper.MemberLessonTicketMapper;
|
import com.sv.mapper.MemberLessonTicketMapper;
|
||||||
import com.sv.service.api.util.DateUtilCard;
|
import com.sv.service.api.util.DateUtilCard;
|
||||||
|
import com.sv.service.common.MemberKeyLock;
|
||||||
import com.sv.service.common.RedisLock;
|
import com.sv.service.common.RedisLock;
|
||||||
import com.sv.service.message.AsyncTaskUtil;
|
import com.sv.service.message.AsyncTaskUtil;
|
||||||
import com.sv.service.message.NotifyAdminMsgThread;
|
import com.sv.service.message.NotifyAdminMsgThread;
|
||||||
@@ -73,6 +74,8 @@ public class MemberLessonTicketService extends BaseServiceImpl {
|
|||||||
private MemberRefundService memberRefundService;
|
private MemberRefundService memberRefundService;
|
||||||
@Resource
|
@Resource
|
||||||
private RedisTemplate<String, Object> redisTemplate;
|
private RedisTemplate<String, Object> redisTemplate;
|
||||||
|
@Resource
|
||||||
|
private MemberKeyLock memberKeyLock;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -175,7 +178,7 @@ public class MemberLessonTicketService extends BaseServiceImpl {
|
|||||||
* 预约课程,微信下单LessonTicketOrderDTO
|
* 预约课程,微信下单LessonTicketOrderDTO
|
||||||
*/
|
*/
|
||||||
@Transactional
|
@Transactional
|
||||||
public synchronized OrderPaySignResponse.WechatPayParam createOrder(Integer memberId, LessonTicketOrderDTO lessonTicketOrderDTO, Integer platformId, String ip) {
|
public OrderPaySignResponse.WechatPayParam createOrder(Integer memberId, LessonTicketOrderDTO lessonTicketOrderDTO, Integer platformId, String ip) {
|
||||||
|
|
||||||
// 判断用户信息
|
// 判断用户信息
|
||||||
if (memberId == null) {
|
if (memberId == null) {
|
||||||
@@ -237,17 +240,16 @@ public class MemberLessonTicketService extends BaseServiceImpl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
OrderPaySignResponse.WechatPayParam wechatPayParam = new OrderPaySignResponse.WechatPayParam();
|
OrderPaySignResponse.WechatPayParam wechatPayParam = new OrderPaySignResponse.WechatPayParam();
|
||||||
synchronized (lessonTicketOrderDTO.getLessonId()) {
|
|
||||||
|
|
||||||
// 2.判断票是否足够
|
// 2.判断票是否足够
|
||||||
Integer count = venueLessonTicketService.findCount(lessonTicketOrderDTO.getLessonId());
|
Integer count = venueLessonTicketService.findCount(lessonTicketOrderDTO.getLessonId());
|
||||||
if (count.intValue() < lessonTicketOrderDTO.getNum().intValue()) {
|
if (count.intValue() < lessonTicketOrderDTO.getNum().intValue()) {
|
||||||
throw new ServiceException(com.sv.exception.api.ExceptionCodeTemplate.LESSON_TICKET_ERROR);
|
throw new ServiceException(com.sv.exception.api.ExceptionCodeTemplate.LESSON_TICKET_ERROR);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* 课程库存锁
|
* 课程库存锁
|
||||||
*/
|
*/
|
||||||
RedisLock redisLock = new RedisLock(redisTemplate, LESSON_TICKET_LOCK_KEY + venueLesson.getId());
|
RedisLock redisLock = new RedisLock(redisTemplate, LESSON_TICKET_LOCK_KEY + venueLesson.getId());
|
||||||
try {
|
try {
|
||||||
//加锁
|
//加锁
|
||||||
boolean flag = redisLock.lock();
|
boolean flag = redisLock.lock();
|
||||||
@@ -298,7 +300,6 @@ public class MemberLessonTicketService extends BaseServiceImpl {
|
|||||||
redisLock.unlock();
|
redisLock.unlock();
|
||||||
throw new ServiceException(com.sv.exception.api.ExceptionCodeTemplate.SERVER_ERROR);
|
throw new ServiceException(com.sv.exception.api.ExceptionCodeTemplate.SERVER_ERROR);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return wechatPayParam;
|
return wechatPayParam;
|
||||||
}
|
}
|
||||||
@@ -313,7 +314,7 @@ public class MemberLessonTicketService extends BaseServiceImpl {
|
|||||||
* 预约课程,会员卡支付
|
* 预约课程,会员卡支付
|
||||||
*/
|
*/
|
||||||
@Transactional
|
@Transactional
|
||||||
public synchronized String createOrderByMemberCard(Integer memberId, LessonTicketOrderDTO lessonTicketOrderDTO, Integer platformId) {
|
public String createOrderByMemberCard(Integer memberId, LessonTicketOrderDTO lessonTicketOrderDTO, Integer platformId) {
|
||||||
|
|
||||||
// 判断用户信息
|
// 判断用户信息
|
||||||
if (memberId == null) {
|
if (memberId == null) {
|
||||||
@@ -355,7 +356,7 @@ public class MemberLessonTicketService extends BaseServiceImpl {
|
|||||||
memberCardService.findByStatus(memberCard.getVenueId(),memberCard.getVeneuType(),memberId,memberCard);
|
memberCardService.findByStatus(memberCard.getVenueId(),memberCard.getVeneuType(),memberId,memberCard);
|
||||||
}*/
|
}*/
|
||||||
String orderSn = "";
|
String orderSn = "";
|
||||||
synchronized (lessonTicketOrderDTO.getLessonId()) {
|
synchronized (memberKeyLock.getLock(lessonTicketOrderDTO.getLessonId())) {
|
||||||
// 2.判断票是否足够
|
// 2.判断票是否足够
|
||||||
Integer count = venueLessonTicketService.findCount(lessonTicketOrderDTO.getLessonId());
|
Integer count = venueLessonTicketService.findCount(lessonTicketOrderDTO.getLessonId());
|
||||||
if (count.intValue() < lessonTicketOrderDTO.getNum().intValue()) {
|
if (count.intValue() < lessonTicketOrderDTO.getNum().intValue()) {
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ package com.sv.service.api;
|
|||||||
|
|
||||||
import com.enums.*;
|
import com.enums.*;
|
||||||
import com.github.pagehelper.PageHelper;
|
import com.github.pagehelper.PageHelper;
|
||||||
|
import com.dw.ccm.wechat.base.pay.response.OrderResponse;
|
||||||
|
import com.sv.dto.api.BasketballPayResult;
|
||||||
import com.sv.dto.api.wechat.BaseResult;
|
import com.sv.dto.api.wechat.BaseResult;
|
||||||
import com.sv.dto.api.wechat.OrderPaySignResponse;
|
import com.sv.dto.api.wechat.OrderPaySignResponse;
|
||||||
import com.sv.entity.*;
|
import com.sv.entity.*;
|
||||||
@@ -11,6 +13,7 @@ import com.sv.mapper.OrderMapper;
|
|||||||
import com.sv.mapper.VenueMapper;
|
import com.sv.mapper.VenueMapper;
|
||||||
import com.sv.mapper.VenuePriceMapper;
|
import com.sv.mapper.VenuePriceMapper;
|
||||||
import com.sv.service.api.config.WechatPayService;
|
import com.sv.service.api.config.WechatPayService;
|
||||||
|
import com.sv.service.common.MemberKeyLock;
|
||||||
import com.ydd.framework.core.common.Pagination;
|
import com.ydd.framework.core.common.Pagination;
|
||||||
import com.ydd.framework.core.common.utils.RequestUtils;
|
import com.ydd.framework.core.common.utils.RequestUtils;
|
||||||
import com.ydd.framework.core.exception.ServiceException;
|
import com.ydd.framework.core.exception.ServiceException;
|
||||||
@@ -61,6 +64,10 @@ public class OrderService extends BaseServiceImpl {
|
|||||||
private VenuePriceMapper venuePriceMapper;
|
private VenuePriceMapper venuePriceMapper;
|
||||||
@Resource
|
@Resource
|
||||||
private BarcodeOrderTimeMapper barcodeOrderTimeMapper;
|
private BarcodeOrderTimeMapper barcodeOrderTimeMapper;
|
||||||
|
@Resource
|
||||||
|
private VenueEnterService venueEnterService;
|
||||||
|
@Resource
|
||||||
|
private MemberKeyLock memberKeyLock;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建订单
|
* 创建订单
|
||||||
@@ -244,11 +251,11 @@ public class OrderService extends BaseServiceImpl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 生成进场订单
|
* 生成进场订单(防重复下单)
|
||||||
* @param memberId
|
* @param memberId
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public OrderPaySignResponse.WechatPayParam createEnterVenueOrder(Integer venueId, Integer memberId, Integer enterFlag,PayTypeEnum payTypeEnum, BigDecimal price){
|
public BasketballPayResult createEnterVenueOrder(Integer venueId, Integer memberId, Integer enterFlag,PayTypeEnum payTypeEnum, BigDecimal price){
|
||||||
Venue venue = venueMapper.findById(venueId);
|
Venue venue = venueMapper.findById(venueId);
|
||||||
if (venue == null) {
|
if (venue == null) {
|
||||||
throw new ServiceException("未找到该场馆");
|
throw new ServiceException("未找到该场馆");
|
||||||
@@ -256,7 +263,6 @@ public class OrderService extends BaseServiceImpl {
|
|||||||
Member member = memberService.findById(memberId);
|
Member member = memberService.findById(memberId);
|
||||||
memberService.verify(member);
|
memberService.verify(member);
|
||||||
|
|
||||||
// 判断用户是否使用微信登录
|
|
||||||
MemberAuth memberAuth = memberAuthService.findByMemberId(memberId);
|
MemberAuth memberAuth = memberAuthService.findByMemberId(memberId);
|
||||||
if (memberAuth == null){
|
if (memberAuth == null){
|
||||||
throw new ServiceException(ExceptionCodeTemplate.BUY_ERROR);
|
throw new ServiceException(ExceptionCodeTemplate.BUY_ERROR);
|
||||||
@@ -269,43 +275,76 @@ public class OrderService extends BaseServiceImpl {
|
|||||||
boolean checkPrice = false;
|
boolean checkPrice = false;
|
||||||
for (VenuePrice venuePrice : priceList) {
|
for (VenuePrice venuePrice : priceList) {
|
||||||
if (price.divideAndRemainder(price)[1].compareTo(BigDecimal.ZERO) == 0) {
|
if (price.divideAndRemainder(price)[1].compareTo(BigDecimal.ZERO) == 0) {
|
||||||
// 取余数为0
|
|
||||||
checkPrice = true;
|
checkPrice = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!checkPrice) {
|
if (!checkPrice) {
|
||||||
throw new ServiceException("价格非法!");
|
throw new ServiceException("价格非法!");
|
||||||
}
|
}
|
||||||
//创建订单
|
|
||||||
Order order = new Order();
|
synchronized (memberKeyLock.getLock(memberId)) {
|
||||||
order.setOrderSn(createSn());
|
Order pendingOrder = orderMapper.findPendingBasketballOrder(memberId, venueId);
|
||||||
order.setPayType(payTypeEnum.value);
|
if (pendingOrder != null) {
|
||||||
order.setPrice(price);
|
OrderResponse wxResponse = wechatPayService.queryWechatOrder(pendingOrder.getOrderSn());
|
||||||
order.setPayStatus(PayStatusEnum.NOT_PAY.value);
|
if (wxResponse != null && wxResponse.isSuccess() && "SUCCESS".equals(wxResponse.getTradeState())) {
|
||||||
order.setType(OrderTypeEnum.BASKETBALL_ORDER.value);
|
pendingOrder.setPayStatus(PayStatusEnum.PAYED.value);
|
||||||
order.setPlatformId(venue.getPlatformId());
|
pendingOrder.setTradeSn(wxResponse.getTransactionId());
|
||||||
order.setMemberId(memberId);
|
pendingOrder.setPayTime(new Date());
|
||||||
order.setParentOrderId(venueId); /** 篮球入场这里输入场馆ID */
|
orderMapper.update(pendingOrder);
|
||||||
order.setCreatedId(enterFlag); /** 篮球入场这里输入出场结算还是入场结算 */
|
venueEnterService.paySuccess(pendingOrder);
|
||||||
orderMapper.insert(order);
|
|
||||||
//扣除用户余额 目前篮球订单不支持余额支付
|
BasketballPayResult paidResult = new BasketballPayResult();
|
||||||
// if(payTypeEnum.value.equals(PayTypeEnum.BALANCE.value)) {
|
paidResult.setPaidFlag(true);
|
||||||
// memberMoneyLogService.create(memberId, venue.getPlatformId(), MoneyLogEnum.JOIN.value, price.negate(), PayTypeEnum.BALANCE.value, null, venue.getId(), venue.getType(), null);
|
paidResult.setOrderSn(pendingOrder.getOrderSn());
|
||||||
// }
|
return paidResult;
|
||||||
if (EnterEnum.OUT.value == enterFlag) {
|
}
|
||||||
// 出场的话,将出场的订单设定 未结算 支付金额为 -1 , 这样批处理不会被结算,需要支付回调处理
|
|
||||||
BarcodeOrderTime lastOrder = barcodeOrderTimeMapper.findLastOrder(memberId, venueId);
|
OrderPaySignResponse.WechatPayParam wechatPayParam;
|
||||||
if (lastOrder != null) {
|
if (pendingOrder.getPrepayId() != null) {
|
||||||
lastOrder.setPaying(1);
|
wechatPayParam = wechatPayService.resignPayParam(pendingOrder.getOrderSn(), pendingOrder.getPrepayId());
|
||||||
lastOrder.setPayMoney(new BigDecimal(-1));
|
} else {
|
||||||
lastOrder.setOrderAddSn(order.getOrderSn());
|
wechatPayParam = memberCardOrderService.createUnifiedOrder(pendingOrder.getOrderSn(), memberId, RequestUtils.getIp(), "入场结算订单");
|
||||||
// lastOrder.setOrderSn(order.getOrderSn());
|
}
|
||||||
lastOrder.setModifiedTime(new Date());
|
wechatPayParam.setOrderSn(pendingOrder.getOrderSn());
|
||||||
barcodeOrderTimeMapper.updateByPrimaryKey(lastOrder);
|
|
||||||
|
BasketballPayResult result = new BasketballPayResult();
|
||||||
|
result.setPaidFlag(false);
|
||||||
|
result.setOrderSn(pendingOrder.getOrderSn());
|
||||||
|
result.setWechatPayParam(wechatPayParam);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Order order = new Order();
|
||||||
|
order.setOrderSn(createSn());
|
||||||
|
order.setPayType(payTypeEnum.value);
|
||||||
|
order.setPrice(price);
|
||||||
|
order.setPayStatus(PayStatusEnum.NOT_PAY.value);
|
||||||
|
order.setType(OrderTypeEnum.BASKETBALL_ORDER.value);
|
||||||
|
order.setPlatformId(venue.getPlatformId());
|
||||||
|
order.setMemberId(memberId);
|
||||||
|
order.setParentOrderId(venueId);
|
||||||
|
order.setCreatedId(enterFlag);
|
||||||
|
orderMapper.insert(order);
|
||||||
|
|
||||||
|
if (EnterEnum.OUT.value == enterFlag) {
|
||||||
|
BarcodeOrderTime lastOrder = barcodeOrderTimeMapper.findLastOrder(memberId, venueId);
|
||||||
|
if (lastOrder != null) {
|
||||||
|
lastOrder.setPaying(1);
|
||||||
|
lastOrder.setPayMoney(new BigDecimal(-1));
|
||||||
|
lastOrder.setOrderAddSn(order.getOrderSn());
|
||||||
|
lastOrder.setModifiedTime(new Date());
|
||||||
|
barcodeOrderTimeMapper.updateByPrimaryKey(lastOrder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
OrderPaySignResponse.WechatPayParam wechatPayParam = memberCardOrderService.createUnifiedOrder(order.getOrderSn(), memberId, RequestUtils.getIp(),"入场结算订单");
|
||||||
|
wechatPayParam.setOrderSn(order.getOrderSn());
|
||||||
|
|
||||||
|
BasketballPayResult result = new BasketballPayResult();
|
||||||
|
result.setPaidFlag(false);
|
||||||
|
result.setOrderSn(order.getOrderSn());
|
||||||
|
result.setWechatPayParam(wechatPayParam);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
OrderPaySignResponse.WechatPayParam wechatPayParam = memberCardOrderService.createUnifiedOrder(order.getOrderSn(), memberId, RequestUtils.getIp(),"入场结算订单");
|
|
||||||
return wechatPayParam;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.sv.service.api;
|
package com.sv.service.api;
|
||||||
|
|
||||||
|
import com.dw.ccm.wechat.base.pay.response.OrderResponse;
|
||||||
import com.enums.*;
|
import com.enums.*;
|
||||||
import com.github.pagehelper.PageHelper;
|
import com.github.pagehelper.PageHelper;
|
||||||
import com.sv.dto.BasketEnterResult;
|
import com.sv.dto.BasketEnterResult;
|
||||||
@@ -9,6 +10,7 @@ import com.sv.exception.api.ExceptionCodeTemplate;
|
|||||||
import com.sv.mapper.BarcodeOrderTimeMapper;
|
import com.sv.mapper.BarcodeOrderTimeMapper;
|
||||||
import com.sv.mapper.OrderMapper;
|
import com.sv.mapper.OrderMapper;
|
||||||
import com.sv.mapper.VenueMapper;
|
import com.sv.mapper.VenueMapper;
|
||||||
|
import com.sv.service.api.config.WechatPayService;
|
||||||
import com.sv.service.api.util.DateUtilCard;
|
import com.sv.service.api.util.DateUtilCard;
|
||||||
import com.ydd.framework.core.common.Pagination;
|
import com.ydd.framework.core.common.Pagination;
|
||||||
import com.ydd.framework.core.common.utils.ValidationUtils;
|
import com.ydd.framework.core.common.utils.ValidationUtils;
|
||||||
@@ -18,6 +20,7 @@ import com.ydd.oms.entity.enums.PayStatusEnum;
|
|||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
@@ -49,6 +52,9 @@ public class VenueEnterService extends BaseServiceImpl {
|
|||||||
BarcodeOrderTimeMapper barcodeOrderTimeMapper;
|
BarcodeOrderTimeMapper barcodeOrderTimeMapper;
|
||||||
@Resource
|
@Resource
|
||||||
OrderMapper orderMapper;
|
OrderMapper orderMapper;
|
||||||
|
@Lazy
|
||||||
|
@Resource
|
||||||
|
private WechatPayService wechatPayService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* api 接口
|
* api 接口
|
||||||
@@ -84,6 +90,30 @@ public class VenueEnterService extends BaseServiceImpl {
|
|||||||
if (!hasEffOrder) {
|
if (!hasEffOrder) {
|
||||||
logger.info(memberId + "&用户创建订单,开始进场,需要支付金额");
|
logger.info(memberId + "&用户创建订单,开始进场,需要支付金额");
|
||||||
if (price.compareTo(BigDecimal.ZERO) > 0) {
|
if (price.compareTo(BigDecimal.ZERO) > 0) {
|
||||||
|
Order pendingOrder = orderMapper.findPendingBasketballOrder(memberId, venueId);
|
||||||
|
if (pendingOrder != null) {
|
||||||
|
OrderResponse wxResponse = wechatPayService.queryWechatOrder(pendingOrder.getOrderSn());
|
||||||
|
if (wxResponse != null && wxResponse.isSuccess() && "SUCCESS".equals(wxResponse.getTradeState())) {
|
||||||
|
pendingOrder.setPayStatus(PayStatusEnum.PAYED.value);
|
||||||
|
pendingOrder.setTradeSn(wxResponse.getTransactionId());
|
||||||
|
pendingOrder.setPayTime(new Date());
|
||||||
|
orderMapper.update(pendingOrder);
|
||||||
|
paySuccess(pendingOrder);
|
||||||
|
basketEnterResult.setFlg(0);
|
||||||
|
basketEnterResult.setOrderSn(pendingOrder.getOrderSn());
|
||||||
|
basketEnterResult.setMsg("已支付成功,请入场");
|
||||||
|
return basketEnterResult;
|
||||||
|
}
|
||||||
|
basketEnterResult.setFlg(2);
|
||||||
|
basketEnterResult.setOrderSn(pendingOrder.getOrderSn());
|
||||||
|
if (PayStyleEnum.HOUR.getValue() == venue.getPayStyle()) {
|
||||||
|
basketEnterResult.setMsg("您有未完成的订单,请继续支付。预付押金" + price + "元,出门后按分钟结算");
|
||||||
|
} else {
|
||||||
|
basketEnterResult.setMsg("您有未完成的订单,请继续支付。订单金额" + price + "元");
|
||||||
|
}
|
||||||
|
basketEnterResult.setMoney(price);
|
||||||
|
return basketEnterResult;
|
||||||
|
}
|
||||||
checkOrderPaying(memberId);
|
checkOrderPaying(memberId);
|
||||||
basketEnterResult.setFlg(2);
|
basketEnterResult.setFlg(2);
|
||||||
if (PayStyleEnum.HOUR.getValue() == venue.getPayStyle()) {
|
if (PayStyleEnum.HOUR.getValue() == venue.getPayStyle()) {
|
||||||
@@ -101,15 +131,18 @@ public class VenueEnterService extends BaseServiceImpl {
|
|||||||
createBarcodeTimeOrder(memberId, venueId, timePayHour, "000");
|
createBarcodeTimeOrder(memberId, venueId, timePayHour, "000");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// 已有有效订单
|
basketEnterResult.setOrderSn(lastOrder.getOrderSn());
|
||||||
if (lastOrder.getPaying() == 1 && PayStyleEnum.TIME.getValue() == venue.getPayStyle()) {
|
if (lastOrder.getLastEnter() == null) {
|
||||||
// 按次计费:10分钟内重新入场,沿用原订单
|
logger.info(memberId + "&支付成功但门禁未开门,允许重试");
|
||||||
lastOrder.setPaying(0);
|
|
||||||
lastOrder.setModifiedTime(new Date());
|
|
||||||
barcodeOrderTimeMapper.updateByPrimaryKey(lastOrder);
|
|
||||||
logger.info(memberId + "&用户10分钟内重新入场,沿用原订单");
|
|
||||||
} else {
|
} else {
|
||||||
logger.info(memberId + "&用户已在场内,无需重复入场");
|
if (lastOrder.getPaying() == 1 && PayStyleEnum.TIME.getValue() == venue.getPayStyle()) {
|
||||||
|
lastOrder.setPaying(0);
|
||||||
|
lastOrder.setModifiedTime(new Date());
|
||||||
|
barcodeOrderTimeMapper.updateByPrimaryKey(lastOrder);
|
||||||
|
logger.info(memberId + "&用户10分钟内重新入场,沿用原订单");
|
||||||
|
} else {
|
||||||
|
logger.info(memberId + "&用户已在场内,无需重复入场");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return basketEnterResult;
|
return basketEnterResult;
|
||||||
@@ -150,6 +183,10 @@ public class VenueEnterService extends BaseServiceImpl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
BigDecimal basePrice = venuePriceEnter.getPrice();
|
BigDecimal basePrice = venuePriceEnter.getPrice();
|
||||||
|
// FIXME orderStart 是支付回调时间(paySuccess→createBarcodeTimeOrder 设的 new Date())
|
||||||
|
// 门禁异常场景下用户实际入场时间(lastEnter)可能晚于 orderStart,
|
||||||
|
// 导致结算时长偏多。如需精准计算,应优先取 lastEnter:
|
||||||
|
// Date startTime = lastOrder.getLastEnter() != null ? lastOrder.getLastEnter() : lastOrder.getOrderStart();
|
||||||
int minutes = DateUtilCard.diffMinute(lastOrder.getOrderStart(), dateNow);
|
int minutes = DateUtilCard.diffMinute(lastOrder.getOrderStart(), dateNow);
|
||||||
|
|
||||||
BigDecimal actualCost = basePrice.multiply(new BigDecimal(minutes))
|
BigDecimal actualCost = basePrice.multiply(new BigDecimal(minutes))
|
||||||
@@ -161,6 +198,25 @@ public class VenueEnterService extends BaseServiceImpl {
|
|||||||
+ difference);
|
+ difference);
|
||||||
|
|
||||||
if (difference.compareTo(BigDecimal.ZERO) > 0) {
|
if (difference.compareTo(BigDecimal.ZERO) > 0) {
|
||||||
|
Order pendingOrder = orderMapper.findPendingBasketballOrder(memberId, venueId);
|
||||||
|
if (pendingOrder != null) {
|
||||||
|
OrderResponse wxResponse = wechatPayService.queryWechatOrder(pendingOrder.getOrderSn());
|
||||||
|
if (wxResponse != null && wxResponse.isSuccess() && "SUCCESS".equals(wxResponse.getTradeState())) {
|
||||||
|
pendingOrder.setPayStatus(PayStatusEnum.PAYED.value);
|
||||||
|
pendingOrder.setTradeSn(wxResponse.getTransactionId());
|
||||||
|
pendingOrder.setPayTime(new Date());
|
||||||
|
orderMapper.update(pendingOrder);
|
||||||
|
paySuccess(pendingOrder);
|
||||||
|
result.setFlg(0);
|
||||||
|
result.setMsg("补交费用已支付成功,出场成功");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
result.setFlg(2);
|
||||||
|
result.setMoney(difference);
|
||||||
|
result.setOrderSn(pendingOrder.getOrderSn());
|
||||||
|
result.setMsg("您有未完成的补交订单,请继续支付。实际费用" + actualCost + "元,需补交" + difference + "元");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
checkOrderPaying(memberId);
|
checkOrderPaying(memberId);
|
||||||
result.setFlg(2);
|
result.setFlg(2);
|
||||||
result.setMoney(difference);
|
result.setMoney(difference);
|
||||||
|
|||||||
@@ -53,6 +53,50 @@ public class WechatPayService extends BaseServiceImpl {
|
|||||||
@Resource
|
@Resource
|
||||||
private VenueEnterService venueEnterService;
|
private VenueEnterService venueEnterService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询微信订单状态
|
||||||
|
*
|
||||||
|
* @param orderSn 商户订单号
|
||||||
|
* @return OrderResponse
|
||||||
|
*/
|
||||||
|
public OrderResponse queryWechatOrder(String orderSn) {
|
||||||
|
try {
|
||||||
|
PayConfig payConfig = payConfigService.findKey("face");
|
||||||
|
Assert.hasText(payConfig.getCert(), "证书找不到");
|
||||||
|
WeChatPayHelper weChatPayHelper = new WeChatPayHelper(payConfig.getCert());
|
||||||
|
weChatPayHelper.setAppId(payConfig.getAppId());
|
||||||
|
weChatPayHelper.setMchId(payConfig.getMchId());
|
||||||
|
weChatPayHelper.setKey(payConfig.getKey());
|
||||||
|
return weChatPayHelper.getOrder(null, orderSn, CommonUtils.CreateNonceStr(30));
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("查询微信订单异常", e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据已存在的订单重新签名支付参数(不调用统一下单)
|
||||||
|
*/
|
||||||
|
public OrderPaySignResponse.WechatPayParam resignPayParam(String orderSn, String prepayId) {
|
||||||
|
PayConfig payConfig = payConfigService.findKey("face");
|
||||||
|
OrderPaySignResponse.WechatPayParam wechatPayParam = new OrderPaySignResponse.WechatPayParam();
|
||||||
|
Map<String, String> param = Maps.newHashMap();
|
||||||
|
param.put("appId", payConfig.getAppId());
|
||||||
|
param.put("nonceStr", CommonUtils.CreateNonceStr(30));
|
||||||
|
param.put("package", "prepay_id=" + prepayId);
|
||||||
|
param.put("signType", "MD5");
|
||||||
|
param.put("timeStamp", String.valueOf(System.currentTimeMillis() / 1000));
|
||||||
|
param.put("paySign", CommonUtils.getSign(param, payConfig.getKey()));
|
||||||
|
wechatPayParam.setAppId(param.get("appId"));
|
||||||
|
wechatPayParam.setPrepayId(prepayId);
|
||||||
|
wechatPayParam.setTimeStamp(param.get("timeStamp"));
|
||||||
|
wechatPayParam.setPaySign(param.get("paySign"));
|
||||||
|
wechatPayParam.setNonceStr(param.get("nonceStr"));
|
||||||
|
wechatPayParam.setSignType("MD5");
|
||||||
|
wechatPayParam.setOrderSn(orderSn);
|
||||||
|
return wechatPayParam;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建微信支付的统一订单
|
* 创建微信支付的统一订单
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package com.sv.service.common;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class MemberKeyLock {
|
||||||
|
|
||||||
|
private final ConcurrentHashMap<Object, Object> lockMap = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
public Object getLock(Object key) {
|
||||||
|
return lockMap.computeIfAbsent(key, k -> new Object());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeLock(Object key) {
|
||||||
|
lockMap.remove(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -10,6 +10,7 @@ import com.sv.mapper.MemberMapper;
|
|||||||
import com.sv.service.api.MemberAuthService;
|
import com.sv.service.api.MemberAuthService;
|
||||||
import com.sv.service.api.MemberTokenService;
|
import com.sv.service.api.MemberTokenService;
|
||||||
import com.sv.service.common.MemberCardCommonService;
|
import com.sv.service.common.MemberCardCommonService;
|
||||||
|
import com.sv.service.common.MemberKeyLock;
|
||||||
import com.sv.service.common.MemberMoney;
|
import com.sv.service.common.MemberMoney;
|
||||||
import com.ydd.framework.core.common.Pagination;
|
import com.ydd.framework.core.common.Pagination;
|
||||||
import com.ydd.framework.core.common.utils.ValidationUtils;
|
import com.ydd.framework.core.common.utils.ValidationUtils;
|
||||||
@@ -150,6 +151,9 @@ public class MemberService extends MemberCardCommonService {
|
|||||||
return memberMapper.updateStatus(ids, status);
|
return memberMapper.updateStatus(ids, status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private MemberKeyLock memberKeyLock;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 保存用户
|
* 保存用户
|
||||||
*/
|
*/
|
||||||
@@ -157,7 +161,7 @@ public class MemberService extends MemberCardCommonService {
|
|||||||
ValidationUtils.assertNotBlank(member.getMobile(), "请输入手机号码");
|
ValidationUtils.assertNotBlank(member.getMobile(), "请输入手机号码");
|
||||||
VenueValidateUtils.assertMobile(member.getMobile());
|
VenueValidateUtils.assertMobile(member.getMobile());
|
||||||
|
|
||||||
synchronized (member.getMobile()){
|
synchronized (memberKeyLock.getLock(member.getMobile())){
|
||||||
// 根据手机号码创建新用户
|
// 根据手机号码创建新用户
|
||||||
Member memberInfo = createByMobile(member);
|
Member memberInfo = createByMobile(member);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import com.sv.mapper.VenueLessonTicketMapper;
|
|||||||
import com.sv.service.api.util.DateUtilCard;
|
import com.sv.service.api.util.DateUtilCard;
|
||||||
import com.sv.service.common.OSSClientUtil;
|
import com.sv.service.common.OSSClientUtil;
|
||||||
import com.sv.service.common.PlatformService;
|
import com.sv.service.common.PlatformService;
|
||||||
|
import com.sv.service.common.MemberKeyLock;
|
||||||
import com.sv.service.common.RedisLock;
|
import com.sv.service.common.RedisLock;
|
||||||
import com.ydd.framework.core.common.Pagination;
|
import com.ydd.framework.core.common.Pagination;
|
||||||
import com.ydd.framework.core.service.CacheService;
|
import com.ydd.framework.core.service.CacheService;
|
||||||
@@ -66,6 +67,8 @@ public class VenueLessonService extends BaseServiceImpl {
|
|||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private OSSClientUtil ossClientUtil;
|
private OSSClientUtil ossClientUtil;
|
||||||
|
@Resource
|
||||||
|
private MemberKeyLock memberKeyLock;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建场馆课程
|
* 创建场馆课程
|
||||||
@@ -77,7 +80,7 @@ public class VenueLessonService extends BaseServiceImpl {
|
|||||||
validateLessonDate(venueLesson);
|
validateLessonDate(venueLesson);
|
||||||
RedisLock redisLock = new RedisLock(redisTemplate,LESSON_TICKET_LOCK_KEY+venueLesson.getId());
|
RedisLock redisLock = new RedisLock(redisTemplate,LESSON_TICKET_LOCK_KEY+venueLesson.getId());
|
||||||
if (venueLesson.getId() != null && venueLesson.getId() > 0) {
|
if (venueLesson.getId() != null && venueLesson.getId() > 0) {
|
||||||
synchronized ("lesson" + venueLesson.getId().toString().intern()) {
|
synchronized (memberKeyLock.getLock(venueLesson.getId())) {
|
||||||
venueLessonMapper.deleteImagesById(venueLesson.getId());
|
venueLessonMapper.deleteImagesById(venueLesson.getId());
|
||||||
venueLessonTagMapper.deleteByLessonId(venueLesson.getId());
|
venueLessonTagMapper.deleteByLessonId(venueLesson.getId());
|
||||||
VenueLesson dbVenueLesson = venueLessonMapper.findById(venueLesson.getId());
|
VenueLesson dbVenueLesson = venueLessonMapper.findById(venueLesson.getId());
|
||||||
|
|||||||
@@ -436,4 +436,20 @@
|
|||||||
WHERE
|
WHERE
|
||||||
deleted = 0 and member_id = #{memberId} order by modified_time desc limit 1
|
deleted = 0 and member_id = #{memberId} order by modified_time desc limit 1
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
<select id="findPendingBasketballOrder" resultMap="OrderMap">
|
||||||
|
SELECT
|
||||||
|
<include refid="Field"></include>
|
||||||
|
FROM
|
||||||
|
<include refid="tableName"></include>
|
||||||
|
WHERE
|
||||||
|
deleted = 0
|
||||||
|
AND member_id = #{memberId}
|
||||||
|
AND parent_order_id = #{venueId}
|
||||||
|
AND type = 3
|
||||||
|
AND pay_status = 0
|
||||||
|
AND created_time >= DATE_SUB(NOW(), INTERVAL 10 MINUTE)
|
||||||
|
ORDER BY created_time DESC
|
||||||
|
LIMIT 1
|
||||||
|
</select>
|
||||||
</mapper>
|
</mapper>
|
||||||
|
|||||||
Reference in New Issue
Block a user