diff --git a/mallinkAdmin/src/main/java/com/iformall/config/ShiroConfig.java b/mallinkAdmin/src/main/java/com/iformall/config/ShiroConfig.java index 6b0de5002..5ae10dc1e 100644 --- a/mallinkAdmin/src/main/java/com/iformall/config/ShiroConfig.java +++ b/mallinkAdmin/src/main/java/com/iformall/config/ShiroConfig.java @@ -102,6 +102,7 @@ public class ShiroConfig { filterChainDefinitionMap.put("/wechat/login", "anon"); // 微信第三方登录callback filterChainDefinitionMap.put("/wechat/callback", "anon"); // 微信网页登录回调 filterChainDefinitionMap.put("/wechat/weChatUserLogin", "anon"); // 微信第三方登录 + // 验证码 filterChainDefinitionMap.put("/captcha.jpg", "anon"); // 官网 @@ -116,7 +117,7 @@ public class ShiroConfig { filterChainDefinitionMap.put("/wxMallApply/sendvalidationcode", "anon"); // 补发消息 - filterChainDefinitionMap.put("/msgrecord/resendMsg", "anon"); + filterChainDefinitionMap.put("/wxCoupon/updateStokeAndValidDate", "anon"); // static files filterChainDefinitionMap.put("/css/**", "anon"); diff --git a/mallinkAdmin/src/main/java/com/iformall/controller/base/BaseController.java b/mallinkAdmin/src/main/java/com/iformall/controller/base/BaseController.java index 032d699dd..c6e190b5e 100644 --- a/mallinkAdmin/src/main/java/com/iformall/controller/base/BaseController.java +++ b/mallinkAdmin/src/main/java/com/iformall/controller/base/BaseController.java @@ -66,7 +66,6 @@ public class BaseController { public TenantEntity getTenantInfo(){ Session session = SecurityUtils.getSubject().getSession(); String tenantId = (String)session.getAttribute(UserSession.tenantId); - TenantEntity tenantEntity = new TenantEntity(){{ setTenantId(tenantId); }}; diff --git a/mallinkAdmin/src/main/java/com/iformall/controller/market/WxCouponController.java b/mallinkAdmin/src/main/java/com/iformall/controller/market/WxCouponController.java index 4fcb9b40f..657835101 100644 --- a/mallinkAdmin/src/main/java/com/iformall/controller/market/WxCouponController.java +++ b/mallinkAdmin/src/main/java/com/iformall/controller/market/WxCouponController.java @@ -99,7 +99,7 @@ public class WxCouponController extends BaseController { if (resultData.code != 200) { return resultData; } - redisLock.setCouponStock(wxCoupon.getId(), wxCoupon.getInventory()); + redisLock.setCouponStock(wxCoupon.getId(), wxCoupon.getRemainInventory()); //启动投放审批 if(wxCoupon.getFlowParams() !=null && wxCoupon.getFlowParams().size()>0) { wxCoupon.getFlowParams().put("businessId",wxCoupon.getId()); @@ -128,7 +128,7 @@ public class WxCouponController extends BaseController { return new ResultData(ResultData.ERROR, "有活动正在上架,请先下架。"); } } - redisLock.setCouponStock(wxCoupon.getId(), wxCoupon.getInventory()); + redisLock.setCouponStock(wxCoupon.getId(), wxCoupon.getRemainInventory()); //启动审批流 if (wxCoupon.getFlowParams() != null && wxCoupon.getFlowParams().size() > 0) { logger.info("------coupon.update().businessType:"+wxCoupon.getFlowParams().get("businessType")); @@ -251,9 +251,9 @@ public class WxCouponController extends BaseController { updateCoupon.setStockApplyStatus(EnumRentContractAppStatus.APPLYING.getCode()); updateCoupon.setUpdateDate(new Date()); wxCouponService.update(updateCoupon); - redisLock.setCouponStock(wxCoupon.getId(), wxCoupon.getInventory()); + redisLock.setCouponStock(wxCoupon.getId(), wxCoupon.getRemainInventory()); } else { - redisLock.setCouponStock(wxCoupon.getId(), wxCoupon.getInventory()); + redisLock.setCouponStock(wxCoupon.getId(), wxCoupon.getRemainInventory()); return wxCouponService.updateCouponStockAndEndTime(wxCoupon); } diff --git a/mallinkAdmin/src/main/resources/application-dev.yml b/mallinkAdmin/src/main/resources/application-dev.yml index 588874364..5e27cca43 100644 --- a/mallinkAdmin/src/main/resources/application-dev.yml +++ b/mallinkAdmin/src/main/resources/application-dev.yml @@ -27,7 +27,7 @@ spring: #date-format: yyyy-MM-dd HH:mm:ss # REDIS redis: - host: 202.165.179.86 + host: 101.201.103.81 port: 6379 password: ENC(xPFDlgd6v8zUhJMbcKc0KmmQiqs9qHtk) timeout: 3600 @@ -98,7 +98,7 @@ wechat: componentToken: "formall2018" componentAesKey: "htKq8EjBMPNndfZQK9JiFojFaqFwFpw42VfeWFtx7HN" redis: - host: 202.165.179.86 + host: 101.201.103.81 port: 6379 password: ENC(xPFDlgd6v8zUhJMbcKc0KmmQiqs9qHtk) timeout: 3600 diff --git a/mallinkCApi/src/main/java/com/iformall/controller/WxCouponController.java b/mallinkCApi/src/main/java/com/iformall/controller/WxCouponController.java index 01ba206ce..73e242049 100644 --- a/mallinkCApi/src/main/java/com/iformall/controller/WxCouponController.java +++ b/mallinkCApi/src/main/java/com/iformall/controller/WxCouponController.java @@ -31,6 +31,7 @@ import com.iformall.service.WxCouponChannelService; import com.iformall.service.WxCouponService; import com.iformall.service.WxMerchantService; import com.iformall.utils.Constant; +import com.iformall.utils.RedisLock; import io.swagger.annotations.Api; import io.swagger.annotations.ApiImplicitParam; @@ -103,6 +104,7 @@ public class WxCouponController extends BaseController { } // end of 更新状态 updateActivityStatus(wxCouponCVo); + return new ResultData(wxCouponCVo); } diff --git a/mallinkCApi/src/main/java/com/iformall/controller/WxOrderController.java b/mallinkCApi/src/main/java/com/iformall/controller/WxOrderController.java index 9c6c6c175..af0026ce3 100644 --- a/mallinkCApi/src/main/java/com/iformall/controller/WxOrderController.java +++ b/mallinkCApi/src/main/java/com/iformall/controller/WxOrderController.java @@ -18,6 +18,8 @@ import com.iformall.service.WxCouponChannelService; import com.iformall.service.WxCouponService; import com.iformall.service.WxOrderService; import com.iformall.utils.Constant; +import com.iformall.utils.RedisLock; + import io.swagger.annotations.Api; import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiImplicitParams; @@ -56,6 +58,9 @@ public class WxOrderController extends BaseController { @Autowired @Qualifier("couponDetailRedisTemplate") RedisTemplate cdRedisTemplate; + + @Autowired + RedisLock redisLock; @ApiOperation(value = "下订单", notes = "{\"couponChannelId\":\"String\",\"couponId\":\"String\",\"press\":\"String\",\"orderGroupId\":\"String\",\"formId\":\"String\"}") @PostMapping("save") @@ -100,6 +105,12 @@ public class WxOrderController extends BaseController { return new ResultData(ErrorCode.COUPON_IS_EMPTY); } + //此处判断是否存在绝对保证库存不超卖的缓存,如果没有,则把当前的库存设置为最大值。如果有,则是后台设置的时候保存的,以那个为准。 + boolean hascache = redisLock.hasCouponStockCache(wxCouponCVo.getCouponId()); + if (!hascache) { + redisLock.setCouponStock(wxCouponCVo.getCouponId(), wxCouponCVo.getRemainInventory()); + } + resultData = couponUserCheck(user, wxCouponCVo); if (resultData != null) return resultData; @@ -120,6 +131,7 @@ public class WxOrderController extends BaseController { if (coupon.getStatus().equals(EnumCouponStatus.COUPON_STATUS_TAKE_OFFF.getCode())) { return new ResultData(ErrorCode.COUPON_IS_TAKE_OFF); } + WxOrder order = wxOrderService.saveOrderForCoupon(user, coupon, orderSaveDto, isPress); return new ResultData(order); } catch (MallinkException e) { diff --git a/mallinkCApi/src/main/java/com/iformall/controller/WxPayOrderController.java b/mallinkCApi/src/main/java/com/iformall/controller/WxPayOrderController.java index 50241c85c..e8ceb32e8 100644 --- a/mallinkCApi/src/main/java/com/iformall/controller/WxPayOrderController.java +++ b/mallinkCApi/src/main/java/com/iformall/controller/WxPayOrderController.java @@ -1,32 +1,47 @@ package com.iformall.controller; +import java.util.Map; + +import javax.servlet.http.HttpServletRequest; + +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RestController; + import com.github.pagehelper.PageInfo; import com.iformall.common.ErrorCode; import com.iformall.common.IdWorker; import com.iformall.common.Result; import com.iformall.common.ResultData; -import com.iformall.domain.po.*; +import com.iformall.domain.po.WxAppinfo; +import com.iformall.domain.po.WxCUser; +import com.iformall.domain.po.WxCUserBasicInfo; +import com.iformall.domain.po.WxOrder; +import com.iformall.domain.po.WxPayAccount; +import com.iformall.domain.po.WxPayOrder; import com.iformall.enums.EnumCreditLockedStatus; import com.iformall.enums.EnumPayStatus; import com.iformall.enums.EnumPayWay; import com.iformall.exception.MallinkException; import com.iformall.service.WxCUserBasicInfoService; +import com.iformall.service.WxOrderGroupService; import com.iformall.service.WxOrderService; import com.iformall.service.WxPayAccountService; import com.iformall.service.WxPayOrderService; import com.iformall.utils.IPUtil; + import io.swagger.annotations.Api; import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiImplicitParams; import io.swagger.annotations.ApiOperation; -import org.apache.commons.lang3.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.*; - -import javax.servlet.http.HttpServletRequest; -import java.util.Map; @RestController @RequestMapping("/api/pay") @@ -45,6 +60,9 @@ public class WxPayOrderController extends BaseController { @Autowired private WxPayAccountService wxPayAccountService; + + @Autowired + private WxOrderGroupService orderGroupService; //@ApiOperation(value = "发起微信小程序支付订单", notes = "{\"orderId\":\"string\"}") @RequestMapping(value = "/create", method = RequestMethod.POST) @@ -142,6 +160,10 @@ public class WxPayOrderController extends BaseController { } if (payOrder.getPayOrderStatus().equals(EnumPayStatus.PAY_STATUS_SUCCESS.getCode())) { order = wxOrderService.getById(orderId); + //如果是拼团,需要处理拼团状态和人数 + if(order.getOrderGroupId() != null && !order.getOrderGroupId().equals(0L)) { + orderGroupService.afterPaySuccessUpdate(order); + } return new ResultData(Result.SUCCESS, "支付状态更新成功", order); } else{ //查询微信订单状态并更新 diff --git a/mallinkCApi/src/main/java/com/iformall/controller/WxPressOrderController.java b/mallinkCApi/src/main/java/com/iformall/controller/WxPressOrderController.java index 50661e33b..9abf71790 100644 --- a/mallinkCApi/src/main/java/com/iformall/controller/WxPressOrderController.java +++ b/mallinkCApi/src/main/java/com/iformall/controller/WxPressOrderController.java @@ -147,7 +147,7 @@ public class WxPressOrderController extends BaseController { return new ResultData(ErrorCode.COUPON_PRESS_HAD_FINISHED); } - long time = System.currentTimeMillis() + RedisLock.TIMEOUT; + long time = System.currentTimeMillis() + RedisLock.LONG_TIMEOUT; String timeStr = String.valueOf(time); if (!redisLock.lock(orderIdStr, timeStr)) { logger.error("此砍价订单被锁定, orderId: " + orderIdStr); diff --git a/mallinkCallback/src/main/resources/application-dev.yml b/mallinkCallback/src/main/resources/application-dev.yml index 6a534086e..2d54ca13f 100644 --- a/mallinkCallback/src/main/resources/application-dev.yml +++ b/mallinkCallback/src/main/resources/application-dev.yml @@ -27,7 +27,7 @@ spring: #date-format: yyyy-MM-dd HH:mm:ss # REDIS redis: - host: 202.165.179.86 + host: 101.201.103.81 port: 6379 password: ENC(xPFDlgd6v8zUhJMbcKc0KmmQiqs9qHtk) timeout: 3600 @@ -97,7 +97,7 @@ wechat: componentToken: "formall2018" componentAesKey: "htKq8EjBMPNndfZQK9JiFojFaqFwFpw42VfeWFtx7HN" redis: - host: 202.165.179.86 + host: 101.201.103.81 port: 6379 password: ENC(xPFDlgd6v8zUhJMbcKc0KmmQiqs9qHtk) timeout: 3600 diff --git a/mallinkMQConsumer/src/main/java/com/iformall/mq/MqBaseConsumer.java b/mallinkMQConsumer/src/main/java/com/iformall/mq/MqBaseConsumer.java index 33df70929..390debf64 100644 --- a/mallinkMQConsumer/src/main/java/com/iformall/mq/MqBaseConsumer.java +++ b/mallinkMQConsumer/src/main/java/com/iformall/mq/MqBaseConsumer.java @@ -101,9 +101,11 @@ public class MqBaseConsumer { UpdateCouponStockMsg msg = (UpdateCouponStockMsg)JsonUtil.readValue(message,UpdateCouponStockMsg.class); updateCouponStockMsgService.send(msg); } - baseMsg.setMsgStatus(EnumMsgRecordStatus.CONSUME_SUCC.getCode()); - wxMsgRecordMapper.updateByBaseMsg(baseMsg); + //baseMsg.setMsgStatus(EnumMsgRecordStatus.CONSUME_SUCC.getCode()); + //wxMsgRecordMapper.updateByBaseMsg(baseMsg); }catch (Throwable e){ + log.error("consum received error: ", e); + /** try { log.error("consum received error: ", e); baseMsg.setStatusMessage(e.getMessage()); @@ -129,7 +131,7 @@ public class MqBaseConsumer { } }catch (Throwable e1){ log.error("更新db状态error: ", e1); - } + }*/ } } diff --git a/mallinkMQConsumer/src/main/java/com/iformall/mq/impl/AliyunRocketMqConsumer.java b/mallinkMQConsumer/src/main/java/com/iformall/mq/impl/AliyunRocketMqConsumer.java index 77827c01e..f74666ca1 100644 --- a/mallinkMQConsumer/src/main/java/com/iformall/mq/impl/AliyunRocketMqConsumer.java +++ b/mallinkMQConsumer/src/main/java/com/iformall/mq/impl/AliyunRocketMqConsumer.java @@ -41,35 +41,39 @@ public class AliyunRocketMqConsumer extends MqBaseConsumer { @Value("${spring.aliyunRocketmq.namesrvAddr}") private String namesrvAddr; - private static Consumer consumer = null; - @PostConstruct public void init() { - Properties properties = new Properties(); - // 您在控制台创建的 Group ID - properties.put(PropertyKeyConst.GROUP_ID, groupId); - // AccessKey 阿里云身份验证,在阿里云服务器管理控制台创建 - properties.put(PropertyKeyConst.AccessKey, accessKeyId); - // SecretKey 阿里云身份验证,在阿里云服务器管理控制台创建 - properties.put(PropertyKeyConst.SecretKey, accessKeySecret); - // 设置 TCP 接入域名,到控制台的实例基本信息中查看 - properties.put(PropertyKeyConst.NAMESRV_ADDR,namesrvAddr); - // 集群订阅方式(默认) - // properties.put(PropertyKeyConst.MessageModel, PropertyValueConst.CLUSTERING); - // 广播订阅方式 - // properties.put(PropertyKeyConst.MessageModel, PropertyValueConst.BROADCASTING); - consumer = ONSFactory.createConsumer(properties); - - consumer.subscribe(EnumMsgMqTopic.DEFAULT.getCode(), "*", new MessageListener() { //订阅多个 Tag - public Action consume(Message message, ConsumeContext context) { - System.out.println("Receive: " + message); - doMessage(new String(message.getBody())); - return Action.CommitMessage; - } - }); - - consumer.start(); - log.info(" aliyunrocketMq consumer start success! "+JSON.toJSONString(consumer)); + for (EnumMsgMqTopic topic: EnumMsgMqTopic.values()) { + Properties properties = new Properties(); + // 您在控制台创建的 Group ID + properties.put(PropertyKeyConst.GROUP_ID, topic.getGroupId()); + // AccessKey 阿里云身份验证,在阿里云服务器管理控制台创建 + properties.put(PropertyKeyConst.AccessKey, accessKeyId); + // SecretKey 阿里云身份验证,在阿里云服务器管理控制台创建 + properties.put(PropertyKeyConst.SecretKey, accessKeySecret); + // 设置 TCP 接入域名,到控制台的实例基本信息中查看 + properties.put(PropertyKeyConst.NAMESRV_ADDR,namesrvAddr); + // 集群订阅方式(默认) + // properties.put(PropertyKeyConst.MessageModel, PropertyValueConst.CLUSTERING); + // 广播订阅方式 + // properties.put(PropertyKeyConst.MessageModel, PropertyValueConst.BROADCASTING); + Consumer consumer = ONSFactory.createConsumer(properties); + consumer.subscribe(topic.getCode(), "*", new MessageListener() { //订阅多个 Tag + public Action consume(Message message, ConsumeContext context) { + try { + System.out.println("Receive: " + message); + doMessage(new String(message.getBody())); + return Action.CommitMessage; + }catch(Exception e) { + log.error("AliyunRocketMqConsumer error:",e); + return Action.ReconsumeLater; + } + } + }); + consumer.start(); + log.info(" aliyunrocketMq consumer start success! "+JSON.toJSONString(consumer)); + } + } } diff --git a/mallinkMQConsumer/src/main/resources/application-dev.yml b/mallinkMQConsumer/src/main/resources/application-dev.yml index 1fbada993..c8b563a80 100644 --- a/mallinkMQConsumer/src/main/resources/application-dev.yml +++ b/mallinkMQConsumer/src/main/resources/application-dev.yml @@ -28,7 +28,7 @@ spring: # REDIS redis: - host: 202.165.179.86 + host: 101.201.103.81 port: 6379 password: ENC(xPFDlgd6v8zUhJMbcKc0KmmQiqs9qHtk) timeout: 3600 @@ -91,7 +91,7 @@ wechat: componentToken: "formall2018" componentAesKey: "htKq8EjBMPNndfZQK9JiFojFaqFwFpw42VfeWFtx7HN" redis: - host: 202.165.179.86 + host: 101.201.103.81 port: 6379 password: ENC(xPFDlgd6v8zUhJMbcKc0KmmQiqs9qHtk) timeout: 3600 diff --git a/mallinkPosApi/src/main/resources/application-dev.yml b/mallinkPosApi/src/main/resources/application-dev.yml index 54c956f1b..dad7f419c 100644 --- a/mallinkPosApi/src/main/resources/application-dev.yml +++ b/mallinkPosApi/src/main/resources/application-dev.yml @@ -26,7 +26,7 @@ spring: #date-format: yyyy-MM-dd HH:mm:ss # REDIS redis: - host: 202.165.179.86 + host: 101.201.103.81 port: 6379 password: ENC(xPFDlgd6v8zUhJMbcKc0KmmQiqs9qHtk) timeout: 3600 @@ -95,7 +95,7 @@ wechat: componentToken: "formall2018" componentAesKey: "htKq8EjBMPNndfZQK9JiFojFaqFwFpw42VfeWFtx7HN" redis: - host: 202.165.179.86 + host: 101.201.103.81 port: 6379 password: ENC(xPFDlgd6v8zUhJMbcKc0KmmQiqs9qHtk) timeout: 3600 diff --git a/mallinkSchedule/src/main/java/com/iformall/ScheduleApplication.java b/mallinkSchedule/src/main/java/com/iformall/ScheduleApplication.java index bc52f3a3e..44a96a203 100644 --- a/mallinkSchedule/src/main/java/com/iformall/ScheduleApplication.java +++ b/mallinkSchedule/src/main/java/com/iformall/ScheduleApplication.java @@ -7,6 +7,8 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.EnableAspectJAutoProxy; + import springfox.documentation.swagger2.annotations.EnableSwagger2; /** @@ -18,6 +20,7 @@ import springfox.documentation.swagger2.annotations.EnableSwagger2; @EnableSwagger2 @EnableRocketMQ @EnableEncryptableProperties +@EnableAspectJAutoProxy(exposeProxy = true) public class ScheduleApplication { @Value("${fm.exception}") diff --git a/mallinkSchedule/src/main/resources/application-dev.yml b/mallinkSchedule/src/main/resources/application-dev.yml index 6a124f9cb..5570f70a0 100644 --- a/mallinkSchedule/src/main/resources/application-dev.yml +++ b/mallinkSchedule/src/main/resources/application-dev.yml @@ -28,7 +28,7 @@ spring: # REDIS redis: - host: 202.165.179.86 + host: 101.201.103.81 port: 6379 password: ENC(xPFDlgd6v8zUhJMbcKc0KmmQiqs9qHtk) timeout: 3600 @@ -91,7 +91,7 @@ wechat: componentToken: "formall2018" componentAesKey: "htKq8EjBMPNndfZQK9JiFojFaqFwFpw42VfeWFtx7HN" redis: - host: 202.165.179.86 + host: 101.201.103.81 port: 6379 password: ENC(xPFDlgd6v8zUhJMbcKc0KmmQiqs9qHtk) timeout: 3600 diff --git a/mallinkService/src/main/java/com/iformall/domain/po/WxCardInfo.java b/mallinkService/src/main/java/com/iformall/domain/po/WxCardInfo.java index 172354dd6..224a6239c 100644 --- a/mallinkService/src/main/java/com/iformall/domain/po/WxCardInfo.java +++ b/mallinkService/src/main/java/com/iformall/domain/po/WxCardInfo.java @@ -16,6 +16,8 @@ import java.util.Date; @EqualsAndHashCode(callSuper = true) public class WxCardInfo extends TenantEntity { + private static final long serialVersionUID = 2974374593127477999L; + @Excel(name = "卡号", width = 20, orderNum = "1") @io.swagger.annotations.ApiModelProperty(value="主键ID-与coupon_order_id一致",name="id") protected Long id; diff --git a/mallinkService/src/main/java/com/iformall/enums/EnumMsgMqTopic.java b/mallinkService/src/main/java/com/iformall/enums/EnumMsgMqTopic.java index e342de989..55cd95f91 100644 --- a/mallinkService/src/main/java/com/iformall/enums/EnumMsgMqTopic.java +++ b/mallinkService/src/main/java/com/iformall/enums/EnumMsgMqTopic.java @@ -4,8 +4,8 @@ package com.iformall.enums; * Created by luozukai */ public enum EnumMsgMqTopic { - DEFAULT("topic-1", "默认"), - STOCK("stock","库存"), + DEFAULT("topic-1","GID_P_1", "默认"), + STOCK("stock","GID_P_2","库存"), ; public static EnumMsgMqTopic getEnum(String code) { @@ -19,10 +19,12 @@ public enum EnumMsgMqTopic { private String code; private String message; + private String groupId; - EnumMsgMqTopic(String code, String message) { + EnumMsgMqTopic(String code, String groupId,String message) { this.code = code; this.message = message; + this.groupId = groupId; } public String getCode() { @@ -32,4 +34,12 @@ public enum EnumMsgMqTopic { public String getMessage() { return message; } + + public String getGroupId() { + return groupId; + } + + public void setGroupId(String groupId) { + this.groupId = groupId; + } } diff --git a/mallinkService/src/main/java/com/iformall/mapper/WxCardInfoMapper.java b/mallinkService/src/main/java/com/iformall/mapper/WxCardInfoMapper.java index 7d4be7a49..ded5eae3d 100644 --- a/mallinkService/src/main/java/com/iformall/mapper/WxCardInfoMapper.java +++ b/mallinkService/src/main/java/com/iformall/mapper/WxCardInfoMapper.java @@ -11,5 +11,7 @@ public interface WxCardInfoMapper extends CommonMapper { List findVoList(WxCardVo wxCardVo); void updateTransferStatusByCouponId(Long couponId); + + List findList(WxCardInfo wxCardInfo); } diff --git a/mallinkService/src/main/java/com/iformall/mq/impl/AliyunRocketMqMessageProducer.java b/mallinkService/src/main/java/com/iformall/mq/impl/AliyunRocketMqMessageProducer.java index 9ef3d3c11..e539e831d 100644 --- a/mallinkService/src/main/java/com/iformall/mq/impl/AliyunRocketMqMessageProducer.java +++ b/mallinkService/src/main/java/com/iformall/mq/impl/AliyunRocketMqMessageProducer.java @@ -1,6 +1,8 @@ package com.iformall.mq.impl; import java.util.Date; +import java.util.HashMap; +import java.util.Map; import java.util.Properties; import javax.annotation.PostConstruct; @@ -18,6 +20,7 @@ import com.aliyun.openservices.ons.api.Producer; import com.aliyun.openservices.ons.api.PropertyKeyConst; import com.aliyun.openservices.ons.api.SendResult; import com.iformall.domain.po.msg.BaseMsg; +import com.iformall.enums.EnumMsgMqTopic; import com.iformall.mq.MQConfig; import com.iformall.mq.MqBaseProducer; import com.iformall.utils.JsonUtil; @@ -52,28 +55,37 @@ public class AliyunRocketMqMessageProducer implements MqBaseProducer { //@Autowired //private WxMsgRecordService wxMsgRecordService; - private static Producer producer = null; + private static Map producerMap = null; @PostConstruct public void init() { - Properties properties = new Properties(); - properties.setProperty(PropertyKeyConst.GROUP_ID, groupId); - // AccessKey 阿里云身份验证,在阿里云服务器管理控制台创建 - properties.put(PropertyKeyConst.AccessKey,accessKeyId); - // SecretKey 阿里云身份验证,在阿里云服务器管理控制台创建 - properties.put(PropertyKeyConst.SecretKey, accessKeySecret); - //设置发送超时时间,单位毫秒 - properties.setProperty(PropertyKeyConst.SendMsgTimeoutMillis, "3000"); - // 设置 TCP 接入域名,到控制台的实例基本信息中查看 - properties.put(PropertyKeyConst.NAMESRV_ADDR,namesrvAddr); - producer = ONSFactory.createProducer(properties); - // 在发送消息前,必须调用 start 方法来启动 Producer,只需调用一次即可 - producer.start(); - log.info("aliyunrocketmq producer info :"+JSON.toJSONString(producer)); + producerMap = new HashMap(); + for (EnumMsgMqTopic topic: EnumMsgMqTopic.values()) { + Properties properties = new Properties(); + properties.setProperty(PropertyKeyConst.GROUP_ID, topic.getGroupId()); + // AccessKey 阿里云身份验证,在阿里云服务器管理控制台创建 + properties.put(PropertyKeyConst.AccessKey,accessKeyId); + // SecretKey 阿里云身份验证,在阿里云服务器管理控制台创建 + properties.put(PropertyKeyConst.SecretKey, accessKeySecret); + //设置发送超时时间,单位毫秒 + properties.setProperty(PropertyKeyConst.SendMsgTimeoutMillis, "3000"); + // 设置 TCP 接入域名,到控制台的实例基本信息中查看 + properties.put(PropertyKeyConst.NAMESRV_ADDR,namesrvAddr); + Producer producer = ONSFactory.createProducer(properties); + // 在发送消息前,必须调用 start 方法来启动 Producer,只需调用一次即可 + producer.start(); + log.info("aliyunrocketmq producer info :"+JSON.toJSONString(producer)); + producerMap.put(topic.getCode(), producer); + } } @Override public void sendMessage(BaseMsg data, String topic, String tags, String keys) { + Producer producer = producerMap.get(topic); + if (null == producer) { + log.error("topic :"+topic+" has no AliyunRocketMqMessageProducer."); + return; + } if (producer.isClosed()) { producer.start(); } diff --git a/mallinkService/src/main/java/com/iformall/service/WxOrderGroupService.java b/mallinkService/src/main/java/com/iformall/service/WxOrderGroupService.java index 2672ecd11..c1aaf7ecb 100644 --- a/mallinkService/src/main/java/com/iformall/service/WxOrderGroupService.java +++ b/mallinkService/src/main/java/com/iformall/service/WxOrderGroupService.java @@ -32,5 +32,10 @@ public interface WxOrderGroupService { List findList(WxOrderGroup group); PageInfo queryOrderGroupMarketingList(WxOrderGroupMarketing marketing, Integer pageNum, Integer pageSize); + + /** + * 支付成功之后,更新接口调用 + */ + void afterPaySuccessUpdate(WxOrder order); } diff --git a/mallinkService/src/main/java/com/iformall/service/WxOrderService.java b/mallinkService/src/main/java/com/iformall/service/WxOrderService.java index 28ecccc3c..9a62b915a 100644 --- a/mallinkService/src/main/java/com/iformall/service/WxOrderService.java +++ b/mallinkService/src/main/java/com/iformall/service/WxOrderService.java @@ -226,5 +226,8 @@ public interface WxOrderService { * H5支付后, 券再注入 */ Long saveOuterOrderForCoupon(WxCUser user, WxCoupon coupon, Long couponChannelId, String formId, Long couponPasswordId); + + + int countGroupOrder(Long groupId,boolean ignoreUnPay); } diff --git a/mallinkService/src/main/java/com/iformall/service/impl/WxOrderGroupServiceImpl.java b/mallinkService/src/main/java/com/iformall/service/impl/WxOrderGroupServiceImpl.java index 491adc7d6..e0d299b5b 100644 --- a/mallinkService/src/main/java/com/iformall/service/impl/WxOrderGroupServiceImpl.java +++ b/mallinkService/src/main/java/com/iformall/service/impl/WxOrderGroupServiceImpl.java @@ -65,6 +65,59 @@ public class WxOrderGroupServiceImpl implements WxOrderGroupService { @Autowired WxCouponChannelMapper wxCouponChannelMapper; + @Override + public void afterPaySuccessUpdate(WxOrder order) { + // 参与拼团 + WxOrderGroup wxOrderGroup = wxOrderGroupMapper.selectById(order.getOrderGroupId()); + if (null == wxOrderGroup) { + //错误,更新状态,定时任务会发起退款,回滚库存 + order.setOrderStatus(EnumOrderStatus.ORDER_STATUS_COOPERATING_UNPAID.getCode()); + wxOrderMapper.updateById(order); + throw new MallinkException(ErrorCode.ORDER_GROUP_COOPERATING_FAILD.getCode(),"WxOrderGroup is null."+order.getOrderGroupId()); + } + WxCoupon wxCoupon = wxCouponMapper.selectById(order.getProductId()); + if (null == wxCoupon) { + throw new MallinkException(ErrorCode.ORDER_GROUP_COOPERATING_FAILD.getCode(),"WxCoupon is null. orderId:"+order.getId()); + } + if (wxOrderGroup.getStatus() == EnumOrderStatus.ORDER_STATUS_COOPERATING_COMPLETE.getCode()) { + return; + } + int remainPeople = updateOrderGroup(wxOrderGroup,order,wxCoupon); + if (remainPeople == 0) { + actionAfterOrderGroupSuccess(order, order.getOrderGroupId()); + } + } + + + private int updateOrderGroup(WxOrderGroup wxOrderGroup,WxOrder order, WxCoupon wxCoupon) { + //锁住人数 + long time = System.currentTimeMillis() + RedisLock.LONG_TIMEOUT; + String timeStr = String.valueOf(time); + boolean grouppeopleLock = redisLock.lock("grouppeopleLock_"+order.getOrderGroupId(), timeStr); + if (!grouppeopleLock) { + throw new MallinkException(ErrorCode.ORDER_GROUP_COOPERATING_FAILD.getCode(),"参团锁定失败,请稍后再试。"); + } + //此处拼团数量应从订单总数查询 + int ordercount = wxOrderService.countGroupOrder(order.getOrderGroupId(),true); + Integer remainPeople = wxCoupon.getPressLimitNum()-ordercount; + //Integer remainPeople = wxOrderGroup.getRemainPeople()-1; + wxOrderGroup.setStatus(remainPeople <= 0 ? EnumOrderStatus.ORDER_STATUS_COOPERATING_COMPLETE.getCode() : wxOrderGroup.getStatus()); + wxOrderGroup.setUpdateDate(new Date()); + wxOrderGroup.setRemainPeople(remainPeople); + logger.info("非首次拼团,更新拼团信息, 剩余人数-1"); + int row = wxOrderGroupMapper.updateOrderGroup(wxOrderGroup); + if (row != 1) { + //错误,更新状态,定时任务会发起退款,回滚库存 + order.setOrderStatus(EnumOrderStatus.ORDER_STATUS_COOPERATING_UNPAID.getCode()); + wxOrderMapper.updateById(order); + redisLock.unlock("grouppeopleLock_"+order.getOrderGroupId(), timeStr); + throw new MallinkException(ErrorCode.ORDER_GROUP_COOPERATING_FAILD.getCode(),"参团失败,将稍后退款."); + }else { + redisLock.unlock("grouppeopleLock_"+order.getOrderGroupId(), timeStr); + } + return remainPeople; + } + @Override @Transactional(propagation = Propagation.REQUIRED, rollbackFor = {Exception.class}) public void createOrderGroup(WxOrder order, WxCoupon wxCoupon) { @@ -75,27 +128,20 @@ public class WxOrderGroupServiceImpl implements WxOrderGroupService { // 参与拼团 WxOrderGroup wxOrderGroup = wxOrderGroupMapper.selectById(orderGroupId); if (null == wxOrderGroup) { - //错误,更新状态,定时任务会发起退款 - order.setOrderStatus(EnumOrderStatus.ORDER_STATUS_COOPERATING_FAILD.getCode()); + //错误,更新状态,定时任务会发起退款,回滚库存 + order.setOrderStatus(EnumOrderStatus.ORDER_STATUS_COOPERATING_UNPAID.getCode()); wxOrderMapper.updateById(order); throw new MallinkException(ErrorCode.ORDER_GROUP_COOPERATING_FAILD.getCode(),"WxOrderGroup is null."+orderGroupId); } if(wxOrderGroup.getRemainPeople()<1) { - //错误,更新状态,定时任务会发起退款 - order.setOrderStatus(EnumOrderStatus.ORDER_STATUS_COOPERATING_FAILD.getCode()); + //错误,更新状态,定时任务会发起退款,回滚库存 + order.setOrderStatus(EnumOrderStatus.ORDER_STATUS_COOPERATING_UNPAID.getCode()); wxOrderMapper.updateById(order); throw new MallinkException(ErrorCode.ORDER_GROUP_COOPERATING_FAILD.getCode(),"参团人数已满,将稍后退款。"); } - Integer remainPeople = wxOrderGroup.getRemainPeople()-1; - wxOrderGroup.setStatus(remainPeople == 0 ? EnumOrderStatus.ORDER_STATUS_COOPERATING_COMPLETE.getCode() : wxOrderGroup.getStatus()); - wxOrderGroup.setUpdateDate(new Date()); - logger.info("非首次拼团,更新拼团信息, 剩余人数-1"); - int row = wxOrderGroupMapper.updateOrderGroup(wxOrderGroup); - if (row != 1) { - //TODO 这个时候应该要发起异步退款。 - throw new MallinkException(ErrorCode.ORDER_GROUP_COOPERATING_FAILD.getCode(),"参团失败,将稍后退款."); - } - + + int remainPeople = updateOrderGroup(wxOrderGroup,order,wxCoupon); + // 更新订单信息 order.setOrderStatus(wxOrderGroup.getStatus()); order.setPressEndDate(wxOrderGroup.getExpiredDate()); @@ -382,4 +428,5 @@ public class WxOrderGroupServiceImpl implements WxOrderGroupService { } } } + } diff --git a/mallinkService/src/main/java/com/iformall/service/impl/WxOrderServiceImpl.java b/mallinkService/src/main/java/com/iformall/service/impl/WxOrderServiceImpl.java index 84882f22b..15e848ebe 100644 --- a/mallinkService/src/main/java/com/iformall/service/impl/WxOrderServiceImpl.java +++ b/mallinkService/src/main/java/com/iformall/service/impl/WxOrderServiceImpl.java @@ -28,6 +28,7 @@ import org.springframework.transaction.annotation.Transactional; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.conditions.Wrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageInfo; @@ -505,7 +506,7 @@ public class WxOrderServiceImpl implements WxOrderService { * @param wxCouponSendVo */ private void stockMerchantReduce(WxCUser user, WxCoupon coupon, String couponIdStr, WxCouponSendVo wxCouponSendVo) { - long time = System.currentTimeMillis() + RedisLock.TIMEOUT; + long time = System.currentTimeMillis() + RedisLock.LONG_TIMEOUT; String timeStr = String.valueOf(time); // 库存加锁 if (!redisLock.lock(couponIdStr, timeStr)) { @@ -621,13 +622,13 @@ public class WxOrderServiceImpl implements WxOrderService { } if (count >= coupon.getUseLimitQuantity()) { logger.error("此券购买数量已超限, couponId: " + couponIdStr + ", count: " + count); - throw new MallinkException(ErrorCode.ORDER_IS_LIMITED); + throw new MallinkException(ErrorCode.ORDER_IS_LIMITED.getCode(),"此券购买数量已超限, couponId: " + couponIdStr + ", count: " + count); } try { //减库存,从redis中取,然后发mq消息同步到数据库 long stock = redisLock.decrease(EnumCacheKey.COUPON_STOCK.getMessage()+coupon.getId(), 1); - if (stock <= 0 ) { + if (stock < 0 ) { throw new MallinkException(ErrorCode.ORDER_IS_FAIL.getCode(),"券库存已为零!"); } UpdateCouponStockMsg msg = new UpdateCouponStockMsg(); @@ -637,8 +638,8 @@ public class WxOrderServiceImpl implements WxOrderService { msg.setMsgType(EnumMsgRecordType.COUPON_STOCK.getCode()); mqBaseProducer.sendMessage(msg, EnumMsgMqTopic.STOCK.getCode(), "*", "decrease_stock_"+coupon.getId()); } catch (RuntimeException e) { - logger.error("此券减库存失败, couponId: " + couponIdStr); - throw new MallinkException(ErrorCode.ORDER_IS_FAIL); + logger.error("此券减库存失败, couponId: " + couponIdStr,e); + throw new MallinkException(ErrorCode.ORDER_IS_FAIL.getCode(),e.getMessage()); } } @@ -737,7 +738,7 @@ public class WxOrderServiceImpl implements WxOrderService { Long couponId = updateOrder.getProductId(); String couponIdStr = "" + couponId; //加锁 - long time = System.currentTimeMillis() + 300*RedisLock.TIMEOUT; + long time = System.currentTimeMillis() + RedisLock.LONG_TIMEOUT; String timeStr = String.valueOf(time); if (!redisLock.lock(couponIdStr, timeStr)) { @@ -1006,86 +1007,102 @@ public class WxOrderServiceImpl implements WxOrderService { if (coupon.getType().equals(EnumCouponType.CARD_MULTIMCH.getCode())) { isCard = true; } - final IdWorker idWorker = IdWorker.get(); - - WxCouponOrder couponOrder = new WxCouponOrder(); - couponOrder.setId(idWorker.nextId()); - couponOrder.updateTenantInfo(order); - couponOrder.setCouponId(order.getProductId()); - couponOrder.setCouponType(coupon.getType()); - couponOrder.setCUserId(user.getId()); - couponOrder.setOwnerId(user.getId()); - couponOrder.setAutoRefund(coupon.getAutoRefund()); - couponOrder.setOrderId(order.getOrderNumber()); - couponOrder.setExpiredTime(valid_date); - if (!isCard) { - couponOrder.setCouponOrderStatus(EnumCouponOrderStatus.COUPON_ORDER_USE_WAIT.getCode()); - } else { - couponOrder.setCouponOrderStatus(EnumCouponOrderStatus.CARD_USING.getCode()); + + //TODO 如果orderId已经存在,则不再添加 + WxCouponOrder couponOrderQ = new WxCouponOrder(); + couponOrderQ.setOrderId(order.getId()); + WxCouponOrder couponOrder = null; + List couponorderlist = wxCouponOrderMapper.findList(couponOrderQ); + if (null != couponorderlist && couponorderlist.size() > 0 ) { + couponOrder = couponorderlist.get(0); + }else { + final IdWorker idWorker = IdWorker.get(); + couponOrder = new WxCouponOrder(); + couponOrder.setId(idWorker.nextId()); + couponOrder.updateTenantInfo(order); + couponOrder.setCouponId(order.getProductId()); + couponOrder.setCouponType(coupon.getType()); + couponOrder.setCUserId(user.getId()); + couponOrder.setOwnerId(user.getId()); + couponOrder.setAutoRefund(coupon.getAutoRefund()); + couponOrder.setOrderId(order.getOrderNumber()); + couponOrder.setExpiredTime(valid_date); + if (!isCard) { + couponOrder.setCouponOrderStatus(EnumCouponOrderStatus.COUPON_ORDER_USE_WAIT.getCode()); + } else { + couponOrder.setCouponOrderStatus(EnumCouponOrderStatus.CARD_USING.getCode()); + } + couponOrder.setCreateDate(curr); + couponOrder.setUpdateDate(curr); + couponOrder.setCouponPrice(order.getPayment()); + wxCouponOrderMapper.insert(couponOrder); } - couponOrder.setCreateDate(curr); - couponOrder.setUpdateDate(curr); - couponOrder.setCouponPrice(order.getPayment()); - - wxCouponOrderMapper.insert(couponOrder); /// 储值卡信息添加 if (isCard) { - Integer fee = 0; - WxCardInfo cardInfo = new WxCardInfo(); - cardInfo.setId(couponOrder.getId()); - cardInfo.updateTenantInfo(order); - cardInfo.setCouponId(order.getProductId()); - cardInfo.setAmount(coupon.getPrice()); - cardInfo.setSaleAmount(coupon.getSalePrice()); - cardInfo.setRemainingAmount(coupon.getPrice()); - if (!coupon.checkIsFree()) { - // 有价卡 - cardInfo.setTransactionId(payOrder.getTransactionId()); - if (payOrder.getShareAmount() != null) { - // 开启分账 - fee = payOrder.getPayAmount() - payOrder.getShareAmount(); - cardInfo.setShareFeeAmount(payOrder.getShareAmount()); - cardInfo.setRemainingShareFeeAmount(payOrder.getShareAmount()); - cardInfo.setRateAmount(payOrder.getRateAmount()); - } else { - // 未开启分账 - fee = PayUtils.getPayRate(payOrder.getPayAmount(), payAccount.getRate(), false); - Integer shareAmount = payOrder.getPayAmount() - fee; - cardInfo.setShareFeeAmount(shareAmount); - cardInfo.setRemainingShareFeeAmount(shareAmount); - if (payAccount.getRealRate() != null) { - int iRealChargeFee = PayUtils.getPayRate(payOrder.getPayAmount(), payAccount.getRealRate(), true); - if (fee > iRealChargeFee) { - cardInfo.setRateAmount(fee - iRealChargeFee); - } - } - } - } else { - // 免费卡 - cardInfo.setShareFeeAmount(0); - cardInfo.setRemainingShareFeeAmount(0); - cardInfo.setRateAmount(0); - if (coupon.getPasswordSupport().equals(EnumCouponPasswordSupport.SUPPORTED.getCode())) { - WxCouponPassword updateCPwd = new WxCouponPassword(); - updateCPwd.setId(couponPasswordId); - updateCPwd.setCardId(cardInfo.getId()); - updateCPwd.setStatus(EnumCouponPasswordStatus.USED.getCode()); - couponPasswordMapper.updateById(updateCPwd); - } - } - - cardInfo.setServiceFeeAmount(fee); - cardInfo.setCreateDate(curr); - cardInfo.setUpdateDate(curr); - cardInfo.setSupportTransfer(coupon.getSupportTransfer()); - - //检查卡是否下架,如果是,不可转赠 - WxCouponChannel wxCouponChannel = wxCouponChannelMapper.selectById(order.getCouponChannelId()); - if (wxCouponChannel != null && wxCouponChannel.getStatus().equals(EnumCouponChannelStatus.STATUS_TAKE_OFFF.getCode())) { - cardInfo.setSupportTransfer(EnumCouponTransfer.NO.getCode()); - } - wxCardInfoMapper.insert(cardInfo); + //判断该transctionId是否已经存在,如果存在,则不添加 + WxCardInfo cardInfoq = new WxCardInfo(); + cardInfoq.setTransactionId(payOrder.getTransactionId()); + List cardInfoList = wxCardInfoMapper.findList(cardInfoq); + if (null != cardInfoList && cardInfoList.size() > 0) { + //do nothing + }else { + Integer fee = 0; + WxCardInfo cardInfo = new WxCardInfo(); + cardInfo.setId(couponOrder.getId()); + cardInfo.updateTenantInfo(order); + cardInfo.setCouponId(order.getProductId()); + cardInfo.setAmount(coupon.getPrice()); + cardInfo.setSaleAmount(coupon.getSalePrice()); + cardInfo.setRemainingAmount(coupon.getPrice()); + if (!coupon.checkIsFree()) { + // 有价卡 + cardInfo.setTransactionId(payOrder.getTransactionId()); + if (payOrder.getShareAmount() != null) { + // 开启分账 + fee = payOrder.getPayAmount() - payOrder.getShareAmount(); + cardInfo.setShareFeeAmount(payOrder.getShareAmount()); + cardInfo.setRemainingShareFeeAmount(payOrder.getShareAmount()); + cardInfo.setRateAmount(payOrder.getRateAmount()); + } else { + // 未开启分账 + fee = PayUtils.getPayRate(payOrder.getPayAmount(), payAccount.getRate(), false); + Integer shareAmount = payOrder.getPayAmount() - fee; + cardInfo.setShareFeeAmount(shareAmount); + cardInfo.setRemainingShareFeeAmount(shareAmount); + if (payAccount.getRealRate() != null) { + int iRealChargeFee = PayUtils.getPayRate(payOrder.getPayAmount(), payAccount.getRealRate(), true); + if (fee > iRealChargeFee) { + cardInfo.setRateAmount(fee - iRealChargeFee); + } + } + } + } else { + // 免费卡 + cardInfo.setShareFeeAmount(0); + cardInfo.setRemainingShareFeeAmount(0); + cardInfo.setRateAmount(0); + if (coupon.getPasswordSupport().equals(EnumCouponPasswordSupport.SUPPORTED.getCode())) { + WxCouponPassword updateCPwd = new WxCouponPassword(); + updateCPwd.setId(couponPasswordId); + updateCPwd.setCardId(cardInfo.getId()); + updateCPwd.setStatus(EnumCouponPasswordStatus.USED.getCode()); + couponPasswordMapper.updateById(updateCPwd); + } + } + + cardInfo.setServiceFeeAmount(fee); + cardInfo.setCreateDate(curr); + cardInfo.setUpdateDate(curr); + cardInfo.setSupportTransfer(coupon.getSupportTransfer()); + + //检查卡是否下架,如果是,不可转赠 + WxCouponChannel wxCouponChannel = wxCouponChannelMapper.selectById(order.getCouponChannelId()); + if (wxCouponChannel != null && wxCouponChannel.getStatus().equals(EnumCouponChannelStatus.STATUS_TAKE_OFFF.getCode())) { + cardInfo.setSupportTransfer(EnumCouponTransfer.NO.getCode()); + } + wxCardInfoMapper.insert(cardInfo); + } } return couponOrder; } @@ -2109,7 +2126,7 @@ public class WxOrderServiceImpl implements WxOrderService { // 2. 拼团检查 if (isOrderGroup(orderGroupId)) { - checkOrderGroup(user, orderGroupId); + checkOrderGroup(user, orderGroupId,coupon); } String couponIdStr = String.valueOf(coupon.getId()); // 3. 减库存操作 @@ -2240,16 +2257,27 @@ public class WxOrderServiceImpl implements WxOrderService { return orderNumber; } - private void checkOrderGroup(WxCUser user, Long orderGroupId) { + private void checkOrderGroup(WxCUser user, Long orderGroupId,WxCoupon coupon) { WxOrderGroup group = wxOrderGroupMapper.selectById(orderGroupId); if (group.getStatus().equals(EnumOrderStatus.ORDER_STATUS_COOPERATING_COMPLETE.getCode())) { logger.error("下订单拼团人数已满>>>" + orderGroupId); throw new MallinkException(ErrorCode.ORDER_GROUP_COOPERATING_FINISHED); } + + if (group.getRemainPeople()<=0) { + throw new MallinkException(ErrorCode.ORDER_GROUP_COOPERATING_FINISHED.getCode(),"下单人数已满"); + } + + //判断拼团人数是否已经超出限制 + int groupCount = countGroupOrder(orderGroupId,false); + if (groupCount>=coupon.getPressLimitNum()) { + throw new MallinkException(ErrorCode.ORDER_GROUP_COOPERATING_FINISHED.getCode(),"下单人数超出优惠券人数限制!"); + } + WxOrder order = new WxOrder(); order.setOrderGroupId(group.getId()); order.setCUserId(user.getId()); - order.setOrderStatus(EnumOrderStatus.ORDER_STATUS_COOPERATING_UNPAID.getCode()); + //order.setOrderStatus(EnumOrderStatus.ORDER_STATUS_COOPERATING_UNPAID.getCode()); long count = wxOrderMapper.selectCount(new QueryWrapper(order)); if (count > 0) { logger.error("重复的拼团>>>" + orderGroupId); @@ -2261,5 +2289,20 @@ public class WxOrderServiceImpl implements WxOrderService { return orderGroupId != null && !orderGroupId.equals(0L); } + @Override + public int countGroupOrder(Long groupId,boolean ignoreUnPay) { + WxOrder query = new WxOrder(); + query.setOrderGroupId(groupId); + List statusS = new ArrayList(); + statusS.add(EnumOrderStatus.ORDER_STATUS_PAYMENT_SUCCESS.getCode()); + statusS.add(EnumOrderStatus.ORDER_STATUS_COOPERATING.getCode()); + statusS.add(EnumOrderStatus.ORDER_STATUS_COOPERATING_COMPLETE.getCode()); + if (!ignoreUnPay) { + statusS.add(EnumOrderStatus.ORDER_STATUS_COOPERATING_UNPAID.getCode()); + } + query.setStatusS(statusS); + return wxOrderMapper.countList(query); + } + } diff --git a/mallinkService/src/main/java/com/iformall/service/impl/WxPayOrderServiceImpl.java b/mallinkService/src/main/java/com/iformall/service/impl/WxPayOrderServiceImpl.java index 206ea7065..1c6396d77 100644 --- a/mallinkService/src/main/java/com/iformall/service/impl/WxPayOrderServiceImpl.java +++ b/mallinkService/src/main/java/com/iformall/service/impl/WxPayOrderServiceImpl.java @@ -124,6 +124,7 @@ public class WxPayOrderServiceImpl implements WxPayOrderService { public void handleSuccessOrder(WxPayOrder oldRecord,WxOrder order,Map retMap) { Date curDate = new Date(); if (oldRecord.getPayOrderStatus() != EnumPayStatus.PAY_STATUS_SUCCESS.getCode()) { + //因为此处是处理订单支付成功了但是订单状态为未支付成功的异常状态,库存不应该再扣减 //更新wxPayOrder oldRecord.setPayOrderStatus(EnumPayStatus.PAY_STATUS_SUCCESS.getCode()); String timEndStr = retMap.get("time_end"); @@ -179,7 +180,6 @@ public class WxPayOrderServiceImpl implements WxPayOrderService { @Override public WxPayOrder handleWxOrderQuery(WxPayOrder oldRecord,WxOrder order,WxAppinfo appInfo,WxPayAccount payAccount,IdWorker idworker,boolean repeatPay) { - //int wxpaystatus = WxPayOrderServiceHelper.wxOrderPayStatus(oldRecord, order, appInfo, payAccount); Map retMap = WxPayOrderServiceHelper.wxOrderPayStatusMap(oldRecord, order, appInfo, payAccount); int wxpaystatus = WxPayOrderServiceHelper.getPayStatusFromMap(retMap, oldRecord.getPayOrderNo()); if (EnumPayStatus.PAY_STATUS_SUCCESS.getCode()==wxpaystatus) { @@ -200,12 +200,6 @@ public class WxPayOrderServiceImpl implements WxPayOrderService { if (repeatPay) { if (oldRecord.getPayOrderStatus()!=EnumPayStatus.PAY_STATUS_WAIT.getCode()) { oldRecord.setPayOrderStatus(EnumPayStatus.PAY_STATUS_WAIT.getCode()); - Long payno = idworker.nextId(); - if (null == payno || payno.longValue() <=0) { - throw new MallinkException(ErrorCode.PAY_ORDER_PAYING.getCode(),"订单支付流水号生成失败!handleWxOrderQuery:oldRecord:"+oldRecord+":wxstatus:"+wxpaystatus); - } - oldRecord.setPayOrderNo(String.valueOf(payno)); - int sqlRow0 =wxPayOrderMapper.updateById(oldRecord); if (sqlRow0 != 1) { logger.error("pay order update error: " + oldRecord.toString()); @@ -240,11 +234,19 @@ public class WxPayOrderServiceImpl implements WxPayOrderService { WxOrder orderParams = new WxOrder(); orderParams.setOrderGroupId(order.getOrderGroupId()); orderParams.setCUserId(user.getId()); - orderParams.setOrderStatus(EnumOrderStatus.ORDER_STATUS_COOPERATING.getCode()); - int count = wxOrderMapper.selectCount(new QueryWrapper(orderParams)); - if (count > 0) { - logger.error("重复的拼团>>>" + order); - throw new MallinkException(ErrorCode.ORDER_GROUP_COOPERATING_ATTEND); + List olist = wxOrderMapper.findList(orderParams); + if (olist == null || olist.size() <=0 ) { + throw new MallinkException(ErrorCode.ORDER_GROUP_COOPERATING_FAILD.getCode(),"未查询到参团订单[user:"+user.getId()+",groupId:"+order.getOrderGroupId()+"]"); + } + if (olist.size() != 1) { + throw new MallinkException(ErrorCode.ORDER_GROUP_COOPERATING_FAILD.getCode(),"参团订单多条[user:"+user.getId()+",groupId:"+order.getOrderGroupId()+"]"); + } + WxOrder orderq = olist.get(0); + if (null == orderq) { + throw new MallinkException(ErrorCode.ORDER_GROUP_COOPERATING_FAILD.getCode(),"未查询到参团订单[user:"+user.getId()+",groupId:"+order.getOrderGroupId()+"]"); + } + if (orderq.getOrderStatus()==EnumOrderStatus.ORDER_STATUS_COOPERATING.getCode()) { + throw new MallinkException(ErrorCode.ORDER_GROUP_COOPERATING_ATTEND.getCode(),"不能重复参团订单[user:"+user.getId()+",groupId:"+order.getOrderGroupId()+"]"); } } @@ -349,12 +351,6 @@ public class WxPayOrderServiceImpl implements WxPayOrderService { }else if(oldRecord.getPayOrderStatus()==EnumPayStatus.PAY_STATUS_FAIL.getCode()|| oldRecord.getPayOrderStatus()==EnumPayStatus.PAY_STATUS_NOTPAY.getCode()) { oldRecord.setPayOrderStatus(EnumPayStatus.PAY_STATUS_WAIT.getCode()); - //重新设置支付no - Long payno = idworker.nextId(); - if (null == payno || payno.longValue() <=0) { - throw new MallinkException(ErrorCode.PAY_ORDER_PAYING.getCode(),"订单支付流水号生成失败!service oldRecord:"+oldRecord); - } - oldRecord.setPayOrderNo(String.valueOf(payno)); int sqlRow0 = wxPayOrderMapper.updateById(oldRecord); if (sqlRow0 != 1) { logger.error("pay order update error: " + record.toString()); diff --git a/mallinkService/src/main/java/com/iformall/utils/RedisLock.java b/mallinkService/src/main/java/com/iformall/utils/RedisLock.java index 07a05aff5..de4241e03 100644 --- a/mallinkService/src/main/java/com/iformall/utils/RedisLock.java +++ b/mallinkService/src/main/java/com/iformall/utils/RedisLock.java @@ -27,6 +27,8 @@ public class RedisLock { public static final int TIMEOUT = 10*1000;//超时时间 10s + public static final int LONG_TIMEOUT = 3600*1000;//超长超时时间,关键业务点失败不能再进行下去的时间点 + /** * 加锁 * @param key productId - 商品的唯一标志 @@ -123,7 +125,7 @@ public class RedisLock { */ public long decrease(String key, long delta) { try { - stringRedisTemplate.opsForValue().decrement(key, delta); + return stringRedisTemplate.opsForValue().decrement(key, delta); }catch(Exception e) { logger.error("[Redis分布式锁] decrease error,{}",e); } @@ -147,6 +149,9 @@ public class RedisLock { }catch(Exception e) { logger.error("[Redis分布式锁] setCouponStock error,{}",e); } - + } + + public boolean hasCouponStockCache(long couponId) { + return stringRedisTemplate.hasKey(EnumCacheKey.COUPON_STOCK.getMessage()+String.valueOf(couponId)); } } diff --git a/mallinkService/src/main/resources/mapper/WxCardInfoMapper.xml b/mallinkService/src/main/resources/mapper/WxCardInfoMapper.xml index 06df2ba06..2eeaaf5ba 100644 --- a/mallinkService/src/main/resources/mapper/WxCardInfoMapper.xml +++ b/mallinkService/src/main/resources/mapper/WxCardInfoMapper.xml @@ -25,7 +25,7 @@ `share_fee_amount`,`remaining_share_fee_amount`, `rate_amount`, `create_date`,`update_date`,`support_transfer` - + where 1 = 1 @@ -211,4 +211,10 @@ update wx_card_info set support_transfer=0,update_date=now() where support_transfer=1 and coupon_id=#{couponId} + + diff --git a/mallinkService/src/main/resources/mapper/WxOrderMapper.xml b/mallinkService/src/main/resources/mapper/WxOrderMapper.xml index 7e0e59b89..2576e5576 100644 --- a/mallinkService/src/main/resources/mapper/WxOrderMapper.xml +++ b/mallinkService/src/main/resources/mapper/WxOrderMapper.xml @@ -133,7 +133,7 @@ diff --git a/mallinkWebSocketServer/src/main/resources/application-dev.yml b/mallinkWebSocketServer/src/main/resources/application-dev.yml index 0c237a876..b726571d6 100644 --- a/mallinkWebSocketServer/src/main/resources/application-dev.yml +++ b/mallinkWebSocketServer/src/main/resources/application-dev.yml @@ -28,7 +28,7 @@ spring: # REDIS redis: - host: 202.165.179.86 + host: 101.201.103.81 port: 6379 password: ENC(xPFDlgd6v8zUhJMbcKc0KmmQiqs9qHtk) timeout: 3600 @@ -91,7 +91,7 @@ wechat: componentToken: "formall2018" componentAesKey: "htKq8EjBMPNndfZQK9JiFojFaqFwFpw42VfeWFtx7HN" redis: - host: 202.165.179.86 + host: 101.201.103.81 port: 6379 password: ENC(xPFDlgd6v8zUhJMbcKc0KmmQiqs9qHtk) timeout: 3600