ApiUserCouponService.java 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293
  1. package com.kmall.api.service;
  2. import com.alibaba.fastjson.JSONObject;
  3. import com.google.common.collect.Maps;
  4. import com.kmall.api.dto.UserCouponDto;
  5. import com.kmall.api.entity.CartVo;
  6. import com.kmall.api.entity.CouponVo;
  7. import com.kmall.api.entity.UserVo;
  8. import com.kmall.api.entity.mk.MkStoreTicketDiscountVo;
  9. import com.kmall.api.service.mk.ApiMkStoreTicketDiscountService;
  10. import com.kmall.api.service.mk.ApiMkStoreTopicStatService;
  11. import com.kmall.common.constant.Dict;
  12. import com.kmall.api.dao.ApiUserCouponMapper;
  13. import com.kmall.api.entity.UserCouponVo;
  14. import com.kmall.common.utils.*;
  15. import org.apache.commons.logging.Log;
  16. import org.apache.commons.logging.LogFactory;
  17. import org.springframework.beans.factory.annotation.Autowired;
  18. import org.springframework.stereotype.Service;
  19. import org.springframework.transaction.annotation.Transactional;
  20. import java.math.BigDecimal;
  21. import java.util.*;
  22. @Service
  23. public class ApiUserCouponService {
  24. private Log logger = LogFactory.getLog(ApiUserCouponService.class);
  25. @Autowired
  26. private ApiUserCouponMapper userCouponDao;
  27. @Autowired
  28. private ApiMkStoreTicketDiscountService mkStoreTicketDiscountService;
  29. @Autowired
  30. private ApiMkStoreTopicStatService apiMkStoreTopicStatService;
  31. public UserCouponVo queryObject(Integer id) {
  32. return userCouponDao.queryObject(id);
  33. }
  34. public List<UserCouponVo> queryList(Map<String, Object> map) {
  35. return userCouponDao.queryList(map);
  36. }
  37. public int queryTotal(Map<String, Object> map) {
  38. return userCouponDao.queryTotal(map);
  39. }
  40. public void save(UserCouponVo goods) {
  41. userCouponDao.save(goods);
  42. }
  43. public void update(UserCouponVo goods) {
  44. userCouponDao.update(goods);
  45. }
  46. public void delete(Integer id) {
  47. userCouponDao.delete(id);
  48. }
  49. public void deleteBatch(Integer[] ids) {
  50. userCouponDao.deleteBatch(ids);
  51. }
  52. public List<UserCouponVo> queryUserCoupons(Map<String, Object> map) {
  53. return userCouponDao.queryUserCoupons(map);
  54. }
  55. /**
  56. * 标记未使用的优惠券是否可用,暂时无用
  57. *
  58. * @param userId
  59. * @param goodsTotalPrice
  60. * @return
  61. */
  62. public List<UserCouponVo> signUserCouponList(Long userId,String merchSn, BigDecimal goodsTotalPrice) {
  63. Map param = Maps.newHashMap();
  64. param.put("user_id", userId);
  65. param.put("unUsed", true);
  66. param.put("enabled", true);
  67. Integer[] send_types = new Integer[]{1, 2, 3, 4, 5, 6}; // 去除订单满减0,运费7
  68. param.put("send_types", send_types);
  69. param.put("merchSn", merchSn);
  70. List<UserCouponVo> couponVos = userCouponDao.queryList(param);
  71. if (null != couponVos && couponVos.size() > 0) {
  72. // 如果没有用户优惠券直接返回新用户优惠券
  73. for (UserCouponVo couponVo : couponVos) {
  74. //// TODO: 2019/5/15 最小金额
  75. // if (couponVo.getTypeMoney().compareTo(goodsTotalPrice) <= 0) {
  76. // couponVo.setEnabled("1");
  77. // }
  78. }
  79. }
  80. return couponVos;
  81. }
  82. /**
  83. * 匹配未使用的优惠券是否可用
  84. *
  85. * @param userCouponDto
  86. * @return
  87. */
  88. public List<UserCouponVo> matchUserCouponList(UserCouponDto userCouponDto) {
  89. List<UserCouponVo> result = new ArrayList();
  90. List<MkStoreTicketDiscountVo> switchList = new ArrayList();
  91. if(userCouponDto.getCartGoodsList() == null || userCouponDto.getCartGoodsList().size() == 0){
  92. return result;
  93. }
  94. //获取订单中商品可支持的优惠券,自动选择减免最大的金额
  95. String isUsed = "0";
  96. //查询未使用已领取的优惠券
  97. Map map = mkStoreTicketDiscountService.queryStoreDiscountByCartGoodsId(userCouponDto, isUsed);
  98. List<MkStoreTicketDiscountVo> discountVoList = (List<MkStoreTicketDiscountVo>)map.get("discountVoList");
  99. if(discountVoList != null && discountVoList.size() > 0){
  100. for (MkStoreTicketDiscountVo discountVo : discountVoList) {
  101. BigDecimal cond = Constant.ZERO;
  102. BigDecimal money = Constant.ZERO;
  103. if(discountVo.getTickDiscType().equalsIgnoreCase(Dict.tickDiscType.item_00.getItem())){//代金券
  104. cond = discountVo.getVoucherCond();
  105. money = discountVo.getVoucherMoney();
  106. }
  107. if(discountVo.getTickDiscType().equalsIgnoreCase(Dict.tickDiscType.item_01.getItem())){//折扣券
  108. cond = discountVo.getDiscCond();
  109. money = discountVo.getDiscRatio();//满多少打几折
  110. }
  111. //// TODO: 2019/5/21 代金券暂时无用
  112. /*if(discountVo.getTickDiscType().equalsIgnoreCase(Dict.tickDiscType.item_02.getItem())){
  113. cond = discountVo.getExchCond();
  114. money = discountVo.getExchCond();
  115. }*/
  116. if(discountVo.getApplyType().equalsIgnoreCase(Dict.applyType.item_00.getItem())){ //全部商品参与
  117. //计算购物车中满足部分商品的销售价
  118. BigDecimal totalByGoodsId = getTotalByGoodsId(userCouponDto.getCartGoodsList(),discountVoList,discountVo.getTickDiscId());
  119. //销售价>满减价,去重
  120. if (totalByGoodsId.compareTo(cond) >= 0 && containsList(switchList,discountVo)) {
  121. UserCouponVo userCouponVo = setUserCouponVo(discountVo, money);
  122. result.add(userCouponVo);
  123. switchList.add(discountVo);
  124. }
  125. }
  126. if(!discountVo.getApplyType().equalsIgnoreCase(Dict.applyType.item_00.getItem())) { //部分商品参与
  127. //计算购物车中满足部分商品的销售价
  128. BigDecimal totalByGoodsId = getTotalByGoodsId(userCouponDto.getCartGoodsList(),discountVoList,discountVo.getTickDiscId());
  129. //销售价>满减价,去重
  130. if(totalByGoodsId.compareTo(cond) >= 0 && containsList(switchList,discountVo)){
  131. UserCouponVo userCouponVo = setUserCouponVo(discountVo, money);
  132. result.add(userCouponVo);
  133. switchList.add(discountVo);
  134. }
  135. }
  136. }
  137. if(result != null && result.size() > 0) {
  138. UserCouponVo userCouponVo = new UserCouponVo();
  139. userCouponVo.setId(0L);
  140. userCouponVo.setCouponName("不参与优惠券");
  141. userCouponVo.setTypeMoney(Constant.ZERO);
  142. userCouponVo.setGoodsBizType(userCouponDto.getBizType());
  143. result.add(userCouponVo);
  144. }
  145. }
  146. return result;
  147. }
  148. /**
  149. * 获取优惠券可支持的商品总销售价
  150. * @param cartGoodsList
  151. * @param discountVoList
  152. * @param tickDistId
  153. * @return
  154. */
  155. private BigDecimal getTotalByGoodsId(List<CartVo> cartGoodsList, List<MkStoreTicketDiscountVo> discountVoList, Integer tickDistId){
  156. BigDecimal total = new BigDecimal(0);
  157. for (CartVo vo: cartGoodsList) {
  158. for(MkStoreTicketDiscountVo discountVo: discountVoList){
  159. if(discountVo.getTickDiscId() == tickDistId && discountVo.getGoodsId().compareTo(vo.getGoods_id().intValue()) == 0){
  160. total = total.add(vo.getRetail_price().multiply(BigDecimal.valueOf(vo.getNumber())));
  161. }
  162. }
  163. }
  164. return total;
  165. }
  166. /**
  167. * 去重
  168. * @param switchList
  169. * @param discountVo
  170. * @return
  171. */
  172. private Boolean containsList(List<MkStoreTicketDiscountVo> switchList,MkStoreTicketDiscountVo discountVo){
  173. for (MkStoreTicketDiscountVo vo: switchList) {
  174. if(vo.getTickDiscId().equals(discountVo.getTickDiscId())){
  175. return false;
  176. }
  177. }
  178. return true;
  179. }
  180. private UserCouponVo setUserCouponVo(MkStoreTicketDiscountVo discountVo,BigDecimal money){
  181. UserCouponVo userCouponVo = new UserCouponVo();
  182. userCouponVo.setTickDiscType(discountVo.getTickDiscType());
  183. userCouponVo.setCouponName(discountVo.getName());
  184. userCouponVo.setTypeMoney(money);
  185. userCouponVo.setId(Long.valueOf(discountVo.getTickDiscId()));
  186. userCouponVo.setSelectTicket(false);
  187. userCouponVo.setGoodsBizType(discountVo.getGoodsBizType());
  188. userCouponVo.setGoodsList(discountVo.getGoodsList());
  189. return userCouponVo;
  190. }
  191. public UserCouponVo queryObjectByStoreTopicIdAndUserId(Integer storeTopicId,Long userId){
  192. return userCouponDao.queryObjectByStoreTopicIdAndUserId(storeTopicId,userId);
  193. }
  194. /**
  195. * 领取优惠券
  196. * @param jsonParam
  197. * @param loginUser
  198. */
  199. @Transactional
  200. public void getUserCoupon(JSONObject jsonParam, UserVo loginUser){
  201. Integer tickDiscId = jsonParam.getInteger("tickDiscId");
  202. Integer storeTopicId = jsonParam.getInteger("storeTopicId");
  203. Integer storeId = jsonParam.getInteger("storeId");
  204. Long userId = loginUser.getId();
  205. MkStoreTicketDiscountVo discountVo = mkStoreTicketDiscountService.queryObject(tickDiscId);
  206. if(discountVo == null){
  207. logger.error("该优惠券无效" );
  208. throw new RRException("该优惠券无效");
  209. }
  210. Map map = new HashMap();
  211. map.put("userId" , userId);
  212. map.put("storeId", storeId);
  213. map.put("storeTopicId", storeTopicId);
  214. map.put("tickDiscId", tickDiscId);
  215. List<MkStoreTicketDiscountVo> list = mkStoreTicketDiscountService.queryStoreDiscountByUserId(map);
  216. if (list.size() > 0 && list.size() == discountVo.getLimitNum()) {
  217. logger.error("您已经领取过该优惠券,不能重复领取" );
  218. throw new RRException("您已经领取过该优惠券,不能重复领取");
  219. }
  220. UserCouponVo userCouponVo = new UserCouponVo();
  221. userCouponVo.setCouponUrl(discountVo.getAdvImgUrl());
  222. userCouponVo.setCouponName(discountVo.getName());
  223. userCouponVo.setUserId(Long.valueOf(userId));
  224. userCouponVo.setAddTime(new Date());
  225. userCouponVo.setSourceKey("小程序");
  226. userCouponVo.setShowState(1);
  227. userCouponVo.setIsUsed(Dict.isUsed.item_0.getItem());
  228. userCouponVo.setEnabled("1");
  229. userCouponVo.setCreateTime(new Date());
  230. userCouponVo.setModTime(new Date());
  231. if(discountVo.getEffectTimeType().equalsIgnoreCase(Dict.effectTimeType.item_00.getItem())){
  232. userCouponVo.setEndTime(discountVo.getFixEndTime());
  233. userCouponVo.setValidTime(discountVo.getFixBegTime());
  234. }
  235. if(discountVo.getEffectTimeType().equalsIgnoreCase(Dict.effectTimeType.item_01.getItem())){
  236. Integer postponeNum = Integer.parseInt(discountVo.getPostponeNum());//领取后多少天后生效
  237. Integer day = postponeNum + Integer.parseInt(discountVo.getValidDayNum());
  238. Date validDate = DateUtils.addDay(new Date(), postponeNum);//生效时间
  239. Date endDate = DateUtils.addDay(new Date(), day);//过期时间
  240. userCouponVo.setEndTime(endDate);
  241. userCouponVo.setValidTime(validDate);
  242. }
  243. userCouponVo.setStoreTopicId(Long.valueOf(storeTopicId));
  244. //// TODO: 2019/5/21 代金券暂时无用
  245. /*if(discountVo.getTickDiscType().equalsIgnoreCase(Dict.tickDiscType.item_02.getItem())){
  246. userCouponVo.setTypeMoney(discountVo.getExchCond());
  247. }*/
  248. if(discountVo.getTickDiscType().equalsIgnoreCase(Dict.tickDiscType.item_00.getItem())){
  249. userCouponVo.setTypeMoney(discountVo.getVoucherMoney());
  250. }
  251. if(discountVo.getTickDiscType().equalsIgnoreCase(Dict.tickDiscType.item_01.getItem())){
  252. userCouponVo.setTypeMoney(discountVo.getDiscRatio());//折扣金额
  253. }
  254. userCouponDao.save(userCouponVo);
  255. //优惠券库存扣减
  256. if(discountVo.getTicketNum()-1 >= 0){
  257. MkStoreTicketDiscountVo mkStoreTicketDiscountVo = new MkStoreTicketDiscountVo();
  258. mkStoreTicketDiscountVo.setTickDiscId(discountVo.getTickDiscId());
  259. mkStoreTicketDiscountVo.setTicketNum(discountVo.getTicketNum()-1);
  260. mkStoreTicketDiscountService.updateDiscount(mkStoreTicketDiscountVo);
  261. //记录活动营销统计领取量数据
  262. apiMkStoreTopicStatService.saveStoreTopicStatByReceiveData(Integer.parseInt(String.valueOf(userCouponVo.getId())));
  263. }
  264. }
  265. }