GoodsDonController.java 49 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113
  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. //存在过滤平台 商品详情不返回
  320. if (CollUtil.isNotEmpty(filter_goodsIds) && filter_goodsIds.contains(id)) {
  321. return GatewayResponse.SUCCESS.newBuilder().toResult();
  322. }
  323. Object o = redisService.get(goodsDetailKey);
  324. if (o == null) {
  325. GoodsFrontListView views = beanSearcher.searchFirst(GoodsFrontListView.class, MapUtils.builder().field(GoodsFrontListView::getId, id)
  326. .build());
  327. views.setSpecs(beanSearcher.searchFirst(GoodsDonSpecFrontView.class, MapUtils.builder().field(GoodsDonSpecFrontView::getGoodsId, views.getId()).build()));
  328. MapBuilder builder = MapUtils.builder().field(GoodsDonSku::getGoodsId, views.getId()).field(GoodsDonSku::getStatus, true);
  329. if (views.getType() == 1) {
  330. builder.orderBy(GoodsDonSku::getOrderBy).asc();
  331. }
  332. views.setSkuList(beanSearcher.searchAll(GoodsDonSkuFrontView.class, builder.build()));
  333. redisService.setNx(goodsDetailKey, views, RedisService.key.YH_HOME_PAGHE_CACHE.getTimeout() + 60 * RandomUtil.randomInt(10));
  334. o = redisService.get(goodsDetailKey);
  335. }
  336. Long fUid = StpUserUtil.getUserIdAfterLogin();
  337. GoodsFrontListView views = Jsons.parseObject(o, GoodsFrontListView.class);
  338. AtomicLong dsUserId = new AtomicLong();
  339. AtomicBoolean existsChannel = new AtomicBoolean(true);
  340. if (StrUtil.isNotBlank(dsCode)) {
  341. UserSharedDto userSharedDto = userService.getUserShredDtoByDsCode(dsCode);
  342. dsUserId.set(userSharedDto.getSharedId());
  343. }
  344. views.setSkuList(views.getSkuList().stream().filter(sku -> {
  345. if (StrUtil.isNotBlank(sku.getUserOwns())) {
  346. if (dsUserId.get() == 0 && fUid != null && existsChannel.get()) {
  347. Long sharedId = userService.getSharedIdByUserId(fUid);
  348. if (sharedId == 0) {
  349. existsChannel.set(false);
  350. }
  351. dsUserId.set(sharedId);
  352. }
  353. if (dsUserId.get() == 0 || !sku.getUserOwns().contains(String.valueOf(dsUserId.get()))) {
  354. return false;
  355. }
  356. }
  357. if (sku.getIsDp()) {
  358. sku.setDpSkuViews(beanSearcher.searchAll(GoodsDiscountPlusPurchaseRelationFrontView.class, MapUtils.builder()
  359. .field(GoodsDiscountPlusPurchaseRelationFrontView::getSkuId, sku.getId())
  360. .build()));
  361. }
  362. if (views.getIsSp()) {
  363. if (fUid == null) {
  364. sku.setSpecificPrice(null);
  365. sku.setSpecificGoodsIds(null);
  366. }else {
  367. //设置特定价格
  368. if (!isPaySpecificGoodsIds(sku.getSpecificGoodsIds(), fUid)) {
  369. sku.setSpecificGoodsIds(null);
  370. sku.setSpecificPrice(null);
  371. } else {
  372. BigDecimal specificPrice = views.getSpecificPrice();
  373. BigDecimal skuSpecificPrice = sku.getSpecificPrice();
  374. Long specificSkuId = sku.getId();
  375. if (specificPrice == null) {
  376. views.setSpecificPrice(skuSpecificPrice);
  377. views.setSpecificSkuId(specificSkuId);
  378. } else if (specificPrice.compareTo(skuSpecificPrice) > 0) {
  379. views.setSpecificPrice(skuSpecificPrice);
  380. views.setSpecificSkuId(specificSkuId);
  381. }
  382. }
  383. }
  384. }
  385. return true;
  386. }).collect(Collectors.toList()));
  387. Integer sold = orderDonMapper.selectCount(Wrappers.lambdaQuery(OrderDon.class)
  388. .eq(OrderDon::getGoodsId, views.getId()).notIn(OrderDon::getStatus, Constant.noOrderStatus));
  389. views.setSold(sold + views.getSold());
  390. //评论
  391. // OrderCommentFrontView comments = beanSearcher.searchFirst(OrderCommentFrontView.class, MapUtils.builder()
  392. // .field(OrderCommentFrontView::getGoodsId, views.getId())
  393. // .orderBy(OrderCommentFrontView::getCommentTime).desc()
  394. // .orderBy(OrderCommentFrontView::getId).desc()
  395. // .build());
  396. // views.setComments(comments);
  397. return GatewayResponse.SUCCESS.newBuilder().toResult(views);
  398. }
  399. /**
  400. * 获取商品推荐平台
  401. */
  402. @GetMapping("/get/recommend/{id}")
  403. public Result<List<GoodsFrontListView>> getRecommendGoodsByGid(@PathVariable Long id, String customId, String dsCode) throws Exception {
  404. String key = RedisService.key.YH_HOME_PAGHE_CACHE.getEnvName() + "recommend:" + id;
  405. Long yhsId = null;
  406. if (StrUtil.isNotBlank(customId)) {
  407. yhsId = yhShopFrontService.getYhsIdByCustomId(customId);
  408. key = RedisService.key.YH_HOME_PAGHE_CACHE_SHOP.getEnvName() + yhsId + ":recommend:" + id;
  409. }
  410. Object o = redisService.get(key);
  411. Long fUid = StpUserUtil.getUserIdAfterLogin();
  412. List<GoodsFrontListView> goodsRecommendViews = null;
  413. if (o == null) {
  414. GoodsDon goodsDon = beanSearcher.searchFirst(GoodsDon.class, MapUtils.builder()
  415. .field(GoodsDon::getId, id).field(GoodsDon::getStatus, true)
  416. .field(GoodsDon::getDeleted, true)
  417. .build());
  418. if (goodsDon != null && StrUtil.isNotEmpty(goodsDon.getRecommendGoods())) {
  419. List<Long> recommend_gidList = Jsons.parseList(goodsDon.getRecommendGoods(), Long.class);
  420. MapBuilder mapBuilder = MapUtils.builder();
  421. if (yhsId != null) {
  422. 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));
  423. }
  424. mapBuilder.field(GoodsFrontListView::getId, recommend_gidList).op(Operator.InList);
  425. goodsRecommendViews = beanSearcher.searchAll(GoodsFrontListView.class, mapBuilder.build());
  426. redisService.setNx(key, Jsons.toJson(goodsRecommendViews), 60 * 15l);
  427. o = redisService.get(key);
  428. } else {
  429. return GatewayResponse.SUCCESS.newBuilder().toResult();
  430. }
  431. }
  432. if (goodsRecommendViews == null) {
  433. goodsRecommendViews = Jsons.parseList(o.toString(), GoodsFrontListView.class);
  434. }
  435. AtomicLong dsUserId = new AtomicLong();
  436. AtomicBoolean existsChannel = new AtomicBoolean(true);
  437. if (StrUtil.isNotBlank(dsCode)) {
  438. UserSharedDto userSharedDto = userService.getUserShredDtoByDsCode(dsCode);
  439. dsUserId.set(userSharedDto.getSharedId());
  440. }
  441. goodsRecommendViews = goodsRecommendViews.stream().filter(data -> {
  442. if (data.getIsOwns()) {
  443. if (dsUserId.get() == 0 && fUid != null && existsChannel.get()) {
  444. Long sharedId = userService.getSharedIdByUserId(fUid);
  445. if (sharedId == 0) {
  446. existsChannel.set(false);
  447. }
  448. dsUserId.set(sharedId);
  449. }
  450. GoodsDonSku minPriceUserOwnsSku = goodsDonSkuMapper.checkAndReturnMinPriceUserOwnsSku(data.getId(), dsUserId.get());
  451. if (minPriceUserOwnsSku == null) {
  452. return false;
  453. }
  454. data.setPrice(minPriceUserOwnsSku.getPrice());
  455. data.setMonths(minPriceUserOwnsSku.getMonths());
  456. data.setDays(minPriceUserOwnsSku.getDays());
  457. }
  458. Integer sold = orderDonMapper.selectCount(Wrappers.lambdaQuery(OrderDon.class)
  459. .eq(OrderDon::getGoodsId, data.getId()).notIn(OrderDon::getStatus, Constant.noOrderStatus));
  460. data.setSold(data.getSold() + sold);
  461. //设置特定价格
  462. setSpecificPrice(data, fUid, dsUserId.get());
  463. return true;
  464. }).collect(Collectors.toList());
  465. return GatewayResponse.SUCCESS.newBuilder().toResult(goodsRecommendViews);
  466. }
  467. /**
  468. * 获取商品多规格列表
  469. */
  470. @GetMapping("/get/sku")
  471. public Result<List<GoodsDonSkuView>> getGoodsDonSkuView(@RequestParam(value = "skuIds") List<Long> skuIds) {
  472. if (skuIds.isEmpty()) {
  473. return GatewayResponse.SUCCESS.newBuilder().toResult();
  474. }
  475. List<GoodsDonSkuView> views = beanSearcher.searchAll(GoodsDonSkuView.class, MapUtils.builder()
  476. .field(GoodsDonSkuView::getSkuId, skuIds).op(Operator.InList)
  477. .build());
  478. return GatewayResponse.SUCCESS.newBuilder().toResult(views);
  479. }
  480. /**
  481. * 获取评价列表
  482. */
  483. @GetMapping("/get/comments")
  484. public Result<SearchResult<OrderCommentFrontView>> getComments() {
  485. SearchResult<OrderCommentFrontView> search = beanSearcher.search(OrderCommentFrontView.class, MapUtils.flatBuilder(request.getParameterMap())
  486. .orderBy(OrderCommentFrontView::getCommentTime).desc()
  487. .orderBy(OrderCommentFrontView::getId).desc()
  488. .build());
  489. return GatewayResponse.SUCCESS.newBuilder().toResult(search);
  490. }
  491. /**
  492. * 获取礼品卡平台性情
  493. */
  494. @GetMapping("/get/card/{id}")
  495. public Result<Map<Integer, List<GiftCardGoodsSkuFrontView>>> getGiftCardDetail(@PathVariable Long id) {
  496. List<GiftCardGoodsSkuFrontView> giftCardGoodsSkuFrontViews = beanSearcher.searchAll(GiftCardGoodsSkuFrontView.class, MapUtils.builder().field(GiftCardGoodsSkuFrontView::getGoodsId, id).build());
  497. Map<Integer, List<GiftCardGoodsSkuFrontView>> map = giftCardGoodsSkuFrontViews.stream().collect(Collectors.groupingBy(GiftCardGoodsSkuFrontView::getGcType));
  498. return GatewayResponse.SUCCESS.newBuilder().toResult(map);
  499. }
  500. /**
  501. * 获取首页配置列表
  502. */
  503. @GetMapping("/get/homeManage")
  504. public Result<Map<String, List<HomeManagementFrontView>>> getHomeManagementFrontPage(String customId, String dsCode) {
  505. String key = RedisService.key.YH_HOME_PAGHE_CACHE.getEnvName() + "homeManage";
  506. Long yhsId = null;
  507. if (StrUtil.isNotBlank(customId)) {
  508. yhsId = yhShopFrontService.getYhsIdByCustomId(customId);
  509. key = RedisService.key.YH_HOME_PAGHE_CACHE_SHOP.getEnvName() + yhsId + ":homeManage";
  510. }
  511. List<Long> filter_goodsIds = getFilterGoodsIds();
  512. if (CollUtil.isNotEmpty(filter_goodsIds)) {
  513. key += ":hz-ip";
  514. }
  515. Long fUid = StpUserUtil.getUserIdAfterLogin();
  516. Object o = redisService.get(key);
  517. if (o == null) {
  518. String condition = "g.deleted is true and g.status is true";
  519. if (yhsId != null) {
  520. 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);
  521. }
  522. Map<String, List<HomeManagementFrontView>> map = new ConcurrentHashMap<>();
  523. final String conditionSql = condition;
  524. Stream.of(HomeManagementConfig.Type.values())
  525. .forEach(type -> {
  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. /**
  586. * @param goodsId
  587. * @param type 1、普通,2、注册平台
  588. * @param yhsId 店铺id
  589. * @return
  590. */
  591. public String getPayMsgTime(Long goodsId, DateTime now, Integer type, Long yhsId) {
  592. Date startTime = null;
  593. StringBuilder notifyMsg = new StringBuilder();
  594. if (type == 1) {
  595. OrderDon orderDon = orderDonMapper.selectOne(Wrappers.lambdaQuery(OrderDon.class)
  596. .eq(OrderDon::getGoodsId, goodsId)
  597. .notIn(OrderDon::getStatus, Constant.noOrderStatus).select(OrderDon::getCreatedTime, OrderDon::getPayTime, OrderDon::getId)
  598. .eq(yhsId != null, OrderDon::getYhsId, yhsId)
  599. .orderByDesc(OrderDon::getId)
  600. .last("limit 1"));
  601. if (orderDon == null) {
  602. notifyMsg.append("点击购买立即上车");
  603. return notifyMsg.toString();
  604. }
  605. startTime = orderDon.getPayTime() != null ? orderDon.getPayTime() : orderDon.getCreatedTime();
  606. } else if (type == 2) {
  607. RegisterOrderDon orderDon = registerOrderDonMapper.selectOne(Wrappers.lambdaQuery(RegisterOrderDon.class)
  608. .eq(RegisterOrderDon::getGoodsId, goodsId)
  609. .notIn(RegisterOrderDon::getStatus, Constant.noOrderStatus).select(RegisterOrderDon::getCreatedTime, RegisterOrderDon::getPayTime, RegisterOrderDon::getId)
  610. .orderByDesc(RegisterOrderDon::getId)
  611. .last("limit 1"));
  612. if (orderDon == null) {
  613. return null;
  614. }
  615. startTime = orderDon.getPayTime() != null ? orderDon.getPayTime() : orderDon.getCreatedTime();
  616. }
  617. long hour = DateUtil.between(startTime, now, DateUnit.HOUR);
  618. if (hour == 0) {
  619. long minute = DateUtil.between(startTime, now, DateUnit.MINUTE);
  620. if (minute == 0) {
  621. notifyMsg.append("1分钟");
  622. } else {
  623. notifyMsg.append(minute);
  624. notifyMsg.append("分钟");
  625. }
  626. } else {
  627. if (hour > 3) {
  628. int hours = RandomUtil.randomInt(3) + 1;
  629. notifyMsg.append(hours);
  630. } else {
  631. notifyMsg.append(hour);
  632. }
  633. notifyMsg.append("小时");
  634. }
  635. notifyMsg.append("前有人购买");
  636. return notifyMsg.toString();
  637. }
  638. /**
  639. * 是否购买过特定平台
  640. */
  641. public Boolean isPaySpecificGoodsIds(String specificGoodsIdsStr, Long userId) {
  642. if (StrUtil.isNotBlank(specificGoodsIdsStr)) {
  643. try {
  644. Set<Long> specificGoodsIds = Jsons.parseSet(specificGoodsIdsStr, Long.class);
  645. Number number = beanSearcher.searchCount(OrderDon.class, MapUtils.builder().field(OrderDon::getGoodsId, specificGoodsIds).op(Operator.InList)
  646. .field(OrderDon::getUserId, userId)
  647. .field(OrderDon::getStatus, Constant.noOrderAllStatus).op(Operator.NotIn)
  648. .build());
  649. if (number.intValue() == 0) {
  650. return false;
  651. }
  652. return true;
  653. } catch (Exception e) {
  654. }
  655. }
  656. return false;
  657. }
  658. /**
  659. * 设置平台 特定价格
  660. */
  661. public void setSpecificPrice(GoodsFrontListView data, Long fUid, Long dsUserId) {
  662. if (fUid != null) {
  663. if (data.getIsSp()) {
  664. //查找所有特定规格最小价格 满足条件
  665. String specificGoodsKey = RedisService.key.YH_HOME_PAGHE_CACHE.getEnvName() + "specific:" + data.getId();
  666. Object speciObj = redisService.get(specificGoodsKey);
  667. List<GoodsDonSku> specificSkus = null;
  668. if (speciObj != null) {
  669. specificSkus = Jsons.parseList(speciObj, GoodsDonSku.class);
  670. } else {
  671. specificSkus = goodsDonSkuMapper.selectList(
  672. Wrappers.lambdaQuery(GoodsDonSku.class)
  673. .eq(GoodsDonSku::getGoodsId, data.getId())
  674. .eq(GoodsDonSku::getStatus, true)
  675. .gt(GoodsDonSku::getSpecificPrice, 0));
  676. redisService.setNx(specificGoodsKey, specificSkus, RedisService.key.YH_HOME_PAGHE_CACHE.getTimeout());
  677. }
  678. specificSkus.forEach(specificSku -> {
  679. if (StrUtil.isNotEmpty(specificSku.getUserOwns()) && (dsUserId == null || !specificSku.getUserOwns().contains(dsUserId.toString()))) {
  680. return;
  681. }
  682. String specificGoodsIdsStr = specificSku.getSpecificGoodsIds();
  683. if (isPaySpecificGoodsIds(specificGoodsIdsStr, fUid)) {
  684. BigDecimal specificPrice = data.getSpecificPrice();
  685. BigDecimal skuSpecificPrice = specificSku.getSpecificPrice();
  686. Long specificSkuId = specificSku.getId();
  687. if (specificPrice == null) {
  688. data.setSpecificPrice(skuSpecificPrice);
  689. data.setSpecificSkuId(specificSkuId);
  690. } else if (specificPrice.compareTo(skuSpecificPrice) > 0) {
  691. data.setSpecificPrice(skuSpecificPrice);
  692. data.setSpecificSkuId(specificSkuId);
  693. }
  694. }
  695. });
  696. List<GoodsDonSkuFrontView> skuList = data.getSkuList();
  697. if (CollUtil.isNotEmpty(skuList)) {
  698. skuList.forEach(sku -> {
  699. //设置特定价格
  700. if (!isPaySpecificGoodsIds(sku.getSpecificGoodsIds(), fUid)) {
  701. sku.setSpecificGoodsIds(null);
  702. sku.setSpecificPrice(null);
  703. }
  704. });
  705. }
  706. }
  707. }
  708. }
  709. /**
  710. * 设置平台 特定价格
  711. */
  712. public void setGcSpecificPrice(GoodsFrontListCategoryView data, Long fUid, Long dsUserId) {
  713. if (fUid != null) {
  714. if (data.getIsSp()) {
  715. //查找所有特定规格最小价格 满足条件
  716. String specificGoodsKey = RedisService.key.YH_HOME_PAGHE_CACHE.getEnvName() + "specific:" + data.getId();
  717. Object speciObj = redisService.get(specificGoodsKey);
  718. List<GoodsDonSku> specificSkus = null;
  719. if (speciObj != null) {
  720. specificSkus = Jsons.parseList(speciObj, GoodsDonSku.class);
  721. } else {
  722. specificSkus = goodsDonSkuMapper.selectList(
  723. Wrappers.lambdaQuery(GoodsDonSku.class)
  724. .eq(GoodsDonSku::getGoodsId, data.getId())
  725. .eq(GoodsDonSku::getStatus, true)
  726. .gt(GoodsDonSku::getSpecificPrice, 0));
  727. redisService.setNx(specificGoodsKey, specificSkus, RedisService.key.YH_HOME_PAGHE_CACHE.getTimeout());
  728. }
  729. specificSkus.forEach(specificSku -> {
  730. if (StrUtil.isNotEmpty(specificSku.getUserOwns()) && (dsUserId == null || !specificSku.getUserOwns().contains(dsUserId.toString()))) {
  731. return;
  732. }
  733. String specificGoodsIdsStr = specificSku.getSpecificGoodsIds();
  734. if (isPaySpecificGoodsIds(specificGoodsIdsStr, fUid)) {
  735. BigDecimal specificPrice = data.getSpecificPrice();
  736. BigDecimal skuSpecificPrice = specificSku.getSpecificPrice();
  737. Long specificSkuId = specificSku.getId();
  738. if (specificPrice == null) {
  739. data.setSpecificPrice(skuSpecificPrice);
  740. data.setSpecificSkuId(specificSkuId);
  741. } else if (specificPrice.compareTo(skuSpecificPrice) > 0) {
  742. data.setSpecificPrice(skuSpecificPrice);
  743. data.setSpecificSkuId(specificSkuId);
  744. }
  745. }
  746. });
  747. List<GoodsDonSkuFrontView> skuList = data.getSkuList();
  748. if (CollUtil.isNotEmpty(skuList)) {
  749. skuList.forEach(sku -> {
  750. //设置特定价格
  751. if (!isPaySpecificGoodsIds(sku.getSpecificGoodsIds(), fUid)) {
  752. sku.setSpecificGoodsIds(null);
  753. sku.setSpecificPrice(null);
  754. }
  755. });
  756. }
  757. }
  758. }
  759. }
  760. /**
  761. * 获取特定规格
  762. */
  763. public List<GoodsDonSku> getSpecificSku(Long goodsId) {
  764. //查找所有特定规格最小价格 满足条件
  765. String specificGoodsKey = RedisService.key.YH_HOME_PAGHE_CACHE.getEnvName() + "specific:" + goodsId;
  766. Object speciObj = redisService.get(specificGoodsKey);
  767. List<GoodsDonSku> specificSkus = null;
  768. if (speciObj != null) {
  769. specificSkus = Jsons.parseList(speciObj, GoodsDonSku.class);
  770. } else {
  771. specificSkus = goodsDonSkuMapper.selectList(
  772. Wrappers.lambdaQuery(GoodsDonSku.class)
  773. .eq(GoodsDonSku::getGoodsId, goodsId)
  774. .eq(GoodsDonSku::getStatus, true)
  775. .gt(GoodsDonSku::getSpecificPrice, 0));
  776. redisService.setNx(specificGoodsKey, specificSkus, RedisService.key.YH_HOME_PAGHE_CACHE.getTimeout());
  777. }
  778. specificSkus = Optional.ofNullable(specificSkus).orElse(new ArrayList<>());
  779. return specificSkus;
  780. }
  781. /**
  782. * 设置首页配置 涉及平台特定价格
  783. */
  784. public void setHomeManageSpecific(List<HomeManagementFrontView> list, Long fUid, Long dsUserId) {
  785. DateTime now = DateTime.now();
  786. list.forEach(data -> {
  787. if (data.getIsSp() != null && data.getIsSp() && fUid != null) {
  788. //查找所有特定规格最小价格 满足条件
  789. List<GoodsDonSku> specificSkus = getSpecificSku(data.getGoodsId());
  790. specificSkus.forEach(specificSku -> {
  791. if (StrUtil.isNotEmpty(specificSku.getUserOwns()) && (dsUserId == null || !specificSku.getUserOwns().contains(dsUserId.toString()))) {
  792. return;
  793. }
  794. String specificGoodsIdsStr = specificSku.getSpecificGoodsIds();
  795. if (isPaySpecificGoodsIds(specificGoodsIdsStr, fUid)) {
  796. BigDecimal specificPrice = data.getSpecificPrice();
  797. BigDecimal skuSpecificPrice = specificSku.getSpecificPrice();
  798. Long specificSkuId = specificSku.getId();
  799. if (specificPrice == null) {
  800. data.setSpecificPrice(skuSpecificPrice);
  801. data.setSpecificSkuId(specificSkuId);
  802. } else if (specificPrice.compareTo(skuSpecificPrice) > 0) {
  803. data.setSpecificPrice(skuSpecificPrice);
  804. data.setSpecificSkuId(specificSkuId);
  805. }
  806. }
  807. });
  808. }
  809. Integer sold = orderDonMapper.selectCount(Wrappers.lambdaQuery(OrderDon.class)
  810. .eq(OrderDon::getGoodsId, data.getGoodsId()).notIn(OrderDon::getStatus, Constant.noOrderStatus));
  811. data.setSold(sold + data.getSold());
  812. data.setNotifyMsg(getPayMsgTime(data.getGoodsId(), now, 1, null));
  813. });
  814. }
  815. public void setHomeConfigGoods(Map<String, List<HomeManagementFrontView>> map, HomeManagementConfig.Type type, List<HomeManagementFrontView> list, AtomicLong dsUserId, AtomicBoolean existsChannel, Long fUid) throws Exception {
  816. //设置特定价格
  817. if (CollUtil.isNotEmpty(list)) {
  818. list = list.stream().filter(data -> {
  819. if (data.getIsOwns()) {
  820. if (dsUserId.get() == 0 && fUid != null && existsChannel.get()) {
  821. Long sharedId = userService.getSharedIdByUserId(fUid);
  822. if (sharedId == 0) {
  823. existsChannel.set(false);
  824. }
  825. dsUserId.set(sharedId);
  826. }
  827. GoodsDonSku minPriceUserOwnsSku = goodsDonSkuMapper.checkAndReturnMinPriceUserOwnsSku(data.getGoodsId(), dsUserId.get());
  828. if (minPriceUserOwnsSku == null) {
  829. return false;
  830. }
  831. data.setPrice(minPriceUserOwnsSku.getPrice());
  832. data.setMonths(minPriceUserOwnsSku.getMonths());
  833. data.setDays(minPriceUserOwnsSku.getDays());
  834. }
  835. return true;
  836. }).collect(Collectors.toList());
  837. setHomeManageSpecific(list, fUid, dsUserId.get());
  838. map.put(type.name(), list);
  839. }
  840. }
  841. /**
  842. * 店铺平台列表
  843. */
  844. @GetMapping("/get/shop/goods/{yhsId}")
  845. public Result<List<YhShopGoodsFrontView>> getShopGoods(@PathVariable Long yhsId) {
  846. String yhShopCacheKey = RedisService.key.YH_HOME_PAGHE_CACHE_SHOP.getEnvName() + yhsId;
  847. Object value = redisService.get(yhShopCacheKey);
  848. List<YhShopGoodsFrontView> list = null;
  849. if (value != null) {
  850. try {
  851. list = Jsons.parseList(value, YhShopGoodsFrontView.class);
  852. } catch (Exception e) {
  853. }
  854. }
  855. if (CollUtil.isEmpty(list)) {
  856. MapBuilder builder = MapUtils.flatBuilder(request.getParameterMap());
  857. builder.put("condition", String.format("and yhs_id = %s", yhsId));
  858. list = beanSearcher.searchAll(YhShopGoodsFrontView.class, builder.build());
  859. redisService.setNx(yhShopCacheKey, list, RedisService.key.YH_HOME_PAGHE_CACHE.getTimeout());
  860. }
  861. DateTime now = DateTime.now();
  862. list.forEach(data->{
  863. Integer sold = orderDonMapper.selectCount(Wrappers.lambdaQuery(OrderDon.class)
  864. .eq(OrderDon::getGoodsId, data.getId()).notIn(OrderDon::getStatus, Constant.noOrderStatus));
  865. data.setSold(sold + data.getSold());
  866. data.setNotifyMsg(getPayMsgTime(data.getId(), now, 1, yhsId));
  867. });
  868. return GatewayResponse.SUCCESS.newBuilder().toResult(list);
  869. }
  870. /**
  871. * 店铺平台详情
  872. */
  873. @GetMapping("/get/shop/goods/detail/{yhsId}/{goodsId}")
  874. public Result<YhShopGoodsFrontView> getGoodsDetailByYhsId(@PathVariable Long yhsId, @PathVariable Long goodsId) {
  875. MapBuilder builder = MapUtils.flatBuilder(request.getParameterMap());
  876. String condition = String.format("and yhs_id = %s and ys.goods_id = %s", yhsId, goodsId);
  877. builder.put("condition", condition);
  878. YhShopGoodsFrontView goodsDetailView = beanSearcher.searchFirst(YhShopGoodsFrontView.class, builder.build());
  879. if (goodsDetailView == null) {
  880. throw BusinessRuntimeException.getInstance("该平台不存在或已下架,请刷新页面");
  881. }
  882. goodsDetailView.setSkuList(beanSearcher.searchAll(YhShopGoodsSkuFrontView.class, MapUtils.builder().put("condition", condition).orderBy(YhShopGoodsSkuFrontView::getOrderBy).asc().build()));
  883. goodsDetailView.setSpecs(beanSearcher.searchFirst(GoodsDonSpecFrontView.class, MapUtils.builder().field(GoodsDonSpecFrontView::getGoodsId, goodsDetailView.getId()).build()));
  884. OrderCommentFrontView comments = beanSearcher.searchFirst(OrderCommentFrontView.class, MapUtils.builder()
  885. .field(OrderCommentFrontView::getGoodsId, goodsDetailView.getId())
  886. .orderBy(OrderCommentFrontView::getCommentTime).desc()
  887. .orderBy(OrderCommentFrontView::getId).desc()
  888. .build());
  889. goodsDetailView.setComments(comments);
  890. return GatewayResponse.SUCCESS.newBuilder().toResult(goodsDetailView);
  891. }
  892. /**
  893. * 根据分类获取对应平台
  894. */
  895. @GetMapping("/get/categoryGoods")
  896. public Result<? extends Object> getGoodsByCategory(Long cgy, String customId, String dsCode) {
  897. if (StrUtil.isNotBlank(customId)) {
  898. Result<List<YhShopGoodsFrontCategoryView>> shopGoods = getShopCategoryGoods(yhShopFrontService.getYhsIdByCustomId(customId), cgy);
  899. return shopGoods;
  900. }
  901. Long fUid = StpUserUtil.getUserIdAfterLogin();
  902. String categoryGoodsKey = RedisService.key.YH_HOME_PAGHE_CACHE.getEnvName() + "category:goods";
  903. if (cgy != null) {
  904. categoryGoodsKey += ":" + cgy;
  905. }
  906. List<Long> filter_goodsIds = getFilterGoodsIds();
  907. if (CollUtil.isNotEmpty(filter_goodsIds)) {
  908. categoryGoodsKey += ":hz-ip";
  909. }
  910. Object o = redisService.get(categoryGoodsKey);
  911. if (o == null) {
  912. MapBuilder mapBuilder = MapUtils.flatBuilder(request.getParameterMap());
  913. if (cgy != null) {
  914. String condition = String.format(" and gcr.category = %s", cgy);
  915. mapBuilder.put("condition", condition);
  916. }
  917. if (CollUtil.isNotEmpty(filter_goodsIds)) {
  918. mapBuilder.field(GoodsFrontListCategoryView::getId, filter_goodsIds).op(Operator.NotIn);
  919. }
  920. List<GoodsFrontListCategoryView> goodsFrontListViews = beanSearcher.searchAll(GoodsFrontListCategoryView.class, mapBuilder.build());
  921. redisService.setNx(categoryGoodsKey, goodsFrontListViews, RedisService.key.YH_HOME_PAGHE_CACHE.getTimeout() + 10 * 60);
  922. o = redisService.get(categoryGoodsKey);
  923. }
  924. List<GoodsFrontListCategoryView> goodsFrontListViews = Jsons.parseList(o, GoodsFrontListCategoryView.class);
  925. DateTime now = DateTime.now();
  926. AtomicLong dsUserId = new AtomicLong();
  927. AtomicBoolean existsChannel = new AtomicBoolean(true);
  928. if (StrUtil.isNotBlank(dsCode)) {
  929. UserSharedDto userSharedDto = userService.getUserShredDtoByDsCode(dsCode);
  930. dsUserId.set(userSharedDto.getSharedId());
  931. }
  932. goodsFrontListViews = goodsFrontListViews.stream().filter(data -> {
  933. if (data.getIsOwns()) {
  934. if (dsUserId.get() == 0 && fUid != null && existsChannel.get()) {
  935. Long sharedId = userService.getSharedIdByUserId(fUid);
  936. if (sharedId == 0) {
  937. existsChannel.set(false);
  938. }
  939. dsUserId.set(sharedId);
  940. }
  941. GoodsDonSku minPriceUserOwnsSku = goodsDonSkuMapper.checkAndReturnMinPriceUserOwnsSku(data.getId(), dsUserId.get());
  942. if (minPriceUserOwnsSku == null) {
  943. return false;
  944. }
  945. data.setPrice(minPriceUserOwnsSku.getPrice());
  946. data.setMonths(minPriceUserOwnsSku.getMonths());
  947. data.setDays(minPriceUserOwnsSku.getDays());
  948. }
  949. Integer sold = orderDonMapper.selectCount(Wrappers.lambdaQuery(OrderDon.class)
  950. .eq(OrderDon::getGoodsId, data.getId()).notIn(OrderDon::getStatus, Constant.noOrderStatus));
  951. data.setSold(sold + data.getSold());
  952. data.setNotifyMsg(getPayMsgTime(data.getId(), now, 1, null));
  953. //设置特定价格
  954. setGcSpecificPrice(data, fUid, dsUserId.get());
  955. return true;
  956. }).collect(Collectors.toList());
  957. return GatewayResponse.SUCCESS.newBuilder().toResult(goodsFrontListViews);
  958. }
  959. @GetMapping("/get/shop/categoryGoods/{yhsId}")
  960. public Result<List<YhShopGoodsFrontCategoryView>> getShopCategoryGoods(@PathVariable Long yhsId, Long category) {
  961. String categoryGoodsKey = RedisService.key.YH_HOME_PAGHE_CACHE_SHOP.getEnvName() + yhsId + ":category";
  962. if (category != null) {
  963. categoryGoodsKey += ":" + category;
  964. }
  965. Object value = redisService.get(categoryGoodsKey);
  966. if (value == null) {
  967. MapBuilder builder = MapUtils.flatBuilder(request.getParameterMap());
  968. builder.put("yhsId", String.format(" and yhs_id = %s", yhsId));
  969. String condition = StrUtil.EMPTY;
  970. if (category != null) {
  971. condition += String.format(" and gcr.category = %s", category);
  972. }
  973. builder.put("condition", condition);
  974. List<YhShopGoodsFrontCategoryView> list = beanSearcher.searchAll(YhShopGoodsFrontCategoryView.class, builder.build());
  975. redisService.setNx(categoryGoodsKey, list, RedisService.key.YH_HOME_PAGHE_CACHE.getTimeout() + 5 * 60);
  976. value = redisService.get(categoryGoodsKey);
  977. }
  978. List<YhShopGoodsFrontCategoryView> list = Jsons.parseList(value, YhShopGoodsFrontCategoryView.class);
  979. DateTime now = DateTime.now();
  980. list.forEach(data -> {
  981. Integer sold = orderDonMapper.selectCount(Wrappers.lambdaQuery(OrderDon.class)
  982. .eq(OrderDon::getGoodsId, data.getId()).notIn(OrderDon::getStatus, Constant.noOrderStatus));
  983. data.setSold(sold + data.getSold());
  984. data.setNotifyMsg(getPayMsgTime(data.getId(), now, 1, yhsId));
  985. });
  986. return GatewayResponse.SUCCESS.newBuilder().toResult(list);
  987. }
  988. /**
  989. * 获取设备活动详情
  990. */
  991. @GetMapping("/get/equipment/activity")
  992. public Result<EquipmentActivityReduce> getEpActivity() {
  993. DateTime now = DateTime.now();
  994. EquipmentActivityReduce equipmentActivityReduce = beanSearcher.searchFirst(EquipmentActivityReduce.class, MapUtils.builder()
  995. .field(EquipmentActivityReduce::getSt, now).op(Operator.LessEqual)
  996. .field(EquipmentActivityReduce::getEt, now).op(Operator.GreaterThan)
  997. .field(EquipmentActivityReduce::getDeleted, 1)
  998. .onlySelect(EquipmentActivityReduce::getF, EquipmentActivityReduce::getQ, EquipmentActivityReduce::getTq, EquipmentActivityReduce::getSt, EquipmentActivityReduce::getEt)
  999. .build());
  1000. return GatewayResponse.SUCCESS.newBuilder().toResult(equipmentActivityReduce);
  1001. }
  1002. /**
  1003. * 获取租赁商品列表
  1004. */
  1005. @GetMapping("/get/deposit")
  1006. public Result<? extends Object> getDepositGoods() {
  1007. String depositGoodsKey = RedisService.key.YH_HOME_PAGHE_CACHE.getEnvName() + "deposit";
  1008. Object o = redisService.get(depositGoodsKey);
  1009. if (o == null) {
  1010. List<GoodsDon> depositList = beanSearcher.searchAll(GoodsDon.class, MapUtils.builder()
  1011. .field(GoodsDon::getType, 4)
  1012. .field(GoodsDon::getStatus, true)
  1013. .field(GoodsDon::getDeleted, true)
  1014. .onlySelect(GoodsDon::getId, GoodsDon::getTitle, GoodsDon::getLogo)
  1015. .build());
  1016. if (CollUtil.isEmpty(depositList)) {
  1017. return GatewayResponse.SUCCESS.newBuilder().toResult();
  1018. }
  1019. redisService.setNx(depositGoodsKey, depositList, RedisService.key.YH_HOME_PAGHE_CACHE.getTimeout() + 60 * RandomUtil.randomInt(10));
  1020. o = redisService.get(depositGoodsKey);
  1021. }
  1022. List<GoodsDon> depositList = Jsons.parseList(o, GoodsDon.class);
  1023. return GatewayResponse.SUCCESS.newBuilder().toResult(depositList);
  1024. }
  1025. /**
  1026. * 获取pc广告配置
  1027. */
  1028. @GetMapping("/get/pc/homeManage")
  1029. public Result<Map<String, List<HomeManagementFrontView>>> getPcHomeManagementFrontPage() {
  1030. String key = RedisService.key.YH_HOME_PAGHE_CACHE.getEnvName() + "pc:homeManage";
  1031. Object o = redisService.get(key);
  1032. if (o == null) {
  1033. MapBuilder builder = MapUtils.builder()
  1034. .field(HomeManagementFrontView::getAdType, List.of(HomeManagementConfig.AdType.pc.name(), HomeManagementConfig.AdType.pcSec.name(), HomeManagementConfig.AdType.pcDis.name())).op(Operator.InList);
  1035. List<HomeManagementFrontView> homeManagementFrontViews = beanSearcher.searchAll(HomeManagementFrontView.class, builder.build());
  1036. Map<HomeManagementConfig.AdType, List<HomeManagementFrontView>> map = homeManagementFrontViews.stream().collect(Collectors.groupingBy(HomeManagementFrontView::getAdType));
  1037. redisService.setNx(key, map, 50 * 60l);
  1038. o = redisService.get(key);
  1039. }
  1040. Map<String, List<HomeManagementFrontView>> map = Jsons.parseObject(o, Map.class);
  1041. return GatewayResponse.SUCCESS.newBuilder().toResult(map);
  1042. }
  1043. /**
  1044. * 获取pc实物配置
  1045. */
  1046. @GetMapping("/get/pc/realGoodsConfig")
  1047. public Result<? extends Object> getPcRealGoodsConfig() throws Exception {
  1048. String key = RedisService.key.YH_HOME_PAGHE_CACHE.getEnvName() + "pc:realHomePage";
  1049. Object o = redisService.get(key);
  1050. List<HomeManagementFrontView> list = null;
  1051. if (o == null) {
  1052. list = goodsDonFrontService.getRealGoodsConfig();
  1053. redisService.setNx(key, list, RedisService.key.YH_HOME_PAGHE_CACHE.getTimeout() + 300);
  1054. }
  1055. if (list == null && o != null) {
  1056. list = Jsons.parseList(o, HomeManagementFrontView.class);
  1057. }
  1058. return GatewayResponse.SUCCESS.newBuilder().toResult(list);
  1059. }
  1060. }