GoodsDonController.java 70 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680
  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.GiftCardGoodsSkuMapper;
  18. import com.cyksj.mapper.GoodsDonSkuMapper;
  19. import com.cyksj.mapper.OrderDonMapper;
  20. import com.cyksj.mapper.RegisterOrderDonMapper;
  21. import com.cyksj.mapper.manage.coupon.CouponUserMapper;
  22. import com.cyksj.mapper.shop.YhShopGoodsSkuMapper;
  23. import com.cyksj.mapper.sys.SysConfigMapper;
  24. import com.cyksj.model.entity.*;
  25. import com.cyksj.model.request.ClickRecordReq;
  26. import com.cyksj.model.views.*;
  27. import com.cyksj.redis.RedisService;
  28. import com.cyksj.service.goods.GoodsDonFrontService;
  29. import com.cyksj.service.home.ClickRecordFrontService;
  30. import com.cyksj.service.shop.YhShopFrontService;
  31. import com.cyksj.service.translations.BackInfoTranslationsFrontService;
  32. import com.cyksj.service.user.UserBindRelationService;
  33. import com.cyksj.service.user.UserService;
  34. import com.cyksj.web.util.StpUserUtil;
  35. import com.ejlchina.searcher.BeanSearcher;
  36. import com.ejlchina.searcher.SearchResult;
  37. import com.ejlchina.searcher.param.Operator;
  38. import com.ejlchina.searcher.util.MapBuilder;
  39. import com.ejlchina.searcher.util.MapUtils;
  40. import lombok.RequiredArgsConstructor;
  41. import lombok.extern.slf4j.Slf4j;
  42. import org.springframework.web.bind.annotation.*;
  43. import javax.servlet.http.HttpServletRequest;
  44. import java.math.BigDecimal;
  45. import java.util.*;
  46. import java.util.concurrent.ConcurrentHashMap;
  47. import java.util.concurrent.atomic.AtomicBoolean;
  48. import java.util.concurrent.atomic.AtomicLong;
  49. import java.util.stream.Collectors;
  50. import java.util.stream.Stream;
  51. /**
  52. * @author chan
  53. * @date 2022/9/26 5:33 PM
  54. */
  55. @Slf4j
  56. @RestController
  57. @RequestMapping("/applets/goods")
  58. @RequiredArgsConstructor
  59. public class GoodsDonController {
  60. private final HttpServletRequest request;
  61. private final BeanSearcher beanSearcher;
  62. private final OrderDonMapper orderDonMapper;
  63. private final RegisterOrderDonMapper registerOrderDonMapper;
  64. private final GoodsDonSkuMapper goodsDonSkuMapper;
  65. private final YhShopGoodsSkuMapper yhShopGoodsSkuMapper;
  66. private final RedisService redisService;
  67. private final SysConfigMapper sysConfigMapper;
  68. private final ClickRecordFrontService clickRecordFrontService;
  69. private final YhShopFrontService yhShopFrontService;
  70. private final UserService userService;
  71. private final CouponUserMapper couponUserMapper;
  72. private final GoodsDonFrontService goodsDonFrontService;
  73. private final UserBindRelationService userBindRelationService;
  74. private final GiftCardGoodsSkuMapper giftCardGoodsSkuMapper;
  75. private final BackInfoTranslationsFrontService backInfoTranslationsFrontService;
  76. /**
  77. * 获取平台商品分类
  78. */
  79. @GetMapping("/get/category")
  80. public Result<List<GoodsDonCategoryFrontView>> getCategory(String customId) {
  81. Long yhsId = null;
  82. if (StrUtil.isNotBlank(customId)) {
  83. yhsId = yhShopFrontService.getYhsIdByCustomId(customId);
  84. }
  85. String key = RedisService.key.YH_HOME_PAGHE_CACHE.getName() + "category";
  86. if (yhsId != null) {
  87. key += ":yhShop:" + yhsId;
  88. }
  89. String lang = request.getHeader("lang");
  90. AtomicBoolean language = new AtomicBoolean(false);
  91. if (lang != null && !StrUtil.equals(UserPageLanguage.Language.zh_CN.name(), lang)) {
  92. key += ":" + lang;
  93. language.set(true);
  94. }
  95. Object o = redisService.get(key);
  96. List<GoodsDonCategoryFrontView> list;
  97. MapBuilder mapBuilder = MapUtils.flatBuilder(request.getParameterMap());
  98. 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";
  99. if (yhsId != null) {
  100. 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));
  101. } else {
  102. condition = String.format(condition, StrUtil.EMPTY);
  103. }
  104. mapBuilder.put("condition", condition);
  105. if (o == null) {
  106. list = beanSearcher.searchAll(GoodsDonCategoryFrontView.class, mapBuilder
  107. .build());
  108. //多语言
  109. if (language.get()) {
  110. backInfoTranslationsFrontService.setListCategoryNameLanguage(list, lang);
  111. }
  112. redisService.setNx(key, list, 30 * 60l);
  113. o = redisService.get(key);
  114. }
  115. List<Long> gptBuyGids = getGptMirrorGiveawayBuyGids();
  116. list = Jsons.parseList(o, GoodsDonCategoryFrontView.class);
  117. for (GoodsDonCategoryFrontView data : list) {
  118. List<GoodsDonCategoryGoodsView> goodsDonCategoryGoodsViews = beanSearcher.searchAll(GoodsDonCategoryGoodsView.class, MapUtils.builder().field(GoodsDonCategoryGoodsView::getCategory, data.getId()).field(GoodsDonCategoryGoodsView::getStatus, 1).onlySelect(GoodsDonCategoryGoodsView::getGoodsId).build());
  119. List<Long> collect = goodsDonCategoryGoodsViews.stream().map(GoodsDonCategoryGoodsView::getGoodsId).distinct().collect(Collectors.toList());
  120. if (CollUtil.isNotEmpty(gptBuyGids) && gptBuyGids.containsAll(collect)) {
  121. data.setIsGptGift(true);
  122. }
  123. }
  124. return GatewayResponse.SUCCESS.newBuilder().toResult(list);
  125. }
  126. /**
  127. * 商品搜索
  128. */
  129. @GetMapping("/search")
  130. public Result<SearchResult<GoodsDonSearchView>> search() {
  131. SearchResult<GoodsDonSearchView> search = beanSearcher.search(GoodsDonSearchView.class, MapUtils.flatBuilder(request.getParameterMap()).build());
  132. return GatewayResponse.SUCCESS.newBuilder().toResult(search);
  133. }
  134. /**
  135. * 获取商品列表
  136. */
  137. @GetMapping("/get")
  138. public Result<SearchResult<GoodsDon>> get() {
  139. SearchResult<GoodsDon> search = beanSearcher.search(GoodsDon.class, MapUtils.flatBuilder(request.getParameterMap())
  140. .field(GoodsDon::getStatus, true)
  141. .field(GoodsDon::getDeleted, true)
  142. .orderBy(GoodsDon::getSortBy).asc()
  143. .orderBy(GoodsDon::getId).asc()
  144. .build()
  145. );
  146. search.getDataList().forEach(goods -> {
  147. GoodsDonSku goodsDonSku = goodsDonSkuMapper.selectOne(Wrappers.lambdaQuery(GoodsDonSku.class).eq(GoodsDonSku::getGoodsId, goods.getId())
  148. .eq(GoodsDonSku::getStatus, true)
  149. .orderByAsc(GoodsDonSku::getPrice)
  150. .last("limit 1")
  151. .select(GoodsDonSku::getPrice));
  152. Optional.ofNullable(goodsDonSku).ifPresent(sku -> {
  153. goods.setPrice(goodsDonSku.getPrice());
  154. goods.setSoldNum(getGoodsSold(goods.getId(), goods.getVirtualSold()));
  155. });
  156. });
  157. return GatewayResponse.SUCCESS.newBuilder().toResult(search);
  158. }
  159. /**
  160. * 推广未登录,虚拟商品列表
  161. */
  162. @GetMapping("/get/popularize")
  163. @Deprecated
  164. public Result<SearchResult<GoodsDonPopularizeView>> getPopularizeVipGoods() {
  165. SearchResult<GoodsDonPopularizeView> search = beanSearcher.search(GoodsDonPopularizeView.class, MapUtils.flatBuilder(request.getParameterMap())
  166. .field(GoodsDonPopularizeView::getStatus, true)
  167. .field(GoodsDonPopularizeView::getDeleted, true)
  168. .field(GoodsDonPopularizeView::getType, 1)
  169. .orderBy(GoodsDonPopularizeView::getSortBy).asc()
  170. .orderBy(GoodsDonPopularizeView::getId).asc()
  171. .build());
  172. DateTime now = DateTime.now();
  173. search.getDataList().forEach(data -> {
  174. data.setSpecs(beanSearcher.searchFirst(GoodsDonSpec.class, MapUtils.builder().field(GoodsDonSpec::getGoodsId, data.getId()).build()));
  175. data.setSkuList(beanSearcher.searchAll(GoodsDonSku.class, MapUtils.builder().field(GoodsDonSku::getGoodsId, data.getId()).field(GoodsDonSku::getStatus, true).orderBy(GoodsDonSku::getPrice).asc().build()));
  176. data.setSold(getGoodsSold(data.getId(), data.getVirtualSold()));
  177. Optional.ofNullable(data.getSkuList()).ifPresent(skuList -> {
  178. if (skuList.size() > 0) {
  179. GoodsDonSku goodsDonSku = skuList.get(0);
  180. data.setPrice(goodsDonSku.getPrice());
  181. data.setMonths(goodsDonSku.getMonths());
  182. }
  183. });
  184. OrderDon orderDon = orderDonMapper.selectOne(Wrappers.lambdaQuery(OrderDon.class)
  185. .eq(OrderDon::getGoodsId, data.getId())
  186. .notIn(OrderDon::getStatus, Constant.noOrderStatus).select(OrderDon::getCreatedTime, OrderDon::getPayTime, OrderDon::getId)
  187. .orderByDesc(OrderDon::getId)
  188. .last("limit 1"));
  189. StringBuilder notifyMsg = new StringBuilder();
  190. if (orderDon == null) {
  191. notifyMsg.append("点击购买立即上车");
  192. data.setNotifyMsg(notifyMsg.toString());
  193. return;
  194. } else {
  195. Date payTime = orderDon.getPayTime();
  196. Date startTime = payTime != null ? payTime : orderDon.getCreatedTime();
  197. long hour = DateUtil.between(startTime, now, DateUnit.HOUR);
  198. if (hour == 0) {
  199. long minute = DateUtil.between(startTime, now, DateUnit.MINUTE);
  200. if (minute == 0) {
  201. notifyMsg.append("1分钟");
  202. } else {
  203. notifyMsg.append(minute);
  204. notifyMsg.append("分钟");
  205. }
  206. } else {
  207. if (hour > 3) {
  208. int hours = RandomUtil.randomInt(3) + 1;
  209. notifyMsg.append(hours);
  210. } else {
  211. notifyMsg.append(hour);
  212. }
  213. notifyMsg.append("小时");
  214. }
  215. }
  216. notifyMsg.append("前有人购买");
  217. data.setNotifyMsg(notifyMsg.toString());
  218. });
  219. return GatewayResponse.SUCCESS.newBuilder().toResult(search);
  220. }
  221. /**
  222. * 官网首页 平台列表
  223. */
  224. @GetMapping("/get/list")
  225. @Deprecated
  226. public Result<? extends Object> getGoodsList(String customId) {
  227. if (StrUtil.isNotBlank(customId)) {
  228. Result<List<YhShopGoodsFrontView>> shopGoods = getShopGoods(yhShopFrontService.getYhsIdByCustomId(customId));
  229. return shopGoods;
  230. }
  231. //List<Long> filter_goodsIds = getFilterGoodsIds();
  232. List<Long> filter_goodsIds = null;
  233. String pcCacheKey = RedisService.key.YH_HOME_PAGHE_CACHE.getName() + "PC";
  234. if (CollUtil.isNotEmpty(filter_goodsIds)) {
  235. pcCacheKey += ":hz-ip";
  236. }
  237. Long fUid = StpUserUtil.getUserIdAfterLogin();
  238. Object o = redisService.get(pcCacheKey);
  239. List<GoodsFrontListView> list = null;
  240. if (o == null) {
  241. MapBuilder builder = MapUtils.flatBuilder(request.getParameterMap());
  242. if (CollUtil.isNotEmpty(filter_goodsIds)) {
  243. builder.field(GoodsFrontListView::getId, filter_goodsIds).op(Operator.NotIn);
  244. }
  245. builder.field(GoodsFrontListView::getType, 1);
  246. list = beanSearcher.searchAll(GoodsFrontListView.class, builder.build());
  247. redisService.setNx(pcCacheKey, list, RedisService.key.YH_HOME_PAGHE_CACHE.getTimeout());
  248. o = redisService.get(pcCacheKey);
  249. }
  250. if (list == null) {
  251. list = Jsons.parseList(o, GoodsFrontListView.class);
  252. }
  253. DateTime now = DateTime.now();
  254. list.forEach(data -> {
  255. data.setSold(getGoodsSold(data.getId(), data.getSold()));
  256. data.setNotifyMsg(getPayMsgTime(data.getId(), now, 1, null));
  257. //设置特定价格
  258. setSpecificPrice(data, fUid, null);
  259. });
  260. return GatewayResponse.SUCCESS.newBuilder().toResult(Optional.of(list));
  261. }
  262. /**
  263. * h5 银河首页平台展示
  264. */
  265. @GetMapping("/get/homePage")
  266. @Deprecated
  267. public Result<? extends Object> getGoodsHomePage(String customId) {
  268. if (StrUtil.isNotBlank(customId)) {
  269. Result<List<YhShopGoodsFrontView>> shopGoods = getShopGoods(yhShopFrontService.getYhsIdByCustomId(customId));
  270. return shopGoods;
  271. }
  272. //List<Long> filter_goodsIds = getFilterGoodsIds();
  273. List<Long> filter_goodsIds = null;
  274. String h5CacheKey = RedisService.key.YH_HOME_PAGHE_CACHE.getName() + "H5";
  275. if (CollUtil.isNotEmpty(filter_goodsIds)) {
  276. h5CacheKey += ":hz-ip";
  277. }
  278. Long fUid = StpUserUtil.getUserIdAfterLogin();
  279. Object o = redisService.get(h5CacheKey);
  280. List<GoodsFrontListView> list = null;
  281. if (o == null) {
  282. MapBuilder builder = MapUtils.flatBuilder(request.getParameterMap());
  283. if (CollUtil.isNotEmpty(filter_goodsIds)) {
  284. builder.field(GoodsFrontListView::getId, filter_goodsIds).op(Operator.NotIn);
  285. }
  286. list = beanSearcher.searchAll(GoodsFrontListView.class, builder.build());
  287. redisService.setNx(h5CacheKey, list, RedisService.key.YH_HOME_PAGHE_CACHE.getTimeout());
  288. o = redisService.get(h5CacheKey);
  289. }
  290. if (list == null) {
  291. list = Jsons.parseList(o, GoodsFrontListView.class);
  292. }
  293. DateTime now = DateTime.now();
  294. list.forEach(data -> {
  295. data.setSold(getGoodsSold(data.getId(), data.getSold()));
  296. data.setNotifyMsg(getPayMsgTime(data.getId(), now, 1, null));
  297. //设置特定价格
  298. setSpecificPrice(data, fUid, null);
  299. });
  300. return GatewayResponse.SUCCESS.newBuilder().toResult(Optional.of(list));
  301. }
  302. /**
  303. * 注册首页平台展示
  304. */
  305. @GetMapping("/get/register")
  306. public Result<List<RegisterGoodsDonView>> getRegisterGoodsDon() {
  307. String registerCacheKey = RedisService.key.REGISTER_HOME_PAGE_CACHE.getName();
  308. Object value = redisService.get(registerCacheKey);
  309. if (value != null) {
  310. try {
  311. List<RegisterGoodsDonView> list = Jsons.parseList(value, RegisterGoodsDonView.class);
  312. if (CollUtil.isNotEmpty(list)) {
  313. return GatewayResponse.SUCCESS.newBuilder().toResult(list);
  314. }
  315. } catch (Exception e) {
  316. }
  317. }
  318. MapBuilder builder = MapUtils.flatBuilder(request.getParameterMap());
  319. List<RegisterGoodsDonView> dataList = beanSearcher.searchAll(RegisterGoodsDonView.class, builder.build());
  320. DateTime now = DateTime.now();
  321. dataList.forEach(data -> {
  322. Integer sold = registerOrderDonMapper.selectCount(Wrappers.lambdaQuery(RegisterOrderDon.class)
  323. .eq(RegisterOrderDon::getGoodsId, data.getId()).notIn(RegisterOrderDon::getStatus, Constant.noOrderStatus));
  324. data.setSold(sold + data.getVirtualSold());
  325. data.setNotifyMsg(getPayMsgTime(data.getId(), now, 2, null));
  326. });
  327. redisService.setNx(registerCacheKey, dataList, RedisService.key.REGISTER_HOME_PAGE_CACHE.getTimeout());
  328. return GatewayResponse.SUCCESS.newBuilder().toResult(dataList);
  329. }
  330. /**
  331. * 获取商品详情
  332. */
  333. @GetMapping("/get/{id}")
  334. public Result<? extends Object> getDetail(@PathVariable Long id, String customId, String dsCode, BigDecimal discount) {
  335. if (StrUtil.isNotBlank(customId) && id != 15) {
  336. Result<YhShopGoodsFrontView> yhShopGoodsDetail = getGoodsDetailByYhsId(yhShopFrontService.getYhsIdByCustomId(customId), id);
  337. return yhShopGoodsDetail;
  338. }
  339. String goodsDetailKey = RedisService.key.YH_HOME_PAGHE_CACHE.getName() + "goods_detail:" + id;
  340. //List<Long> filter_goodsIds = getFilterGoodsIds();
  341. List<Long> filter_goodsIds = null;
  342. String lang = request.getHeader("lang");
  343. AtomicBoolean language = new AtomicBoolean(false);
  344. if (lang != null && !StrUtil.equals(UserPageLanguage.Language.zh_CN.name(), lang)) {
  345. goodsDetailKey += ":" + lang;
  346. language.set(true);
  347. }
  348. //存在过滤平台 商品详情不返回
  349. if (CollUtil.isNotEmpty(filter_goodsIds) && filter_goodsIds.contains(id)) {
  350. return GatewayResponse.SUCCESS.newBuilder().toResult();
  351. }
  352. Object o = redisService.get(goodsDetailKey);
  353. if (o == null) {
  354. GoodsFrontListView views = beanSearcher.searchFirst(GoodsFrontListView.class, MapUtils.builder().field(GoodsFrontListView::getId, id)
  355. .build());
  356. if (views == null) {
  357. return GatewayResponse.SUCCESS.newBuilder().toResult();
  358. }
  359. views.setSpecs(beanSearcher.searchFirst(GoodsDonSpecFrontView.class, MapUtils.builder().field(GoodsDonSpecFrontView::getGoodsId, views.getId()).build()));
  360. MapBuilder builder = MapUtils.builder().field(GoodsDonSkuFrontView::getGoodsId, views.getId()).field(GoodsDonSkuFrontView::getStatus, true);
  361. if (views.getType() == 1) {
  362. builder.orderBy(GoodsDonSkuFrontView::getSorted).asc();
  363. }
  364. views.setSkuList(beanSearcher.searchAll(GoodsDonSkuFrontView.class, builder.build()));
  365. views.setSold(getGoodsSold(views.getId(), views.getSold()));
  366. //多语言
  367. if (language.get()) {
  368. backInfoTranslationsFrontService.setGoodsDetailLanguage(views, lang);
  369. }
  370. List<Long> gptBuyGids = getGptMirrorGiveawayBuyGids();
  371. if (CollUtil.isNotEmpty(gptBuyGids) && gptBuyGids.contains(views.getId())) {
  372. views.setIsGptGift(true);
  373. }
  374. List<GoodsDonQaFrontView> donQaFrontViews = beanSearcher.searchAll(GoodsDonQaFrontView.class, MapUtils.builder().field(GoodsDonQaFrontView::getGoodsId, id).field(GoodsDonQaFrontView::getType, 1).build());
  375. views.setQuestions(donQaFrontViews);
  376. redisService.setNx(goodsDetailKey, views, RedisService.key.YH_HOME_PAGHE_CACHE.getTimeout() + 60 * RandomUtil.randomInt(10));
  377. o = redisService.get(goodsDetailKey);
  378. }
  379. Long fUid = StpUserUtil.getUserIdAfterLogin();
  380. GoodsFrontListView views = Jsons.parseObject(o, GoodsFrontListView.class);
  381. AtomicLong dsUserId = new AtomicLong();
  382. AtomicBoolean existsChannel = new AtomicBoolean(true);
  383. if (StrUtil.isNotBlank(dsCode)) {
  384. UserSharedDto userSharedDto = userService.getUserShredDtoByDsCode(dsCode);
  385. dsUserId.set(userSharedDto.getSharedId());
  386. }
  387. views.setIsGift(giftCardGoodsSkuMapper.selectCount(Wrappers.lambdaQuery(GiftCardGoodsSku.class)
  388. .eq(GiftCardGoodsSku::getGcGoodsId, views.getId())
  389. .eq(GiftCardGoodsSku::getStatus, 1)
  390. .eq(GiftCardGoodsSku::getDeleted, 1)) > 0);
  391. views.setSkuList(views.getSkuList().stream().filter(sku -> {
  392. if (StrUtil.isNotBlank(sku.getUserOwns())) {
  393. if (dsUserId.get() == 0 && fUid != null && existsChannel.get()) {
  394. Long sharedId = userService.getSharedIdByUserId(fUid);
  395. if (sharedId == 0) {
  396. existsChannel.set(false);
  397. }
  398. dsUserId.set(sharedId);
  399. }
  400. if (dsUserId.get() == 0 || !sku.getUserOwns().contains(String.valueOf(dsUserId.get()))) {
  401. return false;
  402. }
  403. }
  404. if (sku.getIsDp()) {
  405. sku.setDpSkuViews(beanSearcher.searchAll(GoodsDiscountPlusPurchaseRelationFrontView.class, MapUtils.builder()
  406. .field(GoodsDiscountPlusPurchaseRelationFrontView::getSkuId, sku.getId())
  407. .build()));
  408. //多语言
  409. if (language.get()) {
  410. for (GoodsDiscountPlusPurchaseRelationFrontView dpSkuView : sku.getDpSkuViews()) {
  411. String languageGoodsTitle = backInfoTranslationsFrontService.getGoodsTitleLanguage(dpSkuView.getDisGid(), lang);
  412. if (StrUtil.isNotBlank(languageGoodsTitle)) {
  413. dpSkuView.setTitle(languageGoodsTitle);
  414. }
  415. String languageSpecVal = backInfoTranslationsFrontService.getLanguageSpecVal(dpSkuView.getDisSid(), lang);
  416. if (StrUtil.isNotBlank(languageSpecVal)) {
  417. dpSkuView.setSpecVal(languageSpecVal);
  418. }
  419. }
  420. }
  421. }
  422. if (views.getIsSp()) {
  423. if (fUid == null) {
  424. sku.setSpecificPrice(null);
  425. sku.setSpecificGoodsIds(null);
  426. } else {
  427. //设置特定价格
  428. if (!isPaySpecificGoodsIds(sku.getSpecificGoodsIds(), fUid)) {
  429. sku.setSpecificGoodsIds(null);
  430. sku.setSpecificPrice(null);
  431. } else {
  432. BigDecimal specificPrice = views.getSpecificPrice();
  433. BigDecimal skuSpecificPrice = sku.getSpecificPrice();
  434. Long specificSkuId = sku.getId();
  435. if (specificPrice == null) {
  436. views.setSpecificPrice(skuSpecificPrice);
  437. views.setSpecificSkuId(specificSkuId);
  438. } else if (specificPrice.compareTo(skuSpecificPrice) > 0) {
  439. views.setSpecificPrice(skuSpecificPrice);
  440. views.setSpecificSkuId(specificSkuId);
  441. }
  442. }
  443. }
  444. }
  445. // if (fUid != null && Constant.SPECIAL_PRICE_SKU_IDS.contains(sku.getId())) {
  446. // UserDistributeShared distributeShared = userDistributeSharedMapper.selectOne(Wrappers.lambdaQuery(UserDistributeShared.class)
  447. // .eq(UserDistributeShared::getUserId, fUid)
  448. // .last("limit 1"));
  449. // if (distributeShared != null) {
  450. // Optional.ofNullable(sysConfigMapper.selectOne(Wrappers.lambdaQuery(SysConfig.class)
  451. // .eq(SysConfig::getSysKey, Constant.MJ_SPECIAL_SKU_PRICE_KEY)
  452. // .last("limit 1"))).ifPresent(sysConfig -> {
  453. // if (StrUtil.isNotBlank(sysConfig.getSysValue())) {
  454. // try {
  455. // GoodsDonPriceDto goodsDonPriceDto = Jsons.parseObject(sysConfig.getSysValue(), GoodsDonPriceDto.class);
  456. // sku.setPrice(goodsDonPriceDto.getPrice());
  457. // } catch (Exception e) {
  458. // }
  459. // }
  460. // });
  461. // }
  462. // }
  463. //设置规格优惠后的价格
  464. sku.setChannelDiscount(discount);
  465. setUserCouponSkuMoney(fUid, sku);
  466. return true;
  467. }).collect(Collectors.toList()));
  468. return GatewayResponse.SUCCESS.newBuilder().toResult(views);
  469. }
  470. /**
  471. * 获取商品推荐平台
  472. */
  473. @GetMapping("/get/recommend/{id}")
  474. public Result<List<GoodsFrontListView>> getRecommendGoodsByGid(@PathVariable Long id, String customId, String dsCode) throws Exception {
  475. String key = RedisService.key.YH_HOME_PAGHE_CACHE.getName() + "recommend:" + id;
  476. Long yhsId = null;
  477. if (StrUtil.isNotBlank(customId)) {
  478. yhsId = yhShopFrontService.getYhsIdByCustomId(customId);
  479. key = RedisService.key.YH_HOME_PAGHE_CACHE_SHOP.getName() + yhsId + ":recommend:" + id;
  480. }
  481. Object o = redisService.get(key);
  482. Long fUid = StpUserUtil.getUserIdAfterLogin();
  483. List<GoodsFrontListView> goodsRecommendViews = null;
  484. if (o == null) {
  485. GoodsDon goodsDon = beanSearcher.searchFirst(GoodsDon.class, MapUtils.builder()
  486. .field(GoodsDon::getId, id).field(GoodsDon::getStatus, true)
  487. .field(GoodsDon::getDeleted, true)
  488. .build());
  489. if (goodsDon != null && StrUtil.isNotEmpty(goodsDon.getRecommendGoods())) {
  490. List<Long> recommend_gidList = Jsons.parseList(goodsDon.getRecommendGoods(), Long.class);
  491. MapBuilder mapBuilder = MapUtils.builder();
  492. if (yhsId != null) {
  493. 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));
  494. }
  495. mapBuilder.field(GoodsFrontListView::getId, recommend_gidList).op(Operator.InList);
  496. goodsRecommendViews = beanSearcher.searchAll(GoodsFrontListView.class, mapBuilder.build());
  497. redisService.setNx(key, Jsons.toJson(goodsRecommendViews), 60 * 15l);
  498. o = redisService.get(key);
  499. } else {
  500. return GatewayResponse.SUCCESS.newBuilder().toResult();
  501. }
  502. }
  503. if (goodsRecommendViews == null) {
  504. goodsRecommendViews = Jsons.parseList(o.toString(), GoodsFrontListView.class);
  505. }
  506. AtomicLong dsUserId = new AtomicLong();
  507. AtomicBoolean existsChannel = new AtomicBoolean(true);
  508. if (StrUtil.isNotBlank(dsCode)) {
  509. UserSharedDto userSharedDto = userService.getUserShredDtoByDsCode(dsCode);
  510. dsUserId.set(userSharedDto.getSharedId());
  511. }
  512. goodsRecommendViews = goodsRecommendViews.stream().filter(data -> {
  513. if (data.getIsOwns()) {
  514. if (dsUserId.get() == 0 && fUid != null && existsChannel.get()) {
  515. Long sharedId = userService.getSharedIdByUserId(fUid);
  516. if (sharedId == 0) {
  517. existsChannel.set(false);
  518. }
  519. dsUserId.set(sharedId);
  520. }
  521. GoodsDonSku minPriceUserOwnsSku = goodsDonSkuMapper.checkAndReturnMinPriceUserOwnsSku(data.getId(), dsUserId.get());
  522. if (minPriceUserOwnsSku == null) {
  523. return false;
  524. }
  525. data.setPrice(minPriceUserOwnsSku.getPrice());
  526. data.setMonths(minPriceUserOwnsSku.getMonths());
  527. data.setDays(minPriceUserOwnsSku.getDays());
  528. }
  529. //销量
  530. data.setSold(getGoodsSold(data.getId(), data.getSold()));
  531. //设置特定价格
  532. setSpecificPrice(data, fUid, dsUserId.get());
  533. return true;
  534. }).collect(Collectors.toList());
  535. return GatewayResponse.SUCCESS.newBuilder().toResult(goodsRecommendViews);
  536. }
  537. /**
  538. * 获取商品多规格列表
  539. */
  540. @GetMapping("/get/sku")
  541. public Result<List<GoodsDonSkuView>> getGoodsDonSkuView(@RequestParam(value = "skuIds") List<Long> skuIds) {
  542. if (skuIds.isEmpty()) {
  543. return GatewayResponse.SUCCESS.newBuilder().toResult();
  544. }
  545. List<GoodsDonSkuView> views = beanSearcher.searchAll(GoodsDonSkuView.class, MapUtils.builder()
  546. .field(GoodsDonSkuView::getSkuId, skuIds).op(Operator.InList)
  547. .build());
  548. return GatewayResponse.SUCCESS.newBuilder().toResult(views);
  549. }
  550. /**
  551. * 获取评价列表
  552. */
  553. @GetMapping("/get/comments")
  554. public Result<SearchResult<OrderCommentFrontView>> getComments() {
  555. SearchResult<OrderCommentFrontView> search = beanSearcher.search(OrderCommentFrontView.class, MapUtils.flatBuilder(request.getParameterMap())
  556. .orderBy(OrderCommentFrontView::getCommentTime).desc()
  557. .orderBy(OrderCommentFrontView::getId).desc()
  558. .build());
  559. return GatewayResponse.SUCCESS.newBuilder().toResult(search);
  560. }
  561. /**
  562. * 获取礼品卡平台性情
  563. */
  564. @GetMapping("/get/card/{id}")
  565. public Result<Map<Integer, List<GiftCardGoodsSkuFrontView>>> getGiftCardDetail(@PathVariable Long id) {
  566. List<GiftCardGoodsSkuFrontView> giftCardGoodsSkuFrontViews = beanSearcher.searchAll(GiftCardGoodsSkuFrontView.class, MapUtils.builder().field(GiftCardGoodsSkuFrontView::getGoodsId, id).build());
  567. Map<Integer, List<GiftCardGoodsSkuFrontView>> map = giftCardGoodsSkuFrontViews.stream().collect(Collectors.groupingBy(GiftCardGoodsSkuFrontView::getGcType));
  568. return GatewayResponse.SUCCESS.newBuilder().toResult(map);
  569. }
  570. /**
  571. * 获取首页配置列表
  572. */
  573. @GetMapping("/get/homeManage")
  574. public Result<Map<String, List<HomeManagementFrontView>>> getHomeManagementFrontPage(String customId, String dsCode, BigDecimal discount) {
  575. String key = RedisService.key.YH_HOME_PAGHE_CACHE.getName() + "homeManage";
  576. Long yhsId = null;
  577. if (StrUtil.isNotBlank(customId)) {
  578. yhsId = yhShopFrontService.getYhsIdByCustomId(customId);
  579. key = RedisService.key.YH_HOME_PAGHE_CACHE_SHOP.getName() + yhsId + ":homeManage";
  580. }
  581. // List<Long> filter_goodsIds = getFilterGoodsIds();
  582. List<Long> filter_goodsIds = null;
  583. AtomicBoolean isRemoveRg = new AtomicBoolean(false);
  584. // if (isHzIp()) {
  585. // key += ":hz-ip";
  586. // isRemoveRg.set(true);
  587. // }
  588. String lang = request.getHeader("lang");
  589. AtomicBoolean language = new AtomicBoolean(false);
  590. if (lang != null && !StrUtil.equals(UserPageLanguage.Language.zh_CN.name(), lang)) {
  591. key += ":" + lang;
  592. language.set(true);
  593. }
  594. Long fUid = StpUserUtil.getUserIdAfterLogin();
  595. Object o = redisService.get(key);
  596. if (o == null) {
  597. String condition = "g.deleted is true and g.status is true";
  598. if (yhsId != null) {
  599. 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);
  600. }
  601. Map<String, List<HomeManagementFrontView>> map = new ConcurrentHashMap<>();
  602. final String conditionSql = condition;
  603. Stream.of(HomeManagementConfig.Type.values())
  604. .forEach(type -> {
  605. if (isRemoveRg.get() && type == HomeManagementConfig.Type.rg) {
  606. return;
  607. }
  608. MapBuilder builder = MapUtils.builder()
  609. .field(HomeManagementFrontView::getType, type.name());
  610. if (type == HomeManagementConfig.Type.ex || type == HomeManagementConfig.Type.vg) {
  611. builder.put("condition", conditionSql);
  612. if (CollUtil.isNotEmpty(filter_goodsIds)) {
  613. builder.field(HomeManagementFrontView::getGoodsId, filter_goodsIds).op(Operator.NotIn);
  614. }
  615. }
  616. List<HomeManagementFrontView> homeManagementFrontViews = beanSearcher.searchAll(HomeManagementFrontView.class, builder.build());
  617. //实物推荐多语言
  618. if (language.get() && type == HomeManagementConfig.Type.rg) {
  619. backInfoTranslationsFrontService.getHomeConfigRealGoodsLanguage(homeManagementFrontViews, lang);
  620. }
  621. map.putIfAbsent(type.name(), homeManagementFrontViews);
  622. });
  623. redisService.setNx(key, map, 50 * 60l);
  624. o = redisService.get(key);
  625. }
  626. AtomicLong dsUserId = new AtomicLong();
  627. AtomicBoolean existsChannel = new AtomicBoolean(true);
  628. if (StrUtil.isNotBlank(dsCode)) {
  629. UserSharedDto userSharedDto = userService.getUserShredDtoByDsCode(dsCode);
  630. dsUserId.set(userSharedDto.getSharedId());
  631. }
  632. Map<String, List<HomeManagementFrontView>> map = Jsons.parseObject(o, Map.class);
  633. if (map.containsKey(HomeManagementConfig.Type.ex.name()) || map.containsKey(HomeManagementConfig.Type.vg.name())) {
  634. try {
  635. //精彩推荐
  636. List<HomeManagementFrontView> exList = Jsons.parseList(Jsons.toJson(map.get(HomeManagementConfig.Type.ex.name())), HomeManagementFrontView.class);
  637. setHomeConfigGoods(map, HomeManagementConfig.Type.ex, exList, dsUserId, existsChannel, fUid, discount);
  638. //虚拟平台
  639. List<HomeManagementFrontView> vgList = Jsons.parseList(Jsons.toJson(map.get(HomeManagementConfig.Type.vg.name())), HomeManagementFrontView.class);
  640. setHomeConfigGoods(map, HomeManagementConfig.Type.vg, vgList, dsUserId, existsChannel, fUid, discount);
  641. } catch (Exception e) {
  642. }
  643. }
  644. return GatewayResponse.SUCCESS.newBuilder().toResult(map);
  645. }
  646. /**
  647. * 首页点击 记录
  648. */
  649. @PostMapping("/homePage/click")
  650. public Result<String> homeManageClick(@RequestBody ClickRecordReq request) {
  651. Long userId = StpUserUtil.getUserIdAfterLogin();
  652. clickRecordFrontService.click(userId, request);
  653. return GatewayResponse.SUCCESS.newBuilder().toResult();
  654. }
  655. public List<Long> getFilterGoodsIds() {
  656. List<Long> filter_goodsIds = null;
  657. //获取当前ip地址
  658. if (StringUtil.getRealAddressByIP(ServletUtil.getClientIP(request)).contains("杭州")) {
  659. //过滤杭州Ai ChatGPT平台
  660. SysConfig sysConfig = sysConfigMapper.selectOne(Wrappers.lambdaQuery(SysConfig.class)
  661. .eq(SysConfig::getSysKey, Constant.LOCATION_FOR_GOODS_IDS).last("limit 1"));
  662. if (sysConfig != null && StrUtil.isNotBlank(sysConfig.getSysValue())) {
  663. try {
  664. filter_goodsIds = Jsons.parseList(sysConfig.getSysValue(), Long.class);
  665. } catch (Exception e) {
  666. }
  667. }
  668. }
  669. return filter_goodsIds;
  670. }
  671. public Boolean isHzIp() {
  672. if (StringUtil.getRealAddressByIP(ServletUtil.getClientIP(request)).contains("无锡")) {
  673. return true;
  674. }
  675. return false;
  676. }
  677. /**
  678. * @param goodsId
  679. * @param type 1、普通,2、注册平台
  680. * @param yhsId 店铺id
  681. * @return
  682. */
  683. public String getPayMsgTime(Long goodsId, DateTime now, Integer type, Long yhsId) {
  684. Date startTime = null;
  685. StringBuilder notifyMsg = new StringBuilder();
  686. if (type == 1) {
  687. OrderDon orderDon = orderDonMapper.selectOne(Wrappers.lambdaQuery(OrderDon.class)
  688. .eq(OrderDon::getGoodsId, goodsId)
  689. .notIn(OrderDon::getStatus, Constant.noOrderStatus).select(OrderDon::getCreatedTime, OrderDon::getPayTime, OrderDon::getId)
  690. .eq(yhsId != null, OrderDon::getYhsId, yhsId)
  691. .orderByDesc(OrderDon::getId)
  692. .last("limit 1"));
  693. if (orderDon == null) {
  694. notifyMsg.append("点击购买立即上车");
  695. return notifyMsg.toString();
  696. }
  697. startTime = orderDon.getPayTime() != null ? orderDon.getPayTime() : orderDon.getCreatedTime();
  698. } else if (type == 2) {
  699. RegisterOrderDon orderDon = registerOrderDonMapper.selectOne(Wrappers.lambdaQuery(RegisterOrderDon.class)
  700. .eq(RegisterOrderDon::getGoodsId, goodsId)
  701. .notIn(RegisterOrderDon::getStatus, Constant.noOrderStatus).select(RegisterOrderDon::getCreatedTime, RegisterOrderDon::getPayTime, RegisterOrderDon::getId)
  702. .orderByDesc(RegisterOrderDon::getId)
  703. .last("limit 1"));
  704. if (orderDon == null) {
  705. return null;
  706. }
  707. startTime = orderDon.getPayTime() != null ? orderDon.getPayTime() : orderDon.getCreatedTime();
  708. }
  709. long hour = DateUtil.between(startTime, now, DateUnit.HOUR);
  710. if (hour == 0) {
  711. long minute = DateUtil.between(startTime, now, DateUnit.MINUTE);
  712. if (minute == 0) {
  713. notifyMsg.append("1分钟");
  714. } else {
  715. notifyMsg.append(minute);
  716. notifyMsg.append("分钟");
  717. }
  718. } else {
  719. if (hour > 3) {
  720. int hours = RandomUtil.randomInt(3) + 1;
  721. notifyMsg.append(hours);
  722. } else {
  723. notifyMsg.append(hour);
  724. }
  725. notifyMsg.append("小时");
  726. }
  727. notifyMsg.append("前有人购买");
  728. return notifyMsg.toString();
  729. }
  730. /**
  731. * 是否购买过特定平台
  732. */
  733. public Boolean isPaySpecificGoodsIds(String specificGoodsIdsStr, Long userId) {
  734. if (StrUtil.isNotBlank(specificGoodsIdsStr)) {
  735. try {
  736. Set<Long> specificGoodsIds = Jsons.parseSet(specificGoodsIdsStr, Long.class);
  737. Number number = beanSearcher.searchCount(OrderDon.class, MapUtils.builder().field(OrderDon::getGoodsId, specificGoodsIds).op(Operator.InList)
  738. .field(OrderDon::getUserId, userId)
  739. .field(OrderDon::getStatus, Constant.noOrderAllStatus).op(Operator.NotIn)
  740. .build());
  741. if (number.intValue() == 0) {
  742. return false;
  743. }
  744. return true;
  745. } catch (Exception e) {
  746. }
  747. }
  748. return false;
  749. }
  750. /**
  751. * 设置平台 特定价格
  752. */
  753. public void setSpecificPrice(GoodsFrontListView data, Long fUid, Long dsUserId) {
  754. if (fUid != null) {
  755. if (data.getIsSp()) {
  756. //查找所有特定规格最小价格 满足条件
  757. String specificGoodsKey = RedisService.key.YH_HOME_PAGHE_CACHE.getName() + "specific:" + data.getId();
  758. Object speciObj = redisService.get(specificGoodsKey);
  759. List<GoodsDonSku> specificSkus = null;
  760. if (speciObj != null) {
  761. specificSkus = Jsons.parseList(speciObj, GoodsDonSku.class);
  762. } else {
  763. specificSkus = goodsDonSkuMapper.selectList(
  764. Wrappers.lambdaQuery(GoodsDonSku.class)
  765. .eq(GoodsDonSku::getGoodsId, data.getId())
  766. .eq(GoodsDonSku::getStatus, true)
  767. .gt(GoodsDonSku::getSpecificPrice, 0));
  768. redisService.setNx(specificGoodsKey, specificSkus, RedisService.key.YH_HOME_PAGHE_CACHE.getTimeout());
  769. }
  770. specificSkus.forEach(specificSku -> {
  771. if (StrUtil.isNotEmpty(specificSku.getUserOwns()) && (dsUserId == null || !specificSku.getUserOwns().contains(dsUserId.toString()))) {
  772. return;
  773. }
  774. String specificGoodsIdsStr = specificSku.getSpecificGoodsIds();
  775. if (isPaySpecificGoodsIds(specificGoodsIdsStr, fUid)) {
  776. BigDecimal specificPrice = data.getSpecificPrice();
  777. BigDecimal skuSpecificPrice = specificSku.getSpecificPrice();
  778. Long specificSkuId = specificSku.getId();
  779. if (specificPrice == null) {
  780. data.setSpecificPrice(skuSpecificPrice);
  781. data.setSpecificSkuId(specificSkuId);
  782. } else if (specificPrice.compareTo(skuSpecificPrice) > 0) {
  783. data.setSpecificPrice(skuSpecificPrice);
  784. data.setSpecificSkuId(specificSkuId);
  785. }
  786. }
  787. });
  788. List<GoodsDonSkuFrontView> skuList = data.getSkuList();
  789. if (CollUtil.isNotEmpty(skuList)) {
  790. skuList.forEach(sku -> {
  791. //设置特定价格
  792. if (!isPaySpecificGoodsIds(sku.getSpecificGoodsIds(), fUid)) {
  793. sku.setSpecificGoodsIds(null);
  794. sku.setSpecificPrice(null);
  795. }
  796. });
  797. }
  798. }
  799. }
  800. }
  801. /**
  802. * 设置平台 特定价格
  803. */
  804. public void setGcSpecificPrice(GoodsFrontListCategoryView data, Long fUid, Long dsUserId) {
  805. if (fUid != null) {
  806. if (data.getIsSp()) {
  807. //查找所有特定规格最小价格 满足条件
  808. String specificGoodsKey = RedisService.key.YH_HOME_PAGHE_CACHE.getName() + "specific:" + data.getId();
  809. Object speciObj = redisService.get(specificGoodsKey);
  810. List<GoodsDonSku> specificSkus = null;
  811. if (speciObj != null) {
  812. specificSkus = Jsons.parseList(speciObj, GoodsDonSku.class);
  813. } else {
  814. specificSkus = goodsDonSkuMapper.selectList(
  815. Wrappers.lambdaQuery(GoodsDonSku.class)
  816. .eq(GoodsDonSku::getGoodsId, data.getId())
  817. .eq(GoodsDonSku::getStatus, true)
  818. .gt(GoodsDonSku::getSpecificPrice, 0));
  819. redisService.setNx(specificGoodsKey, specificSkus, RedisService.key.YH_HOME_PAGHE_CACHE.getTimeout());
  820. }
  821. specificSkus.forEach(specificSku -> {
  822. if (StrUtil.isNotEmpty(specificSku.getUserOwns()) && (dsUserId == null || !specificSku.getUserOwns().contains(dsUserId.toString()))) {
  823. return;
  824. }
  825. String specificGoodsIdsStr = specificSku.getSpecificGoodsIds();
  826. if (isPaySpecificGoodsIds(specificGoodsIdsStr, fUid)) {
  827. BigDecimal specificPrice = data.getSpecificPrice();
  828. BigDecimal skuSpecificPrice = specificSku.getSpecificPrice();
  829. Long specificSkuId = specificSku.getId();
  830. if (specificPrice == null) {
  831. data.setSpecificPrice(skuSpecificPrice);
  832. data.setSpecificSkuId(specificSkuId);
  833. } else if (specificPrice.compareTo(skuSpecificPrice) > 0) {
  834. data.setSpecificPrice(skuSpecificPrice);
  835. data.setSpecificSkuId(specificSkuId);
  836. }
  837. }
  838. });
  839. List<GoodsDonSkuFrontView> skuList = data.getSkuList();
  840. if (CollUtil.isNotEmpty(skuList)) {
  841. skuList.forEach(sku -> {
  842. //设置特定价格
  843. if (!isPaySpecificGoodsIds(sku.getSpecificGoodsIds(), fUid)) {
  844. sku.setSpecificGoodsIds(null);
  845. sku.setSpecificPrice(null);
  846. }
  847. });
  848. }
  849. }
  850. }
  851. }
  852. /**
  853. * 获取特定规格
  854. */
  855. public List<GoodsDonSku> getSpecificSku(Long goodsId) {
  856. //查找所有特定规格最小价格 满足条件
  857. String specificGoodsKey = RedisService.key.YH_HOME_PAGHE_CACHE.getName() + "specific:" + goodsId;
  858. Object speciObj = redisService.get(specificGoodsKey);
  859. List<GoodsDonSku> specificSkus = null;
  860. if (speciObj != null) {
  861. specificSkus = Jsons.parseList(speciObj, GoodsDonSku.class);
  862. } else {
  863. specificSkus = goodsDonSkuMapper.selectList(
  864. Wrappers.lambdaQuery(GoodsDonSku.class)
  865. .eq(GoodsDonSku::getGoodsId, goodsId)
  866. .eq(GoodsDonSku::getStatus, true)
  867. .gt(GoodsDonSku::getSpecificPrice, 0));
  868. redisService.setNx(specificGoodsKey, specificSkus, RedisService.key.YH_HOME_PAGHE_CACHE.getTimeout());
  869. }
  870. specificSkus = Optional.ofNullable(specificSkus).orElse(new ArrayList<>());
  871. return specificSkus;
  872. }
  873. /**
  874. * 设置首页配置 涉及平台特定价格
  875. */
  876. public void setHomeManageSpecific(List<HomeManagementFrontView> list, Long fUid, Long dsUserId, BigDecimal discount) {
  877. DateTime now = DateTime.now();
  878. String lang = request.getHeader("lang");
  879. list.forEach(data -> {
  880. if (data.getIsSp() != null && data.getIsSp() && fUid != null) {
  881. //查找所有特定规格最小价格 满足条件
  882. List<GoodsDonSku> specificSkus = getSpecificSku(data.getGoodsId());
  883. specificSkus.forEach(specificSku -> {
  884. if (StrUtil.isNotEmpty(specificSku.getUserOwns()) && (dsUserId == null || !specificSku.getUserOwns().contains(dsUserId.toString()))) {
  885. return;
  886. }
  887. String specificGoodsIdsStr = specificSku.getSpecificGoodsIds();
  888. if (isPaySpecificGoodsIds(specificGoodsIdsStr, fUid)) {
  889. BigDecimal specificPrice = data.getSpecificPrice();
  890. BigDecimal skuSpecificPrice = specificSku.getSpecificPrice();
  891. Long specificSkuId = specificSku.getId();
  892. if (specificPrice == null) {
  893. data.setSpecificPrice(skuSpecificPrice);
  894. data.setSpecificSkuId(specificSkuId);
  895. } else if (specificPrice.compareTo(skuSpecificPrice) > 0) {
  896. data.setSpecificPrice(skuSpecificPrice);
  897. data.setSpecificSkuId(specificSkuId);
  898. }
  899. }
  900. });
  901. }
  902. data.setSold(getGoodsSold(data.getGoodsId(), data.getSold()));
  903. data.setNotifyMsg(getPayMsgTime(data.getGoodsId(), now, 1, null));
  904. //设置用户存在优惠券的优惠商品价格
  905. data.setChannelDiscount(discount);
  906. setHomeManageUserCouponGoodsMoney(fUid, data);
  907. });
  908. }
  909. public void setHomeConfigGoods(Map<String, List<HomeManagementFrontView>> map, HomeManagementConfig.Type type, List<HomeManagementFrontView> list, AtomicLong dsUserId, AtomicBoolean existsChannel, Long fUid, BigDecimal discount) throws Exception {
  910. //设置特定价格
  911. List<Long> gptBuyGids = getGptMirrorGiveawayBuyGids();
  912. if (CollUtil.isNotEmpty(list)) {
  913. list = list.stream().filter(data -> {
  914. if (CollUtil.isNotEmpty(gptBuyGids) && gptBuyGids.contains(data.getGoodsId())) {
  915. data.setIsGptGift(true);
  916. }
  917. if (data.getIsOwns()) {
  918. if (dsUserId.get() == 0 && fUid != null && existsChannel.get()) {
  919. Long sharedId = userService.getSharedIdByUserId(fUid);
  920. if (sharedId == 0) {
  921. existsChannel.set(false);
  922. }
  923. dsUserId.set(sharedId);
  924. }
  925. GoodsDonSku minPriceUserOwnsSku = goodsDonSkuMapper.checkAndReturnMinPriceUserOwnsSku(data.getGoodsId(), dsUserId.get());
  926. if (minPriceUserOwnsSku == null) {
  927. return false;
  928. }
  929. data.setPrice(minPriceUserOwnsSku.getPrice());
  930. data.setMonths(minPriceUserOwnsSku.getMonths());
  931. data.setDays(minPriceUserOwnsSku.getDays());
  932. }
  933. //未登录
  934. if (fUid == null) {
  935. //推荐优惠券商品最低折扣
  936. setHomeConfigGoodsCouponMoney(data);
  937. }
  938. return true;
  939. }).collect(Collectors.toList());
  940. setHomeManageSpecific(list, fUid, dsUserId.get(), discount);
  941. map.put(type.name(), list);
  942. }
  943. }
  944. /**
  945. * 店铺平台列表
  946. */
  947. @GetMapping("/get/shop/goods/{yhsId}")
  948. public Result<List<YhShopGoodsFrontView>> getShopGoods(@PathVariable Long yhsId) {
  949. String yhShopCacheKey = RedisService.key.YH_HOME_PAGHE_CACHE_SHOP.getName() + yhsId;
  950. Object value = redisService.get(yhShopCacheKey);
  951. List<YhShopGoodsFrontView> list = null;
  952. if (value != null) {
  953. try {
  954. list = Jsons.parseList(value, YhShopGoodsFrontView.class);
  955. } catch (Exception e) {
  956. }
  957. }
  958. if (CollUtil.isEmpty(list)) {
  959. MapBuilder builder = MapUtils.flatBuilder(request.getParameterMap());
  960. builder.put("condition", String.format("and yhs_id = %s", yhsId));
  961. list = beanSearcher.searchAll(YhShopGoodsFrontView.class, builder.build());
  962. redisService.setNx(yhShopCacheKey, list, RedisService.key.YH_HOME_PAGHE_CACHE_SHOP.getTimeout());
  963. }
  964. DateTime now = DateTime.now();
  965. list.forEach(data -> {
  966. data.setSold(getGoodsSold(data.getId(), data.getSold()));
  967. data.setNotifyMsg(getPayMsgTime(data.getId(), now, 1, yhsId));
  968. Optional.ofNullable(yhShopGoodsSkuMapper.selectOne(Wrappers.lambdaQuery(YhShopGoodsSku.class)
  969. .eq(YhShopGoodsSku::getYhsId, yhsId)
  970. .eq(YhShopGoodsSku::getGoodsId, data.getId())
  971. .eq(YhShopGoodsSku::getPrice, data.getPrice())
  972. .eq(YhShopGoodsSku::getStatus, 1)
  973. .eq(YhShopGoodsSku::getDeleted, 1)
  974. .last("limit 1"))).ifPresent(yhSku -> {
  975. GoodsDonSku sku = goodsDonSkuMapper.selectById(yhSku.getSkuId());
  976. if (sku != null) {
  977. data.setMonths(sku.getMonths());
  978. data.setDays(sku.getDays());
  979. }
  980. });
  981. });
  982. return GatewayResponse.SUCCESS.newBuilder().toResult(list);
  983. }
  984. /**
  985. * 店铺平台详情
  986. */
  987. @GetMapping("/get/shop/goods/detail/{yhsId}/{goodsId}")
  988. public Result<YhShopGoodsFrontView> getGoodsDetailByYhsId(@PathVariable Long yhsId, @PathVariable Long goodsId) {
  989. String yhShopDetailCacheKey = RedisService.key.YH_HOME_PAGHE_CACHE_SHOP.getName() + yhsId + ":goodsId:" + goodsId;
  990. Object value = redisService.get(yhShopDetailCacheKey);
  991. if (value == null) {
  992. MapBuilder builder = MapUtils.flatBuilder(request.getParameterMap());
  993. String condition = String.format("and yhs_id = %s and ys.goods_id = %s", yhsId, goodsId);
  994. builder.put("condition", condition);
  995. YhShopGoodsFrontView goodsDetailView = beanSearcher.searchFirst(YhShopGoodsFrontView.class, builder.build());
  996. if (goodsDetailView == null) {
  997. throw BusinessRuntimeException.getInstance("该平台不存在或已下架,请刷新页面");
  998. }
  999. goodsDetailView.setSkuList(beanSearcher.searchAll(YhShopGoodsSkuFrontView.class, MapUtils.builder().put("condition", condition).orderBy(YhShopGoodsSkuFrontView::getSorted).asc().build()));
  1000. goodsDetailView.setSpecs(beanSearcher.searchFirst(GoodsDonSpecFrontView.class, MapUtils.builder().field(GoodsDonSpecFrontView::getGoodsId, goodsDetailView.getId()).build()));
  1001. OrderCommentFrontView comments = beanSearcher.searchFirst(OrderCommentFrontView.class, MapUtils.builder()
  1002. .field(OrderCommentFrontView::getGoodsId, goodsDetailView.getId())
  1003. .orderBy(OrderCommentFrontView::getCommentTime).desc()
  1004. .orderBy(OrderCommentFrontView::getId).desc()
  1005. .build());
  1006. goodsDetailView.setComments(comments);
  1007. redisService.setNx(yhShopDetailCacheKey, goodsDetailView, RedisService.key.YH_HOME_PAGHE_CACHE_SHOP.getTimeout() + RandomUtil.randomInt(1000));
  1008. value = redisService.get(yhShopDetailCacheKey);
  1009. }
  1010. YhShopGoodsFrontView goodsDetailView = Jsons.parseObject(value, YhShopGoodsFrontView.class);
  1011. return GatewayResponse.SUCCESS.newBuilder().toResult(goodsDetailView);
  1012. }
  1013. /**
  1014. * 根据分类获取对应平台
  1015. */
  1016. @GetMapping("/get/categoryGoods")
  1017. public Result<? extends Object> getGoodsByCategory(Long cgy, String customId, String dsCode, BigDecimal discount) {
  1018. if (StrUtil.isNotBlank(customId)) {
  1019. Result<List<YhShopGoodsFrontCategoryView>> shopGoods = getShopCategoryGoods(yhShopFrontService.getYhsIdByCustomId(customId), cgy);
  1020. return shopGoods;
  1021. }
  1022. Long fUid = StpUserUtil.getUserIdAfterLogin();
  1023. String categoryGoodsKey = RedisService.key.YH_HOME_PAGHE_CACHE.getName() + "category:goods";
  1024. if (cgy != null) {
  1025. categoryGoodsKey += ":" + cgy;
  1026. }
  1027. //List<Long> filter_goodsIds = getFilterGoodsIds();
  1028. List<Long> filter_goodsIds = null;
  1029. if (CollUtil.isNotEmpty(filter_goodsIds)) {
  1030. categoryGoodsKey += ":hz-ip";
  1031. }
  1032. String lang = request.getHeader("lang");
  1033. AtomicBoolean language = new AtomicBoolean(false);
  1034. if (lang != null && UserPageLanguage.Language.en_US.name().equals(lang)) {
  1035. categoryGoodsKey += ":" + lang;
  1036. language.set(true);
  1037. }
  1038. Object o = redisService.get(categoryGoodsKey);
  1039. if (o == null) {
  1040. DateTime now = DateTime.now();
  1041. MapBuilder mapBuilder = MapUtils.flatBuilder(request.getParameterMap());
  1042. if (cgy != null) {
  1043. String condition = String.format(" and gcr.category = %s", cgy);
  1044. mapBuilder.put("condition", condition);
  1045. }
  1046. if (CollUtil.isNotEmpty(filter_goodsIds)) {
  1047. mapBuilder.field(GoodsFrontListCategoryView::getId, filter_goodsIds).op(Operator.NotIn);
  1048. }
  1049. List<GoodsFrontListCategoryView> goodsFrontListViews = beanSearcher.searchAll(GoodsFrontListCategoryView.class, mapBuilder.build());
  1050. List<Long> gptBuyGids = getGptMirrorGiveawayBuyGids();
  1051. goodsFrontListViews.forEach(data -> {
  1052. data.setSold(getGoodsSold(data.getId(), data.getSold()));
  1053. data.setNotifyMsg(getPayMsgTime(data.getId(), now, 1, null));
  1054. if (CollUtil.isNotEmpty(gptBuyGids) && gptBuyGids.contains(data.getId())) {
  1055. data.setIsGptGift(true);
  1056. }
  1057. if (language.get()) {
  1058. //多语言
  1059. backInfoTranslationsFrontService.setCategoryGoodsLanguage(data, lang);
  1060. }
  1061. });
  1062. redisService.setNx(categoryGoodsKey, goodsFrontListViews, RedisService.key.YH_HOME_PAGHE_CACHE.getTimeout() + 10 * 60);
  1063. o = redisService.get(categoryGoodsKey);
  1064. }
  1065. List<GoodsFrontListCategoryView> goodsFrontListViews = Jsons.parseList(o, GoodsFrontListCategoryView.class);
  1066. AtomicLong dsUserId = new AtomicLong();
  1067. AtomicBoolean existsChannel = new AtomicBoolean(true);
  1068. if (StrUtil.isNotBlank(dsCode)) {
  1069. UserSharedDto userSharedDto = userService.getUserShredDtoByDsCode(dsCode);
  1070. dsUserId.set(userSharedDto.getSharedId());
  1071. }
  1072. AtomicBoolean filterCourseGoods = new AtomicBoolean(false);
  1073. //增值服务分类
  1074. if (fUid != null && cgy != null && (cgy == 3 || cgy == 4)) {
  1075. //GPT Plus基础2月 课程不展示
  1076. List<Long> userIdList = userBindRelationService.getRelationUserIdList(fUid, null);
  1077. Integer orders = orderDonMapper.selectCount(Wrappers.lambdaQuery(OrderDon.class)
  1078. .in(OrderDon::getUserId, userIdList)
  1079. .eq(OrderDon::getSkuId, 444)
  1080. .notIn(OrderDon::getStatus, Constant.noOrderStatus));
  1081. if (orders > 0) {
  1082. filterCourseGoods.set(true);
  1083. }
  1084. }
  1085. goodsFrontListViews = goodsFrontListViews.stream().filter(data -> {
  1086. if (data.getIsOwns()) {
  1087. if (dsUserId.get() == 0 && fUid != null && existsChannel.get()) {
  1088. Long sharedId = userService.getSharedIdByUserId(fUid);
  1089. if (sharedId == 0) {
  1090. existsChannel.set(false);
  1091. }
  1092. dsUserId.set(sharedId);
  1093. }
  1094. GoodsDonSku minPriceUserOwnsSku = goodsDonSkuMapper.checkAndReturnMinPriceUserOwnsSku(data.getId(), dsUserId.get());
  1095. if (minPriceUserOwnsSku == null) {
  1096. return false;
  1097. }
  1098. data.setPrice(minPriceUserOwnsSku.getPrice());
  1099. data.setMonths(minPriceUserOwnsSku.getMonths());
  1100. data.setDays(minPriceUserOwnsSku.getDays());
  1101. }
  1102. //课件类型 且过滤
  1103. if (filterCourseGoods.get() && data.getSpecialType() != null && data.getSpecialType() == GoodsDon.SpecialType.courseware) {
  1104. return false;
  1105. }
  1106. //设置特定价格
  1107. setGcSpecificPrice(data, fUid, dsUserId.get());
  1108. //设置用户存在优惠券的优惠商品价格
  1109. data.setChannelDiscount(discount);
  1110. //商品优惠折扣
  1111. setUserCouponGoodsMoney(fUid, data);
  1112. //未登录
  1113. if (fUid == null) {
  1114. //推荐优惠券商品最低折扣
  1115. setGoodsCouponMoney(data);
  1116. }
  1117. return true;
  1118. }).collect(Collectors.toList());
  1119. return GatewayResponse.SUCCESS.newBuilder().toResult(goodsFrontListViews);
  1120. }
  1121. @GetMapping("/get/shop/categoryGoods/{yhsId}")
  1122. public Result<List<YhShopGoodsFrontCategoryView>> getShopCategoryGoods(@PathVariable Long yhsId, Long category) {
  1123. String categoryGoodsKey = RedisService.key.YH_HOME_PAGHE_CACHE_SHOP.getName() + yhsId + ":category";
  1124. if (category != null) {
  1125. categoryGoodsKey += ":" + category;
  1126. }
  1127. Object value = redisService.get(categoryGoodsKey);
  1128. if (value == null) {
  1129. DateTime now = DateTime.now();
  1130. MapBuilder builder = MapUtils.flatBuilder(request.getParameterMap());
  1131. builder.put("yhsId", String.format(" and yhs_id = %s", yhsId));
  1132. String condition = StrUtil.EMPTY;
  1133. if (category != null) {
  1134. condition += String.format(" and gcr.category = %s", category);
  1135. }
  1136. builder.put("condition", condition);
  1137. List<YhShopGoodsFrontCategoryView> list = beanSearcher.searchAll(YhShopGoodsFrontCategoryView.class, builder.build());
  1138. list.forEach(data->{
  1139. data.setSold(getGoodsSold(data.getId(), data.getSold()));
  1140. data.setNotifyMsg(getPayMsgTime(data.getId(), now, 1, yhsId));
  1141. //重新设置最低价格规格
  1142. YhShopGoodsSku sku = yhShopGoodsSkuMapper.selectMinPriceSkuByYhsId(yhsId, data.getId());
  1143. data.setPrice(sku.getPrice());
  1144. data.setSkuId(sku.getSkuId());
  1145. });
  1146. redisService.setNx(categoryGoodsKey, list, RedisService.key.YH_HOME_PAGHE_CACHE.getTimeout() + 5 * 60);
  1147. value = redisService.get(categoryGoodsKey);
  1148. }
  1149. List<YhShopGoodsFrontCategoryView> list = Jsons.parseList(value, YhShopGoodsFrontCategoryView.class);
  1150. list.forEach(data->{
  1151. Optional.ofNullable(yhShopGoodsSkuMapper.selectOne(Wrappers.lambdaQuery(YhShopGoodsSku.class)
  1152. .eq(YhShopGoodsSku::getYhsId, yhsId)
  1153. .eq(YhShopGoodsSku::getGoodsId, data.getId())
  1154. .eq(YhShopGoodsSku::getPrice, data.getPrice())
  1155. .eq(YhShopGoodsSku::getStatus, 1)
  1156. .eq(YhShopGoodsSku::getDeleted, 1)
  1157. .last("limit 1"))).ifPresent(yhSku -> {
  1158. GoodsDonSku sku = goodsDonSkuMapper.selectById(yhSku.getSkuId());
  1159. if (sku != null) {
  1160. data.setMonths(sku.getMonths());
  1161. data.setDays(sku.getDays());
  1162. }
  1163. });
  1164. });
  1165. return GatewayResponse.SUCCESS.newBuilder().toResult(list);
  1166. }
  1167. /**
  1168. * 获取设备活动详情
  1169. */
  1170. @GetMapping("/get/equipment/activity")
  1171. public Result<EquipmentActivityReduce> getEpActivity() {
  1172. DateTime now = DateTime.now();
  1173. EquipmentActivityReduce equipmentActivityReduce = beanSearcher.searchFirst(EquipmentActivityReduce.class, MapUtils.builder()
  1174. .field(EquipmentActivityReduce::getSt, now).op(Operator.LessEqual)
  1175. .field(EquipmentActivityReduce::getEt, now).op(Operator.GreaterThan)
  1176. .field(EquipmentActivityReduce::getDeleted, 1)
  1177. .onlySelect(EquipmentActivityReduce::getF, EquipmentActivityReduce::getQ, EquipmentActivityReduce::getTq, EquipmentActivityReduce::getSt, EquipmentActivityReduce::getEt)
  1178. .build());
  1179. return GatewayResponse.SUCCESS.newBuilder().toResult(equipmentActivityReduce);
  1180. }
  1181. /**
  1182. * 获取租赁商品列表
  1183. */
  1184. @GetMapping("/get/deposit")
  1185. public Result<? extends Object> getDepositGoods() {
  1186. String depositGoodsKey = RedisService.key.YH_HOME_PAGHE_CACHE.getName() + "deposit";
  1187. Object o = redisService.get(depositGoodsKey);
  1188. if (o == null) {
  1189. List<GoodsDon> depositList = beanSearcher.searchAll(GoodsDon.class, MapUtils.builder()
  1190. .field(GoodsDon::getType, 4)
  1191. .field(GoodsDon::getStatus, true)
  1192. .field(GoodsDon::getDeleted, true)
  1193. .onlySelect(GoodsDon::getId, GoodsDon::getTitle, GoodsDon::getLogo)
  1194. .build());
  1195. if (CollUtil.isEmpty(depositList)) {
  1196. return GatewayResponse.SUCCESS.newBuilder().toResult();
  1197. }
  1198. redisService.setNx(depositGoodsKey, depositList, RedisService.key.YH_HOME_PAGHE_CACHE.getTimeout() + 60 * RandomUtil.randomInt(10));
  1199. o = redisService.get(depositGoodsKey);
  1200. }
  1201. List<GoodsDon> depositList = Jsons.parseList(o, GoodsDon.class);
  1202. return GatewayResponse.SUCCESS.newBuilder().toResult(depositList);
  1203. }
  1204. /**
  1205. * 获取pc广告配置
  1206. */
  1207. @GetMapping("/get/pc/homeManage")
  1208. public Result<Map<String, List<HomeManagementFrontView>>> getPcHomeManagementFrontPage() {
  1209. String key = RedisService.key.YH_HOME_PAGHE_CACHE.getName() + "pc:homeManage";
  1210. //移除奈飞客厅 临时
  1211. Long filterConfigId = null;
  1212. // if (isHzIp()) {
  1213. // key += ":hz_ip";
  1214. // filterConfigId = 55l;
  1215. // }
  1216. Object o = redisService.get(key);
  1217. if (o == null) {
  1218. MapBuilder builder = MapUtils.builder()
  1219. .field(HomeManagementFrontView::getAdType, List.of(HomeManagementConfig.AdType.pc.name(), HomeManagementConfig.AdType.pcBanner.name(), HomeManagementConfig.AdType.pcSec.name(), HomeManagementConfig.AdType.pcDis.name())).op(Operator.InList);
  1220. if (filterConfigId != null) {
  1221. builder.field(HomeManagementFrontView::getHomeManageConfigId, filterConfigId).op(Operator.NotEqual);
  1222. }
  1223. List<HomeManagementFrontView> homeManagementFrontViews = beanSearcher.searchAll(HomeManagementFrontView.class, builder.build());
  1224. Map<HomeManagementConfig.AdType, List<HomeManagementFrontView>> map = homeManagementFrontViews.stream().collect(Collectors.groupingBy(HomeManagementFrontView::getAdType));
  1225. redisService.setNx(key, map, 50 * 60l);
  1226. o = redisService.get(key);
  1227. }
  1228. Map<String, List<HomeManagementFrontView>> map = Jsons.parseObject(o, Map.class);
  1229. return GatewayResponse.SUCCESS.newBuilder().toResult(map);
  1230. }
  1231. /**
  1232. * 获取pc实物配置
  1233. */
  1234. @GetMapping("/get/pc/realGoodsConfig")
  1235. public Result<? extends Object> getPcRealGoodsConfig() throws Exception {
  1236. String key = RedisService.key.YH_HOME_PAGHE_CACHE.getName() + "pc:realHomePage";
  1237. Object o = redisService.get(key);
  1238. List<HomeManagementFrontView> list = null;
  1239. if (o == null) {
  1240. list = goodsDonFrontService.getRealGoodsConfig();
  1241. redisService.setNx(key, list, RedisService.key.YH_HOME_PAGHE_CACHE.getTimeout() + 300);
  1242. }
  1243. if (list == null && o != null) {
  1244. list = Jsons.parseList(o, HomeManagementFrontView.class);
  1245. }
  1246. return GatewayResponse.SUCCESS.newBuilder().toResult(list);
  1247. }
  1248. /**
  1249. * 百亿补贴
  1250. * 补贴规格列表
  1251. */
  1252. @GetMapping("/get/subsidy")
  1253. public Result<List<GoodsDonSkuSubsidyFrontView>> getSubsidyGoods() {
  1254. String key = RedisService.key.YH_HOME_PAGHE_CACHE.getName() + "subsidy";
  1255. Object o = redisService.get(key);
  1256. if (o == null) {
  1257. List<GoodsDonSkuSubsidyFrontView> subsidyList = beanSearcher.searchAll(GoodsDonSkuSubsidyFrontView.class, MapUtils.builder().build());
  1258. subsidyList.forEach(e -> {
  1259. Optional.ofNullable(beanSearcher.searchFirst(GoodsDonSkuSubsidyDetailView.class, MapUtils.builder().field(GoodsDonSkuSubsidyDetailView::getGoodsId, e.getId()).field(GoodsDonSkuSubsidyDetailView::getPrice, e.getPrice()).build())).ifPresent(sku -> {
  1260. e.setOriPrice(sku.getOriPrice());
  1261. e.setMonths(sku.getMonths());
  1262. e.setDays(sku.getDays());
  1263. e.setSkuId(sku.getId());
  1264. e.setPicture(sku.getSubsidyPicture());
  1265. });
  1266. });
  1267. redisService.setNx(key, subsidyList, RedisService.key.YH_HOME_PAGHE_CACHE.getTimeout() + 60 * RandomUtil.randomInt(10));
  1268. o = redisService.get(key);
  1269. }
  1270. List<GoodsDonSkuSubsidyFrontView> subsidyList = Jsons.parseList(o, GoodsDonSkuSubsidyFrontView.class);
  1271. if (CollUtil.isEmpty(subsidyList)) {
  1272. return GatewayResponse.SUCCESS.newBuilder().toResult(subsidyList);
  1273. }
  1274. Long userId = StpUserUtil.getUserIdAfterLogin();
  1275. if (userId != null) {
  1276. List<Long> relationUserIdList = userBindRelationService.getRelationUserIdList(userId, null);
  1277. //过滤用户已经购买过平台
  1278. List<Long> goodsIds = orderDonMapper.getPayGoodsIds(relationUserIdList);
  1279. if (CollUtil.isNotEmpty(goodsIds)) {
  1280. subsidyList = subsidyList.stream().filter(data -> !goodsIds.contains(data.getId())).collect(Collectors.toList());
  1281. }
  1282. }
  1283. return GatewayResponse.SUCCESS.newBuilder().toResult(subsidyList);
  1284. }
  1285. /**
  1286. * 百亿补贴规格详情
  1287. */
  1288. @GetMapping("/get/subsidy/detail/{id}")
  1289. public Result<GoodsDonSubsidyDetailView> getSubsidyDetailById(@PathVariable Long id) throws Exception {
  1290. String goodsDetailKey = RedisService.key.YH_HOME_PAGHE_CACHE.getName() + "subsidy:detail:" + id;
  1291. Object o = redisService.get(goodsDetailKey);
  1292. GoodsDonSubsidyDetailView subsidyDetail = null;
  1293. if (o == null) {
  1294. subsidyDetail = beanSearcher.searchFirst(GoodsDonSubsidyDetailView.class, MapUtils.builder().field(GoodsDonSubsidyDetailView::getId, id).build());
  1295. if (subsidyDetail == null) {
  1296. return GatewayResponse.SUCCESS.newBuilder().toResult();
  1297. }
  1298. subsidyDetail.setSpecs(beanSearcher.searchFirst(GoodsDonSpecFrontView.class, MapUtils.builder().field(GoodsDonSpecFrontView::getGoodsId, subsidyDetail.getId()).build()));
  1299. MapBuilder builder = MapUtils.builder().field(GoodsDonSkuSubsidyDetailView::getGoodsId, subsidyDetail.getId());
  1300. subsidyDetail.setSkuList(beanSearcher.searchAll(GoodsDonSkuSubsidyDetailView.class, builder.build()));
  1301. subsidyDetail.setSold(getGoodsSold(subsidyDetail.getId(), subsidyDetail.getSold()));
  1302. redisService.setNx(goodsDetailKey, Jsons.toJson(subsidyDetail), RedisService.key.YH_HOME_PAGHE_CACHE.getTimeout() + 60 * RandomUtil.randomInt(10));
  1303. }
  1304. if (subsidyDetail == null) {
  1305. o = redisService.get(goodsDetailKey);
  1306. subsidyDetail = Jsons.parseObject(o.toString(), GoodsDonSubsidyDetailView.class);
  1307. }
  1308. return GatewayResponse.SUCCESS.newBuilder().toResult(subsidyDetail);
  1309. }
  1310. /**
  1311. * 可选百亿补贴规格列表
  1312. */
  1313. @GetMapping("/get/available/subsidy/sku/{goodsId}")
  1314. public Result<List<GoodsDonSkuSubsidyAvailableView>> getAvailableSubsidySku(@PathVariable Long goodsId) {
  1315. String key = RedisService.key.YH_HOME_PAGHE_CACHE.getName() + "subsidy:" + goodsId;
  1316. Object o = redisService.get(key);
  1317. if (o == null) {
  1318. List<GoodsDonSkuSubsidyAvailableView> goodsDonSkuSubsidyAvailableViews = beanSearcher.searchAll(GoodsDonSkuSubsidyAvailableView.class, MapUtils.builder().put("gid", String.format(" and goods_id = %s", goodsId)).build());
  1319. if (CollUtil.isEmpty(goodsDonSkuSubsidyAvailableViews)) {
  1320. return GatewayResponse.SUCCESS.newBuilder().toResult();
  1321. }
  1322. redisService.set(key, goodsDonSkuSubsidyAvailableViews, RedisService.key.YH_HOME_PAGHE_CACHE.getTimeout() + RandomUtil.randomInt(10000));
  1323. o = redisService.get(key);
  1324. }
  1325. List<GoodsDonSkuSubsidyAvailableView> goodsDonSkuSubsidyAvailableViews = Jsons.parseList(o, GoodsDonSkuSubsidyAvailableView.class);
  1326. return GatewayResponse.SUCCESS.newBuilder().toResult(goodsDonSkuSubsidyAvailableViews);
  1327. }
  1328. /**
  1329. * 获取用户店铺首页配置列表
  1330. */
  1331. @GetMapping("/get/shop/homeManage")
  1332. public Result<Map<String, List<HomeManagementFrontView>>> getShopHomeManageConfig(String customId) {
  1333. //是否同意展示对应首页广告位
  1334. String key = RedisService.key.YH_HOME_PAGHE_CACHE_SHOP.getName() + customId + ":homeManage";
  1335. Object o = redisService.get(key);
  1336. if (o == null) {
  1337. MapBuilder builder = MapUtils.builder()
  1338. .field(HomeManagementFrontView::getType, HomeManagementConfig.Type.ad.name())
  1339. .field(HomeManagementFrontView::getIsShop, 1);
  1340. List<HomeManagementFrontView> homeManagementFrontViews = beanSearcher.searchAll(HomeManagementFrontView.class, builder.build());
  1341. if (homeManagementFrontViews == null) {
  1342. return GatewayResponse.SUCCESS.newBuilder().toResult();
  1343. }
  1344. Map<String, List<HomeManagementFrontView>> map = new ConcurrentHashMap<>();
  1345. map.putIfAbsent(HomeManagementConfig.Type.ad.name(), homeManagementFrontViews);
  1346. redisService.setNx(key, map, 50 * 60l);
  1347. o = redisService.get(key);
  1348. }
  1349. Map map = Jsons.parseObject(o, Map.class);
  1350. return GatewayResponse.SUCCESS.newBuilder().toResult(map);
  1351. }
  1352. /**
  1353. * 获取套餐列表
  1354. */
  1355. @GetMapping("/get/upgradePackage")
  1356. public Result<SearchResult<UpgradePackageView>> list(Long skuId) {
  1357. long userId = StpUserUtil.getLoginIdAsLong();
  1358. log.info("userId:{}获取套餐列表", userId);
  1359. Map<String, Object> build = MapUtils.flatBuilder(request.getParameterMap()).build();
  1360. if (skuId != null) {
  1361. build.put("sku", String.format(" and JSON_CONTAINS(up.sku_ids,'\"%s\"')", skuId));
  1362. }
  1363. SearchResult<UpgradePackageView> search = beanSearcher.search(UpgradePackageView.class, build);
  1364. return GatewayResponse.SUCCESS.newBuilder().toResult(search);
  1365. }
  1366. /**
  1367. * 获取所有平台列表
  1368. */
  1369. @GetMapping("/get/goods")
  1370. public Result<List<GoodsDon>> getAllGoodsList() {
  1371. List<GoodsDon> goodsDons = beanSearcher.searchAll(GoodsDon.class, MapUtils.flatBuilder(request.getParameterMap()).field(GoodsDon::getStatus, 1)
  1372. .onlySelect(GoodsDon::getId, GoodsDon::getTitle)
  1373. .build());
  1374. return GatewayResponse.SUCCESS.newBuilder().toResult(goodsDons);
  1375. }
  1376. /**
  1377. * 获取平台销量
  1378. * @param goodsId
  1379. * @param virtualSold
  1380. * @return
  1381. */
  1382. private Integer getGoodsSold(Long goodsId, Integer virtualSold) {
  1383. Object soldObj = redisService.get(RedisService.key.YH_HOME_PAGHE_CACHE.getName() + "sold:" + goodsId);
  1384. if (soldObj == null) {
  1385. Integer sold = orderDonMapper.selectCount(Wrappers.lambdaQuery(OrderDon.class)
  1386. .eq(OrderDon::getGoodsId, goodsId).notIn(OrderDon::getStatus, Constant.noOrderStatus));
  1387. soldObj = sold + virtualSold;
  1388. redisService.set(RedisService.key.YH_HOME_PAGHE_CACHE.getName() + "sold:" + goodsId, soldObj, RedisService.key.YH_HOME_PAGHE_CACHE.getTimeout());
  1389. }
  1390. return Integer.parseInt(soldObj.toString());
  1391. }
  1392. /**
  1393. * 设置平台优惠价格
  1394. */
  1395. private void setUserCouponGoodsMoney(Long userId, GoodsFrontListCategoryView data) {
  1396. //登录后
  1397. if (userId != null) {
  1398. //特定价格
  1399. BigDecimal specificPrice = data.getSpecificPrice();
  1400. //渠道折扣
  1401. BigDecimal channelDiscount = data.getChannelDiscount();
  1402. //支付来源
  1403. Integer source = 0;
  1404. BigDecimal presentCouponMoney = null;
  1405. //寻找对应最低规格的优惠券
  1406. Coupon coupon = couponUserMapper.selectUserCouponByGidAndPrice(userId, data.getId(), data.getPrice());
  1407. if (coupon != null) {
  1408. source = 1;
  1409. data.setDiscount(coupon.getDiscount());
  1410. data.setReduceMoney(coupon.getReduceMoney());
  1411. data.setDiscountPrice(data.getPrice().subtract(coupon.getCouponMoney()));
  1412. data.setValidEndTime(coupon.getValidEndTime());
  1413. data.setCouponId(coupon.getId());
  1414. presentCouponMoney = data.getDiscountPrice();
  1415. }
  1416. if (channelDiscount != null) {
  1417. BigDecimal channelCouponMoney = data.getPrice().multiply(channelDiscount);
  1418. if (presentCouponMoney == null) {
  1419. presentCouponMoney = channelCouponMoney;
  1420. }
  1421. if (channelCouponMoney.compareTo(presentCouponMoney) <= 0) {
  1422. source = 2;
  1423. presentCouponMoney = channelCouponMoney;
  1424. data.setDiscount(channelDiscount);
  1425. data.setReduceMoney(null);
  1426. data.setDiscountPrice(channelCouponMoney);
  1427. data.setValidEndTime(null);
  1428. data.setCouponId(null);
  1429. }
  1430. }
  1431. if (specificPrice != null && specificPrice.compareTo(BigDecimal.ZERO) > 0) {
  1432. if (presentCouponMoney == null) {
  1433. presentCouponMoney = specificPrice;
  1434. }
  1435. if (specificPrice.compareTo(presentCouponMoney) <= 0) {
  1436. source = 3;
  1437. data.setDiscount(null);
  1438. data.setReduceMoney(null);
  1439. data.setDiscountPrice(specificPrice);
  1440. data.setValidEndTime(null);
  1441. data.setCouponId(null);
  1442. }
  1443. }
  1444. data.setSource(source);
  1445. }
  1446. }
  1447. /**
  1448. * 设置平台规格优惠价格
  1449. */
  1450. private void setUserCouponSkuMoney(Long userId, GoodsDonSkuFrontView sku) {
  1451. //登录后
  1452. if (userId != null) {
  1453. //特定价格
  1454. BigDecimal specificPrice = sku.getSpecificPrice();
  1455. //渠道折扣
  1456. BigDecimal channelDiscount = sku.getChannelDiscount();
  1457. //支付来源
  1458. Integer source = 0;
  1459. BigDecimal presentCouponMoney = null;
  1460. //寻找对应最低规格的优惠券
  1461. Coupon coupon = couponUserMapper.selectUserCouponBySkuId(userId, sku.getId());
  1462. if (coupon != null) {
  1463. source = 1;
  1464. sku.setDiscount(coupon.getDiscount());
  1465. sku.setReduceMoney(coupon.getReduceMoney());
  1466. sku.setDiscountPrice(sku.getPrice().subtract(coupon.getCouponMoney()));
  1467. sku.setValidEndTime(coupon.getValidEndTime());
  1468. sku.setCouponId(coupon.getId());
  1469. presentCouponMoney = sku.getDiscountPrice();
  1470. }
  1471. if (channelDiscount != null) {
  1472. BigDecimal channelCouponMoney = sku.getPrice().multiply(channelDiscount);
  1473. if (presentCouponMoney == null) {
  1474. presentCouponMoney = channelCouponMoney;
  1475. }
  1476. if (channelCouponMoney.compareTo(presentCouponMoney) <= 0) {
  1477. source = 2;
  1478. presentCouponMoney = channelCouponMoney;
  1479. sku.setDiscount(channelDiscount);
  1480. sku.setReduceMoney(null);
  1481. sku.setDiscountPrice(channelCouponMoney);
  1482. sku.setValidEndTime(null);
  1483. sku.setCouponId(null);
  1484. }
  1485. }
  1486. if (specificPrice != null && specificPrice.compareTo(BigDecimal.ZERO) > 0) {
  1487. if (presentCouponMoney == null) {
  1488. presentCouponMoney = specificPrice;
  1489. }
  1490. if (specificPrice.compareTo(presentCouponMoney) <= 0) {
  1491. source = 3;
  1492. sku.setDiscount(null);
  1493. sku.setReduceMoney(null);
  1494. sku.setDiscountPrice(specificPrice);
  1495. sku.setValidEndTime(null);
  1496. sku.setCouponId(null);
  1497. }
  1498. }
  1499. sku.setSource(source);
  1500. }
  1501. }
  1502. /**
  1503. * 设置推荐平台优惠价格
  1504. */
  1505. private void setHomeManageUserCouponGoodsMoney(Long userId, HomeManagementFrontView data) {
  1506. //登录后
  1507. if (userId != null) {
  1508. //特定价格
  1509. BigDecimal specificPrice = data.getSpecificPrice();
  1510. //渠道折扣
  1511. BigDecimal channelDiscount = data.getChannelDiscount();
  1512. //支付来源
  1513. Integer source = 0;
  1514. BigDecimal presentCouponMoney = null;
  1515. //寻找对应最低规格的优惠券
  1516. Coupon coupon = couponUserMapper.selectUserCouponByGidAndPrice(userId, data.getGoodsId(), data.getPrice());
  1517. if (coupon != null) {
  1518. source = 1;
  1519. data.setDiscount(coupon.getDiscount());
  1520. data.setReduceMoney(coupon.getReduceMoney());
  1521. data.setDiscountPrice(data.getPrice().subtract(coupon.getCouponMoney()));
  1522. data.setValidEndTime(coupon.getValidEndTime());
  1523. data.setCouponId(coupon.getId());
  1524. presentCouponMoney = data.getDiscountPrice();
  1525. }
  1526. if (channelDiscount != null) {
  1527. BigDecimal channelCouponMoney = data.getPrice().multiply(channelDiscount);
  1528. if (presentCouponMoney == null) {
  1529. presentCouponMoney = channelCouponMoney;
  1530. }
  1531. if (channelCouponMoney.compareTo(presentCouponMoney) <= 0) {
  1532. source = 2;
  1533. presentCouponMoney = channelCouponMoney;
  1534. data.setDiscount(channelDiscount);
  1535. data.setReduceMoney(null);
  1536. data.setDiscountPrice(channelCouponMoney);
  1537. data.setValidEndTime(null);
  1538. data.setCouponId(null);
  1539. }
  1540. }
  1541. if (specificPrice != null && specificPrice.compareTo(BigDecimal.ZERO) > 0) {
  1542. if (presentCouponMoney == null) {
  1543. presentCouponMoney = specificPrice;
  1544. }
  1545. if (specificPrice.compareTo(presentCouponMoney) <= 0) {
  1546. source = 3;
  1547. data.setDiscount(null);
  1548. data.setReduceMoney(null);
  1549. data.setDiscountPrice(specificPrice);
  1550. data.setValidEndTime(null);
  1551. data.setCouponId(null);
  1552. }
  1553. }
  1554. data.setSource(source);
  1555. }
  1556. }
  1557. /**
  1558. * 获取gpt镜像天卡活动参与平台ids
  1559. * @return
  1560. */
  1561. private List<Long> getGptMirrorGiveawayBuyGids() {
  1562. GptMirrorDayCardGiveawayActivity gptMirrorDayCardGiveawayActivity = beanSearcher.searchFirst(GptMirrorDayCardGiveawayActivity.class, MapUtils.builder().build());
  1563. if (gptMirrorDayCardGiveawayActivity != null) {
  1564. String buyGoodsIds = gptMirrorDayCardGiveawayActivity.getBuyGoodsIds();
  1565. try {
  1566. return Jsons.parseList(buyGoodsIds, Long.class);
  1567. } catch (Exception e) {
  1568. }
  1569. }
  1570. return null;
  1571. }
  1572. /**
  1573. * 未登录 分类下平台推荐优惠券
  1574. */
  1575. private void setGoodsCouponMoney(GoodsFrontListCategoryView data) {
  1576. //寻找对应最低规格的推荐优惠券
  1577. Coupon coupon = couponUserMapper.selectNoLoginRecommendCouponReduce(data.getId(), data.getPrice());
  1578. if (coupon != null) {
  1579. data.setDiscount(coupon.getDiscount());
  1580. data.setReduceMoney(coupon.getReduceMoney());
  1581. data.setDiscountPrice(data.getPrice().subtract(coupon.getCouponMoney()));
  1582. data.setValidEndTime(coupon.getValidEndTime());
  1583. data.setCouponId(coupon.getId());
  1584. data.setSource(1);
  1585. }
  1586. }
  1587. /**
  1588. * 未登录 首页推荐推荐优惠券
  1589. */
  1590. private void setHomeConfigGoodsCouponMoney(HomeManagementFrontView data) {
  1591. //寻找对应最低规格的推荐优惠券
  1592. Coupon coupon = couponUserMapper.selectNoLoginRecommendCouponReduce(data.getGoodsId(), data.getPrice());
  1593. if (coupon != null) {
  1594. data.setDiscount(coupon.getDiscount());
  1595. data.setReduceMoney(coupon.getReduceMoney());
  1596. data.setDiscountPrice(data.getPrice().subtract(coupon.getCouponMoney()));
  1597. data.setValidEndTime(coupon.getValidEndTime());
  1598. data.setCouponId(coupon.getId());
  1599. data.setSource(1);
  1600. }
  1601. }
  1602. }