CouponFrontController.java 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383
  1. package com.cyksj.web.controller.coupon;
  2. import cn.hutool.core.date.DateTime;
  3. import cn.hutool.core.date.DateUtil;
  4. import com.baomidou.mybatisplus.core.toolkit.Wrappers;
  5. import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
  6. import com.cyksj.common.annotation.NoSubmit;
  7. import com.cyksj.common.exception.BusinessRuntimeException;
  8. import com.cyksj.common.util.Jsons;
  9. import com.cyksj.dto.Result;
  10. import com.cyksj.enums.GatewayResponse;
  11. import com.cyksj.mapper.UserMapper;
  12. import com.cyksj.mapper.manage.coupon.CouponMapper;
  13. import com.cyksj.mapper.manage.coupon.CouponRecommendMapper;
  14. import com.cyksj.mapper.manage.coupon.CouponSkuMapper;
  15. import com.cyksj.mapper.manage.coupon.CouponUserMapper;
  16. import com.cyksj.mapper.manage.distribute.UserDistributeMapper;
  17. import com.cyksj.mapper.manage.distribute.UserDistributeSharedMapper;
  18. import com.cyksj.model.dto.CouponPopularizeDto;
  19. import com.cyksj.model.entity.*;
  20. import com.cyksj.model.request.ChannelPopularizeCouponReq;
  21. import com.cyksj.model.request.CouponCollectReq;
  22. import com.cyksj.model.views.*;
  23. import com.cyksj.redis.RedisService;
  24. import com.cyksj.service.coupon.CouponFontService;
  25. import com.cyksj.web.util.StpUserUtil;
  26. import com.ejlchina.searcher.BeanSearcher;
  27. import com.ejlchina.searcher.param.Operator;
  28. import com.ejlchina.searcher.util.MapUtils;
  29. import lombok.RequiredArgsConstructor;
  30. import org.springframework.validation.annotation.Validated;
  31. import org.springframework.web.bind.annotation.*;
  32. import java.math.BigDecimal;
  33. import java.util.List;
  34. import java.util.stream.Collectors;
  35. /*
  36. *项目名: netflix
  37. *文件名: CouponFrontController
  38. *创建者: JavaZou
  39. *创建时间:2022/11/18 10:56
  40. */
  41. @RestController
  42. @RequestMapping("/applet/coupon")
  43. @RequiredArgsConstructor
  44. public class CouponFrontController {
  45. private final CouponUserMapper couponUserMapper;
  46. private final BeanSearcher beanSearcher;
  47. private final CouponFontService couponFontService;
  48. private final RedisService redisService;
  49. private final CouponSkuMapper couponSkuMapper;
  50. private final CouponMapper couponMapper;
  51. private final UserDistributeMapper userDistributeMapper;
  52. private final CouponRecommendMapper couponRecommendMapper;
  53. private final UserDistributeSharedMapper userDistributeSharedMapper;
  54. private final UserMapper userMapper;
  55. /**
  56. * 优惠券领取中心列表
  57. */
  58. @GetMapping("/center/list")
  59. public Result<Page<CouponActiveView>> couponCenterList(@RequestParam(defaultValue = "1") Long start, @RequestParam(defaultValue = "5") Long limit) {
  60. Long userId = StpUserUtil.getLoginIdAsLong();
  61. Page<CouponActiveView> page = couponUserMapper.couponCenterList(userId, new Page<>(start, limit));
  62. page.getRecords().forEach(data -> {
  63. String str = couponSkuMapper.selectGoodsSkuStr(data.getCouponId());
  64. data.setGoodsSkuStr(str.replaceAll(",", "/").replaceAll(";", ""));
  65. List<CouponSkuView> couponSkus = couponSkuMapper.getGoodsSkuByCouponId(data.getCouponId());
  66. try {
  67. data.setGoodsSkuIds(Jsons.toJson(couponSkus));
  68. } catch (Exception e) {
  69. }
  70. });
  71. return GatewayResponse.SUCCESS.newBuilder().toResult(page);
  72. }
  73. /**
  74. * 个人优惠券列表
  75. */
  76. @GetMapping("/personal/list")
  77. public Result<Page<CouponUserView>> couponPersonalList(@RequestParam(defaultValue = "1") Long start, @RequestParam(defaultValue = "5") Long limit, Long couponId) {
  78. Long userId = StpUserUtil.getLoginIdAsLong();
  79. Page<CouponUserView> page = couponUserMapper.couponPersonalList(userId, new Page<>(start, limit), couponId);
  80. page.getRecords().forEach(data -> {
  81. String str = couponSkuMapper.selectGoodsSkuStr(data.getCouponId());
  82. data.setGoodsSkuStr(str.replaceAll(",", "/").replaceAll(";", ""));
  83. List<CouponSkuView> couponSkus = couponSkuMapper.getGoodsSkuByCouponId(data.getCouponId());
  84. try {
  85. data.setGoodsSkuIds(Jsons.toJson(couponSkus));
  86. } catch (Exception e) {
  87. }
  88. });
  89. return GatewayResponse.SUCCESS.newBuilder().toResult(page);
  90. }
  91. /**
  92. * 可用优惠券展示数量
  93. */
  94. @GetMapping("/available/num")
  95. public Result<Integer> availableCouponNum(Long skuId, Boolean isRenew) {
  96. Long userId = StpUserUtil.getLoginIdAsLong();
  97. Long goodsId = null;
  98. //实物还是虚物
  99. GoodsDonSkuView goodsDonSkuView = beanSearcher.searchFirst(GoodsDonSkuView.class, MapUtils.builder().field(GoodsDonSkuView::getSkuId, skuId).op(Operator.Equal).build());
  100. if (goodsDonSkuView == null) {
  101. throw BusinessRuntimeException.getInstance("规格不存在");
  102. }
  103. BigDecimal skuMoney = goodsDonSkuView.getMoney();
  104. if (goodsDonSkuView.getType() == 2) {
  105. goodsId = goodsDonSkuView.getGoodsId();
  106. }
  107. List<CouponUserView> couponUserViews = couponUserMapper.countAvailableCouponList(goodsId, skuId, userId, isRenew);
  108. Integer total = couponUserViews.size();
  109. if (goodsDonSkuView.getType() == 2) {
  110. List<CouponUserView> collect = couponUserViews.stream().filter(coupon -> {
  111. if (coupon.getType() == Coupon.Type.reduce && skuMoney.compareTo(coupon.getReduceCondition()) < 0) {
  112. return false;
  113. }
  114. return true;
  115. }).collect(Collectors.toList());
  116. total = collect.size();
  117. }
  118. return GatewayResponse.SUCCESS.newBuilder().toResult(total);
  119. }
  120. @GetMapping("/available/list")
  121. public Result<Page<CouponUserView>> availableCouponList(Long skuId, Long couponId, Boolean isRenew, @RequestParam(defaultValue = "1") Long start, @RequestParam(defaultValue = "5") Long limit) {
  122. Long userId = StpUserUtil.getLoginIdAsLong();
  123. Page<CouponUserView> couponActiveViewList = couponFontService.getAvailableCouponList(skuId, couponId, userId, isRenew, start, limit);
  124. return GatewayResponse.SUCCESS.newBuilder().toResult(couponActiveViewList);
  125. }
  126. /**
  127. * 推荐优惠券列表
  128. */
  129. @GetMapping("/recommend/list")
  130. public Result<Page<CouponRecommendView>> getRecommendList(@RequestParam(defaultValue = "1") Long start, @RequestParam(defaultValue = "5") Long limit, Long couponId) {
  131. Long userId = StpUserUtil.getLoginIdAsLong();
  132. CouponNewUserView couponNewUserView = beanSearcher.searchFirst(CouponNewUserView.class, MapUtils.builder().field(CouponNewUserView::getUserId, userId).op(Operator.Equal).build());
  133. Boolean isNewUser = true;
  134. if (couponNewUserView != null) {
  135. isNewUser = false;
  136. }
  137. Page<CouponRecommendView> page = couponRecommendMapper.getRecommendCouponViewList(userId, isNewUser, new Page<>(start, limit), couponId);
  138. page.getRecords().forEach(data -> {
  139. if (data.getCouponStatus() == CouponActiveView.CouponStatus.received) {
  140. data.setValidStartTime(data.getUserValidStartTime());
  141. data.setValidEndTime(data.getUserValidEndTime());
  142. }
  143. String str = couponSkuMapper.selectGoodsSkuStr(data.getCouponId());
  144. data.setGoodsSkuStr(str.replaceAll(",", "/").replaceAll(";", ""));
  145. List<CouponSkuView> couponSkus = couponSkuMapper.getGoodsSkuByCouponId(data.getCouponId());
  146. try {
  147. data.setGoodsSkuIds(Jsons.toJson(couponSkus));
  148. } catch (Exception e) {
  149. }
  150. });
  151. return GatewayResponse.SUCCESS.newBuilder().toResult(page);
  152. }
  153. /**
  154. * 一键领取推荐优惠券
  155. */
  156. @PostMapping("/collect/recommend/whole")
  157. @NoSubmit
  158. public Result<String> collectWholeRecommendCoupon() {
  159. Long userId = StpUserUtil.getLoginIdAsLong();
  160. couponFontService.collectWholeRecommendCoupon(userId);
  161. return GatewayResponse.SUCCESS.newBuilder().toResult("领取成功");
  162. }
  163. /**
  164. * 今日推荐优惠券弹窗已弹
  165. */
  166. @GetMapping("/get/recommend/appear")
  167. public Result<Boolean> recommendIsAppear() {
  168. Long userId = StpUserUtil.getLoginIdAsLong();
  169. String zero = DateUtil.beginOfDay(DateTime.now()).toString();
  170. Object exists = redisService.get(RedisService.key.RECOMMEND_COUPON_DAY.getNameFormat(String.format("%s-%s", zero, userId)));
  171. if (exists == null) {
  172. redisService.set(RedisService.key.RECOMMEND_COUPON_DAY.getNameFormat(String.format("%s-%s", zero, userId)), userId, RedisService.key.RECOMMEND_COUPON_DAY.getTimeout());
  173. }
  174. return GatewayResponse.SUCCESS.newBuilder().toResult(exists == null ? false : true);
  175. }
  176. /**
  177. * 领取优惠券
  178. */
  179. @PostMapping("/collect")
  180. public Result<String> collectCoupon(@RequestBody CouponCollectReq couponCollectReq) {
  181. Long userId = StpUserUtil.getLoginIdAsLong();
  182. couponFontService.collectCoupon(couponCollectReq, userId);
  183. return GatewayResponse.SUCCESS.newBuilder().toResult("领取优惠券成功");
  184. }
  185. /**
  186. * 领取推荐优惠券
  187. */
  188. @PostMapping("/recommend/collect")
  189. public Result<String> collectRecommendCoupon(@RequestBody CouponCollectReq couponCollectReq) {
  190. Long userId = StpUserUtil.getLoginIdAsLong();
  191. couponFontService.collectRecommendCoupon(couponCollectReq, userId);
  192. return GatewayResponse.SUCCESS.newBuilder().toResult("领取优惠券成功");
  193. }
  194. /**
  195. * 查询有可以领取的推荐优惠券
  196. */
  197. @GetMapping("/recommend/collect/num")
  198. public Result<Integer> collectRecommendCouponNum() {
  199. Long userId = StpUserUtil.getLoginIdAsLong();
  200. CouponNewUserView couponNewUserView = beanSearcher.searchFirst(CouponNewUserView.class, MapUtils.builder().field(CouponNewUserView::getUserId, userId).op(Operator.Equal).build());
  201. Boolean isNewUser = true;
  202. if (couponNewUserView != null) {
  203. isNewUser = false;
  204. }
  205. Integer num = couponFontService.collectRecommendCouponNum(userId, isNewUser);
  206. return GatewayResponse.SUCCESS.newBuilder().toResult(num);
  207. }
  208. /**
  209. * 优惠码详情
  210. */
  211. @GetMapping("/get/exCode/detail")
  212. public Result<CouponPopularizeDto> getExCodeDetail(Long skuId, String exCode, Boolean isRenew) {
  213. Long userId = StpUserUtil.getLoginIdAsLong();
  214. GoodsDonSkuView goodsDonSkuView = beanSearcher.searchFirst(GoodsDonSkuView.class, MapUtils.builder().field(GoodsDonSkuView::getSkuId, skuId).op(Operator.Equal).build());
  215. if (goodsDonSkuView == null) {
  216. throw BusinessRuntimeException.getInstance("该规格不存在");
  217. }
  218. BigDecimal skuMoney = goodsDonSkuView.getMoney();
  219. if (goodsDonSkuView.getType() == 2) {
  220. throw BusinessRuntimeException.getInstance("实物不支持使用优惠码");
  221. }
  222. CouponPopularizeDto dto = couponMapper.checkExCode(exCode);
  223. if (dto == null) {
  224. throw BusinessRuntimeException.getInstance("该优惠码不存在");
  225. }
  226. if (dto.getIsGeneral() != null) {
  227. if (dto.getIsGeneral() && userId.equals(dto.getUserId())) {
  228. throw BusinessRuntimeException.getInstance("不可以使用自己的优惠码");
  229. }
  230. if (!dto.getIsGeneral()) {
  231. UserDistribute userDistribute = userDistributeMapper.selectById(dto.getDistributeId());
  232. if (userDistribute != null && userDistribute.getUserId().equals(userId)) {
  233. throw BusinessRuntimeException.getInstance("不可以使用自己的优惠码");
  234. }
  235. }
  236. //是否有上下级关系
  237. if (dto.getIsGeneral()) {
  238. UserDistributeShared userDistributeShared = userDistributeSharedMapper.selectOne(Wrappers.lambdaQuery(UserDistributeShared.class)
  239. .eq(UserDistributeShared::getUserId, userId).last("limit 1"));
  240. if (userDistributeShared == null) {
  241. //是否是 当天注册新用户 且下过单
  242. User user = userMapper.selectById(userId);
  243. if (user.getCreatedTime().before(DateUtil.beginOfDay(DateTime.now()))) {
  244. throw BusinessRuntimeException.getInstance("该优惠码只适用于新用户");
  245. }
  246. CouponNewUserView couponNewUserView = beanSearcher.searchFirst(CouponNewUserView.class, MapUtils.builder().field(CouponNewUserView::getUserId, userId).op(Operator.Equal).build());
  247. if (couponNewUserView != null) throw BusinessRuntimeException.getInstance("该优惠码只适用于新用户");
  248. }
  249. if (userDistributeShared != null && !userDistributeShared.getSharedId().equals(dto.getUserId())) {
  250. throw BusinessRuntimeException.getInstance("您已有推广,无法使用其他人推广码");
  251. }
  252. }
  253. }
  254. if (dto.getScope() == Coupon.Scope.newUser) {
  255. CouponNewUserView couponNewUserView = beanSearcher.searchFirst(CouponNewUserView.class, MapUtils.builder().field(CouponNewUserView::getUserId, userId).op(Operator.Equal).build());
  256. if (couponNewUserView != null) {
  257. throw BusinessRuntimeException.getInstance("该优惠码只适用于新用户");
  258. }
  259. }
  260. if (isRenew != null && isRenew) {
  261. Coupon.UseScope useScope = dto.getUseScope();
  262. if (useScope == Coupon.UseScope.orders) {
  263. throw BusinessRuntimeException.getInstance("该优惠码续费时不可使用");
  264. }
  265. }
  266. if (isRenew == null || !isRenew) {
  267. Coupon.UseScope useScope = dto.getUseScope();
  268. if (useScope == Coupon.UseScope.renew) {
  269. throw BusinessRuntimeException.getInstance("该优惠码下单时不可使用");
  270. }
  271. }
  272. if (dto.getIsValidTime() && dto.getValidStartTime().after(DateTime.now())) {
  273. throw BusinessRuntimeException.getInstance("该优惠码待生效");
  274. }
  275. if (dto.getIsValidTime() && dto.getValidEndTime().before(DateTime.now())) {
  276. throw BusinessRuntimeException.getInstance("该优惠码已失效");
  277. }
  278. CouponSku couponSku = couponSkuMapper.selectOne(Wrappers.lambdaQuery(CouponSku.class)
  279. .eq(CouponSku::getSkuId, skuId)
  280. .eq(CouponSku::getCouponId, dto.getCouponId())
  281. .select(CouponSku::getId).last("limit 1"));
  282. if (couponSku == null) {
  283. throw BusinessRuntimeException.getInstance("该优惠码不适用于该规格");
  284. }
  285. if (goodsDonSkuView.getType() == 2) {
  286. if (dto.getType() == Coupon.Type.reduce && skuMoney.compareTo(dto.getReduceCondition()) < 0) {
  287. throw BusinessRuntimeException.getInstance(String.format("满%s可用", dto.getReduceCondition().divide(BigDecimal.valueOf(100))));
  288. }
  289. }
  290. return GatewayResponse.SUCCESS.newBuilder().toResult(dto);
  291. }
  292. /**
  293. * 查询优惠券
  294. */
  295. @GetMapping("/get/couponList")
  296. public Result<List<CouponView>> getCouponList(@RequestParam(value = "couponIds") List<Long> couponIds) {
  297. if (couponIds.isEmpty()) {
  298. return GatewayResponse.SUCCESS.newBuilder().toResult();
  299. }
  300. List<CouponView> couponViews = beanSearcher.searchAll(CouponView.class, MapUtils.builder()
  301. .field(CouponView::getId, couponIds).op(Operator.InList)
  302. .orderBy(CouponView::getId).desc()
  303. .build());
  304. return GatewayResponse.SUCCESS.newBuilder().toResult(couponViews);
  305. }
  306. /**
  307. * 渠道推广用户领取优惠券
  308. */
  309. @PostMapping("/channel/popularize/receive")
  310. public Result<String> receiveChannelPopularizeCoupon(@RequestBody @Validated ChannelPopularizeCouponReq req) {
  311. long userId = StpUserUtil.getLoginIdAsLong();
  312. req.setUserId(userId);
  313. couponFontService.receiveChannelPopularizeCoupon(req);
  314. return GatewayResponse.SUCCESS.newBuilder().toResult("领取成功");
  315. }
  316. /**
  317. * 渠道推广一键领取优惠券
  318. */
  319. @PostMapping("/channel/popularize/collectAll/{popularizeId}")
  320. public Result<String> collectAllChannelCoupons(@PathVariable Long popularizeId) {
  321. long userId = StpUserUtil.getLoginIdAsLong();
  322. couponFontService.collectAllChannelCoupons(userId, popularizeId);
  323. return GatewayResponse.SUCCESS.newBuilder().toResult("领取成功");
  324. }
  325. /**
  326. * 新用户福利 优惠券详情展示
  327. */
  328. @GetMapping("/get/newUser/welfare")
  329. public Result<CouponUserView> getNewUserWelfare() {
  330. long userId = StpUserUtil.getLoginIdAsLong();
  331. DateTime now = DateTime.now();
  332. CouponUserView couponUserView = couponFontService.getNewUserWelfareCoupons(userId, now);
  333. return GatewayResponse.SUCCESS.newBuilder().toResult(couponUserView);
  334. }
  335. @GetMapping("/get/coupon/detail/{couponId}")
  336. public Result<CouponUserView> getCouponDetailById(@PathVariable Long couponId) {
  337. long userId = StpUserUtil.getLoginIdAsLong();
  338. CouponUserView couponUserView = couponFontService.getCouponDetailById(userId, couponId);
  339. return GatewayResponse.SUCCESS.newBuilder().toResult(couponUserView);
  340. }
  341. /**
  342. * 领取优惠券
  343. */
  344. @PostMapping("/receive/coupon/{couponId}")
  345. public Result<CouponUserView> receiveCoupon(@PathVariable Long couponId) {
  346. long userId = StpUserUtil.getLoginIdAsLong();
  347. CouponUserView couponUserView = couponFontService.receiveCoupon(userId, couponId);
  348. return GatewayResponse.SUCCESS.newBuilder().toResult(couponUserView);
  349. }
  350. }