GroupRelationFrontServiceImpl.java 43 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026
  1. package com.cyksj.service.relation.impl;
  2. import cn.hutool.core.collection.CollUtil;
  3. import cn.hutool.core.collection.CollectionUtil;
  4. import cn.hutool.core.date.BetweenFormater;
  5. import cn.hutool.core.date.DateTime;
  6. import cn.hutool.core.date.DateUtil;
  7. import cn.hutool.core.lang.Assert;
  8. import cn.hutool.core.lang.Validator;
  9. import cn.hutool.core.util.StrUtil;
  10. import com.baomidou.mybatisplus.core.toolkit.Wrappers;
  11. import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
  12. import com.cyksj.common.constant.Constant;
  13. import com.cyksj.common.exception.BusinessRuntimeException;
  14. import com.cyksj.common.task.GlobalThreadPoolTaskExecutor;
  15. import com.cyksj.common.util.Jsons;
  16. import com.cyksj.common.util.StringUtil;
  17. import com.cyksj.enums.GatewayApiCode;
  18. import com.cyksj.mapper.*;
  19. import com.cyksj.mapper.manage.distribute.DistributeGeneralSkuRateMapper;
  20. import com.cyksj.mapper.manage.distribute.UserDistributeMapper;
  21. import com.cyksj.mapper.manage.distribute.UserPlatDistributeRateMapper;
  22. import com.cyksj.mapper.manage.distribute.UserPlatSkuDistributeRateMapper;
  23. import com.cyksj.mapper.renew.RenewUpgradePackageMapper;
  24. import com.cyksj.mapper.sys.SysEmailMapper;
  25. import com.cyksj.model.entity.*;
  26. import com.cyksj.model.request.SpecialGoodsTicketReq;
  27. import com.cyksj.model.request.TicketLoginReq;
  28. import com.cyksj.model.views.*;
  29. import com.cyksj.redis.RedisService;
  30. import com.cyksj.service.chatgpt.ChatGptAccountService;
  31. import com.cyksj.service.chatgpt.ChatGptAuthService;
  32. import com.cyksj.service.claude.ClaudeService;
  33. import com.cyksj.service.groups.GroupsFuncService;
  34. import com.cyksj.service.luma.LumaService;
  35. import com.cyksj.service.mail.CuiQiuMailService;
  36. import com.cyksj.service.mail.MailService;
  37. import com.cyksj.service.mail.YhMailService;
  38. import com.cyksj.service.mange.coupon.CouponCommonService;
  39. import com.cyksj.service.midjourney.MidjourneyAccountService;
  40. import com.cyksj.service.relation.GroupRelationFrontService;
  41. import com.cyksj.service.relation.GroupsRelationNetflixService;
  42. import com.cyksj.service.user.UserBindRelationService;
  43. import com.cyksj.service.user.UserLoginRecordService;
  44. import com.ejlchina.searcher.BeanSearcher;
  45. import com.ejlchina.searcher.SearchResult;
  46. import com.ejlchina.searcher.param.Operator;
  47. import com.ejlchina.searcher.util.MapBuilder;
  48. import com.ejlchina.searcher.util.MapUtils;
  49. import com.github.rholder.retry.*;
  50. import lombok.RequiredArgsConstructor;
  51. import lombok.extern.slf4j.Slf4j;
  52. import org.springframework.stereotype.Service;
  53. import org.springframework.transaction.annotation.Transactional;
  54. import javax.servlet.http.HttpServletRequest;
  55. import java.math.BigDecimal;
  56. import java.math.RoundingMode;
  57. import java.util.Date;
  58. import java.util.List;
  59. import java.util.Objects;
  60. import java.util.Optional;
  61. import java.util.concurrent.ExecutionException;
  62. import java.util.concurrent.TimeUnit;
  63. import java.util.concurrent.atomic.AtomicInteger;
  64. import java.util.stream.Collectors;
  65. import static com.cyksj.enums.GatewayApiCode.GROUP_INDEX_ALREADY_BE_USER;
  66. import static com.cyksj.enums.GatewayApiCode.GROUP_INDEX_NOT_FIND;
  67. /*
  68. *项目名: netflix
  69. *文件名: GroupRelationFrontServiceImpl
  70. *创建者: JavaZou
  71. *创建时间:2022/12/29 15:42
  72. */
  73. @Service
  74. @RequiredArgsConstructor
  75. @Slf4j
  76. public class GroupRelationFrontServiceImpl implements GroupRelationFrontService {
  77. private final UserBindRelationService userBindRelationService;
  78. private final UserMapper userMapper;
  79. private final BeanSearcher beanSearcher;
  80. private final CouponCommonService couponCommonService;
  81. private final GroupsRelationMapper groupsRelationMapper;
  82. private final GroupsMapper groupsMapper;
  83. private final ChatGptAuthService chatGptAuthService;
  84. private final RedisService redisService;
  85. private final MailService mailService;
  86. private final OrderDonMapper orderDonMapper;
  87. private final GroupsRelationExpiryNotifyRecordMapper groupsRelationExpiryNotifyRecordMapper;
  88. private final HttpServletRequest request;
  89. private final GroupsFuncService groupsFuncService;
  90. private final OrderDiscountPlusPurchaseSkuRelationMapper orderDiscountPlusPurchaseSkuRelationMapper;
  91. private final GroupsRelationLoginCodeRecordMapper groupsRelationLoginCodeRecordMapper;
  92. private final SysEmailMapper sysEmailMapper;
  93. private final GoodsDonSkuMapper goodsDonSkuMapper;
  94. private final UserFuncPropertyMapper userFuncPropertyMapper;
  95. private static final GlobalThreadPoolTaskExecutor TASK_EXECUTOR = GlobalThreadPoolTaskExecutor.getInstance();
  96. private final UserLoginRecordService userLoginRecordService;
  97. private final CuiQiuMailService cuiQiuMailService;
  98. private final UserCertRecordMapper userCertRecordMapper;
  99. private final MidjourneyAccountService midjourneyAccountService;
  100. private final ChatGptAccountService chatGptAccountService;
  101. private final UpgradePackageMapper upgradePackageMapper;
  102. private final LumaService lumaService;
  103. private final GroupsRelationNetflixService groupsRelationNetflixService;
  104. private final UserDistributeMapper userDistributeMapper;
  105. private final UserPlatDistributeRateMapper userPlatDistributeRateMapper;
  106. private final GoodsDonMapper goodsDonMapper;
  107. private final UserPlatSkuDistributeRateMapper userPlatSkuDistributeRateMapper;
  108. private final DistributeGeneralSkuRateMapper distributeGeneralSkuRateMapper;
  109. private final RenewUpgradePackageMapper renewUpgradePackageMapper;
  110. private final ClaudeService claudeService;
  111. private final YhMailService yhMailService;
  112. private final UserDistributePosterRecordMapper userDistributePosterRecordMapper;
  113. private final OrderDonRenewRecordMapper orderDonRenewRecordMapper;
  114. private final UpgradeOrderDonMapper upgradeOrderDonMapper;
  115. @Override
  116. public SearchResult<RenewalView> getMyTicket(long userId, Boolean isLoginPopularize, String customId, String account) {
  117. User u = userMapper.selectById(userId);
  118. if (u == null) throw BusinessRuntimeException.getGatewayApiCode(GatewayApiCode.CMS_TOKEN_VALID);
  119. if (u.getIsBlack()) {
  120. return new SearchResult<>();
  121. }
  122. List<Long> userIds = userBindRelationService.getRelationUserIdList(userId, u);
  123. MapBuilder builder = MapUtils.flatBuilder(request.getParameterMap());
  124. //Long yhsId = yhShopFrontService.getYhsIdByCustomId(customId);
  125. DateTime now = DateTime.now();
  126. if (StrUtil.isNotBlank(account)) {
  127. builder.field(RenewalView::getAccount, account).op(Operator.Contain);
  128. }
  129. SearchResult<RenewalView> list = beanSearcher.search(RenewalView.class, builder
  130. .field(RenewalView::getUserId, 0).op(Operator.GreaterThan)
  131. .field(RenewalView::getUserId, userIds).op(Operator.InList)
  132. //.field(RenewalView::getYhsId, yhsId)
  133. .put("condition", String.format("(gr.expiry_time is null or gr.expiry_time > '%s')", now))
  134. .field(RenewalView::getStatus, List.of("validity", "overdue", "outside")).op(Operator.InList)
  135. .orderBy(RenewalView::getExpiryTime).asc()
  136. .build());
  137. //过滤邀请制、已失效的车位
  138. Integer size = list.getTotalCount().intValue();
  139. list.getDataList().forEach(ticket -> {
  140. if (ticket.getSkuId() == null || ticket.getGoodsId() == null) {
  141. return;
  142. }
  143. if (ticket.getGoodsId() == 18 && ticket.getSkuNum() > 1) {
  144. ticket.setPassword(null);
  145. }
  146. ticket.setIsMulti(false);
  147. if (ticket.getSkuNum() > 1) {
  148. ticket.setIsMulti(true);
  149. }
  150. //chatGPT直连
  151. if (ticket.getGoodsId().equals(42l)) {
  152. if (StrUtil.isNotBlank(ticket.getAccount())) {
  153. String accessToken;
  154. try {
  155. accessToken = chatGptAuthService.getAccessToken(ticket.getAccount());
  156. ticket.setGptRefreshToken(accessToken);
  157. } catch (Exception e) {
  158. redisService.set(RedisService.key.CHAT_GPT_TOKEN_EXCEPTION_KEY.getName() + ticket.getAccount(), ticket.getAccount());
  159. }
  160. }
  161. ticket.setAccount(null);
  162. ticket.setPassword(null);
  163. } else {
  164. ticket.setGptRefreshToken(null);
  165. }
  166. if (ticket.getSecondType() == 1) {
  167. ticket.setAccount(null);
  168. ticket.setPassword(null);
  169. }
  170. if (isLoginPopularize != null && isLoginPopularize) {
  171. GoodsDonViews views = beanSearcher.searchFirst(GoodsDonViews.class, MapUtils.builder().field(GoodsDonViews::getId, ticket.getGoodsId()).build());
  172. views.setSpecs(beanSearcher.searchFirst(GoodsDonSpecFrontView.class, MapUtils.builder().field(GoodsDonSpecFrontView::getGoodsId, views.getId()).build()));
  173. views.setSkuList(beanSearcher.searchAll(GoodsDonSkuFrontView.class, MapUtils.builder().field(GoodsDonSkuFrontView::getGoodsId, views.getId()).field(GoodsDonSkuFrontView::getStatus, true).build()));
  174. ticket.setGoodsDonViews(views);
  175. }
  176. if (ticket.getMonths() != null && ticket.getMonths() >= 300) {
  177. ticket.setExpiryTime(null);
  178. }
  179. if (ticket.getExpiryTime() != null && ticket.getGoodsType() == 1 && ticket.getSecondType() == 2) {
  180. String remainDays = DateUtil.formatBetween(now, ticket.getExpiryTime(), BetweenFormater.Level.DAY);
  181. if ("0天".equals(remainDays)) {
  182. remainDays = "小于1天";
  183. } else {
  184. //当天也算
  185. int days = Integer.parseInt(remainDays.substring(0, remainDays.indexOf("天")));
  186. remainDays = days + 1 + "天";
  187. }
  188. ticket.setRemainDays(remainDays);
  189. }
  190. OrderDon orderDon = orderDonMapper.selectOne(Wrappers.lambdaQuery(OrderDon.class)
  191. .eq(OrderDon::getRelationId, ticket.getRelationId())
  192. .eq(OrderDon::getUserId, ticket.getUserId())
  193. .notIn(OrderDon::getStatus, Constant.noOrderAllStatus)
  194. .orderByDesc(OrderDon::getId)
  195. .last("limit 1"));
  196. if (orderDon != null) {
  197. ticket.setOrderNo(orderDon.getOrderNo());
  198. ticket.setOrderId(orderDon.getId());
  199. ticket.setTransactionId(orderDon.getTransactionId());
  200. }
  201. if (size > 1 && ticket.getGoodsId() != 18) {
  202. Date payTime = null;
  203. if (orderDon != null) {
  204. payTime = Optional.ofNullable(orderDon.getPayTime()).orElse(orderDon.getCreatedTime());
  205. }
  206. //加购订单
  207. if (orderDon == null) {
  208. List<OrderDiscountPlusPurchaseSkuRelation> plusPurchaseSkuRelations = orderDiscountPlusPurchaseSkuRelationMapper.selectPlusRelationByIdAndUserId(ticket.getRelationId(), ticket.getUserId());
  209. for (OrderDiscountPlusPurchaseSkuRelation data : plusPurchaseSkuRelations) {
  210. String relationIds = data.getRelationIds();
  211. if (StrUtil.isEmpty(relationIds)) {
  212. return;
  213. }
  214. try {
  215. List<Long> relationList = Jsons.parseList(relationIds, Long.class);
  216. if (relationList.contains(ticket.getRelationId())) {
  217. OrderDon plusOrder = orderDonMapper.selectById(data.getOrderId());
  218. if (plusOrder != null) {
  219. payTime = Optional.ofNullable(plusOrder.getPayTime()).orElse(plusOrder.getCreatedTime());
  220. }
  221. break;
  222. }
  223. } catch (Exception e) {
  224. }
  225. }
  226. }
  227. ticket.setPayTime(payTime);
  228. }
  229. //设置镜像车票信息
  230. setMirrorTicketInfo(ticket);
  231. List<GroupsRelationUserView> relationUserViews = groupsRelationMapper.getUserRelationUserViews(ticket.getGroupId(), ticket.getRelationId(), ticket.getUserId(), List.of(GroupsRelation.Status.validity, GroupsRelation.Status.outside));
  232. ticket.setRelationViews(relationUserViews);
  233. if (ticket.getExpiryTime() != null) {
  234. ticket.setExpiryTimeStr(DateUtil.format(ticket.getExpiryTime(), "yyyy-MM-dd"));
  235. }
  236. //查看双重验证码
  237. if (StrUtil.isNotEmpty(ticket.getApiSecret())) {
  238. Boolean isHasVerifyCode = StrUtil.isNotBlank(ticket.getVerifyCode()) ? true : false;
  239. Integer codeNum = getUserCodeNumBySkuId(ticket.getUserId(), ticket.getSkuId(), isHasVerifyCode);
  240. ticket.setCodeNum(codeNum);
  241. }
  242. Long qaId = groupsRelationMapper.selectGoodsDonQaByGoodsId(ticket.getGoodsId());
  243. ticket.setQa(qaId > 0 ? true : false);
  244. //是否存在海报
  245. ticket.setPosterInfo(setGoodsPoster(ticket, u, userIds));
  246. //续费升级折扣
  247. setRenewDiscount(ticket);
  248. });
  249. userLoginRecordService.saveUserLoginDayRecord(userId);
  250. return list;
  251. }
  252. @Override
  253. public Boolean isJoinCorpWx(Long userId, Boolean isJoin, Boolean noCoupon) {
  254. if (!isJoin) {
  255. User user = userMapper.selectById(userId);
  256. if (user == null || StrUtil.isEmpty(user.getUnionid())) {
  257. return true;
  258. }
  259. // CorpUser corpUser = corpUserMapper.selectOne(Wrappers.lambdaQuery(CorpUser.class)
  260. // .ne(CorpUser::getUnionid, "")
  261. // .eq(CorpUser::getUnionid, user.getUnionid())
  262. // .last("limit 1")
  263. // .select(CorpUser::getId)
  264. // );
  265. CorpUserFollowView corpUserFollowView = beanSearcher.searchFirst(CorpUserFollowView.class, MapUtils.builder()
  266. .field(CorpUserFollowView::getUnionId, user.getUnionid())
  267. .field(CorpUserFollowView::getStatus, 1).build());
  268. if (corpUserFollowView == null) {
  269. return false;
  270. }
  271. }
  272. //用户是否买了奈飞车票
  273. Number number = beanSearcher.searchCount(RenewalView.class, MapUtils.builder()
  274. .field(RenewalView::getUserId, userId)
  275. .field(RenewalView::getGoodsId, 1)
  276. .field(RenewalView::getStatus, List.of("validity", "overdue")).op(Operator.InList)
  277. .build());
  278. if (number.intValue() > 0 && !noCoupon) {
  279. couponCommonService.sendCouponToUser(userId, 34l, 0l, 0l, 0l, CouponUser.Channel.wxCorp);
  280. }
  281. return true;
  282. }
  283. @Override
  284. public GroupsRelation getSimilarExpiredGroupRelation(GoodsDonSku sku, List<Long> errorsRelationIds, String ip) {
  285. Long skuId = sku.getId();
  286. Integer days = sku.getDays();
  287. Integer months = sku.getMonths();
  288. Integer maxNum = sku.getNum();
  289. DateTime expiryTime = null;
  290. if (days != null && days > 0) {
  291. expiryTime = DateUtil.offsetDay(DateTime.now(), days);
  292. } else {
  293. expiryTime = DateUtil.offsetMonth(DateTime.now(), months);
  294. }
  295. Integer extraNum = 5;
  296. if (sku.getId() == 178l) {
  297. extraNum = 2;
  298. }
  299. maxNum += extraNum;
  300. DateTime minExpiryTime = DateUtil.offsetDay(expiryTime, -5);
  301. Long groupsId = groupsRelationMapper.selectSimilarExpiredRelation(skuId, minExpiryTime, maxNum, ip);
  302. if (groupsId == null) {
  303. log.info("暂无相似过期时间车队");
  304. return null;
  305. }
  306. GroupsRelation relation = groupsRelationMapper.selectOne(Wrappers.lambdaQuery(GroupsRelation.class)
  307. .notIn(errorsRelationIds != null && errorsRelationIds.size() > 0, GroupsRelation::getId, errorsRelationIds)
  308. .eq(GroupsRelation::getGroupsId, groupsId)
  309. .eq(GroupsRelation::getStatus, GroupsRelation.Status.none)
  310. .eq(GroupsRelation::getUserId, 0)
  311. .orderByAsc(GroupsRelation::getNum)
  312. .last("limit 1"));
  313. if (relation != null) {
  314. log.info("用户userId:{},获取相似车队的车位relationId:{}", relation.getId());
  315. }
  316. return relation;
  317. }
  318. @Override
  319. public Page<UserRecommendGoodsFrontView> getRecommendGoodsViews(Boolean isPayNf, List<Long> filter_goods_id, Boolean filterCourseGoods, Integer start, Integer limit) {
  320. return groupsRelationMapper.getRecommendGoodsViews(new Page<>(start, limit), filter_goods_id, isPayNf, filterCourseGoods);
  321. }
  322. @Override
  323. @Transactional(rollbackFor = Throwable.class)
  324. public void sendCourseWare(SpecialGoodsTicketReq request) throws Exception {
  325. Long userId = request.getUserId();
  326. Long relationId = request.getRelationId();
  327. String email = request.getEmail();
  328. List<Long> userIdList = userBindRelationService.getRelationUserIdList(userId, null);
  329. RenewalView relation = beanSearcher.searchFirst(RenewalView.class, MapUtils.builder().field(RenewalView::getRelationId, relationId).build());
  330. Assert.notNull(relation, "您的车票不存在");
  331. Long relationUserId = relation.getUserId();
  332. if (!userIdList.contains(relationUserId)) {
  333. throw BusinessRuntimeException.getInstance("您的车票不存在");
  334. }
  335. if (relation.getSpecialType() != GoodsDon.SpecialType.courseware) {
  336. throw BusinessRuntimeException.getInstance("");
  337. }
  338. //是否已发送
  339. if (StrUtil.isNotBlank(relation.getGrAccount())) {
  340. throw BusinessRuntimeException.getInstance("已领取课件,请前往邮箱查看");
  341. }
  342. if (!Validator.isEmail(email)) {
  343. throw BusinessRuntimeException.getInstance("请输入正确的邮箱");
  344. }
  345. int update = groupsRelationMapper.update(null, Wrappers.lambdaUpdate(GroupsRelation.class)
  346. .set(GroupsRelation::getAccount, email)
  347. .and(qr -> qr.isNull(GroupsRelation::getAccount).or().eq(GroupsRelation::getAccount, StrUtil.EMPTY))
  348. .eq(GroupsRelation::getId, relationId));
  349. if (update > 0) {
  350. orderDonMapper.update(null, Wrappers.lambdaUpdate(OrderDon.class)
  351. .set(OrderDon::getStatus, OrderDon.Status.complete)
  352. .eq(OrderDon::getRelationId, relationId)
  353. .eq(OrderDon::getUserId, userId)
  354. .eq(OrderDon::getStatus, OrderDon.Status.hasPayment));
  355. mailService.sendCoursewareByGoodsId(relation.getGoodsId(), relation.getRelationId(), relation.getUserId(), relation.getTitle(), email);
  356. }
  357. }
  358. @Override
  359. public GroupsRelation getRelation(Long payRelationId, Long userId, GoodsDonSku sku, String ip) {
  360. GroupsRelation relation = null;
  361. Integer maxNum = sku.getNum();
  362. if (payRelationId != null && payRelationId > 0) {
  363. relation = groupsRelationMapper.selectById(payRelationId);
  364. if (relation == null) {
  365. throw new BusinessRuntimeException(GROUP_INDEX_NOT_FIND.getCode(), GROUP_INDEX_NOT_FIND.getMsg());
  366. }
  367. if (relation.getUserId() != null && relation.getUserId() > 0L) {
  368. throw new BusinessRuntimeException(GROUP_INDEX_ALREADY_BE_USER.getCode(), GROUP_INDEX_ALREADY_BE_USER.getMsg());
  369. }
  370. } else {
  371. GroupsTrips groups = null;
  372. //ChatGpt Plus、Midjourney非独立规格 上车先获取硬塞座位 硬塞5个座位
  373. //主账号过期时间25天以外
  374. //23-12-06 MidJourney 不硬塞
  375. if (sku.getNum() > 1 && Constant.AI_goodsIds.get(0) == sku.getGoodsId()) {
  376. Integer extraNum = 5;
  377. if (sku.getId() == 178l || sku.getId() == 423l) {
  378. extraNum = 2;
  379. }
  380. maxNum += extraNum;
  381. DateTime time = DateUtil.offsetDay(DateUtil.beginOfDay(DateTime.now()), 25);
  382. //不塞存在该用户的车队
  383. Long groupsId = groupsRelationMapper.getOutSideGroupsTripsRelationByGoodsId(sku.getId(), time, extraNum, userId, sku.getNum(), maxNum);
  384. if (groupsId != null) {
  385. relation = groupsRelationMapper.selectOne(Wrappers.lambdaQuery(GroupsRelation.class)
  386. .eq(GroupsRelation::getGroupsId, groupsId)
  387. .eq(GroupsRelation::getUserId, 0)
  388. .eq(GroupsRelation::getStatus, GroupsRelation.Status.outside)
  389. .last("limit 1"));
  390. if (relation == null) {
  391. relation = new GroupsRelation();
  392. relation.setStatus(GroupsRelation.Status.outside);
  393. relation.setUserId(userId);
  394. relation.setGroupsId(groupsId);
  395. GroupsRelation maxNumRelation = groupsRelationMapper.selectOne(Wrappers.lambdaQuery(GroupsRelation.class).eq(GroupsRelation::getGroupsId, groupsId).orderByDesc(GroupsRelation::getNum).last("limit 1"));
  396. Integer nextNum = maxNumRelation.getNum() + 1;
  397. if (redisService.setNx(RedisService.key.GROUPS_TRIPS_OUTSIDE_RELATION.getNameFormat(groupsId, nextNum), nextNum, RedisService.key.GROUPS_TRIPS_OUTSIDE_RELATION.getTimeout())) {
  398. relation.setNum(nextNum);
  399. groupsRelationMapper.insert(relation);
  400. } else {
  401. throw BusinessRuntimeException.getInstance("系统繁忙,请重试...");
  402. }
  403. }
  404. groups = groupsMapper.selectById(groupsId);
  405. }
  406. }
  407. if (groups == null) {
  408. //寻找差不多过期时间规格的车位
  409. relation = getSimilarExpiredGroupRelation(sku, null, ip);
  410. if (relation == null) {
  411. //TODO 如果没指定座位,等待逻辑确认
  412. groups = groupsMapper.selectTicketGroups(sku.getId(), GroupsTrips.Status.validity, maxNum, ip);
  413. if (groups == null) {
  414. //待发车
  415. groups = groupsMapper.selectTicketGroups(sku.getId(), GroupsTrips.Status.waiting, maxNum, ip);
  416. }
  417. //新增空车队
  418. if (groups == null) {
  419. relation = groupsFuncService.createNewGroupsTrips(sku);
  420. }
  421. //获取车位
  422. if (relation == null) {
  423. //寻找快满编车队进行占座
  424. relation = groupsRelationMapper.selectRandomOneRelationByGroupsId(groups.getId());
  425. if (relation == null) {
  426. Long groupsId = groups.getId();
  427. TASK_EXECUTOR.execute(() -> groupsMapper.updateAvailableNum(groupsId));
  428. throw BusinessRuntimeException.getInstance("系统繁忙,请重试...");
  429. }
  430. }
  431. }
  432. }
  433. if (groups == null) {
  434. groups = groupsMapper.selectById(relation.getGroupsId());
  435. }
  436. //车队目前可用停车数
  437. relation.setGroupsAvailParkingNum(groups.getAvailableParkingNum());
  438. relation.setMaxNum(maxNum);
  439. }
  440. return relation;
  441. }
  442. @Override
  443. public String getAiVerifyCode(TicketLoginReq loginReq) throws Exception {
  444. Long userId = loginReq.getUserId();
  445. Long relationId = loginReq.getRelationId();
  446. Integer type = loginReq.getType();
  447. Boolean sync = loginReq.getSync();
  448. List<Long> relationUserIdList = userBindRelationService.getRelationUserIdList(userId, null);
  449. RenewalView renewalView = beanSearcher.searchFirst(RenewalView.class, MapUtils.builder().field(RenewalView::getUserId, relationUserIdList).op(Operator.InList)
  450. .field(RenewalView::getRelationId, relationId).build());
  451. if (renewalView == null) {
  452. throw BusinessRuntimeException.getInstance("您的车票不存在...");
  453. }
  454. if (StrUtil.isEmpty(renewalView.getAccount())) {
  455. throw BusinessRuntimeException.getInstance("车票未配置账号");
  456. }
  457. String account = renewalView.getAccount();
  458. String password = renewalView.getPassword();
  459. if (StrUtil.hasEmpty(account, password)) {
  460. throw BusinessRuntimeException.getInstance("您的车票账号密码异常,请联系客服...");
  461. }
  462. if (renewalView.getGoodsId() == 1l) {
  463. Integer linkType = loginReq.getLinkType();
  464. if (type == null && linkType == null) {
  465. throw BusinessRuntimeException.getInstance("系统异常");
  466. }
  467. String key = RedisService.key.NF_UPGRAD_USER_LIMIT_KEY.getNameFormat(DateUtil.hour(DateTime.now(), true), linkType, renewalView.getUserId());
  468. if (!redisService.hasKey(key)) {
  469. redisService.set(key, 1l, RedisService.key.NF_UPGRAD_USER_LIMIT_KEY.getTimeout());
  470. } else {
  471. Integer value = (Integer) redisService.get(key);
  472. if (value >= 5) {
  473. throw BusinessRuntimeException.getInstance("获取失败,请联系客服");
  474. }
  475. redisService.incr(key, 1L);
  476. }
  477. }
  478. if (cuiQiuMailService.isCuiQiuEmail(renewalView.getAccount())) {
  479. return cuiQiuMailService.getVerifyCode(renewalView.getAccount(), renewalView.getGoodsId(), type, loginReq.getLinkType());
  480. }
  481. //银河域名邮件
  482. String code = yhMailService.getVerifyCode(account, renewalView.getGoodsId(), type, loginReq.getLinkType());
  483. GroupsRelationLoginCodeRecord record = new GroupsRelationLoginCodeRecord();
  484. record.setUserId(userId);
  485. record.setRelationId(relationId);
  486. record.setAccount(renewalView.getAccount());
  487. record.setGoodsId(renewalView.getGoodsId());
  488. record.setSkuId(renewalView.getSkuId());
  489. groupsRelationLoginCodeRecordMapper.insert(record);
  490. return code;
  491. }
  492. @Override
  493. public void checkGroupsAvailParkingNum(Long skuId, Long groupsId, Integer availableParkingNum, Integer maxNum) {
  494. //GPT10人月付、4人月付
  495. if (skuId == 161l || skuId == 178l) {
  496. //为0时,不参与限制
  497. if (availableParkingNum == 0) {
  498. return;
  499. }
  500. //目前车队可用停车数
  501. //目前上车人数
  502. Integer currentParkingNum = groupsRelationMapper.selectCount(Wrappers.lambdaQuery(GroupsRelation.class)
  503. .eq(GroupsRelation::getGroupsId, groupsId)
  504. .ne(GroupsRelation::getUserId, 0)
  505. .le(GroupsRelation::getNum, maxNum));
  506. if (currentParkingNum > availableParkingNum) {
  507. throw BusinessRuntimeException.getInstance("系统繁忙,请重试...");
  508. }
  509. }
  510. }
  511. @Override
  512. public void adjustGroupsParkingTime(Long relationId, GoodsDonSku sku) {
  513. if (sku == null) {
  514. return;
  515. }
  516. Long skuId = sku.getId();
  517. //更新GPT Plus10人、4人月付车队状态 待优化
  518. if (skuId == 161l || skuId == 178l || skuId == 422l || skuId == 423l) {
  519. GroupsRelation relation = groupsRelationMapper.selectById(relationId);
  520. Long groupsId = relation.getGroupsId();
  521. GroupsTrips groupsTrips = groupsMapper.selectById(groupsId);
  522. Integer availableParkingNum = groupsTrips.getAvailableParkingNum();
  523. //为0时 不参与限制
  524. if (availableParkingNum == 0) {
  525. return;
  526. }
  527. Integer extraNum = 5;
  528. if (skuId == 178l || skuId == 423l) {
  529. extraNum = 2;
  530. }
  531. Integer maxNum = sku.getNum() + extraNum;
  532. if (availableParkingNum >= maxNum) {
  533. return;
  534. }
  535. //目前上车人数
  536. Integer currentParkingNum = groupsRelationMapper.selectCount(Wrappers.lambdaQuery(GroupsRelation.class)
  537. .eq(GroupsRelation::getGroupsId, groupsId)
  538. .ne(GroupsRelation::getUserId, 0)
  539. .le(GroupsRelation::getNum, maxNum));
  540. if (currentParkingNum >= availableParkingNum) {
  541. //锁住
  542. DateTime parkingTime = DateUtil.offsetDay(DateTime.now(), 1);
  543. groupsMapper.update(null, Wrappers.lambdaUpdate(GroupsTrips.class)
  544. .eq(GroupsTrips::getId, groupsTrips.getId())
  545. .set(GroupsTrips::getParkingTime, parkingTime)
  546. .isNull(GroupsTrips::getParkingTime));
  547. }
  548. }
  549. }
  550. @Override
  551. public void setGroupsTripsParkingTimeEmpty(GoodsDonSku sku, Long relationId) {
  552. Long skuId = sku.getId();
  553. if (skuId == 161l || skuId == 178l) {
  554. GroupsRelation relation = groupsRelationMapper.selectById(relationId);
  555. Long groupsId = relation.getGroupsId();
  556. GroupsTrips groupsTrips = groupsMapper.selectById(groupsId);
  557. Integer availableParkingNum = groupsTrips.getAvailableParkingNum();
  558. if (groupsTrips.getParkingTime() == null || availableParkingNum == 0) {
  559. return;
  560. }
  561. Integer extraNum = 5;
  562. if (skuId == 178l) {
  563. extraNum = 2;
  564. }
  565. Integer skuNum = sku.getNum();
  566. if (availableParkingNum >= skuNum + extraNum) {
  567. return;
  568. }
  569. //目前上车人数
  570. Integer currentParkingNum = groupsRelationMapper.selectCount(Wrappers.lambdaQuery(GroupsRelation.class)
  571. .eq(GroupsRelation::getGroupsId, groupsId)
  572. .ne(GroupsRelation::getUserId, 0));
  573. if (currentParkingNum < availableParkingNum) {
  574. groupsMapper.update(null, Wrappers.lambdaUpdate(GroupsTrips.class)
  575. .eq(GroupsTrips::getId, groupsTrips.getId())
  576. .set(GroupsTrips::getParkingTime, null)
  577. .isNotNull(GroupsTrips::getParkingTime));
  578. }
  579. }
  580. }
  581. @Override
  582. public Integer getUserCodeNumBySkuId(Long userId, Long skuId, Boolean isHasVerifyCode) {
  583. //查看双重验证码
  584. UserFuncProperty userFuncProperty = userFuncPropertyMapper.selectOne(Wrappers.lambdaQuery(UserFuncProperty.class).eq(UserFuncProperty::getUserId, userId).last("limit 1"));
  585. //默认2次
  586. int num = 2;
  587. //有安全码查看次数 置为0
  588. if (isHasVerifyCode) {
  589. num = 0;
  590. //存在身份实名认证有两次机会
  591. List<Long> userIdList = userBindRelationService.getRelationUserIdList(userId, null);
  592. Integer selectCount = userCertRecordMapper.selectCount(Wrappers.lambdaQuery(UserCertRecord.class)
  593. .in(UserCertRecord::getUserId, userIdList));
  594. if (selectCount > 0) {
  595. num = 2;
  596. }
  597. return num;
  598. }
  599. //查看双重验证码次数
  600. GoodsDonSku sku = goodsDonSkuMapper.selectById(skuId);
  601. if (sku.getCodeNum() > 0) {
  602. num = sku.getCodeNum();
  603. }
  604. if (userFuncProperty != null) num = userFuncProperty.getVerifyCheckNum();
  605. return num;
  606. }
  607. @Override
  608. public List<RenewalView> getHasPayGoods(long userId) {
  609. User user = userMapper.selectById(userId);
  610. List<Long> userIds = userBindRelationService.getRelationUserIdList(userId, user);
  611. DateTime now = DateTime.now();
  612. List<RenewalView> list = groupsRelationMapper.getUserHasPayGoods(userIds, now);
  613. return list;
  614. }
  615. @Override
  616. public List<RenewalView> getExpiryRenewalNotify(Long userId) {
  617. DateTime now = DateTime.now();
  618. DateTime thisZero = DateUtil.beginOfDay(now);
  619. String thisDate = thisZero.toDateStr();
  620. Object exists = redisService.get(RedisService.key.TICKET_EXPIRY_NOTIFY_DAY.getNameFormat(thisDate, userId));
  621. if (exists != null) {
  622. return null;
  623. }
  624. User u = userMapper.selectById(userId);
  625. if (u == null) throw BusinessRuntimeException.getGatewayApiCode(GatewayApiCode.CMS_TOKEN_VALID);
  626. if (u.getIsBlack()) {
  627. redisService.setNx(RedisService.key.TICKET_EXPIRY_NOTIFY_DAY.getNameFormat(thisDate, userId), userId, RedisService.key.TICKET_EXPIRY_NOTIFY_DAY.getTimeout());
  628. return null;
  629. }
  630. List<Long> userIds = userBindRelationService.getRelationUserIdList(userId, u);
  631. MapBuilder builder = MapUtils.flatBuilder(request.getParameterMap());
  632. List<RenewalView> list = beanSearcher.searchAll(RenewalView.class, builder
  633. .field(RenewalView::getUserId, 0).op(Operator.GreaterThan)
  634. .field(RenewalView::getUserId, userIds).op(Operator.InList)
  635. .field(RenewalView::getExpiryTime, now).op(Operator.GreaterThan)
  636. .field(RenewalView::getStatus, List.of("validity", "overdue", "outside")).op(Operator.InList)
  637. .field(RenewalView::getAqType, 1)
  638. .orderBy(RenewalView::getExpiryTime).asc()
  639. .build());
  640. if (list.size() > 5) {
  641. redisService.setNx(RedisService.key.TICKET_EXPIRY_NOTIFY_DAY.getNameFormat(thisDate, userId), userId, RedisService.key.TICKET_EXPIRY_NOTIFY_DAY.getTimeout());
  642. return null;
  643. }
  644. //提前7天
  645. AtomicInteger day = new AtomicInteger(7);
  646. List<RenewalView> expiryTickets = list.stream().filter(ticket -> {
  647. //下架
  648. if (ticket.getGoodsStatus() == null || ticket.getSkuStatus() == null || !ticket.getGoodsStatus() || !ticket.getSkuStatus()) {
  649. return false;
  650. }
  651. Integer skuMonths = ticket.getMonths();
  652. if (skuMonths == null) {
  653. return false;
  654. }
  655. Date expiryTime = ticket.getExpiryTime();
  656. //年付 提前一个月
  657. if (skuMonths >= 12) {
  658. day.set(30);
  659. } else {
  660. day.set(7);
  661. }
  662. if (DateUtil.beginOfDay(expiryTime).compareTo(DateUtil.offsetDay(thisZero, day.get())) <= 0) {
  663. ticket.setExpiryTimeStr(DateUtil.format(ticket.getExpiryTime(), "yyyy-MM-dd"));
  664. //GPT镜像信息
  665. setGptMirrorInfo(ticket);
  666. ticket.setExpiryTime(null);
  667. return true;
  668. }
  669. return false;
  670. }).collect(Collectors.toList());
  671. redisService.setNx(RedisService.key.TICKET_EXPIRY_NOTIFY_DAY.getNameFormat(thisDate, userId), userId, RedisService.key.TICKET_EXPIRY_NOTIFY_DAY.getTimeout());
  672. if (CollUtil.isNotEmpty(expiryTickets)) {
  673. groupsRelationExpiryNotifyRecordMapper.batchInsert(userId, expiryTickets);
  674. }
  675. return expiryTickets;
  676. }
  677. @Override
  678. public void getCollegeStudentUserGptTicket(Long userId) {
  679. Retryer<Boolean> build = RetryerBuilder.<Boolean>newBuilder()
  680. .retryIfException()
  681. //运行时异常重试
  682. .retryIfRuntimeException()
  683. //false重试
  684. .retryIfResult(res -> Objects.equals(res, false))
  685. //1s 间隔
  686. .withWaitStrategy(WaitStrategies.fixedWait(1, TimeUnit.SECONDS))
  687. //停止策略 : 尝试请求3次
  688. .withStopStrategy(StopStrategies.stopAfterAttempt(3)).build();
  689. try {
  690. build.call(() -> {
  691. //体验规格
  692. Long gptMirrorSkuId = Constant.GPT_MIRROR_SKU_ID;
  693. GroupsTrips groups = groupsMapper.selectCollegeStudentUserGptTicket(gptMirrorSkuId);
  694. GroupsRelation relation = null;
  695. if (groups != null) {
  696. relation = groupsRelationMapper.selectRandomOneRelationByGroupsId(groups.getId());
  697. }
  698. if (relation == null) {
  699. //生成空车队
  700. GoodsDonSku sku = goodsDonSkuMapper.selectById(gptMirrorSkuId);
  701. relation = groupsFuncService.createNewGroupsTrips(sku);
  702. }
  703. DateTime startTime = DateTime.now();
  704. DateTime expiryTime = DateUtil.offsetDay(startTime, 1);
  705. int update = groupsRelationMapper.update(null, Wrappers.lambdaUpdate(GroupsRelation.class)
  706. .set(GroupsRelation::getUserId, userId)
  707. .set(GroupsRelation::getStartTime, startTime)
  708. .set(GroupsRelation::getExpiryTime, expiryTime)
  709. .set(GroupsRelation::getStatus, GroupsRelation.Status.validity)
  710. .set(GroupsRelation::getAqType, 2)
  711. .eq(GroupsRelation::getId, relation.getId())
  712. .eq(GroupsRelation::getUserId, 0));
  713. if (update > 0) {
  714. groupsMapper.decrAvailableNum(groups.getId());
  715. return true;
  716. }
  717. log.error("发送用户:{} GPT镜像车票体验失败,进行重试", userId);
  718. return false;
  719. });
  720. } catch (ExecutionException | RetryException e) {
  721. log.error("发送用户GPT镜像体验失败:{}", StringUtil.getErrorText(e));
  722. }
  723. }
  724. @Override
  725. public RenewalView getTicketDetail(long userId, Long relationId) {
  726. User u = userMapper.selectById(userId);
  727. List<Long> userIds = userBindRelationService.getRelationUserIdList(userId, u);
  728. MapBuilder builder = MapUtils.builder();
  729. RenewalView renewalView = beanSearcher.searchFirst(RenewalView.class, builder
  730. .field(RenewalView::getRelationId, relationId)
  731. .field(RenewalView::getUserId, 0).op(Operator.GreaterThan)
  732. .field(RenewalView::getUserId, userIds).op(Operator.InList)
  733. .field("condition", String.format("(gr.expiry_time is null or gr.expiry_time > '%s')", DateTime.now()))
  734. .field(RenewalView::getStatus, List.of("validity", "outside")).op(Operator.InList)
  735. .orderBy(RenewalView::getExpiryTime).asc()
  736. .onlySelect(RenewalView::getRelationId, RenewalView::getExpiryTime, RenewalView::getTitle, RenewalView::getSpecVal, RenewalView::getGoodsId, RenewalView::getSkuId, RenewalView::getSkuNum, RenewalView::getSkuStatus, RenewalView::getGoodsStatus)
  737. .build());
  738. if (renewalView != null) {
  739. renewalView.setExpiryTimeStr(DateUtil.format(renewalView.getExpiryTime(), "yyyy-MM-dd"));
  740. }
  741. return renewalView;
  742. }
  743. @Override
  744. public GroupsRelation ticketLogin(TicketLoginReq loginReq) {
  745. String account = loginReq.getAccount();
  746. String password = loginReq.getPassword();
  747. Integer num = loginReq.getNum();
  748. Long goodsId = Optional.ofNullable(loginReq.getGoodsId()).orElse(1l);
  749. GroupsRelation relation = groupsRelationMapper.selectRelationByAccountAndNum(account, password, goodsId, num);
  750. if (relation == null) {
  751. log.info("外部入口使用账号account:{},pwd:{},座位num:{}登录失败...", account, password, num);
  752. if (StrUtil.equals(loginReq.getLang(), Constant.EN_US)) {
  753. throw BusinessRuntimeException.getInstance("Please enter the correct account information");
  754. }
  755. throw BusinessRuntimeException.getInstance("请输入正确的账号信息");
  756. }
  757. return relation;
  758. }
  759. @Override
  760. public String outsideTicketVerify(TicketLoginReq loginReq) {
  761. String account = loginReq.getAccount();
  762. String password = loginReq.getPassword();
  763. Integer num = loginReq.getNum();
  764. Long goodsId = Optional.ofNullable(loginReq.getGoodsId()).orElse(1l);
  765. GroupsRelation relation = groupsRelationMapper.selectRelationByAccountAndNum(account, password, goodsId, num);
  766. if (relation == null) {
  767. log.info("外部入口使用账号account:{},pwd:{},座位num:{}同步验证链接失败...", account, password, num);
  768. if (StrUtil.equals(loginReq.getLang(), Constant.EN_US)) {
  769. throw BusinessRuntimeException.getInstance("This account is no longer valid");
  770. }
  771. throw BusinessRuntimeException.getInstance("该账号已失效");
  772. }
  773. loginReq.setUserId(relation.getUserId());
  774. loginReq.setRelationId(relation.getId());
  775. loginReq.setGoodsId(goodsId);
  776. try {
  777. String aiVerifyCode = getAiVerifyCode(loginReq);
  778. if (StrUtil.isEmpty(aiVerifyCode)) {
  779. throw BusinessRuntimeException.getInstance("");
  780. }
  781. return aiVerifyCode;
  782. } catch (Exception e) {
  783. if (StrUtil.equals(loginReq.getLang(), Constant.EN_US)) {
  784. throw BusinessRuntimeException.getInstance("Please verify that the link was sent");
  785. }
  786. throw BusinessRuntimeException.getInstance("请校验链接是否已发送");
  787. }
  788. }
  789. private DistributePosterGoodsDetailView setGoodsPoster(RenewalView ticket, User user, List<Long> userIds) {
  790. DistributePosterGoodsDetailView distributePosterGoodsDetailView = beanSearcher.searchFirst(DistributePosterGoodsDetailView.class, MapUtils.flatBuilder(request.getParameterMap())
  791. .field(DistributePosterGoodsFrontView::getGoodsId, ticket.getGoodsId()).build());
  792. if (distributePosterGoodsDetailView == null) {
  793. return null;
  794. }
  795. distributePosterGoodsDetailView.setNickname(user.getNickname());
  796. UserDistribute userDistribute = userDistributeMapper.selectOne(Wrappers.lambdaQuery(UserDistribute.class)
  797. .eq(UserDistribute::getUserId, user.getId())
  798. .eq(UserDistribute::getDeleted, 1)
  799. .last("limit 1"));
  800. if (userDistribute != null) {
  801. UserPlatDistributeRate userPlatDistributeRate = userPlatDistributeRateMapper.selectOne(Wrappers.lambdaQuery(UserPlatDistributeRate.class)
  802. .eq(UserPlatDistributeRate::getDistributeId, userDistribute.getId())
  803. .eq(UserPlatDistributeRate::getGoodsId, ticket.getGoodsId())
  804. .last("limit 1"));
  805. if (userPlatDistributeRate != null) {
  806. distributePosterGoodsDetailView.setRate(userPlatDistributeRate.getRate());
  807. }
  808. }
  809. GoodsDon goodsDon = goodsDonMapper.selectById(ticket.getGoodsId());
  810. if (goodsDon.getIsSkuDistribute()) {
  811. if (userDistribute != null) {
  812. UserPlatSkuDistributeRate userPlatSkuDistributeRate = userPlatSkuDistributeRateMapper.selectOne(Wrappers.lambdaQuery(UserPlatSkuDistributeRate.class)
  813. .eq(UserPlatSkuDistributeRate::getDistributeId, userDistribute.getId())
  814. .eq(UserPlatSkuDistributeRate::getSkuId, ticket.getSkuId())
  815. .last("limit 1"));
  816. if (userPlatSkuDistributeRate != null) {
  817. distributePosterGoodsDetailView.setRate(userPlatSkuDistributeRate.getRate());
  818. }
  819. } else {
  820. DistributeGeneralSkuRate distributeGeneralSkuRate = distributeGeneralSkuRateMapper.selectOne(Wrappers.lambdaQuery(DistributeGeneralSkuRate.class)
  821. .eq(DistributeGeneralSkuRate::getSkuId, ticket.getSkuId())
  822. .last("limit 1"));
  823. if (distributeGeneralSkuRate != null) {
  824. distributePosterGoodsDetailView.setRate(distributeGeneralSkuRate.getRate());
  825. }
  826. }
  827. }
  828. //用户推广海报记录id
  829. Optional.ofNullable(userDistributePosterRecordMapper.selectOne(Wrappers.lambdaQuery(UserDistributePosterRecord.class)
  830. .eq(UserDistributePosterRecord::getPosterId, distributePosterGoodsDetailView.getId())
  831. .in(UserDistributePosterRecord::getUserId, userIds)
  832. .last("limit 1"))).ifPresent(re -> distributePosterGoodsDetailView.setRid(re.getId()));
  833. return distributePosterGoodsDetailView;
  834. }
  835. private void setRenewDiscount(RenewalView ticket) {
  836. if (ticket.getIsMirror()) {
  837. RenewUpgradePackage renewUpgradePackage = renewUpgradePackageMapper.selectOne(Wrappers.lambdaQuery(RenewUpgradePackage.class)
  838. .eq(RenewUpgradePackage::getGoodsId, ticket.getGoodsId())
  839. .eq(RenewUpgradePackage::getStatus, 1)
  840. .eq(RenewUpgradePackage::getDeleted, 1)
  841. .eq(RenewUpgradePackage::getSkuId, ticket.getSkuId())
  842. .orderByAsc(RenewUpgradePackage::getDiscount)
  843. .last("limit 1")
  844. .select(RenewUpgradePackage::getId, RenewUpgradePackage::getDiscount));
  845. if (renewUpgradePackage != null) {
  846. ticket.setDiscount(renewUpgradePackage.getDiscount());
  847. }
  848. }
  849. }
  850. private void setMirrorTicketInfo(RenewalView ticket) {
  851. //设置MJ镜像信息
  852. setMjMirrorInfo(ticket);
  853. //设置GPT镜像信息
  854. setGptMirrorInfo(ticket);
  855. //clause pro
  856. setClaudeProInfo(ticket);
  857. //luma
  858. setLumaInfo(ticket);
  859. }
  860. private void setMjMirrorInfo(RenewalView ticket) {
  861. if (ticket.getGoodsId() == 26 && ticket.getIsMirror()) {
  862. List<UpgradePackage> upgradePackages = upgradePackageMapper.selectList(Wrappers.lambdaQuery(UpgradePackage.class).apply("JSON_CONTAINS(sku_ids,'\"" + ticket.getSkuId() + "\"')").eq(UpgradePackage::getStatus, Boolean.TRUE).eq(UpgradePackage::getDeleted, Boolean.TRUE));
  863. if (CollectionUtil.isNotEmpty(upgradePackages)) {
  864. upgradePackages.stream().map(e -> e.getPrice().divide(BigDecimal.valueOf(e.getNum()), 2, RoundingMode.HALF_UP)).min(BigDecimal::compareTo).ifPresent(ticket::setMjPackagePrice);
  865. }
  866. try {
  867. MidjourneyUserView search = beanSearcher.searchFirst(MidjourneyUserView.class, MapUtils.flatBuilder(request.getParameterMap())
  868. .field(MidjourneyUserView::getUserId, ticket.getUserId()).field(MidjourneyUserView::getRelationId, ticket.getRelationId())
  869. .onlySelect(MidjourneyUserView::getMjUserRelaxNum, MidjourneyUserView::getMjUserFastNum, MidjourneyUserView::getIsCar)
  870. .build());
  871. if (search == null) {
  872. MidjourneyUser midjourneyUser = midjourneyAccountService.getMidjourneyUserToken(ticket.getUserId(), ticket.getRelationId());
  873. ticket.setMjUserFastNum(midjourneyUser.getMjFastNum());
  874. ticket.setMjUserRelaxNum(midjourneyUser.getMjRelaxNum());
  875. ticket.setIsCar(false);
  876. } else {
  877. ticket.setIsCar(search.getIsCar());
  878. ticket.setMjUserFastNum(search.getMjUserFastNum());
  879. ticket.setMjUserRelaxNum(search.getMjUserRelaxNum());
  880. }
  881. } catch (Exception e) {
  882. }
  883. }
  884. }
  885. public void setGptMirrorInfo(RenewalView ticket) {
  886. if (ticket.getGoodsId() == 18 && ticket.getIsCar() && ticket.getExpiryTime() != null) {
  887. try {
  888. //gpt用户镜像
  889. ChatGptUserView userInfo = chatGptAccountService.getUserInfo(ticket.getUserId(), ticket.getRelationId());
  890. ticket.setGptUserLimitNum(userInfo.getLimitNum());
  891. ticket.setGptUserLimitTime(userInfo.getLimitTime());
  892. ticket.setUse(userInfo.getUse());
  893. Integer count = upgradePackageMapper.selectCount(Wrappers.lambdaQuery(UpgradePackage.class).apply("JSON_CONTAINS(sku_ids,'\"" + ticket.getSkuId() + "\"')")
  894. .gt(UpgradePackage::getNum, userInfo.getLimitNum())
  895. .eq(UpgradePackage::getStatus, Boolean.TRUE)
  896. .eq(UpgradePackage::getGptType, 0)
  897. .eq(UpgradePackage::getDeleted, Boolean.TRUE));
  898. ticket.setUpgrade(count > 0 ? true : false);
  899. ticket.setPackageId(userInfo.getPackageId());
  900. if (userInfo.getPackageId() != 0) {
  901. UpgradePackage upgradePackage = upgradePackageMapper.selectById(userInfo.getPackageId());
  902. ticket.setPackagePrice(upgradePackage.getPrice());
  903. Long upgradeOrderDonSkuId = upgradePackage.getUpgradeSkuId();
  904. GoodsDonSkuRenewView renewSku = beanSearcher.searchFirst(GoodsDonSkuRenewView.class, MapUtils.builder().field(GoodsDonSkuRenewView::getSkuId, upgradeOrderDonSkuId).build());
  905. renewSku.setPackageId(userInfo.getPackageId());
  906. ticket.setRenewSku(renewSku);
  907. }
  908. ticket.setIsRenewPackage(userInfo.getIsRenewPackage());
  909. Long renewSkuId = userInfo.getRenewSkuId();
  910. if (renewSkuId != null) {
  911. GoodsDonSkuRenewView upgradeSkuRenewView = ticket.getRenewSku();
  912. GoodsDonSkuRenewView renewSku = beanSearcher.searchFirst(GoodsDonSkuRenewView.class, MapUtils.builder().field(GoodsDonSkuRenewView::getSkuId, renewSkuId).build());
  913. //续费升级是更高级规格
  914. if (upgradeSkuRenewView == null || (renewSku.getGptUserLimitNum() >= upgradeSkuRenewView.getGptUserLimitNum() && renewSku.getMonths() >= userInfo.getMonths())) {
  915. Optional.ofNullable(orderDonRenewRecordMapper.selectOne(Wrappers.lambdaQuery(OrderDonRenewRecord.class)
  916. .eq(OrderDonRenewRecord::getOrderId, userInfo.getRenewOrderId())
  917. .last("limit 1"))).ifPresent(e -> renewSku.setOriginalOrderId(e.getOrderId()));
  918. ticket.setRenewSku(renewSku);
  919. }
  920. }
  921. } catch (Exception e) {
  922. }
  923. }
  924. }
  925. public void setClaudeProInfo(RenewalView ticket) {
  926. //clause pro
  927. if (ticket.getGoodsId() == 75l && ticket.getExpiryTime() != null) {
  928. try {
  929. ClaudeUserView userInfo = claudeService.getUserInfo(ticket.getUserId(), ticket.getRelationId());
  930. ticket.setGptUserLimitNum(userInfo.getLimitNum());
  931. ticket.setGptUserLimitTime(userInfo.getLimitTime());
  932. ticket.setUse(userInfo.getUse());
  933. } catch (Exception e) {
  934. }
  935. }
  936. }
  937. public void setLumaInfo(RenewalView ticket) {
  938. if (ticket.getGoodsId() == Constant.LUMA_GOODS_ID && ticket.getExpiryTime() != null) {
  939. try {
  940. List<UpgradePackage> upgradePackages = upgradePackageMapper.selectList(Wrappers.lambdaQuery(UpgradePackage.class).apply("JSON_CONTAINS(sku_ids,'\"" + ticket.getSkuId() + "\"')").eq(UpgradePackage::getStatus, Boolean.TRUE).eq(UpgradePackage::getDeleted, Boolean.TRUE));
  941. if (CollectionUtil.isNotEmpty(upgradePackages)){
  942. upgradePackages.stream().map(e -> e.getPrice().divide(BigDecimal.valueOf(e.getNum()), 2, RoundingMode.HALF_UP)).min(BigDecimal::compareTo).ifPresent(ticket::setLumaPackagePrice);
  943. }
  944. LumaUser lumaUser = lumaService.getLumaUser(ticket.getUserId(), ticket.getRelationId());
  945. ticket.setLumaUserNum(lumaUser.getNum());
  946. } catch (Exception e) {
  947. }
  948. }
  949. }
  950. }