|
|
|
@@ -2,15 +2,16 @@ package com.iformall.controller; |
|
|
|
|
|
|
|
import com.iformall.common.ErrorCode; |
|
|
|
import com.iformall.common.ResultData; |
|
|
|
import com.iformall.domain.po.WxCUser; |
|
|
|
import com.iformall.domain.po.WxCoupon; |
|
|
|
import com.iformall.domain.po.WxOrder; |
|
|
|
import com.iformall.domain.po.WxOrderPress; |
|
|
|
import com.iformall.domain.vo.WxCouponCVo; |
|
|
|
import com.iformall.enums.EnumOrderPressStatus; |
|
|
|
import com.iformall.enums.EnumOrderStatus; |
|
|
|
import com.iformall.exception.MallinkException; |
|
|
|
import com.iformall.service.WxCouponService; |
|
|
|
import com.iformall.service.WxOrderPressService; |
|
|
|
import com.iformall.service.WxOrderService; |
|
|
|
import com.iformall.utils.RedisLock; |
|
|
|
import io.swagger.annotations.Api; |
|
|
|
import io.swagger.annotations.ApiImplicitParam; |
|
|
|
import io.swagger.annotations.ApiOperation; |
|
|
|
@@ -18,11 +19,16 @@ import org.apache.commons.lang3.StringUtils; |
|
|
|
import org.slf4j.Logger; |
|
|
|
import org.slf4j.LoggerFactory; |
|
|
|
import org.springframework.beans.factory.annotation.Autowired; |
|
|
|
import org.springframework.beans.factory.annotation.Qualifier; |
|
|
|
import org.springframework.data.redis.core.RedisTemplate; |
|
|
|
import org.springframework.data.redis.core.ValueOperations; |
|
|
|
import org.springframework.transaction.annotation.Transactional; |
|
|
|
import org.springframework.web.bind.annotation.*; |
|
|
|
|
|
|
|
import java.util.Date; |
|
|
|
import java.util.HashMap; |
|
|
|
import java.util.Map; |
|
|
|
import java.util.concurrent.TimeUnit; |
|
|
|
|
|
|
|
@RestController |
|
|
|
@RequestMapping("/api/press") |
|
|
|
@@ -39,6 +45,17 @@ public class WxPressOrderController extends BaseController { |
|
|
|
@Autowired |
|
|
|
WxOrderPressService wxOrderPressService; |
|
|
|
|
|
|
|
@Autowired |
|
|
|
@Qualifier("pressOrderRedisTemplate") |
|
|
|
RedisTemplate<String, WxOrder> orderRedisTemplate; |
|
|
|
|
|
|
|
@Autowired |
|
|
|
@Qualifier("couponDetailRedisTemplate") |
|
|
|
RedisTemplate<String, WxCouponCVo> couponCVoRedisTemplate; |
|
|
|
|
|
|
|
@Autowired |
|
|
|
RedisLock redisLock; |
|
|
|
|
|
|
|
// 砍价列表 - /api/wxCouponChannel/list |
|
|
|
// 我的砍价 - /api/order/pressOrderList |
|
|
|
// 砍价订单详情 - /api/order/pressOrderDetail |
|
|
|
@@ -49,6 +66,7 @@ public class WxPressOrderController extends BaseController { |
|
|
|
|
|
|
|
@ApiOperation(value = "参与砍价", notes = "{\"orderId\":\"String\"}") |
|
|
|
@PostMapping("pressOrderJoin") |
|
|
|
@Transactional |
|
|
|
public ResultData pressOrderJoin(@RequestBody Map<String, String> paramMap) { |
|
|
|
Date curDate = new Date(); |
|
|
|
String orderIdStr = paramMap.get("orderId"); |
|
|
|
@@ -56,19 +74,50 @@ public class WxPressOrderController extends BaseController { |
|
|
|
return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "orderId不能为空"); |
|
|
|
} |
|
|
|
Long orderId = 0L; |
|
|
|
WxOrder order = null; |
|
|
|
try { |
|
|
|
orderId = Long.valueOf(orderIdStr); |
|
|
|
} catch (NumberFormatException e) { |
|
|
|
logger.error("orderId convert error, " + orderIdStr + ", e:" + e.getMessage()); |
|
|
|
return new ResultData(ErrorCode.SYS_PARAMETER_CAST_ERROR.getCode(), "orderId: " + orderIdStr + ", e:" + e.getMessage()); |
|
|
|
} |
|
|
|
WxOrder order = wxOrderService.getById(orderId); |
|
|
|
String key = "pressorder:" + orderId; |
|
|
|
ValueOperations<String, WxOrder> operations = orderRedisTemplate.opsForValue(); |
|
|
|
// 缓存 |
|
|
|
boolean hasKey = orderRedisTemplate.hasKey(key); |
|
|
|
if (hasKey) { |
|
|
|
// 从缓存获取砍价订单信息 |
|
|
|
order = operations.get(key); |
|
|
|
} else { |
|
|
|
// 订单没有入缓存,需要从数据库中读取 |
|
|
|
order = wxOrderService.getById(orderId); |
|
|
|
if (order != null) { |
|
|
|
// 订单优化,进缓存 |
|
|
|
orderRedisTemplate.opsForValue().set(key, order, 3600, TimeUnit.SECONDS); |
|
|
|
} |
|
|
|
} |
|
|
|
if(order == null) { |
|
|
|
logger.error("订单不存在:" + orderId); |
|
|
|
return new ResultData(ErrorCode.ORDER_IS_NOT_FIND); |
|
|
|
} |
|
|
|
WxCoupon coupon = wxCouponService.getById(order.getProductId()); |
|
|
|
if(coupon == null) { |
|
|
|
WxCouponCVo wxCouponCVo = null; |
|
|
|
String cdKey = "cd:" + order.getProductId(); |
|
|
|
|
|
|
|
ValueOperations<String, WxCouponCVo> cdOperations = couponCVoRedisTemplate.opsForValue(); |
|
|
|
// 缓存 |
|
|
|
boolean cdHasKey = couponCVoRedisTemplate.hasKey(cdKey); |
|
|
|
if (cdHasKey) { |
|
|
|
// 从缓存获取券信息 |
|
|
|
wxCouponCVo = cdOperations.get(cdKey); |
|
|
|
} else { |
|
|
|
// 券信息没有入缓存,需要从数据库中读取 |
|
|
|
wxCouponCVo = wxCouponService.getVoById(order.getProductId()); |
|
|
|
if (wxCouponCVo != null) { |
|
|
|
// 券详情优化,进缓存 |
|
|
|
couponCVoRedisTemplate.opsForValue().set(cdKey, wxCouponCVo, 3600, TimeUnit.SECONDS); |
|
|
|
} |
|
|
|
} |
|
|
|
if(wxCouponCVo == null) { |
|
|
|
logger.error("券不存在:" + order.getProductId()); |
|
|
|
return new ResultData(ErrorCode.COUPON_IS_EMPTY); |
|
|
|
} |
|
|
|
@@ -93,21 +142,98 @@ public class WxPressOrderController extends BaseController { |
|
|
|
return new ResultData(ErrorCode.ORDER_HAD_CANCEL); |
|
|
|
} |
|
|
|
|
|
|
|
if(order.getPressCurrentNum() + 1 > coupon.getPressLimitNum()) { |
|
|
|
if(order.getPressCurrentNum() + 1 >= wxCouponCVo.getPressLimitNum()) { |
|
|
|
logger.error("砍价已结束:" + orderId); |
|
|
|
return new ResultData(ErrorCode.COUPON_PRESS_HAD_FINISHED); |
|
|
|
} |
|
|
|
|
|
|
|
long time = System.currentTimeMillis() + RedisLock.TIMEOUT; |
|
|
|
String timeStr = String.valueOf(time); |
|
|
|
if (!redisLock.lock(orderIdStr, timeStr)) { |
|
|
|
logger.error("此砍价订单被锁定, orderId: " + orderIdStr); |
|
|
|
return new ResultData(ErrorCode.TOO_MANY_REQUEST); |
|
|
|
} |
|
|
|
|
|
|
|
Long cUserId = getUserId(); |
|
|
|
// 检查此人是否已参与砍价 |
|
|
|
boolean hadJoin = wxOrderPressService.checkCUserHasJoin(order, cUserId); |
|
|
|
if (hadJoin) { |
|
|
|
redisLock.unlock(orderIdStr, timeStr); |
|
|
|
logger.error("用户已参与砍价"); |
|
|
|
return new ResultData(ErrorCode.COUPON_PRESS_IS_EXIST); |
|
|
|
} |
|
|
|
|
|
|
|
try { |
|
|
|
wxOrderPressService.pressCouponJoin(order, coupon, getUserId()); |
|
|
|
WxOrderPress orderPress = wxOrderPressService.pressCouponJoin(order, wxCouponCVo, cUserId); |
|
|
|
if (orderPress != null) { |
|
|
|
// 更新砍价信息 |
|
|
|
Integer index = order.getPressCurrentNum() + 1; |
|
|
|
if(index < wxCouponCVo.getPressLimitNum()) { |
|
|
|
// 未完成 |
|
|
|
order.setId(order.getId()); |
|
|
|
order.setPressCurrentNum(index); |
|
|
|
order.setPressCurrentValue(order.getPressCurrentValue() - orderPress.getPressValue()); |
|
|
|
order.setOrderStatus(EnumOrderStatus.ORDER_STATUS_PRESSING.getCode()); |
|
|
|
order.setUpdateDate(new Date()); |
|
|
|
orderRedisTemplate.opsForValue().set(key, order, 3600, TimeUnit.SECONDS); |
|
|
|
updatePressOrderPressing(order, key, orderPress, index); |
|
|
|
} else { |
|
|
|
order.setPressCurrentNum(index); |
|
|
|
order.setPressCurrentValue(order.getPressCurrentValue() - orderPress.getPressValue()); |
|
|
|
order.setOrderStatus(EnumOrderStatus.ORDER_STATUS_PRESS_COMPLETE.getCode()); |
|
|
|
order.setUpdateDate(curDate); |
|
|
|
orderRedisTemplate.opsForValue().set(key, order, 3600, TimeUnit.SECONDS); |
|
|
|
updatePressOrder(order, wxCouponCVo, orderPress, index); |
|
|
|
} |
|
|
|
} |
|
|
|
} catch (MallinkException e) { |
|
|
|
redisLock.unlock(orderIdStr, timeStr); |
|
|
|
logger.error(e.getMessage()); |
|
|
|
return new ResultData(e.getErrorCode(), e.getMessage()); |
|
|
|
} |
|
|
|
|
|
|
|
redisLock.unlock(orderIdStr, timeStr); |
|
|
|
return new ResultData(); |
|
|
|
} |
|
|
|
|
|
|
|
private void updatePressOrderPressing(WxOrder order, String key, WxOrderPress orderPress, Integer index) { |
|
|
|
|
|
|
|
WxOrder orderUpdatePress = new WxOrder(); |
|
|
|
orderUpdatePress.setId(order.getId()); |
|
|
|
orderUpdatePress.setPressCurrentNum(index); |
|
|
|
orderUpdatePress.setPressCurrentValue(order.getPressCurrentValue() - orderPress.getPressValue()); |
|
|
|
orderUpdatePress.setOrderStatus(EnumOrderStatus.ORDER_STATUS_PRESSING.getCode()); |
|
|
|
orderUpdatePress.setUpdateDate(new Date()); |
|
|
|
// 保存订单 |
|
|
|
wxOrderService.saveOrUpdate(orderUpdatePress); |
|
|
|
} |
|
|
|
|
|
|
|
private void updatePressOrderPressing(WxOrder order, WxOrderPress orderPress, Integer index) { |
|
|
|
WxOrder orderUpdatePress = new WxOrder(); |
|
|
|
orderUpdatePress.setId(order.getId()); |
|
|
|
orderUpdatePress.setPressCurrentNum(index); |
|
|
|
orderUpdatePress.setPressCurrentValue(order.getPressCurrentValue() - orderPress.getPressValue()); |
|
|
|
orderUpdatePress.setOrderStatus(EnumOrderStatus.ORDER_STATUS_PRESSING.getCode()); |
|
|
|
orderUpdatePress.setUpdateDate(new Date()); |
|
|
|
// 保存订单 |
|
|
|
wxOrderService.saveOrUpdate(orderUpdatePress); |
|
|
|
} |
|
|
|
|
|
|
|
private void updatePressOrder(WxOrder order, WxCouponCVo wxCouponCVo, WxOrderPress orderPress, Integer index) { |
|
|
|
WxOrder orderUpdatePress = new WxOrder(); |
|
|
|
orderUpdatePress.setId(order.getId()); |
|
|
|
orderUpdatePress.setPressCurrentNum(index); |
|
|
|
orderUpdatePress.setPressCurrentValue(order.getPressCurrentValue() - orderPress.getPressValue()); |
|
|
|
orderUpdatePress.setOrderStatus(EnumOrderStatus.ORDER_STATUS_PRESS_COMPLETE.getCode()); |
|
|
|
orderUpdatePress.setPayment(wxCouponCVo.getSalePrice()); |
|
|
|
orderUpdatePress.setUpdateDate(new Date()); |
|
|
|
// 保存订单 |
|
|
|
wxOrderService.saveOrUpdate(orderUpdatePress); |
|
|
|
// 发送砍价成功消息 |
|
|
|
if(index.equals(wxCouponCVo.getPressLimitNum())) { |
|
|
|
wxOrderPressService.sendPressComplateMsg(orderUpdatePress); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
@ApiOperation(value = "砍价状态(1:我发起的砍价,2:未参与的砍价, 3:已参与的砍价)", notes = "") |
|
|
|
@GetMapping("getPressOrderStatus") |
|
|
|
@ApiImplicitParam(name = "orderId", value = "orderId", dataType = "String", paramType = "query", required = true) |
|
|
|
|