| @@ -195,6 +195,11 @@ public enum ErrorCode{ | |||||
| ORDER_PRESS_IS_OVERTIME(3010, "砍价已过期"), | ORDER_PRESS_IS_OVERTIME(3010, "砍价已过期"), | ||||
| ORDER_PRESS_IS_COMPLETE(3011, "砍价已完成"), | ORDER_PRESS_IS_COMPLETE(3011, "砍价已完成"), | ||||
| ORDER_UNPAID(3012, "您有未支付的订单"), | ORDER_UNPAID(3012, "您有未支付的订单"), | ||||
| ORDER_IS_FIND(3013, "订单已存在"), | |||||
| ORDER_PAY_IN_REFUND(3014, "订单待退款"), | |||||
| ORDER_PAY_REFUND(3015, "订单已退款"), | |||||
| ORDER_PAY_REFUND_FAIL(3016, "订单退款失败"), | |||||
| ORDER_PAY_EVALUATE(3017, "订单已评价"), | |||||
| ORDER_USER_NOT_MATCH(2013, "订单用户不匹配"), | ORDER_USER_NOT_MATCH(2013, "订单用户不匹配"), | ||||
| ORDER_COUPON_CHANNEL_NOT_MATCH(2014, "订单渠道不匹配"), | ORDER_COUPON_CHANNEL_NOT_MATCH(2014, "订单渠道不匹配"), | ||||
| ORDER_COUPON_NOT_MATCH(2015, "订单券不匹配"), | ORDER_COUPON_NOT_MATCH(2015, "订单券不匹配"), | ||||
| @@ -609,6 +614,12 @@ public enum ErrorCode{ | |||||
| GOOAGOO_OPEN_FAIL(62002,"数衍信息请求失败"), | GOOAGOO_OPEN_FAIL(62002,"数衍信息请求失败"), | ||||
| /** | |||||
| * tt | |||||
| */ | |||||
| TTCOUPON_IS_EMPTY(63000, "课程不存在"), | |||||
| TTCOUPON_IS_TAKE_OFF(63001, "课程不在上架状态"), | |||||
| ; | ; | ||||
| private int code; | private int code; | ||||
| @@ -4,6 +4,7 @@ import cn.afterturn.easypoi.excel.annotation.Excel; | |||||
| import com.baomidou.mybatisplus.annotation.TableField; | import com.baomidou.mybatisplus.annotation.TableField; | ||||
| import com.baomidou.mybatisplus.annotation.TableName; | import com.baomidou.mybatisplus.annotation.TableName; | ||||
| import com.iformall.common.SortColumn; | import com.iformall.common.SortColumn; | ||||
| import com.iformall.domain.po.WxMerchant; | |||||
| import com.iformall.domain.po.base.TenantEntity; | import com.iformall.domain.po.base.TenantEntity; | ||||
| import lombok.Data; | import lombok.Data; | ||||
| import lombok.EqualsAndHashCode; | import lombok.EqualsAndHashCode; | ||||
| @@ -115,9 +116,9 @@ public class TtCoupon extends TenantEntity { | |||||
| @io.swagger.annotations.ApiModelProperty(value="作者",name="merchantId") | @io.swagger.annotations.ApiModelProperty(value="作者",name="merchantId") | ||||
| private Long merchantId; | private Long merchantId; | ||||
| @io.swagger.annotations.ApiModelProperty(value="",name="merchantName") | |||||
| @io.swagger.annotations.ApiModelProperty(value="",name="merchantName")//弃用 | |||||
| private String merchantName; | private String merchantName; | ||||
| @io.swagger.annotations.ApiModelProperty(value="",name="merchantPic") | |||||
| @io.swagger.annotations.ApiModelProperty(value="",name="merchantPic")//弃用 | |||||
| private String merchantPic; | private String merchantPic; | ||||
| @io.swagger.annotations.ApiModelProperty(value="业态",name="businessId") | @io.swagger.annotations.ApiModelProperty(value="业态",name="businessId") | ||||
| @@ -125,6 +126,9 @@ public class TtCoupon extends TenantEntity { | |||||
| @io.swagger.annotations.ApiModelProperty(value="",name="businessName") | @io.swagger.annotations.ApiModelProperty(value="",name="businessName") | ||||
| private String businessName; | private String businessName; | ||||
| @TableField(exist = false) | |||||
| private WxMerchant author; | |||||
| @TableField(exist = false) | @TableField(exist = false) | ||||
| @io.swagger.annotations.ApiModelProperty(value = "审批流参数", name = "columnCoupons") | @io.swagger.annotations.ApiModelProperty(value = "审批流参数", name = "columnCoupons") | ||||
| private List<TtCoupon> columnCoupons; | private List<TtCoupon> columnCoupons; | ||||
| @@ -10,6 +10,7 @@ import lombok.ToString; | |||||
| import java.math.BigDecimal; | import java.math.BigDecimal; | ||||
| import java.util.Date; | import java.util.Date; | ||||
| import java.util.List; | |||||
| @TableName(value = "tt_order") | @TableName(value = "tt_order") | ||||
| @Data | @Data | ||||
| @@ -37,7 +38,7 @@ public class TtOrder extends TenantEntity { | |||||
| private String author; | private String author; | ||||
| @TableField(exist = false) | @TableField(exist = false) | ||||
| private String authorPic; | private String authorPic; | ||||
| @io.swagger.annotations.ApiModelProperty(value="支付类型(1:支付宝,2:微信)",name="type") | |||||
| @io.swagger.annotations.ApiModelProperty(value="支付类型(1:微信,)",name="type") | |||||
| private Integer type; | private Integer type; | ||||
| @io.swagger.annotations.ApiModelProperty(value="0: 付款 1: 退款",name="paymentType") | @io.swagger.annotations.ApiModelProperty(value="0: 付款 1: 退款",name="paymentType") | ||||
| private Integer paymentType; | private Integer paymentType; | ||||
| @@ -66,6 +67,9 @@ public class TtOrder extends TenantEntity { | |||||
| @TableField(exist = false) | @TableField(exist = false) | ||||
| private String paymentStr; | private String paymentStr; | ||||
| @TableField(exist = false) | |||||
| protected List<Integer> statusS; | |||||
| @TableField(exist = false) | @TableField(exist = false) | ||||
| @io.swagger.annotations.ApiModelProperty(value="查询-起始时间",name="startdate") | @io.swagger.annotations.ApiModelProperty(value="查询-起始时间",name="startdate") | ||||
| private Date startdate; | private Date startdate; | ||||
| @@ -10,6 +10,7 @@ public enum EnumPayWay { | |||||
| PAY_WAY_WECHAT_WAP(2, "微信H5",EnumPayWayType.WX_H5PAY,EnumAppPlat.WX,null), | PAY_WAY_WECHAT_WAP(2, "微信H5",EnumPayWayType.WX_H5PAY,EnumAppPlat.WX,null), | ||||
| PAY_WAY_ALIPAY(3, "支付宝",EnumPayWayType.ALI_MINIPAY,EnumAppPlat.ALI,null), | PAY_WAY_ALIPAY(3, "支付宝",EnumPayWayType.ALI_MINIPAY,EnumAppPlat.ALI,null), | ||||
| PAY_WAY_ALIPAY_WAP(4, "支付宝H5",EnumPayWayType.ALI_H5PAY,EnumAppPlat.ALI,null), | PAY_WAY_ALIPAY_WAP(4, "支付宝H5",EnumPayWayType.ALI_H5PAY,EnumAppPlat.ALI,null), | ||||
| PAY_WAY_TT(5, "抖音担保支付",EnumPayWayType.TT_PAY,EnumAppPlat.TOUTIAO,null), | |||||
| PAY_WAY_POS_B(10, "POS B端",EnumPayWayType.POS,null,null), | PAY_WAY_POS_B(10, "POS B端",EnumPayWayType.POS,null,null), | ||||
| PAY_WAY_POS_NEU(11, "POS 东软",EnumPayWayType.NEU_POS,null,EnumCardSpendFrom.POS), | PAY_WAY_POS_NEU(11, "POS 东软",EnumPayWayType.NEU_POS,null,EnumCardSpendFrom.POS), | ||||
| PAY_WAY_NOT_UNPAY_MERCHANT(91, "商户注券,无需支付",null,null,null), | PAY_WAY_NOT_UNPAY_MERCHANT(91, "商户注券,无需支付",null,null,null), | ||||
| @@ -71,6 +72,6 @@ public enum EnumPayWay { | |||||
| public static enum EnumPayWayType { | public static enum EnumPayWayType { | ||||
| WX_MINIPAY,WX_H5PAY,ALI_MINIPAY,ALI_H5PAY,NEU_POS,POS | |||||
| WX_MINIPAY,WX_H5PAY,ALI_MINIPAY,ALI_H5PAY,TT_PAY,NEU_POS,POS | |||||
| } | } | ||||
| } | } | ||||
| @@ -0,0 +1,41 @@ | |||||
| package com.iformall.enums; | |||||
| /** | |||||
| * Created by Stormeye on 2018/08/09. | |||||
| */ | |||||
| public enum EnumTtCouponStatus { | |||||
| TTCOUPON_STATUS_DRAFT(1, "草稿"), | |||||
| TTCOUPON_STATUS_EXAMINE(2, "审核中"), | |||||
| TTCOUPON_STATUS_REJECT(3, "已驳回"), | |||||
| TTCOUPON_STATUS_BEFOR_SHELF(4, "待上架"), | |||||
| TTCOUPON_STATUS_SHELFING(5, "已上架"), | |||||
| TTCOUPON_STATUS_AFTER_SHELF(6, "已下架"), | |||||
| ; | |||||
| public static EnumTtCouponStatus getEnum(Integer code) { | |||||
| for (EnumTtCouponStatus value : values()) { | |||||
| if (value.getCode().equals(code)) { | |||||
| return value; | |||||
| } | |||||
| } | |||||
| return null; | |||||
| } | |||||
| private Integer code; | |||||
| private String message; | |||||
| EnumTtCouponStatus(Integer code, String message) { | |||||
| this.code = code; | |||||
| this.message = message; | |||||
| } | |||||
| public Integer getCode() { | |||||
| return code; | |||||
| } | |||||
| public String getMessage() { | |||||
| return message; | |||||
| } | |||||
| } | |||||
| @@ -16,4 +16,5 @@ public interface TtOrderMapper extends CommonMapper<TtOrder, Long> { | |||||
| List<TtOrder> findList(TtOrder record); | List<TtOrder> findList(TtOrder record); | ||||
| Integer findListCount(TtOrder orderQ); | |||||
| } | } | ||||
| @@ -38,4 +38,5 @@ public interface TtCouponService { | |||||
| */ | */ | ||||
| void deleteById(Long id); | void deleteById(Long id); | ||||
| TtCoupon detail(Long productId); | |||||
| } | } | ||||
| @@ -1,7 +1,11 @@ | |||||
| package com.iformall.service.tt; | package com.iformall.service.tt; | ||||
| import com.github.pagehelper.PageInfo; | import com.github.pagehelper.PageInfo; | ||||
| import com.iformall.common.ResultData; | |||||
| import com.iformall.domain.dto.OrderSaveDto; | |||||
| import com.iformall.domain.po.base.TenantEntity; | |||||
| import com.iformall.domain.po.tt.TtOrder; | import com.iformall.domain.po.tt.TtOrder; | ||||
| import com.iformall.enums.EnumPayWay; | |||||
| public interface TtOrderService { | public interface TtOrderService { | ||||
| @@ -15,4 +19,9 @@ public interface TtOrderService { | |||||
| */ | */ | ||||
| PageInfo<TtOrder> listAsPage(TtOrder record, Integer pageIndex, Integer pageSize); | PageInfo<TtOrder> listAsPage(TtOrder record, Integer pageIndex, Integer pageSize); | ||||
| ResultData saveOrder(Long couponId, Long memberId, EnumPayWay payWay, TenantEntity tenantInfo); | |||||
| ResultData cancelOrder(Long orderId, Long memberId); | |||||
| TtOrder detail(Long orderId, Long memberId); | |||||
| } | } | ||||
| @@ -69,7 +69,6 @@ public class TtCouponServiceImpl implements TtCouponService { | |||||
| } else { | } else { | ||||
| record.setUpdateDate(new Date()); | record.setUpdateDate(new Date()); | ||||
| ttCouponMapper.updateById(record); | ttCouponMapper.updateById(record); | ||||
| } | } | ||||
| return new ResultData(record.getId()); | return new ResultData(record.getId()); | ||||
| } | } | ||||
| @@ -78,4 +77,10 @@ public class TtCouponServiceImpl implements TtCouponService { | |||||
| public void deleteById(Long id) { | public void deleteById(Long id) { | ||||
| ttCouponMapper.deleteById(id); | ttCouponMapper.deleteById(id); | ||||
| } | } | ||||
| @Override | |||||
| public TtCoupon detail(Long productId) { | |||||
| TtCoupon byId = this.getById(productId); | |||||
| return byId; | |||||
| } | |||||
| } | } | ||||
| @@ -13,6 +13,7 @@ import com.iformall.domain.dto.WxSharingOrderDto; | |||||
| import com.iformall.domain.po.*; | import com.iformall.domain.po.*; | ||||
| import com.iformall.domain.po.base.TenantEntity; | import com.iformall.domain.po.base.TenantEntity; | ||||
| import com.iformall.domain.po.msg.FmInsideOrderSuccessMsg; | import com.iformall.domain.po.msg.FmInsideOrderSuccessMsg; | ||||
| import com.iformall.domain.po.tt.TtCoupon; | |||||
| import com.iformall.domain.po.tt.TtOrder; | import com.iformall.domain.po.tt.TtOrder; | ||||
| import com.iformall.domain.vo.*; | import com.iformall.domain.vo.*; | ||||
| import com.iformall.enums.*; | import com.iformall.enums.*; | ||||
| @@ -20,6 +21,7 @@ import com.iformall.exception.MallinkException; | |||||
| import com.iformall.mapper.*; | import com.iformall.mapper.*; | ||||
| import com.iformall.mq.MqBaseProducer; | import com.iformall.mq.MqBaseProducer; | ||||
| import com.iformall.service.*; | import com.iformall.service.*; | ||||
| import com.iformall.service.tt.TtCouponService; | |||||
| import com.iformall.service.tt.TtOrderService; | import com.iformall.service.tt.TtOrderService; | ||||
| import com.iformall.utils.*; | import com.iformall.utils.*; | ||||
| import org.apache.commons.lang3.StringUtils; | import org.apache.commons.lang3.StringUtils; | ||||
| @@ -51,6 +53,9 @@ public class TtOrderServiceImpl implements TtOrderService { | |||||
| @Autowired | @Autowired | ||||
| private TtOrderMapper ttOrderMapper; | private TtOrderMapper ttOrderMapper; | ||||
| @Autowired | |||||
| private TtCouponService ttCouponService; | |||||
| @Autowired | @Autowired | ||||
| RedisLock redisLock; | RedisLock redisLock; | ||||
| @@ -153,6 +158,117 @@ public class TtOrderServiceImpl implements TtOrderService { | |||||
| return PageHelper.startPage(pageIndex, pageSize).doSelectPageInfo(() -> ttOrderMapper.findList(record)); | return PageHelper.startPage(pageIndex, pageSize).doSelectPageInfo(() -> ttOrderMapper.findList(record)); | ||||
| } | } | ||||
| @Override | |||||
| public ResultData saveOrder(Long couponId,Long cUserId,EnumPayWay payWay,TenantEntity tenantEntity) { | |||||
| logger.info("OrderSave: couponId:" + couponId + "---cUserId:"+cUserId); | |||||
| WxCUserBasicInfo wxCUserBasicInfo = wxCUserBasicInfoService.getById(cUserId,tenantEntity.getFinalTenantId()); | |||||
| if(wxCUserBasicInfo == null){ | |||||
| return new ResultData(ErrorCode.USER_IS_EMPTY); | |||||
| } | |||||
| TtOrder orderQ = new TtOrder(); | |||||
| orderQ.setCUserId(cUserId); | |||||
| orderQ.setProductId(couponId); | |||||
| List<Integer> statuss = new ArrayList<>(); | |||||
| statuss.add(EnumOrderStatus.ORDER_STATUS_PENDING_PAYMENT.getCode()); | |||||
| statuss.add(EnumOrderStatus.ORDER_STATUS_PAYMENT_SUCCESS.getCode()); | |||||
| orderQ.setStatusS(statuss); | |||||
| Integer listCount = ttOrderMapper.findListCount(orderQ); | |||||
| if(listCount.intValue() > 0){ | |||||
| return new ResultData(ErrorCode.ORDER_IS_FIND); | |||||
| } | |||||
| if (wxCUserBasicInfo.getStatus().equals(EnumCUserBasicInfoStatus.LOCKED.getCode())) { | |||||
| logger.info("会员权益被锁定:cUserId:" + cUserId); | |||||
| return new ResultData(ErrorCode.MEMBER_IS_LOCKED); | |||||
| } | |||||
| TtCoupon coupon = ttCouponService.getById(couponId); | |||||
| if (null == coupon) { | |||||
| return new ResultData(ErrorCode.TTCOUPON_IS_EMPTY); | |||||
| } | |||||
| if (!coupon.getStatus().equals(EnumTtCouponStatus.TTCOUPON_STATUS_SHELFING.getCode())) { | |||||
| return new ResultData(ErrorCode.TTCOUPON_IS_TAKE_OFF); | |||||
| } | |||||
| try { | |||||
| // 4.2 保存订单 | |||||
| final IdWorker idWorker = IdWorker.get(); | |||||
| Date now = new Date(); | |||||
| TtOrder order = new TtOrder(); | |||||
| order.setId(idWorker.nextId()); | |||||
| order.updateTenantInfo(tenantEntity); | |||||
| order.setCUserId(wxCUserBasicInfo.getId()); | |||||
| order.setProductId(coupon.getId()); | |||||
| order.setType(payWay.getCode()); | |||||
| order.setPaymentType(EnumPayType.PAY_PAYMENT.getCode()); | |||||
| order.setPayment(coupon.getSalePrice()); | |||||
| if(order.getPayment() == null || order.getPayment().intValue() == 0){ | |||||
| order.setOrderStatus(EnumOrderStatus.ORDER_STATUS_PAYMENT_SUCCESS.getCode()); | |||||
| order.setPaymentTime(now); | |||||
| }else{ | |||||
| order.setOrderStatus(EnumOrderStatus.ORDER_STATUS_PENDING_PAYMENT.getCode()); | |||||
| } | |||||
| order.setCreateDate(now); | |||||
| order.setUpdateDate(now); | |||||
| ttOrderMapper.insert(order); | |||||
| return new ResultData(order); | |||||
| } catch (MallinkException e) { | |||||
| logger.error(e.getMessage()); | |||||
| return new ResultData(e.getErrorCode(), e.getMessage()); | |||||
| } catch (Exception e) { | |||||
| logger.error(e.getMessage()); | |||||
| return new ResultData(ErrorCode.ORDER_IS_FAIL, e.getMessage()); | |||||
| } | |||||
| } | |||||
| @Override | |||||
| public ResultData cancelOrder(Long orderId, Long memberId) { | |||||
| TtOrder ttOrder = ttOrderMapper.selectById(orderId); | |||||
| if(ttOrder == null){ | |||||
| return new ResultData(ErrorCode.ORDER_IS_NOT_FIND); | |||||
| } | |||||
| if(memberId != null && !ttOrder.getCUserId().equals(memberId)){ | |||||
| return new ResultData(ErrorCode.ORDER_USER_NOT_MATCH); | |||||
| } | |||||
| if(ttOrder.getOrderStatus().equals(EnumOrderStatus.ORDER_STATUS_PENDING_PAYMENT.getCode())){//订单待付款 | |||||
| TtOrder record = new TtOrder(); | |||||
| record.setId(ttOrder.getId()); | |||||
| record.setOrderStatus(EnumOrderStatus.ORDER_STATUS_OVERTIME_CANCEL.getCode()); | |||||
| record.setUpdateDate(new Date()); | |||||
| ttOrderMapper.updateById(record); | |||||
| return new ResultData(); | |||||
| }else | |||||
| if(ttOrder.getOrderStatus().equals(EnumOrderStatus.ORDER_STATUS_PAYMENT_SUCCESS.getCode())){//订单已支付 | |||||
| return new ResultData(ErrorCode.ORDER_HAD_PAY); | |||||
| }else | |||||
| if(ttOrder.getOrderStatus().equals(EnumOrderStatus.ORDER_STATUS_OVERTIME_CANCEL.getCode())){//订单已取消 | |||||
| return new ResultData(ErrorCode.ORDER_HAD_CANCEL); | |||||
| }else | |||||
| if(ttOrder.getOrderStatus().equals(EnumOrderStatus.ORDER_STATUS_PENDING_REFUND.getCode())){//订单待退款 | |||||
| return new ResultData(ErrorCode.ORDER_PAY_IN_REFUND); | |||||
| }else | |||||
| if(ttOrder.getOrderStatus().equals(EnumOrderStatus.ORDER_STATUS_REFUND_SUCCESS.getCode())){//订单已退款 | |||||
| return new ResultData(ErrorCode.ORDER_PAY_REFUND); | |||||
| }else | |||||
| if(ttOrder.getOrderStatus().equals(EnumOrderStatus.ORDER_STATUS_REFUND_FAILD.getCode())){//订单退款失败 | |||||
| return new ResultData(ErrorCode.ORDER_PAY_REFUND_FAIL); | |||||
| } | |||||
| return new ResultData(ErrorCode.ORDER_IS_FAIL); | |||||
| } | |||||
| @Override | |||||
| public TtOrder detail(Long orderId, Long memberId) { | |||||
| TtOrder ttOrder = ttOrderMapper.selectById(orderId); | |||||
| if(ttOrder == null){ | |||||
| return null; | |||||
| } | |||||
| if(memberId != null && !ttOrder.getCUserId().equals(memberId)){ | |||||
| return null; | |||||
| } | |||||
| TtCoupon coupon = ttCouponService.detail(ttOrder.getProductId()); | |||||
| return null; | |||||
| } | |||||
| @Override | @Override | ||||
| public ResultData microPayListOnDateAsPage(Long bUserId, Integer type, String date, Integer pageIndex, Integer pageSize) { | public ResultData microPayListOnDateAsPage(Long bUserId, Integer type, String date, Integer pageIndex, Integer pageSize) { | ||||
| WxMerchantBUser wxMerchantBUser = wxMerchantBUserMapper.selectById(bUserId.longValue()); | WxMerchantBUser wxMerchantBUser = wxMerchantBUserMapper.selectById(bUserId.longValue()); | ||||
| @@ -1899,54 +2015,8 @@ public class TtOrderServiceImpl implements TtOrderService { | |||||
| @Qualifier("cUserBasicInfoRedisTemplate") | @Qualifier("cUserBasicInfoRedisTemplate") | ||||
| RedisTemplate<String, WxCUserBasicInfo> cUserBasicInfoRedisTemplate; | RedisTemplate<String, WxCUserBasicInfo> cUserBasicInfoRedisTemplate; | ||||
| @Override | |||||
| public WxOrder saveOrderForCoupon(WxCUserBasicInfo user, WxCoupon coupon, OrderSaveDto orderSaveDto, boolean isPress,EnumPayWay payWay) { | |||||
| WxOrder order = null; | |||||
| // 防止同一用户重复抽奖(一分钟内) | |||||
| // 1. 订单保存时 加入redis缓存,key --> action:userId:couponId , 时间1000ms | |||||
| // 2. 如果存在,说明该用户正在下单,返回异常提示 | |||||
| // 3. 方法结束时清除 key | |||||
| if (checkCouponIsFree(coupon)) { | |||||
| // 免费券 | |||||
| String key = StringUtils.join("action", ":", user.getId(), coupon.getId()); | |||||
| boolean hasKey = cUserBasicInfoRedisTemplate.hasKey(key); | |||||
| if (hasKey) { | |||||
| logger.error("用户正在下单,请求异常返回,user: {} " + JSON.toJSONString(user)); | |||||
| throw new MallinkException(ErrorCode.SYS_REPEAT_SUBMIT_EXCEPTION); | |||||
| } | |||||
| cUserBasicInfoRedisTemplate.opsForValue().set(key, user, 1000, TimeUnit.MILLISECONDS); | |||||
| order = saveFreeOrderForCoupon(user, coupon, orderSaveDto.getCouponChannelId(), orderSaveDto.getFormId(), null,payWay); | |||||
| if (order != null) { | |||||
| // 6. 下订单完成,发送内部消息 | |||||
| // 下订单完成,发送内部消息 | |||||
| try { | |||||
| sendOrderSuccessActionMsg(order); | |||||
| } catch (Exception e) { | |||||
| logger.error("内部消息发送失败: " + e.getMessage()); | |||||
| throw new MallinkException(ErrorCode.MSG_INSIDE_ERROR); | |||||
| } | |||||
| } | |||||
| } else { | |||||
| // 有价券 | |||||
| order = saveNoFreeOrderForCoupon(user, coupon, orderSaveDto.getCouponChannelId(), isPress, orderSaveDto.getOrderGroupId(), orderSaveDto.getFormId()); | |||||
| } | |||||
| // couponActionLog | |||||
| try { | |||||
| wxCouponActionLogService.addOne(order, order.getProductId(), order.getOrderNumber(), EnumCouponSendSendType.ACTIVE.getCode(), orderSaveDto.getCouponChannelId(),0L); | |||||
| } catch (Exception e) { | |||||
| // 库存恢复 | |||||
| stockBack(order); | |||||
| logger.error("保存订单:" + e.getMessage()); | |||||
| throw new MallinkException(ErrorCode.ORDER_SAVE_ERR); | |||||
| } | |||||
| return order; | |||||
| } | |||||
| @Override | |||||
| public boolean checkCouponIsFree(WxCoupon coupon) { | |||||
| return coupon.getSalePrice() == 0; | |||||
| } | |||||
| @Override | @Override | ||||
| @Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = {Exception.class}) | @Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = {Exception.class}) | ||||
| @@ -2343,107 +2413,6 @@ public class TtOrderServiceImpl implements TtOrderService { | |||||
| return wxOrderMapper.countList(query); | return wxOrderMapper.countList(query); | ||||
| } | } | ||||
| @Override | |||||
| public ResultData saveOrder(OrderSaveDto orderSaveDto,Long cUserId,EnumPayWay payWay,TenantEntity tenantEntity) { | |||||
| logger.info("OrderSave: " + orderSaveDto); | |||||
| if (orderSaveDto.getCouponChannelId() == null) { | |||||
| return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "couponChannelId不能为空"); | |||||
| } | |||||
| WxCouponChannel wxCouponChannel = wxCouponChannelService.getById(orderSaveDto.getCouponChannelId(),tenantEntity.getTenantId()); | |||||
| if (wxCouponChannel == null) { | |||||
| logger.error("couponChannelId find error, " + orderSaveDto.getCouponChannelId()); | |||||
| return new ResultData(ErrorCode.COUPON_CHANNEL_IS_TAKE_OFF); | |||||
| } | |||||
| ResultData resultData = couponChannelCheck(orderSaveDto, wxCouponChannel); | |||||
| if (resultData != null) return resultData; | |||||
| WxCUserBasicInfo wxCUserBasicInfo = wxCUserBasicInfoService.getById(cUserId,tenantEntity.getFinalTenantId()); | |||||
| if (wxCUserBasicInfo != null && wxCUserBasicInfo.getStatus().equals(EnumCUserBasicInfoStatus.LOCKED.getCode())) { | |||||
| logger.info("会员权益被锁定:cUserId:" + cUserId); | |||||
| return new ResultData(ErrorCode.MEMBER_IS_LOCKED); | |||||
| } | |||||
| WxCoupon coupon = wxCouponService.getById(wxCouponChannel.getCouponId(),wxCouponChannel.getTenantId()); | |||||
| if (null == coupon) { | |||||
| return new ResultData(ErrorCode.COUPON_IS_EMPTY); | |||||
| } | |||||
| if (coupon.getStatus().equals(EnumCouponStatus.COUPON_STATUS_TAKE_OFFF.getCode())) { | |||||
| return new ResultData(ErrorCode.COUPON_IS_TAKE_OFF); | |||||
| } | |||||
| //判断是否是拼团订单,如果是拼团订单,判断现在进行中的,和已完成的数量是否超出券的限制 | |||||
| if (coupon.getType().equals(EnumCouponType.COUPON_GROUP.getCode())) { | |||||
| int ordercount = this.countUserCouponGroupOrder(cUserId,coupon.getId(),coupon.getTenantId()); | |||||
| if (ordercount>=coupon.getUseLimitQuantity()) { | |||||
| return new ResultData(ErrorCode.COUPON_IS_TAKE_OFF.getCode(),"您当前此券的有效拼团数量达到券的限购次数。"); | |||||
| } | |||||
| } | |||||
| WxCouponCVo wxCouponCVo = null; | |||||
| String key = "cc:" + orderSaveDto.getCouponChannelId(); | |||||
| ValueOperations<String, WxCouponCVo> operations = cdRedisTemplate.opsForValue(); | |||||
| // 缓存 | |||||
| boolean hasKey = cdRedisTemplate.hasKey(key); | |||||
| if (hasKey) { | |||||
| // 从缓存获取用户信息 | |||||
| wxCouponCVo = operations.get(key); | |||||
| } else { | |||||
| // 游戏没有入缓存,需要从数据库中读取 | |||||
| wxCouponCVo = wxCouponChannelService.findDetailVo(orderSaveDto.getCouponChannelId(),wxCouponChannel.getTenantId()); | |||||
| if (wxCouponCVo != null) { | |||||
| // 游戏优化,进缓存 | |||||
| cdRedisTemplate.opsForValue().set(key, wxCouponCVo, 3600, TimeUnit.SECONDS); | |||||
| } | |||||
| } | |||||
| if (wxCouponCVo == null) { | |||||
| return new ResultData(ErrorCode.COUPON_IS_EMPTY); | |||||
| } | |||||
| //此处判断是否存在绝对保证库存不超卖的缓存,如果没有,则把当前的库存设置为最大值。如果有,则是后台设置的时候保存的,以那个为准。 | |||||
| boolean hascache = redisLock.hasCouponStockCache(wxCouponCVo.getCouponId()); | |||||
| if (!hascache) { | |||||
| long time = System.currentTimeMillis() + RedisLock.TIMEOUT; | |||||
| String timeStr = String.valueOf(time); | |||||
| boolean stocksetlock = redisLock.lock("couponLockStockSetByOrder_"+coupon.getId(), timeStr); | |||||
| if (stocksetlock) { | |||||
| try { | |||||
| if (!redisLock.hasCouponStockCache(wxCouponCVo.getCouponId())) { | |||||
| redisLock.setCouponStock(wxCouponCVo.getCouponId(), coupon.getRemainInventory()); | |||||
| } | |||||
| }catch(Exception e) { | |||||
| logger.error("save order stock cache error.",e); | |||||
| }finally { | |||||
| redisLock.unlock("couponLockStockSetByOrder_"+coupon.getId(), timeStr); | |||||
| } | |||||
| }else { | |||||
| redisLock.unlock("couponLockStockSetByOrder_"+coupon.getId(), timeStr); | |||||
| } | |||||
| } | |||||
| resultData = couponUserCheck(wxCUserBasicInfo, wxCouponCVo); | |||||
| if (resultData != null) return resultData; | |||||
| Long couponId = orderSaveDto.getCouponId() == null ? wxCouponChannel.getCouponId() : orderSaveDto.getCouponId(); | |||||
| if (couponId == null) { | |||||
| logger.error("couponChannelId或者couponId不能为空"); | |||||
| return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "couponChannelId或者couponId不能为空"); | |||||
| } | |||||
| // 是否砍价 | |||||
| boolean isPress = orderSaveDto.getPress() != null ? orderSaveDto.getPress() : false; | |||||
| try { | |||||
| WxOrder order = this.saveOrderForCoupon(wxCUserBasicInfo, coupon, orderSaveDto, isPress,payWay); | |||||
| return new ResultData(order); | |||||
| } catch (MallinkException e) { | |||||
| logger.error(e.getMessage()); | |||||
| return new ResultData(e.getErrorCode(), e.getMessage()); | |||||
| } catch (Exception e) { | |||||
| logger.error(e.getMessage()); | |||||
| return new ResultData(ErrorCode.ORDER_IS_FAIL, e.getMessage()); | |||||
| } | |||||
| } | |||||
| private ResultData couponChannelCheck(OrderSaveDto orderSaveDto, WxCouponChannel wxCouponChannel) { | private ResultData couponChannelCheck(OrderSaveDto orderSaveDto, WxCouponChannel wxCouponChannel) { | ||||
| if (wxCouponChannel.getTargetAd().equals(EnumCouponChannelType.COUPON_CHANNEL_ID_TIMED.getCode())) { | if (wxCouponChannel.getTargetAd().equals(EnumCouponChannelType.COUPON_CHANNEL_ID_TIMED.getCode())) { | ||||
| Date now = new Date(); | Date now = new Date(); | ||||
| @@ -92,6 +92,13 @@ | |||||
| and m.`name` like concat('%', #{author},'%') | and m.`name` like concat('%', #{author},'%') | ||||
| </if> | </if> | ||||
| <if test=" null != statusS "> | |||||
| and o.`order_status` in | |||||
| <foreach collection="statusS" index="index" item="sItem" open="(" separator="," close=")"> | |||||
| #{sItem} | |||||
| </foreach> | |||||
| </if> | |||||
| <if test=" null != ids "> | <if test=" null != ids "> | ||||
| and o.`id` in | and o.`id` in | ||||
| <foreach collection="ids" index="index" item="idItem" open="(" separator="," close=")"> | <foreach collection="ids" index="index" item="idItem" open="(" separator="," close=")"> | ||||
| @@ -111,4 +118,35 @@ | |||||
| <include refid="dynamicWhereConditions"/> | <include refid="dynamicWhereConditions"/> | ||||
| </select> | </select> | ||||
| <select id="findListCount" parameterType="com.iformall.domain.po.WxOrder" resultType="Integer"> | |||||
| select count(1) | |||||
| from wx_order | |||||
| where 1 = 1 | |||||
| <if test=" null != tenantId and '' != tenantId"> | |||||
| and `tenant_id` = #{tenantId} | |||||
| </if> | |||||
| <if test=" null != parentTenantId and '' != parentTenantId"> | |||||
| and `parent_tenant_id` = #{parentTenantId} | |||||
| </if> | |||||
| <if test=" null != cUserId "> | |||||
| and `c_user_id` = #{cUserId} | |||||
| </if> | |||||
| <if test=" null != productId "> | |||||
| and `product_id` = #{productId} | |||||
| </if> | |||||
| <if test=" null != orderStatus "> | |||||
| and `order_status` = #{orderStatus} | |||||
| </if> | |||||
| <if test=" null != statusS "> | |||||
| and `order_status` in | |||||
| <foreach collection="statusS" index="index" item="sItem" open="(" separator="," close=")"> | |||||
| #{sItem} | |||||
| </foreach> | |||||
| </if> | |||||
| </select> | |||||
| </mapper> | </mapper> | ||||
| @@ -79,8 +79,8 @@ public class TtOrderController extends BaseController { | |||||
| Long memberId; | Long memberId; | ||||
| try { | try { | ||||
| memberId = getMemberId(); | memberId = getMemberId(); | ||||
| } catch (Exception e) { | |||||
| return new ResultData(Result.ERROR,e.getMessage()); | |||||
| } catch (MallinkException e) { | |||||
| return new ResultData(e.getErrorCode(), e.getMessage()); | |||||
| } | } | ||||
| order.setCUserId(memberId); | order.setCUserId(memberId); | ||||
| return new ResultData(ttOrderService.listAsPage(order, pageNum, pageSize)); | return new ResultData(ttOrderService.listAsPage(order, pageNum, pageSize)); | ||||
| @@ -88,14 +88,25 @@ public class TtOrderController extends BaseController { | |||||
| @ApiOperation(value = "下订单", notes = "{\"couponChannelId\":\"String\",\"couponId\":\"String\",\"press\":\"String\",\"orderGroupId\":\"String\",\"formId\":\"String\"}") | @ApiOperation(value = "下订单", notes = "{\"couponChannelId\":\"String\",\"couponId\":\"String\",\"press\":\"String\",\"orderGroupId\":\"String\",\"formId\":\"String\"}") | ||||
| @PostMapping("save") | @PostMapping("save") | ||||
| public ResultData saveOrder(@RequestBody OrderSaveDto orderSaveDto) { | |||||
| public ResultData saveOrder(@RequestBody Map<String, String> paramMap) { | |||||
| String couponIdStr = paramMap.get("couponId"); | |||||
| if (StringUtils.isBlank(couponIdStr) || couponIdStr.equalsIgnoreCase(Constant.UNDEFINED)) { | |||||
| return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "couponId不能为空"); | |||||
| } | |||||
| Long couponId; | |||||
| try { | |||||
| couponId = Long.valueOf(couponIdStr); | |||||
| } catch (NumberFormatException e) { | |||||
| logger.error(e.getMessage()); | |||||
| return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL, "couponId: " + couponIdStr + ", e: " + e.getMessage()); | |||||
| } | |||||
| Long memberId; | Long memberId; | ||||
| try { | try { | ||||
| memberId = getMemberId(); | |||||
| } catch (Exception e) { | |||||
| return new ResultData(Result.ERROR,e.getMessage()); | |||||
| } | |||||
| return wxOrderService.saveOrder(orderSaveDto,memberId,EnumPayWay.PAY_WAY_WECHAT,getTenantInfo()); | |||||
| memberId = getMemberId(); | |||||
| } catch (MallinkException e) { | |||||
| return new ResultData(e.getErrorCode(), e.getMessage()); | |||||
| } | |||||
| return ttOrderService.saveOrder(couponId,memberId,EnumPayWay.PAY_WAY_TT,getTenantInfo()); | |||||
| } | } | ||||
| @@ -106,56 +117,27 @@ public class TtOrderController extends BaseController { | |||||
| if (StringUtils.isBlank(orderIdStr) || orderIdStr.equalsIgnoreCase(Constant.UNDEFINED)) { | if (StringUtils.isBlank(orderIdStr) || orderIdStr.equalsIgnoreCase(Constant.UNDEFINED)) { | ||||
| return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "orderId不能为空"); | return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "orderId不能为空"); | ||||
| } | } | ||||
| Long orderId = 0L; | |||||
| Long orderId; | |||||
| try { | try { | ||||
| orderId = Long.valueOf(orderIdStr); | orderId = Long.valueOf(orderIdStr); | ||||
| } catch (NumberFormatException e) { | } catch (NumberFormatException e) { | ||||
| logger.error(e.getMessage()); | logger.error(e.getMessage()); | ||||
| return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL, "orderId: " + orderIdStr + ", e: " + e.getMessage()); | return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL, "orderId: " + orderIdStr + ", e: " + e.getMessage()); | ||||
| } | } | ||||
| Long memberId; | |||||
| try { | try { | ||||
| WxOrder order = wxOrderService.getById(orderId,getTenantInfo().getTenantId()); | |||||
| if (order != null) { | |||||
| wxOrderService.updateOrderStatus(order, EnumOrderStatus.ORDER_STATUS_OVERTIME_CANCEL); | |||||
| } | |||||
| } catch (Exception e) { | |||||
| logger.error("取消订单失败: " + e.getMessage()); | |||||
| return new ResultData(ErrorCode.ORDER_IS_FAIL.getCode(), "取消订单失败: " + e.getMessage()); | |||||
| } | |||||
| return new ResultData(); | |||||
| } | |||||
| @ApiOperation(value = "订单已过期", notes = "{\"orderId\":\"string\"}") | |||||
| @PostMapping("expired") | |||||
| public ResultData expiredOrder(@RequestBody Map<String, String> paramMap) { | |||||
| //Assert.notNull(wxOrders.getName(), "角色名不能为空"); | |||||
| //Assert.isTrue(!checkUnique(sysRole.getName(), null), "重复的角色名"); | |||||
| String orderIdStr = paramMap.get("orderId"); | |||||
| if (StringUtils.isBlank(orderIdStr) || orderIdStr.equalsIgnoreCase(Constant.UNDEFINED)) { | |||||
| return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "退款订单ID不能为空"); | |||||
| } | |||||
| Long orderId = 0L; | |||||
| try { | |||||
| orderId = Long.valueOf(orderIdStr); | |||||
| } catch (NumberFormatException e) { | |||||
| logger.error(e.getMessage()); | |||||
| return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "退款订单ID转换失败"); | |||||
| memberId = getMemberId(); | |||||
| } catch (MallinkException e) { | |||||
| return new ResultData(e.getErrorCode(), e.getMessage()); | |||||
| } | } | ||||
| try { | try { | ||||
| WxOrder order = wxOrderService.getById(orderId,getTenantInfo().getTenantId()); | |||||
| if (order != null) { | |||||
| wxOrderService.updateOrderStatus(order, EnumOrderStatus.ORDER_STATUS_REFUND_SUCCESS); | |||||
| } | |||||
| return ttOrderService.cancelOrder(orderId,memberId); | |||||
| } catch (Exception e) { | } catch (Exception e) { | ||||
| logger.error("更新退款订单状态失败:" + e.getMessage()); | |||||
| return new ResultData(ErrorCode.REFUND_ORDER_ERROR.getCode(), "更新退款订单状态失败:" + e.getMessage()); | |||||
| logger.error("取消订单失败: " + e.getMessage()); | |||||
| return new ResultData(ErrorCode.ORDER_IS_FAIL.getCode(), "取消订单失败: " + e.getMessage()); | |||||
| } | } | ||||
| return new ResultData(); | |||||
| } | } | ||||
| @ApiOperation("订单详情接口") | @ApiOperation("订单详情接口") | ||||
| @GetMapping("detail") | @GetMapping("detail") | ||||
| @ApiImplicitParams({ | @ApiImplicitParams({ | ||||
| @@ -165,53 +147,21 @@ public class TtOrderController extends BaseController { | |||||
| if (StringUtils.isBlank(orderId) || orderId.equalsIgnoreCase(Constant.UNDEFINED)) { | if (StringUtils.isBlank(orderId) || orderId.equalsIgnoreCase(Constant.UNDEFINED)) { | ||||
| return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL); | return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL); | ||||
| } | } | ||||
| // c端用户应该只能看到自己的订单细节 | |||||
| WxOrder wxOrder = new WxOrder(); | |||||
| Long id = 0L; | |||||
| Long id; | |||||
| try { | try { | ||||
| id = Long.valueOf(orderId); | id = Long.valueOf(orderId); | ||||
| } catch (NumberFormatException e) { | } catch (NumberFormatException e) { | ||||
| logger.error("parse orderId failed"); | |||||
| return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "订单ID转换异常"); | |||||
| logger.error(e.getMessage()); | |||||
| return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL, "orderId: " + orderId + ", e: " + e.getMessage()); | |||||
| } | } | ||||
| wxOrder.setId(id); | |||||
| Long memberId; | Long memberId; | ||||
| try { | try { | ||||
| memberId = getMemberId(); | |||||
| } catch (Exception e) { | |||||
| return new ResultData(Result.ERROR,e.getMessage()); | |||||
| } | |||||
| wxOrder.setCUserId(memberId); | |||||
| WxOrderCouponVo wxOrderCVo = wxOrderService.detailCUserVo(wxOrder); | |||||
| if (wxOrderCVo == null) | |||||
| return new ResultData(ErrorCode.ORDER_IS_NOT_FIND); | |||||
| Date now = new Date(); | |||||
| if (wxOrderCVo.getValidStartDate() != null && wxOrderCVo.getValidEndDate() != null | |||||
| && !wxOrderCVo.getType().equals(EnumCouponType.COUPON_PREORDER.getCode())) { | |||||
| if (wxOrderCVo.getValidStartDate().getTime() > now.getTime()) { | |||||
| wxOrderCVo.setValidStatus(EnumCouponOrderValidStatus.PREPARED.getCode()); | |||||
| } else if (wxOrderCVo.getValidEndDate().getTime() < now.getTime()) { | |||||
| wxOrderCVo.setValidStatus(EnumCouponOrderValidStatus.ENDED.getCode()); | |||||
| } else { | |||||
| wxOrderCVo.setValidStatus(EnumCouponChannelActivityStatus.STARTED.getCode()); | |||||
| } | |||||
| } | |||||
| if(wxOrderCVo.getType().equals(EnumCouponType.COUPON_PREORDER.getCode()) | |||||
| && wxOrderCVo.getPickStartDate() != null && wxOrderCVo.getPickEndDate() != null){ | |||||
| // wxOrderCVo.setValidStartDate(wxOrderCVo.getPickStartDate()); | |||||
| // wxOrderCVo.setValidEndDate(wxOrderCVo.getPickEndDate()); | |||||
| if (wxOrderCVo.getPickStartDate().getTime() > now.getTime()) { | |||||
| wxOrderCVo.setValidStatus(EnumCouponOrderValidStatus.PREPARED.getCode()); | |||||
| } else if (wxOrderCVo.getPickEndDate().getTime() < now.getTime()) { | |||||
| wxOrderCVo.setValidStatus(EnumCouponOrderValidStatus.ENDED.getCode()); | |||||
| } else { | |||||
| wxOrderCVo.setValidStatus(EnumCouponChannelActivityStatus.STARTED.getCode()); | |||||
| } | |||||
| memberId = getMemberId(); | |||||
| } catch (MallinkException e) { | |||||
| return new ResultData(e.getErrorCode(), e.getMessage()); | |||||
| } | } | ||||
| return new ResultData(wxOrderCVo); | |||||
| TtOrder order = ttOrderService.detail(id,memberId); | |||||
| return new ResultData(order); | |||||
| } | } | ||||
| @ApiOperation(value = "根据orderId查询接口", notes = "{\"orderId\":\"string\"}") | @ApiOperation(value = "根据orderId查询接口", notes = "{\"orderId\":\"string\"}") | ||||