GoodsDonController.java 69 KB

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