GoodsDonController.java 49 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132
  1. package com.cyksj.web.controller.goods;
  2. import cn.hutool.core.collection.CollUtil;
  3. import cn.hutool.core.date.DateTime;
  4. import cn.hutool.core.date.DateUnit;
  5. import cn.hutool.core.date.DateUtil;
  6. import cn.hutool.core.util.RandomUtil;
  7. import cn.hutool.core.util.StrUtil;
  8. import cn.hutool.extra.servlet.ServletUtil;
  9. import com.baomidou.mybatisplus.core.toolkit.Wrappers;
  10. import com.cyksj.common.constant.Constant;
  11. import com.cyksj.common.exception.BusinessRuntimeException;
  12. import com.cyksj.common.util.Jsons;
  13. import com.cyksj.common.util.StringUtil;
  14. import com.cyksj.dto.Result;
  15. import com.cyksj.dto.UserSharedDto;
  16. import com.cyksj.enums.GatewayResponse;
  17. import com.cyksj.mapper.GoodsDonSkuMapper;
  18. import com.cyksj.mapper.OrderDonMapper;
  19. import com.cyksj.mapper.RegisterOrderDonMapper;
  20. import com.cyksj.mapper.sys.SysConfigMapper;
  21. import com.cyksj.model.entity.*;
  22. import com.cyksj.model.request.ClickRecordReq;
  23. import com.cyksj.model.views.*;
  24. import com.cyksj.redis.RedisService;
  25. import com.cyksj.service.goods.GoodsDonFrontService;
  26. import com.cyksj.service.home.ClickRecordFrontService;
  27. import com.cyksj.service.shop.YhShopFrontService;
  28. import com.cyksj.service.user.UserService;
  29. import com.cyksj.web.util.StpUserUtil;
  30. import com.ejlchina.searcher.BeanSearcher;
  31. import com.ejlchina.searcher.SearchResult;
  32. import com.ejlchina.searcher.param.Operator;
  33. import com.ejlchina.searcher.util.MapBuilder;
  34. import com.ejlchina.searcher.util.MapUtils;
  35. import lombok.RequiredArgsConstructor;
  36. import lombok.extern.slf4j.Slf4j;
  37. import org.springframework.web.bind.annotation.*;
  38. import javax.servlet.http.HttpServletRequest;
  39. import java.math.BigDecimal;
  40. import java.util.*;
  41. import java.util.concurrent.ConcurrentHashMap;
  42. import java.util.concurrent.atomic.AtomicBoolean;
  43. import java.util.concurrent.atomic.AtomicLong;
  44. import java.util.stream.Collectors;
  45. import java.util.stream.Stream;
  46. /**
  47. * @author chan
  48. * @date 2022/9/26 5:33 PM
  49. */
  50. @Slf4j
  51. @RestController
  52. @RequestMapping("/applets/goods")
  53. @RequiredArgsConstructor
  54. public class GoodsDonController {
  55. private final HttpServletRequest request;
  56. private final BeanSearcher beanSearcher;
  57. private final OrderDonMapper orderDonMapper;
  58. private final RegisterOrderDonMapper registerOrderDonMapper;
  59. private final GoodsDonSkuMapper goodsDonSkuMapper;
  60. private final RedisService redisService;
  61. private final SysConfigMapper sysConfigMapper;
  62. private final ClickRecordFrontService clickRecordFrontService;
  63. private final YhShopFrontService yhShopFrontService;
  64. private final UserService userService;
  65. private final GoodsDonFrontService goodsDonFrontService;
  66. /**
  67. * 获取平台商品分类
  68. */
  69. @GetMapping("/get/category")
  70. public Result<List<GoodsDonCategoryFrontView>> getCategory(String customId) {
  71. Long yhsId = null;
  72. if (StrUtil.isNotBlank(customId)) {
  73. yhsId = yhShopFrontService.getYhsIdByCustomId(customId);
  74. }
  75. String key = RedisService.key.YH_HOME_PAGHE_CACHE.getEnvName() + "category";
  76. if (yhsId != null) {
  77. key += ":yhShop:" + yhsId;
  78. }
  79. Object o = redisService.get(key);
  80. List<GoodsDonCategoryFrontView> list;
  81. MapBuilder mapBuilder = MapUtils.flatBuilder(request.getParameterMap());
  82. String condition = " and (select count(*) from goods_don_category_relate gcr inner join goods_don g on g.id = gcr.goods_id %s where gcr.category = gc.id) > 0";
  83. if (yhsId != null) {
  84. condition = String.format(condition, String.format(" and (select count(*) from yh_shop_goods_sku ys where ys.goods_id = g.id and ys.status is true and ys.deleted is true and g.is_distribute is true and ys.yhs_id = %s) > 0", yhsId));
  85. } else {
  86. condition = String.format(condition, StrUtil.EMPTY);
  87. }
  88. mapBuilder.put("condition", condition);
  89. if (o == null) {
  90. list = beanSearcher.searchAll(GoodsDonCategoryFrontView.class, mapBuilder
  91. .build());
  92. redisService.setNx(key, list, 30 * 60l);
  93. o = redisService.get(key);
  94. }
  95. list = Jsons.parseList(o, GoodsDonCategoryFrontView.class);
  96. return GatewayResponse.SUCCESS.newBuilder().toResult(list);
  97. }
  98. /**
  99. * 商品搜索
  100. */
  101. @GetMapping("/search")
  102. public Result<SearchResult<GoodsDonSearchView>> search() {
  103. SearchResult<GoodsDonSearchView> search = beanSearcher.search(GoodsDonSearchView.class, MapUtils.flatBuilder(request.getParameterMap()).build());
  104. return GatewayResponse.SUCCESS.newBuilder().toResult(search);
  105. }
  106. /**
  107. * 获取商品列表
  108. */
  109. @GetMapping("/get")
  110. public Result<SearchResult<GoodsDon>> get() {
  111. SearchResult<GoodsDon> search = beanSearcher.search(GoodsDon.class, MapUtils.flatBuilder(request.getParameterMap())
  112. .field(GoodsDon::getStatus, true)
  113. .field(GoodsDon::getDeleted, true)
  114. .orderBy(GoodsDon::getSortBy).asc()
  115. .orderBy(GoodsDon::getId).asc()
  116. .build()
  117. );
  118. search.getDataList().forEach(goods -> {
  119. GoodsDonSku goodsDonSku = goodsDonSkuMapper.selectOne(Wrappers.lambdaQuery(GoodsDonSku.class).eq(GoodsDonSku::getGoodsId, goods.getId())
  120. .eq(GoodsDonSku::getStatus, true)
  121. .orderByAsc(GoodsDonSku::getPrice)
  122. .last("limit 1")
  123. .select(GoodsDonSku::getPrice));
  124. Optional.ofNullable(goodsDonSku).ifPresent(sku -> {
  125. goods.setPrice(goodsDonSku.getPrice());
  126. goods.setSoldNum(goods.getVirtualSold() + orderDonMapper.selectCount(Wrappers.lambdaQuery(OrderDon.class)
  127. .eq(OrderDon::getGoodsId, goods.getId())
  128. .notIn(OrderDon::getStatus, Constant.noOrderStatus)));
  129. });
  130. });
  131. return GatewayResponse.SUCCESS.newBuilder().toResult(search);
  132. }
  133. /**
  134. * 推广未登录,虚拟商品列表
  135. */
  136. @GetMapping("/get/popularize")
  137. @Deprecated
  138. public Result<SearchResult<GoodsDonPopularizeView>> getPopularizeVipGoods() {
  139. SearchResult<GoodsDonPopularizeView> search = beanSearcher.search(GoodsDonPopularizeView.class, MapUtils.flatBuilder(request.getParameterMap())
  140. .field(GoodsDonPopularizeView::getStatus, true)
  141. .field(GoodsDonPopularizeView::getDeleted, true)
  142. .field(GoodsDonPopularizeView::getType, 1)
  143. .orderBy(GoodsDonPopularizeView::getSortBy).asc()
  144. .orderBy(GoodsDonPopularizeView::getId).asc()
  145. .build());
  146. DateTime now = DateTime.now();
  147. search.getDataList().forEach(data -> {
  148. data.setSpecs(beanSearcher.searchFirst(GoodsDonSpec.class, MapUtils.builder().field(GoodsDonSpec::getGoodsId, data.getId()).build()));
  149. data.setSkuList(beanSearcher.searchAll(GoodsDonSku.class, MapUtils.builder().field(GoodsDonSku::getGoodsId, data.getId()).field(GoodsDonSku::getStatus, true).orderBy(GoodsDonSku::getPrice).asc().build()));
  150. Integer sold = orderDonMapper.selectCount(Wrappers.lambdaQuery(OrderDon.class)
  151. .eq(OrderDon::getGoodsId, data.getId()).notIn(OrderDon::getStatus, Constant.noOrderStatus));
  152. data.setSold(sold + data.getVirtualSold());
  153. Optional.ofNullable(data.getSkuList()).ifPresent(skuList -> {
  154. if (skuList.size() > 0) {
  155. GoodsDonSku goodsDonSku = skuList.get(0);
  156. data.setPrice(goodsDonSku.getPrice());
  157. data.setMonths(goodsDonSku.getMonths());
  158. }
  159. });
  160. OrderDon orderDon = orderDonMapper.selectOne(Wrappers.lambdaQuery(OrderDon.class)
  161. .eq(OrderDon::getGoodsId, data.getId())
  162. .notIn(OrderDon::getStatus, Constant.noOrderStatus).select(OrderDon::getCreatedTime, OrderDon::getPayTime, OrderDon::getId)
  163. .orderByDesc(OrderDon::getId)
  164. .last("limit 1"));
  165. StringBuilder notifyMsg = new StringBuilder();
  166. if (orderDon == null) {
  167. notifyMsg.append("点击购买立即上车");
  168. data.setNotifyMsg(notifyMsg.toString());
  169. return;
  170. } else {
  171. Date payTime = orderDon.getPayTime();
  172. Date startTime = payTime != null ? payTime : orderDon.getCreatedTime();
  173. long hour = DateUtil.between(startTime, now, DateUnit.HOUR);
  174. if (hour == 0) {
  175. long minute = DateUtil.between(startTime, now, DateUnit.MINUTE);
  176. if (minute == 0) {
  177. notifyMsg.append("1分钟");
  178. } else {
  179. notifyMsg.append(minute);
  180. notifyMsg.append("分钟");
  181. }
  182. } else {
  183. if (hour > 3) {
  184. int hours = RandomUtil.randomInt(3) + 1;
  185. notifyMsg.append(hours);
  186. } else {
  187. notifyMsg.append(hour);
  188. }
  189. notifyMsg.append("小时");
  190. }
  191. }
  192. notifyMsg.append("前有人购买");
  193. data.setNotifyMsg(notifyMsg.toString());
  194. });
  195. return GatewayResponse.SUCCESS.newBuilder().toResult(search);
  196. }
  197. /**
  198. * 官网首页 平台列表
  199. */
  200. @GetMapping("/get/list")
  201. @Deprecated
  202. public Result<? extends Object> getGoodsList(String customId) {
  203. if (StrUtil.isNotBlank(customId)) {
  204. Result<List<YhShopGoodsFrontView>> shopGoods = getShopGoods(yhShopFrontService.getYhsIdByCustomId(customId));
  205. return shopGoods;
  206. }
  207. List<Long> filter_goodsIds = getFilterGoodsIds();
  208. String pcCacheKey = RedisService.key.YH_HOME_PAGHE_CACHE.getEnvName() + "PC";
  209. if (CollUtil.isNotEmpty(filter_goodsIds)) {
  210. pcCacheKey += ":hz-ip";
  211. }
  212. Long fUid = StpUserUtil.getUserIdAfterLogin();
  213. Object o = redisService.get(pcCacheKey);
  214. List<GoodsFrontListView> list = null;
  215. if (o == null) {
  216. MapBuilder builder = MapUtils.flatBuilder(request.getParameterMap());
  217. if (CollUtil.isNotEmpty(filter_goodsIds)) {
  218. builder.field(GoodsFrontListView::getId, filter_goodsIds).op(Operator.NotIn);
  219. }
  220. builder.field(GoodsFrontListView::getType, 1);
  221. list = beanSearcher.searchAll(GoodsFrontListView.class, builder.build());
  222. redisService.setNx(pcCacheKey, list, RedisService.key.YH_HOME_PAGHE_CACHE.getTimeout());
  223. o = redisService.get(pcCacheKey);
  224. }
  225. if (list == null) {
  226. list = Jsons.parseList(o, GoodsFrontListView.class);
  227. }
  228. DateTime now = DateTime.now();
  229. list.forEach(data -> {
  230. Integer sold = orderDonMapper.selectCount(Wrappers.lambdaQuery(OrderDon.class)
  231. .eq(OrderDon::getGoodsId, data.getId()).notIn(OrderDon::getStatus, Constant.noOrderStatus));
  232. data.setSold(sold + data.getSold());
  233. data.setNotifyMsg(getPayMsgTime(data.getId(), now, 1, null));
  234. //设置特定价格
  235. setSpecificPrice(data, fUid, null);
  236. });
  237. return GatewayResponse.SUCCESS.newBuilder().toResult(Optional.of(list));
  238. }
  239. /**
  240. * h5 银河首页平台展示
  241. */
  242. @GetMapping("/get/homePage")
  243. @Deprecated
  244. public Result<? extends Object> getGoodsHomePage(String customId) {
  245. if (StrUtil.isNotBlank(customId)) {
  246. Result<List<YhShopGoodsFrontView>> shopGoods = getShopGoods(yhShopFrontService.getYhsIdByCustomId(customId));
  247. return shopGoods;
  248. }
  249. List<Long> filter_goodsIds = getFilterGoodsIds();
  250. String h5CacheKey = RedisService.key.YH_HOME_PAGHE_CACHE.getEnvName() + "H5";
  251. if (CollUtil.isNotEmpty(filter_goodsIds)) {
  252. h5CacheKey += ":hz-ip";
  253. }
  254. Long fUid = StpUserUtil.getUserIdAfterLogin();
  255. Object o = redisService.get(h5CacheKey);
  256. List<GoodsFrontListView> list = null;
  257. if (o == null) {
  258. MapBuilder builder = MapUtils.flatBuilder(request.getParameterMap());
  259. if (CollUtil.isNotEmpty(filter_goodsIds)) {
  260. builder.field(GoodsFrontListView::getId, filter_goodsIds).op(Operator.NotIn);
  261. }
  262. list = beanSearcher.searchAll(GoodsFrontListView.class, builder.build());
  263. redisService.setNx(h5CacheKey, list, RedisService.key.YH_HOME_PAGHE_CACHE.getTimeout());
  264. o = redisService.get(h5CacheKey);
  265. }
  266. if (list == null) {
  267. list = Jsons.parseList(o, GoodsFrontListView.class);
  268. }
  269. DateTime now = DateTime.now();
  270. list.forEach(data -> {
  271. Integer sold = orderDonMapper.selectCount(Wrappers.lambdaQuery(OrderDon.class)
  272. .eq(OrderDon::getGoodsId, data.getId()).notIn(OrderDon::getStatus, Constant.noOrderStatus));
  273. data.setSold(sold + data.getSold());
  274. data.setNotifyMsg(getPayMsgTime(data.getId(), now, 1, null));
  275. //设置特定价格
  276. setSpecificPrice(data, fUid, null);
  277. });
  278. return GatewayResponse.SUCCESS.newBuilder().toResult(Optional.of(list));
  279. }
  280. /**
  281. * 注册首页平台展示
  282. */
  283. @GetMapping("/get/register")
  284. public Result<List<RegisterGoodsDonView>> getRegisterGoodsDon() {
  285. String registerCacheKey = RedisService.key.REGISTER_HOME_PAGE_CACHE.getEnvName();
  286. Object value = redisService.get(registerCacheKey);
  287. if (value != null) {
  288. try {
  289. List<RegisterGoodsDonView> list = Jsons.parseList(value, RegisterGoodsDonView.class);
  290. if (CollUtil.isNotEmpty(list)) {
  291. return GatewayResponse.SUCCESS.newBuilder().toResult(list);
  292. }
  293. } catch (Exception e) {
  294. }
  295. }
  296. MapBuilder builder = MapUtils.flatBuilder(request.getParameterMap());
  297. List<RegisterGoodsDonView> dataList = beanSearcher.searchAll(RegisterGoodsDonView.class, builder.build());
  298. DateTime now = DateTime.now();
  299. dataList.forEach(data -> {
  300. Integer sold = registerOrderDonMapper.selectCount(Wrappers.lambdaQuery(RegisterOrderDon.class)
  301. .eq(RegisterOrderDon::getGoodsId, data.getId()).notIn(RegisterOrderDon::getStatus, Constant.noOrderStatus));
  302. data.setSold(sold + data.getVirtualSold());
  303. data.setNotifyMsg(getPayMsgTime(data.getId(), now, 2, null));
  304. });
  305. redisService.setNx(registerCacheKey, dataList, RedisService.key.REGISTER_HOME_PAGE_CACHE.getTimeout());
  306. return GatewayResponse.SUCCESS.newBuilder().toResult(dataList);
  307. }
  308. /**
  309. * 获取商品详情
  310. */
  311. @GetMapping("/get/{id}")
  312. public Result<? extends Object> getDetail(@PathVariable Long id, String customId, String dsCode) {
  313. if (StrUtil.isNotBlank(customId) && id != 15) {
  314. Result<YhShopGoodsFrontView> yhShopGoodsDetail = getGoodsDetailByYhsId(yhShopFrontService.getYhsIdByCustomId(customId), id);
  315. return yhShopGoodsDetail;
  316. }
  317. String goodsDetailKey = RedisService.key.YH_HOME_PAGHE_CACHE.getEnvName() + "goods_detail:" + id;
  318. //List<Long> filter_goodsIds = getFilterGoodsIds();
  319. List<Long> filter_goodsIds = null;
  320. //存在过滤平台 商品详情不返回
  321. if (CollUtil.isNotEmpty(filter_goodsIds) && filter_goodsIds.contains(id)) {
  322. return GatewayResponse.SUCCESS.newBuilder().toResult();
  323. }
  324. Object o = redisService.get(goodsDetailKey);
  325. if (o == null) {
  326. GoodsFrontListView views = beanSearcher.searchFirst(GoodsFrontListView.class, MapUtils.builder().field(GoodsFrontListView::getId, id)
  327. .build());
  328. views.setSpecs(beanSearcher.searchFirst(GoodsDonSpecFrontView.class, MapUtils.builder().field(GoodsDonSpecFrontView::getGoodsId, views.getId()).build()));
  329. MapBuilder builder = MapUtils.builder().field(GoodsDonSkuFrontView::getGoodsId, views.getId()).field(GoodsDonSkuFrontView::getStatus, true);
  330. if (views.getType() == 1) {
  331. builder.orderBy(GoodsDonSkuFrontView::getSorted).asc();
  332. }
  333. views.setSkuList(beanSearcher.searchAll(GoodsDonSkuFrontView.class, builder.build()));
  334. Integer sold = orderDonMapper.selectCount(Wrappers.lambdaQuery(OrderDon.class)
  335. .eq(OrderDon::getGoodsId, views.getId()).notIn(OrderDon::getStatus, Constant.noOrderStatus));
  336. views.setSold(sold + views.getSold());
  337. redisService.setNx(goodsDetailKey, views, RedisService.key.YH_HOME_PAGHE_CACHE.getTimeout() + 60 * RandomUtil.randomInt(10));
  338. o = redisService.get(goodsDetailKey);
  339. }
  340. Long fUid = StpUserUtil.getUserIdAfterLogin();
  341. GoodsFrontListView views = Jsons.parseObject(o, GoodsFrontListView.class);
  342. AtomicLong dsUserId = new AtomicLong();
  343. AtomicBoolean existsChannel = new AtomicBoolean(true);
  344. if (StrUtil.isNotBlank(dsCode)) {
  345. UserSharedDto userSharedDto = userService.getUserShredDtoByDsCode(dsCode);
  346. dsUserId.set(userSharedDto.getSharedId());
  347. }
  348. views.setSkuList(views.getSkuList().stream().filter(sku -> {
  349. if (StrUtil.isNotBlank(sku.getUserOwns())) {
  350. if (dsUserId.get() == 0 && fUid != null && existsChannel.get()) {
  351. Long sharedId = userService.getSharedIdByUserId(fUid);
  352. if (sharedId == 0) {
  353. existsChannel.set(false);
  354. }
  355. dsUserId.set(sharedId);
  356. }
  357. if (dsUserId.get() == 0 || !sku.getUserOwns().contains(String.valueOf(dsUserId.get()))) {
  358. return false;
  359. }
  360. }
  361. if (sku.getIsDp()) {
  362. sku.setDpSkuViews(beanSearcher.searchAll(GoodsDiscountPlusPurchaseRelationFrontView.class, MapUtils.builder()
  363. .field(GoodsDiscountPlusPurchaseRelationFrontView::getSkuId, sku.getId())
  364. .build()));
  365. }
  366. if (views.getIsSp()) {
  367. if (fUid == null) {
  368. sku.setSpecificPrice(null);
  369. sku.setSpecificGoodsIds(null);
  370. }else {
  371. //设置特定价格
  372. if (!isPaySpecificGoodsIds(sku.getSpecificGoodsIds(), fUid)) {
  373. sku.setSpecificGoodsIds(null);
  374. sku.setSpecificPrice(null);
  375. } else {
  376. BigDecimal specificPrice = views.getSpecificPrice();
  377. BigDecimal skuSpecificPrice = sku.getSpecificPrice();
  378. Long specificSkuId = sku.getId();
  379. if (specificPrice == null) {
  380. views.setSpecificPrice(skuSpecificPrice);
  381. views.setSpecificSkuId(specificSkuId);
  382. } else if (specificPrice.compareTo(skuSpecificPrice) > 0) {
  383. views.setSpecificPrice(skuSpecificPrice);
  384. views.setSpecificSkuId(specificSkuId);
  385. }
  386. }
  387. }
  388. }
  389. return true;
  390. }).collect(Collectors.toList()));
  391. return GatewayResponse.SUCCESS.newBuilder().toResult(views);
  392. }
  393. /**
  394. * 获取商品推荐平台
  395. */
  396. @GetMapping("/get/recommend/{id}")
  397. public Result<List<GoodsFrontListView>> getRecommendGoodsByGid(@PathVariable Long id, String customId, String dsCode) throws Exception {
  398. String key = RedisService.key.YH_HOME_PAGHE_CACHE.getEnvName() + "recommend:" + id;
  399. Long yhsId = null;
  400. if (StrUtil.isNotBlank(customId)) {
  401. yhsId = yhShopFrontService.getYhsIdByCustomId(customId);
  402. key = RedisService.key.YH_HOME_PAGHE_CACHE_SHOP.getEnvName() + yhsId + ":recommend:" + id;
  403. }
  404. Object o = redisService.get(key);
  405. Long fUid = StpUserUtil.getUserIdAfterLogin();
  406. List<GoodsFrontListView> goodsRecommendViews = null;
  407. if (o == null) {
  408. GoodsDon goodsDon = beanSearcher.searchFirst(GoodsDon.class, MapUtils.builder()
  409. .field(GoodsDon::getId, id).field(GoodsDon::getStatus, true)
  410. .field(GoodsDon::getDeleted, true)
  411. .build());
  412. if (goodsDon != null && StrUtil.isNotEmpty(goodsDon.getRecommendGoods())) {
  413. List<Long> recommend_gidList = Jsons.parseList(goodsDon.getRecommendGoods(), Long.class);
  414. MapBuilder mapBuilder = MapUtils.builder();
  415. if (yhsId != null) {
  416. mapBuilder.put("condition", String.format(" and g.id in (select distinct goods_id from yh_shop_goods_sku where yhs_id = %s and status is true and deleted is true) and g.is_distribute is true", yhsId));
  417. }
  418. mapBuilder.field(GoodsFrontListView::getId, recommend_gidList).op(Operator.InList);
  419. goodsRecommendViews = beanSearcher.searchAll(GoodsFrontListView.class, mapBuilder.build());
  420. redisService.setNx(key, Jsons.toJson(goodsRecommendViews), 60 * 15l);
  421. o = redisService.get(key);
  422. } else {
  423. return GatewayResponse.SUCCESS.newBuilder().toResult();
  424. }
  425. }
  426. if (goodsRecommendViews == null) {
  427. goodsRecommendViews = Jsons.parseList(o.toString(), GoodsFrontListView.class);
  428. }
  429. AtomicLong dsUserId = new AtomicLong();
  430. AtomicBoolean existsChannel = new AtomicBoolean(true);
  431. if (StrUtil.isNotBlank(dsCode)) {
  432. UserSharedDto userSharedDto = userService.getUserShredDtoByDsCode(dsCode);
  433. dsUserId.set(userSharedDto.getSharedId());
  434. }
  435. goodsRecommendViews = goodsRecommendViews.stream().filter(data -> {
  436. if (data.getIsOwns()) {
  437. if (dsUserId.get() == 0 && fUid != null && existsChannel.get()) {
  438. Long sharedId = userService.getSharedIdByUserId(fUid);
  439. if (sharedId == 0) {
  440. existsChannel.set(false);
  441. }
  442. dsUserId.set(sharedId);
  443. }
  444. GoodsDonSku minPriceUserOwnsSku = goodsDonSkuMapper.checkAndReturnMinPriceUserOwnsSku(data.getId(), dsUserId.get());
  445. if (minPriceUserOwnsSku == null) {
  446. return false;
  447. }
  448. data.setPrice(minPriceUserOwnsSku.getPrice());
  449. data.setMonths(minPriceUserOwnsSku.getMonths());
  450. data.setDays(minPriceUserOwnsSku.getDays());
  451. }
  452. Integer sold = orderDonMapper.selectCount(Wrappers.lambdaQuery(OrderDon.class)
  453. .eq(OrderDon::getGoodsId, data.getId()).notIn(OrderDon::getStatus, Constant.noOrderStatus));
  454. data.setSold(data.getSold() + sold);
  455. //设置特定价格
  456. setSpecificPrice(data, fUid, dsUserId.get());
  457. return true;
  458. }).collect(Collectors.toList());
  459. return GatewayResponse.SUCCESS.newBuilder().toResult(goodsRecommendViews);
  460. }
  461. /**
  462. * 获取商品多规格列表
  463. */
  464. @GetMapping("/get/sku")
  465. public Result<List<GoodsDonSkuView>> getGoodsDonSkuView(@RequestParam(value = "skuIds") List<Long> skuIds) {
  466. if (skuIds.isEmpty()) {
  467. return GatewayResponse.SUCCESS.newBuilder().toResult();
  468. }
  469. List<GoodsDonSkuView> views = beanSearcher.searchAll(GoodsDonSkuView.class, MapUtils.builder()
  470. .field(GoodsDonSkuView::getSkuId, skuIds).op(Operator.InList)
  471. .build());
  472. return GatewayResponse.SUCCESS.newBuilder().toResult(views);
  473. }
  474. /**
  475. * 获取评价列表
  476. */
  477. @GetMapping("/get/comments")
  478. public Result<SearchResult<OrderCommentFrontView>> getComments() {
  479. SearchResult<OrderCommentFrontView> search = beanSearcher.search(OrderCommentFrontView.class, MapUtils.flatBuilder(request.getParameterMap())
  480. .orderBy(OrderCommentFrontView::getCommentTime).desc()
  481. .orderBy(OrderCommentFrontView::getId).desc()
  482. .build());
  483. return GatewayResponse.SUCCESS.newBuilder().toResult(search);
  484. }
  485. /**
  486. * 获取礼品卡平台性情
  487. */
  488. @GetMapping("/get/card/{id}")
  489. public Result<Map<Integer, List<GiftCardGoodsSkuFrontView>>> getGiftCardDetail(@PathVariable Long id) {
  490. List<GiftCardGoodsSkuFrontView> giftCardGoodsSkuFrontViews = beanSearcher.searchAll(GiftCardGoodsSkuFrontView.class, MapUtils.builder().field(GiftCardGoodsSkuFrontView::getGoodsId, id).build());
  491. Map<Integer, List<GiftCardGoodsSkuFrontView>> map = giftCardGoodsSkuFrontViews.stream().collect(Collectors.groupingBy(GiftCardGoodsSkuFrontView::getGcType));
  492. return GatewayResponse.SUCCESS.newBuilder().toResult(map);
  493. }
  494. /**
  495. * 获取首页配置列表
  496. */
  497. @GetMapping("/get/homeManage")
  498. public Result<Map<String, List<HomeManagementFrontView>>> getHomeManagementFrontPage(String customId, String dsCode) {
  499. String key = RedisService.key.YH_HOME_PAGHE_CACHE.getEnvName() + "homeManage";
  500. Long yhsId = null;
  501. if (StrUtil.isNotBlank(customId)) {
  502. yhsId = yhShopFrontService.getYhsIdByCustomId(customId);
  503. key = RedisService.key.YH_HOME_PAGHE_CACHE_SHOP.getEnvName() + yhsId + ":homeManage";
  504. }
  505. // List<Long> filter_goodsIds = getFilterGoodsIds();
  506. List<Long> filter_goodsIds = null;
  507. AtomicBoolean isRemoveRg = new AtomicBoolean(false);
  508. // if (isHzIp()) {
  509. // key += ":hz-ip";
  510. // isRemoveRg.set(true);
  511. // }
  512. Long fUid = StpUserUtil.getUserIdAfterLogin();
  513. Object o = redisService.get(key);
  514. if (o == null) {
  515. String condition = "g.deleted is true and g.status is true";
  516. if (yhsId != null) {
  517. condition += String.format(" and g.id in (select distinct goods_id from yh_shop_goods_sku where yhs_id = %s and status is true and deleted is true) and g.is_distribute is true", yhsId);
  518. }
  519. Map<String, List<HomeManagementFrontView>> map = new ConcurrentHashMap<>();
  520. final String conditionSql = condition;
  521. Stream.of(HomeManagementConfig.Type.values())
  522. .forEach(type -> {
  523. if (isRemoveRg.get() && type == HomeManagementConfig.Type.rg) {
  524. return;
  525. }
  526. MapBuilder builder = MapUtils.builder()
  527. .field(HomeManagementFrontView::getType, type.name());
  528. if (type == HomeManagementConfig.Type.ex || type == HomeManagementConfig.Type.vg) {
  529. builder.put("condition", conditionSql);
  530. if (CollUtil.isNotEmpty(filter_goodsIds)) {
  531. builder.field(HomeManagementFrontView::getGoodsId, filter_goodsIds).op(Operator.NotIn);
  532. }
  533. }
  534. List<HomeManagementFrontView> homeManagementFrontViews = beanSearcher.searchAll(HomeManagementFrontView.class, builder.build());
  535. map.putIfAbsent(type.name(), homeManagementFrontViews);
  536. });
  537. redisService.setNx(key, map, 50 * 60l);
  538. o = redisService.get(key);
  539. }
  540. AtomicLong dsUserId = new AtomicLong();
  541. AtomicBoolean existsChannel = new AtomicBoolean(true);
  542. if (StrUtil.isNotBlank(dsCode)) {
  543. UserSharedDto userSharedDto = userService.getUserShredDtoByDsCode(dsCode);
  544. dsUserId.set(userSharedDto.getSharedId());
  545. }
  546. Map<String, List<HomeManagementFrontView>> map = Jsons.parseObject(o, Map.class);
  547. if (map.containsKey(HomeManagementConfig.Type.ex.name()) || map.containsKey(HomeManagementConfig.Type.vg.name())) {
  548. try {
  549. //精彩推荐
  550. List<HomeManagementFrontView> exList = Jsons.parseList(Jsons.toJson(map.get(HomeManagementConfig.Type.ex.name())), HomeManagementFrontView.class);
  551. setHomeConfigGoods(map, HomeManagementConfig.Type.ex, exList, dsUserId, existsChannel, fUid);
  552. //虚拟平台
  553. List<HomeManagementFrontView> vgList = Jsons.parseList(Jsons.toJson(map.get(HomeManagementConfig.Type.vg.name())), HomeManagementFrontView.class);
  554. setHomeConfigGoods(map, HomeManagementConfig.Type.vg, vgList, dsUserId, existsChannel, fUid);
  555. } catch (Exception e) {
  556. }
  557. }
  558. return GatewayResponse.SUCCESS.newBuilder().toResult(map);
  559. }
  560. /**
  561. * 首页点击 记录
  562. */
  563. @PostMapping("/homePage/click")
  564. public Result<String> homeManageClick(@RequestBody ClickRecordReq request) {
  565. Long userId = StpUserUtil.getUserIdAfterLogin();
  566. clickRecordFrontService.click(userId, request);
  567. return GatewayResponse.SUCCESS.newBuilder().toResult();
  568. }
  569. public List<Long> getFilterGoodsIds() {
  570. List<Long> filter_goodsIds = null;
  571. //获取当前ip地址
  572. if (StringUtil.getRealAddressByIP(ServletUtil.getClientIP(request)).contains("杭州")) {
  573. //过滤杭州Ai ChatGPT平台
  574. SysConfig sysConfig = sysConfigMapper.selectOne(Wrappers.lambdaQuery(SysConfig.class)
  575. .eq(SysConfig::getSysKey, Constant.LOCATION_FOR_GOODS_IDS).last("limit 1"));
  576. if (sysConfig != null && StrUtil.isNotBlank(sysConfig.getSysValue())) {
  577. try {
  578. filter_goodsIds = Jsons.parseList(sysConfig.getSysValue(), Long.class);
  579. } catch (Exception e) {
  580. }
  581. }
  582. }
  583. return filter_goodsIds;
  584. }
  585. public Boolean isHzIp() {
  586. if (StringUtil.getRealAddressByIP(ServletUtil.getClientIP(request)).contains("杭州")) {
  587. return true;
  588. }
  589. return false;
  590. }
  591. /**
  592. * @param goodsId
  593. * @param type 1、普通,2、注册平台
  594. * @param yhsId 店铺id
  595. * @return
  596. */
  597. public String getPayMsgTime(Long goodsId, DateTime now, Integer type, Long yhsId) {
  598. Date startTime = null;
  599. StringBuilder notifyMsg = new StringBuilder();
  600. if (type == 1) {
  601. OrderDon orderDon = orderDonMapper.selectOne(Wrappers.lambdaQuery(OrderDon.class)
  602. .eq(OrderDon::getGoodsId, goodsId)
  603. .notIn(OrderDon::getStatus, Constant.noOrderStatus).select(OrderDon::getCreatedTime, OrderDon::getPayTime, OrderDon::getId)
  604. .eq(yhsId != null, OrderDon::getYhsId, yhsId)
  605. .orderByDesc(OrderDon::getId)
  606. .last("limit 1"));
  607. if (orderDon == null) {
  608. notifyMsg.append("点击购买立即上车");
  609. return notifyMsg.toString();
  610. }
  611. startTime = orderDon.getPayTime() != null ? orderDon.getPayTime() : orderDon.getCreatedTime();
  612. } else if (type == 2) {
  613. RegisterOrderDon orderDon = registerOrderDonMapper.selectOne(Wrappers.lambdaQuery(RegisterOrderDon.class)
  614. .eq(RegisterOrderDon::getGoodsId, goodsId)
  615. .notIn(RegisterOrderDon::getStatus, Constant.noOrderStatus).select(RegisterOrderDon::getCreatedTime, RegisterOrderDon::getPayTime, RegisterOrderDon::getId)
  616. .orderByDesc(RegisterOrderDon::getId)
  617. .last("limit 1"));
  618. if (orderDon == null) {
  619. return null;
  620. }
  621. startTime = orderDon.getPayTime() != null ? orderDon.getPayTime() : orderDon.getCreatedTime();
  622. }
  623. long hour = DateUtil.between(startTime, now, DateUnit.HOUR);
  624. if (hour == 0) {
  625. long minute = DateUtil.between(startTime, now, DateUnit.MINUTE);
  626. if (minute == 0) {
  627. notifyMsg.append("1分钟");
  628. } else {
  629. notifyMsg.append(minute);
  630. notifyMsg.append("分钟");
  631. }
  632. } else {
  633. if (hour > 3) {
  634. int hours = RandomUtil.randomInt(3) + 1;
  635. notifyMsg.append(hours);
  636. } else {
  637. notifyMsg.append(hour);
  638. }
  639. notifyMsg.append("小时");
  640. }
  641. notifyMsg.append("前有人购买");
  642. return notifyMsg.toString();
  643. }
  644. /**
  645. * 是否购买过特定平台
  646. */
  647. public Boolean isPaySpecificGoodsIds(String specificGoodsIdsStr, Long userId) {
  648. if (StrUtil.isNotBlank(specificGoodsIdsStr)) {
  649. try {
  650. Set<Long> specificGoodsIds = Jsons.parseSet(specificGoodsIdsStr, Long.class);
  651. Number number = beanSearcher.searchCount(OrderDon.class, MapUtils.builder().field(OrderDon::getGoodsId, specificGoodsIds).op(Operator.InList)
  652. .field(OrderDon::getUserId, userId)
  653. .field(OrderDon::getStatus, Constant.noOrderAllStatus).op(Operator.NotIn)
  654. .build());
  655. if (number.intValue() == 0) {
  656. return false;
  657. }
  658. return true;
  659. } catch (Exception e) {
  660. }
  661. }
  662. return false;
  663. }
  664. /**
  665. * 设置平台 特定价格
  666. */
  667. public void setSpecificPrice(GoodsFrontListView data, Long fUid, Long dsUserId) {
  668. if (fUid != null) {
  669. if (data.getIsSp()) {
  670. //查找所有特定规格最小价格 满足条件
  671. String specificGoodsKey = RedisService.key.YH_HOME_PAGHE_CACHE.getEnvName() + "specific:" + data.getId();
  672. Object speciObj = redisService.get(specificGoodsKey);
  673. List<GoodsDonSku> specificSkus = null;
  674. if (speciObj != null) {
  675. specificSkus = Jsons.parseList(speciObj, GoodsDonSku.class);
  676. } else {
  677. specificSkus = goodsDonSkuMapper.selectList(
  678. Wrappers.lambdaQuery(GoodsDonSku.class)
  679. .eq(GoodsDonSku::getGoodsId, data.getId())
  680. .eq(GoodsDonSku::getStatus, true)
  681. .gt(GoodsDonSku::getSpecificPrice, 0));
  682. redisService.setNx(specificGoodsKey, specificSkus, RedisService.key.YH_HOME_PAGHE_CACHE.getTimeout());
  683. }
  684. specificSkus.forEach(specificSku -> {
  685. if (StrUtil.isNotEmpty(specificSku.getUserOwns()) && (dsUserId == null || !specificSku.getUserOwns().contains(dsUserId.toString()))) {
  686. return;
  687. }
  688. String specificGoodsIdsStr = specificSku.getSpecificGoodsIds();
  689. if (isPaySpecificGoodsIds(specificGoodsIdsStr, fUid)) {
  690. BigDecimal specificPrice = data.getSpecificPrice();
  691. BigDecimal skuSpecificPrice = specificSku.getSpecificPrice();
  692. Long specificSkuId = specificSku.getId();
  693. if (specificPrice == null) {
  694. data.setSpecificPrice(skuSpecificPrice);
  695. data.setSpecificSkuId(specificSkuId);
  696. } else if (specificPrice.compareTo(skuSpecificPrice) > 0) {
  697. data.setSpecificPrice(skuSpecificPrice);
  698. data.setSpecificSkuId(specificSkuId);
  699. }
  700. }
  701. });
  702. List<GoodsDonSkuFrontView> skuList = data.getSkuList();
  703. if (CollUtil.isNotEmpty(skuList)) {
  704. skuList.forEach(sku -> {
  705. //设置特定价格
  706. if (!isPaySpecificGoodsIds(sku.getSpecificGoodsIds(), fUid)) {
  707. sku.setSpecificGoodsIds(null);
  708. sku.setSpecificPrice(null);
  709. }
  710. });
  711. }
  712. }
  713. }
  714. }
  715. /**
  716. * 设置平台 特定价格
  717. */
  718. public void setGcSpecificPrice(GoodsFrontListCategoryView data, Long fUid, Long dsUserId) {
  719. if (fUid != null) {
  720. if (data.getIsSp()) {
  721. //查找所有特定规格最小价格 满足条件
  722. String specificGoodsKey = RedisService.key.YH_HOME_PAGHE_CACHE.getEnvName() + "specific:" + data.getId();
  723. Object speciObj = redisService.get(specificGoodsKey);
  724. List<GoodsDonSku> specificSkus = null;
  725. if (speciObj != null) {
  726. specificSkus = Jsons.parseList(speciObj, GoodsDonSku.class);
  727. } else {
  728. specificSkus = goodsDonSkuMapper.selectList(
  729. Wrappers.lambdaQuery(GoodsDonSku.class)
  730. .eq(GoodsDonSku::getGoodsId, data.getId())
  731. .eq(GoodsDonSku::getStatus, true)
  732. .gt(GoodsDonSku::getSpecificPrice, 0));
  733. redisService.setNx(specificGoodsKey, specificSkus, RedisService.key.YH_HOME_PAGHE_CACHE.getTimeout());
  734. }
  735. specificSkus.forEach(specificSku -> {
  736. if (StrUtil.isNotEmpty(specificSku.getUserOwns()) && (dsUserId == null || !specificSku.getUserOwns().contains(dsUserId.toString()))) {
  737. return;
  738. }
  739. String specificGoodsIdsStr = specificSku.getSpecificGoodsIds();
  740. if (isPaySpecificGoodsIds(specificGoodsIdsStr, fUid)) {
  741. BigDecimal specificPrice = data.getSpecificPrice();
  742. BigDecimal skuSpecificPrice = specificSku.getSpecificPrice();
  743. Long specificSkuId = specificSku.getId();
  744. if (specificPrice == null) {
  745. data.setSpecificPrice(skuSpecificPrice);
  746. data.setSpecificSkuId(specificSkuId);
  747. } else if (specificPrice.compareTo(skuSpecificPrice) > 0) {
  748. data.setSpecificPrice(skuSpecificPrice);
  749. data.setSpecificSkuId(specificSkuId);
  750. }
  751. }
  752. });
  753. List<GoodsDonSkuFrontView> skuList = data.getSkuList();
  754. if (CollUtil.isNotEmpty(skuList)) {
  755. skuList.forEach(sku -> {
  756. //设置特定价格
  757. if (!isPaySpecificGoodsIds(sku.getSpecificGoodsIds(), fUid)) {
  758. sku.setSpecificGoodsIds(null);
  759. sku.setSpecificPrice(null);
  760. }
  761. });
  762. }
  763. }
  764. }
  765. }
  766. /**
  767. * 获取特定规格
  768. */
  769. public List<GoodsDonSku> getSpecificSku(Long goodsId) {
  770. //查找所有特定规格最小价格 满足条件
  771. String specificGoodsKey = RedisService.key.YH_HOME_PAGHE_CACHE.getEnvName() + "specific:" + goodsId;
  772. Object speciObj = redisService.get(specificGoodsKey);
  773. List<GoodsDonSku> specificSkus = null;
  774. if (speciObj != null) {
  775. specificSkus = Jsons.parseList(speciObj, GoodsDonSku.class);
  776. } else {
  777. specificSkus = goodsDonSkuMapper.selectList(
  778. Wrappers.lambdaQuery(GoodsDonSku.class)
  779. .eq(GoodsDonSku::getGoodsId, goodsId)
  780. .eq(GoodsDonSku::getStatus, true)
  781. .gt(GoodsDonSku::getSpecificPrice, 0));
  782. redisService.setNx(specificGoodsKey, specificSkus, RedisService.key.YH_HOME_PAGHE_CACHE.getTimeout());
  783. }
  784. specificSkus = Optional.ofNullable(specificSkus).orElse(new ArrayList<>());
  785. return specificSkus;
  786. }
  787. /**
  788. * 设置首页配置 涉及平台特定价格
  789. */
  790. public void setHomeManageSpecific(List<HomeManagementFrontView> list, Long fUid, Long dsUserId) {
  791. DateTime now = DateTime.now();
  792. list.forEach(data -> {
  793. if (data.getIsSp() != null && data.getIsSp() && fUid != null) {
  794. //查找所有特定规格最小价格 满足条件
  795. List<GoodsDonSku> specificSkus = getSpecificSku(data.getGoodsId());
  796. specificSkus.forEach(specificSku -> {
  797. if (StrUtil.isNotEmpty(specificSku.getUserOwns()) && (dsUserId == null || !specificSku.getUserOwns().contains(dsUserId.toString()))) {
  798. return;
  799. }
  800. String specificGoodsIdsStr = specificSku.getSpecificGoodsIds();
  801. if (isPaySpecificGoodsIds(specificGoodsIdsStr, fUid)) {
  802. BigDecimal specificPrice = data.getSpecificPrice();
  803. BigDecimal skuSpecificPrice = specificSku.getSpecificPrice();
  804. Long specificSkuId = specificSku.getId();
  805. if (specificPrice == null) {
  806. data.setSpecificPrice(skuSpecificPrice);
  807. data.setSpecificSkuId(specificSkuId);
  808. } else if (specificPrice.compareTo(skuSpecificPrice) > 0) {
  809. data.setSpecificPrice(skuSpecificPrice);
  810. data.setSpecificSkuId(specificSkuId);
  811. }
  812. }
  813. });
  814. }
  815. Integer sold = orderDonMapper.selectCount(Wrappers.lambdaQuery(OrderDon.class)
  816. .eq(OrderDon::getGoodsId, data.getGoodsId()).notIn(OrderDon::getStatus, Constant.noOrderStatus));
  817. data.setSold(sold + data.getSold());
  818. data.setNotifyMsg(getPayMsgTime(data.getGoodsId(), now, 1, null));
  819. });
  820. }
  821. public void setHomeConfigGoods(Map<String, List<HomeManagementFrontView>> map, HomeManagementConfig.Type type, List<HomeManagementFrontView> list, AtomicLong dsUserId, AtomicBoolean existsChannel, Long fUid) throws Exception {
  822. //设置特定价格
  823. if (CollUtil.isNotEmpty(list)) {
  824. list = list.stream().filter(data -> {
  825. if (data.getIsOwns()) {
  826. if (dsUserId.get() == 0 && fUid != null && existsChannel.get()) {
  827. Long sharedId = userService.getSharedIdByUserId(fUid);
  828. if (sharedId == 0) {
  829. existsChannel.set(false);
  830. }
  831. dsUserId.set(sharedId);
  832. }
  833. GoodsDonSku minPriceUserOwnsSku = goodsDonSkuMapper.checkAndReturnMinPriceUserOwnsSku(data.getGoodsId(), dsUserId.get());
  834. if (minPriceUserOwnsSku == null) {
  835. return false;
  836. }
  837. data.setPrice(minPriceUserOwnsSku.getPrice());
  838. data.setMonths(minPriceUserOwnsSku.getMonths());
  839. data.setDays(minPriceUserOwnsSku.getDays());
  840. }
  841. return true;
  842. }).collect(Collectors.toList());
  843. setHomeManageSpecific(list, fUid, dsUserId.get());
  844. map.put(type.name(), list);
  845. }
  846. }
  847. /**
  848. * 店铺平台列表
  849. */
  850. @GetMapping("/get/shop/goods/{yhsId}")
  851. public Result<List<YhShopGoodsFrontView>> getShopGoods(@PathVariable Long yhsId) {
  852. String yhShopCacheKey = RedisService.key.YH_HOME_PAGHE_CACHE_SHOP.getEnvName() + yhsId;
  853. Object value = redisService.get(yhShopCacheKey);
  854. List<YhShopGoodsFrontView> list = null;
  855. if (value != null) {
  856. try {
  857. list = Jsons.parseList(value, YhShopGoodsFrontView.class);
  858. } catch (Exception e) {
  859. }
  860. }
  861. if (CollUtil.isEmpty(list)) {
  862. MapBuilder builder = MapUtils.flatBuilder(request.getParameterMap());
  863. builder.put("condition", String.format("and yhs_id = %s", yhsId));
  864. list = beanSearcher.searchAll(YhShopGoodsFrontView.class, builder.build());
  865. redisService.setNx(yhShopCacheKey, list, RedisService.key.YH_HOME_PAGHE_CACHE.getTimeout());
  866. }
  867. DateTime now = DateTime.now();
  868. list.forEach(data->{
  869. Integer sold = orderDonMapper.selectCount(Wrappers.lambdaQuery(OrderDon.class)
  870. .eq(OrderDon::getGoodsId, data.getId()).notIn(OrderDon::getStatus, Constant.noOrderStatus));
  871. data.setSold(sold + data.getSold());
  872. data.setNotifyMsg(getPayMsgTime(data.getId(), now, 1, yhsId));
  873. });
  874. return GatewayResponse.SUCCESS.newBuilder().toResult(list);
  875. }
  876. /**
  877. * 店铺平台详情
  878. */
  879. @GetMapping("/get/shop/goods/detail/{yhsId}/{goodsId}")
  880. public Result<YhShopGoodsFrontView> getGoodsDetailByYhsId(@PathVariable Long yhsId, @PathVariable Long goodsId) {
  881. MapBuilder builder = MapUtils.flatBuilder(request.getParameterMap());
  882. String condition = String.format("and yhs_id = %s and ys.goods_id = %s", yhsId, goodsId);
  883. builder.put("condition", condition);
  884. YhShopGoodsFrontView goodsDetailView = beanSearcher.searchFirst(YhShopGoodsFrontView.class, builder.build());
  885. if (goodsDetailView == null) {
  886. throw BusinessRuntimeException.getInstance("该平台不存在或已下架,请刷新页面");
  887. }
  888. goodsDetailView.setSkuList(beanSearcher.searchAll(YhShopGoodsSkuFrontView.class, MapUtils.builder().put("condition", condition).orderBy(YhShopGoodsSkuFrontView::getSorted).asc().build()));
  889. goodsDetailView.setSpecs(beanSearcher.searchFirst(GoodsDonSpecFrontView.class, MapUtils.builder().field(GoodsDonSpecFrontView::getGoodsId, goodsDetailView.getId()).build()));
  890. OrderCommentFrontView comments = beanSearcher.searchFirst(OrderCommentFrontView.class, MapUtils.builder()
  891. .field(OrderCommentFrontView::getGoodsId, goodsDetailView.getId())
  892. .orderBy(OrderCommentFrontView::getCommentTime).desc()
  893. .orderBy(OrderCommentFrontView::getId).desc()
  894. .build());
  895. goodsDetailView.setComments(comments);
  896. return GatewayResponse.SUCCESS.newBuilder().toResult(goodsDetailView);
  897. }
  898. /**
  899. * 根据分类获取对应平台
  900. */
  901. @GetMapping("/get/categoryGoods")
  902. public Result<? extends Object> getGoodsByCategory(Long cgy, String customId, String dsCode) {
  903. if (StrUtil.isNotBlank(customId)) {
  904. Result<List<YhShopGoodsFrontCategoryView>> shopGoods = getShopCategoryGoods(yhShopFrontService.getYhsIdByCustomId(customId), cgy);
  905. return shopGoods;
  906. }
  907. Long fUid = StpUserUtil.getUserIdAfterLogin();
  908. String categoryGoodsKey = RedisService.key.YH_HOME_PAGHE_CACHE.getEnvName() + "category:goods";
  909. if (cgy != null) {
  910. categoryGoodsKey += ":" + cgy;
  911. }
  912. //List<Long> filter_goodsIds = getFilterGoodsIds();
  913. List<Long> filter_goodsIds = null;
  914. if (CollUtil.isNotEmpty(filter_goodsIds)) {
  915. categoryGoodsKey += ":hz-ip";
  916. }
  917. Object o = redisService.get(categoryGoodsKey);
  918. if (o == null) {
  919. DateTime now = DateTime.now();
  920. MapBuilder mapBuilder = MapUtils.flatBuilder(request.getParameterMap());
  921. if (cgy != null) {
  922. String condition = String.format(" and gcr.category = %s", cgy);
  923. mapBuilder.put("condition", condition);
  924. }
  925. if (CollUtil.isNotEmpty(filter_goodsIds)) {
  926. mapBuilder.field(GoodsFrontListCategoryView::getId, filter_goodsIds).op(Operator.NotIn);
  927. }
  928. List<GoodsFrontListCategoryView> goodsFrontListViews = beanSearcher.searchAll(GoodsFrontListCategoryView.class, mapBuilder.build());
  929. goodsFrontListViews.forEach(data -> {
  930. Integer sold = orderDonMapper.selectCount(Wrappers.lambdaQuery(OrderDon.class)
  931. .eq(OrderDon::getGoodsId, data.getId()).notIn(OrderDon::getStatus, Constant.noOrderStatus));
  932. data.setSold(sold + data.getSold());
  933. data.setNotifyMsg(getPayMsgTime(data.getId(), now, 1, null));
  934. });
  935. redisService.setNx(categoryGoodsKey, goodsFrontListViews, RedisService.key.YH_HOME_PAGHE_CACHE.getTimeout() + 10 * 60);
  936. o = redisService.get(categoryGoodsKey);
  937. }
  938. List<GoodsFrontListCategoryView> goodsFrontListViews = Jsons.parseList(o, GoodsFrontListCategoryView.class);
  939. AtomicLong dsUserId = new AtomicLong();
  940. AtomicBoolean existsChannel = new AtomicBoolean(true);
  941. if (StrUtil.isNotBlank(dsCode)) {
  942. UserSharedDto userSharedDto = userService.getUserShredDtoByDsCode(dsCode);
  943. dsUserId.set(userSharedDto.getSharedId());
  944. }
  945. goodsFrontListViews = goodsFrontListViews.stream().filter(data -> {
  946. if (data.getIsOwns()) {
  947. if (dsUserId.get() == 0 && fUid != null && existsChannel.get()) {
  948. Long sharedId = userService.getSharedIdByUserId(fUid);
  949. if (sharedId == 0) {
  950. existsChannel.set(false);
  951. }
  952. dsUserId.set(sharedId);
  953. }
  954. GoodsDonSku minPriceUserOwnsSku = goodsDonSkuMapper.checkAndReturnMinPriceUserOwnsSku(data.getId(), dsUserId.get());
  955. if (minPriceUserOwnsSku == null) {
  956. return false;
  957. }
  958. data.setPrice(minPriceUserOwnsSku.getPrice());
  959. data.setMonths(minPriceUserOwnsSku.getMonths());
  960. data.setDays(minPriceUserOwnsSku.getDays());
  961. }
  962. //设置特定价格
  963. setGcSpecificPrice(data, fUid, dsUserId.get());
  964. return true;
  965. }).collect(Collectors.toList());
  966. return GatewayResponse.SUCCESS.newBuilder().toResult(goodsFrontListViews);
  967. }
  968. @GetMapping("/get/shop/categoryGoods/{yhsId}")
  969. public Result<List<YhShopGoodsFrontCategoryView>> getShopCategoryGoods(@PathVariable Long yhsId, Long category) {
  970. String categoryGoodsKey = RedisService.key.YH_HOME_PAGHE_CACHE_SHOP.getEnvName() + yhsId + ":category";
  971. if (category != null) {
  972. categoryGoodsKey += ":" + category;
  973. }
  974. Object value = redisService.get(categoryGoodsKey);
  975. if (value == null) {
  976. DateTime now = DateTime.now();
  977. MapBuilder builder = MapUtils.flatBuilder(request.getParameterMap());
  978. builder.put("yhsId", String.format(" and yhs_id = %s", yhsId));
  979. String condition = StrUtil.EMPTY;
  980. if (category != null) {
  981. condition += String.format(" and gcr.category = %s", category);
  982. }
  983. builder.put("condition", condition);
  984. List<YhShopGoodsFrontCategoryView> list = beanSearcher.searchAll(YhShopGoodsFrontCategoryView.class, builder.build());
  985. list.forEach(data->{
  986. Integer sold = orderDonMapper.selectCount(Wrappers.lambdaQuery(OrderDon.class)
  987. .eq(OrderDon::getGoodsId, data.getId()).notIn(OrderDon::getStatus, Constant.noOrderStatus));
  988. data.setSold(sold + data.getSold());
  989. data.setNotifyMsg(getPayMsgTime(data.getId(), now, 1, yhsId));
  990. });
  991. redisService.setNx(categoryGoodsKey, list, RedisService.key.YH_HOME_PAGHE_CACHE.getTimeout() + 5 * 60);
  992. value = redisService.get(categoryGoodsKey);
  993. }
  994. List<YhShopGoodsFrontCategoryView> list = Jsons.parseList(value, YhShopGoodsFrontCategoryView.class);
  995. return GatewayResponse.SUCCESS.newBuilder().toResult(list);
  996. }
  997. /**
  998. * 获取设备活动详情
  999. */
  1000. @GetMapping("/get/equipment/activity")
  1001. public Result<EquipmentActivityReduce> getEpActivity() {
  1002. DateTime now = DateTime.now();
  1003. EquipmentActivityReduce equipmentActivityReduce = beanSearcher.searchFirst(EquipmentActivityReduce.class, MapUtils.builder()
  1004. .field(EquipmentActivityReduce::getSt, now).op(Operator.LessEqual)
  1005. .field(EquipmentActivityReduce::getEt, now).op(Operator.GreaterThan)
  1006. .field(EquipmentActivityReduce::getDeleted, 1)
  1007. .onlySelect(EquipmentActivityReduce::getF, EquipmentActivityReduce::getQ, EquipmentActivityReduce::getTq, EquipmentActivityReduce::getSt, EquipmentActivityReduce::getEt)
  1008. .build());
  1009. return GatewayResponse.SUCCESS.newBuilder().toResult(equipmentActivityReduce);
  1010. }
  1011. /**
  1012. * 获取租赁商品列表
  1013. */
  1014. @GetMapping("/get/deposit")
  1015. public Result<? extends Object> getDepositGoods() {
  1016. String depositGoodsKey = RedisService.key.YH_HOME_PAGHE_CACHE.getEnvName() + "deposit";
  1017. Object o = redisService.get(depositGoodsKey);
  1018. if (o == null) {
  1019. List<GoodsDon> depositList = beanSearcher.searchAll(GoodsDon.class, MapUtils.builder()
  1020. .field(GoodsDon::getType, 4)
  1021. .field(GoodsDon::getStatus, true)
  1022. .field(GoodsDon::getDeleted, true)
  1023. .onlySelect(GoodsDon::getId, GoodsDon::getTitle, GoodsDon::getLogo)
  1024. .build());
  1025. if (CollUtil.isEmpty(depositList)) {
  1026. return GatewayResponse.SUCCESS.newBuilder().toResult();
  1027. }
  1028. redisService.setNx(depositGoodsKey, depositList, RedisService.key.YH_HOME_PAGHE_CACHE.getTimeout() + 60 * RandomUtil.randomInt(10));
  1029. o = redisService.get(depositGoodsKey);
  1030. }
  1031. List<GoodsDon> depositList = Jsons.parseList(o, GoodsDon.class);
  1032. return GatewayResponse.SUCCESS.newBuilder().toResult(depositList);
  1033. }
  1034. /**
  1035. * 获取pc广告配置
  1036. */
  1037. @GetMapping("/get/pc/homeManage")
  1038. public Result<Map<String, List<HomeManagementFrontView>>> getPcHomeManagementFrontPage() {
  1039. String key = RedisService.key.YH_HOME_PAGHE_CACHE.getEnvName() + "pc:homeManage";
  1040. //移除奈飞客厅 临时
  1041. Long filterConfigId = null;
  1042. // if (isHzIp()) {
  1043. // key += ":hz_ip";
  1044. // filterConfigId = 55l;
  1045. // }
  1046. Object o = redisService.get(key);
  1047. if (o == null) {
  1048. MapBuilder builder = MapUtils.builder()
  1049. .field(HomeManagementFrontView::getAdType, List.of(HomeManagementConfig.AdType.pc.name(), HomeManagementConfig.AdType.pcSec.name(), HomeManagementConfig.AdType.pcDis.name())).op(Operator.InList);
  1050. if (filterConfigId != null) {
  1051. builder.field(HomeManagementFrontView::getHomeManageConfigId, filterConfigId).op(Operator.NotEqual);
  1052. }
  1053. List<HomeManagementFrontView> homeManagementFrontViews = beanSearcher.searchAll(HomeManagementFrontView.class, builder.build());
  1054. Map<HomeManagementConfig.AdType, List<HomeManagementFrontView>> map = homeManagementFrontViews.stream().collect(Collectors.groupingBy(HomeManagementFrontView::getAdType));
  1055. redisService.setNx(key, map, 50 * 60l);
  1056. o = redisService.get(key);
  1057. }
  1058. Map<String, List<HomeManagementFrontView>> map = Jsons.parseObject(o, Map.class);
  1059. return GatewayResponse.SUCCESS.newBuilder().toResult(map);
  1060. }
  1061. /**
  1062. * 获取pc实物配置
  1063. */
  1064. @GetMapping("/get/pc/realGoodsConfig")
  1065. public Result<? extends Object> getPcRealGoodsConfig() throws Exception {
  1066. String key = RedisService.key.YH_HOME_PAGHE_CACHE.getEnvName() + "pc:realHomePage";
  1067. Object o = redisService.get(key);
  1068. List<HomeManagementFrontView> list = null;
  1069. if (o == null) {
  1070. list = goodsDonFrontService.getRealGoodsConfig();
  1071. redisService.setNx(key, list, RedisService.key.YH_HOME_PAGHE_CACHE.getTimeout() + 300);
  1072. }
  1073. if (list == null && o != null) {
  1074. list = Jsons.parseList(o, HomeManagementFrontView.class);
  1075. }
  1076. return GatewayResponse.SUCCESS.newBuilder().toResult(list);
  1077. }
  1078. }