GroupRelationController.java 56 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146
  1. package com.cyksj.web.controller.group;
  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.lang.Assert;
  7. import cn.hutool.core.thread.ThreadUtil;
  8. import cn.hutool.core.util.StrUtil;
  9. import cn.hutool.extra.servlet.ServletUtil;
  10. import cn.hutool.json.JSONObject;
  11. import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
  12. import com.baomidou.mybatisplus.core.toolkit.Wrappers;
  13. import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
  14. import com.cyksj.common.annotation.NoSubmit;
  15. import com.cyksj.common.constant.Constant;
  16. import com.cyksj.common.exception.BusinessRuntimeException;
  17. import com.cyksj.common.snowflake.Sequence;
  18. import com.cyksj.common.task.GlobalThreadPoolTaskExecutor;
  19. import com.cyksj.common.util.GoogleGenerator;
  20. import com.cyksj.common.util.Jsons;
  21. import com.cyksj.common.util.StringUtil;
  22. import com.cyksj.dto.Result;
  23. import com.cyksj.enums.GatewayResponse;
  24. import com.cyksj.mapper.*;
  25. import com.cyksj.mapper.manage.form.FormFieldsDataMapper;
  26. import com.cyksj.mapper.manage.form.QuestionnairePromotionMapper;
  27. import com.cyksj.model.dto.DoubleVerifyDto;
  28. import com.cyksj.model.dto.QuestionnaireView;
  29. import com.cyksj.model.entity.*;
  30. import com.cyksj.model.manage.views.AccountView;
  31. import com.cyksj.model.manage.views.GroupsRelationView;
  32. import com.cyksj.model.request.*;
  33. import com.cyksj.model.response.GptStandbyResp;
  34. import com.cyksj.model.views.*;
  35. import com.cyksj.redis.RedisService;
  36. import com.cyksj.service.chatgpt.ChatGptAuthService;
  37. import com.cyksj.service.mange.CmsOrderDonService;
  38. import com.cyksj.service.mange.coupon.CouponCommonService;
  39. import com.cyksj.service.mange.ticket.TicketAdvertiseConfigClickRecordService;
  40. import com.cyksj.service.order.OrderDonService;
  41. import com.cyksj.service.relation.GroupRelationFrontService;
  42. import com.cyksj.service.relation.GroupsRelationNetflixService;
  43. import com.cyksj.service.user.UserBindRelationService;
  44. import com.cyksj.service.user.UserService;
  45. import com.cyksj.web.util.StpUserUtil;
  46. import com.ejlchina.searcher.BeanSearcher;
  47. import com.ejlchina.searcher.SearchResult;
  48. import com.ejlchina.searcher.operator.LessEqual;
  49. import com.ejlchina.searcher.param.Operator;
  50. import com.ejlchina.searcher.util.MapBuilder;
  51. import com.ejlchina.searcher.util.MapUtils;
  52. import lombok.RequiredArgsConstructor;
  53. import lombok.extern.slf4j.Slf4j;
  54. import org.springframework.transaction.annotation.Transactional;
  55. import org.springframework.validation.annotation.Validated;
  56. import org.springframework.web.bind.annotation.*;
  57. import javax.servlet.http.HttpServletRequest;
  58. import javax.validation.constraints.NotEmpty;
  59. import javax.validation.constraints.NotNull;
  60. import java.math.BigDecimal;
  61. import java.math.RoundingMode;
  62. import java.util.*;
  63. import java.util.concurrent.TimeUnit;
  64. import java.util.concurrent.atomic.AtomicInteger;
  65. import java.util.concurrent.atomic.AtomicLong;
  66. import java.util.stream.Collectors;
  67. /**
  68. * @author chan
  69. * @date 2022/9/27 11:48 AM
  70. */
  71. @Slf4j
  72. @RequiredArgsConstructor
  73. @RestController
  74. @RequestMapping("/applets/group/relation")
  75. public class GroupRelationController {
  76. private final BeanSearcher beanSearcher;
  77. private final OrderDonService orderDonService;
  78. private final GroupsRelationMapper relationMapper;
  79. private final GroupRelationFrontService groupRelationFrontService;
  80. private final UserService userService;
  81. private final UserBindRelationService userBindRelationService;
  82. private final TicketPwdViewRecordMapper ticketPwdViewRecordMapper;
  83. private final HttpServletRequest request;
  84. private final AccountDoubleVerifyRecordMapper accountDoubleVerifyRecordMapper;
  85. private final DoubleVerifyClickRecordMapper doubleVerifyRecordMapper;
  86. private final RedisService redisService;
  87. private final DoubleVerifyClickRefreshRecordMapper refreshRecordMapper;
  88. private final QuestionResponseRecordMapper questionResponseRecordMapper;
  89. private final CouponCommonService couponCommonService;
  90. private final FormFieldsDataMapper formFieldsDataMapper;
  91. private final QuestionnairePromotionMapper questionnairePromotionMapper;
  92. private final TicketAdvertiseConfigClickRecordService ticketAdvertiseConfigClickRecordService;
  93. private final GlobalThreadPoolTaskExecutor THREAD_POOL;
  94. private final ChatGptAuthService chatGptAuthService;
  95. private final GoodsCoursewareFileMapper goodsCoursewareFileMapper;
  96. private final GptTicketStandbyMapper gptTicketStandbyMapper;
  97. private final CmsOrderDonService cmsOrderDonService;
  98. private final GoodsDonSkuMapper goodsDonSkuMapper;
  99. private final AccountBlockedReplaceRecordMapper accountBlockedReplaceRecordMapper;
  100. private final OrderDonMapper orderDonMapper;
  101. private final UserGoodsNewbieGuideRecordMapper userGoodsNewbieGuideRecordMapper;
  102. private final GroupsRelationNetflixService groupsRelationNetflixService;
  103. private final ChatgptUserMapper chatgptUserMapper;
  104. private final UpgradeOrderDonMapper upgradeOrderDonMapper;
  105. private final UserBenefitsOrderRecordMapper userBenefitsOrderRecordMapper;
  106. private final static Sequence SEQUENCE = new Sequence(0);
  107. @RequestMapping("/get/renewal")
  108. public Result<SearchResult<RenewalView>> get(Boolean isLoginPopularize, String customId, String account, String orderNo, Integer cmt) {
  109. long userId = StpUserUtil.getLoginIdAsLong();
  110. SearchResult<RenewalView> list = groupRelationFrontService.getMyTicket(userId, isLoginPopularize, customId, account, orderNo, cmt);
  111. return GatewayResponse.SUCCESS.newBuilder().toResult(list);
  112. }
  113. @GetMapping("/get/pay/goods")
  114. public Result<List<RenewalView>> getHasPayGoods() {
  115. long userId = StpUserUtil.getLoginIdAsLong();
  116. List<RenewalView> hasPayGoods = groupRelationFrontService.getHasPayGoods(userId);
  117. return GatewayResponse.SUCCESS.newBuilder().toResult(hasPayGoods);
  118. }
  119. @PostMapping("/post/renewal")
  120. public Result<OrderDon> renewal(@RequestBody OrderPayRequest payRequest) throws Exception {
  121. long userId = StpUserUtil.getLoginIdAsLong();
  122. payRequest.setUserId(userId);
  123. String ip = ServletUtil.getClientIP(request);
  124. payRequest.setIp(ip);
  125. OrderDon orderDon = orderDonService.renewal(payRequest);
  126. return GatewayResponse.SUCCESS.newBuilder().toResult(orderDon);
  127. }
  128. @PutMapping("/update/set/account")
  129. public Result<String> setAccount(@RequestBody GroupsRelation relation) {
  130. long userId = StpUserUtil.getLoginIdAsLong();
  131. List<Long> userIds = userBindRelationService.getRelationUserIdList(userId, null);
  132. GroupsRelation re = relationMapper.selectOne(Wrappers.lambdaQuery(GroupsRelation.class)
  133. .eq(GroupsRelation::getId, relation.getId())
  134. .in(GroupsRelation::getUserId, userIds)
  135. .last(" limit 1"));
  136. if (re == null) {
  137. throw new BusinessRuntimeException("该车票不存在,请联系客服.");
  138. }
  139. LambdaUpdateWrapper<GroupsRelation> updateWrapper = Wrappers.lambdaUpdate(GroupsRelation.class)
  140. .set(GroupsRelation::getAccount, relation.getAccount())
  141. .set(GroupsRelation::getPassword, relation.getPassword())
  142. .eq(GroupsRelation::getId, relation.getId());
  143. if (re.getRechargeStatus() != null) {
  144. if (re.getRechargeStatus() == GroupsRelation.RechargeStatus.complete) {
  145. throw BusinessRuntimeException.getInstance("代充账号已充值");
  146. }
  147. if (StrUtil.isEmpty(relation.getAccount()) || StrUtil.isEmpty(relation.getPassword())) {
  148. throw BusinessRuntimeException.getInstance("请输入正确的账号密码信息");
  149. }
  150. if (re.getRechargeStatus() == GroupsRelation.RechargeStatus.error) {
  151. updateWrapper.set(GroupsRelation::getRechargeStatus, GroupsRelation.RechargeStatus.waiting);
  152. }
  153. }
  154. relationMapper.update(relation, updateWrapper);
  155. return GatewayResponse.SUCCESS.newBuilder().toResult();
  156. }
  157. /**
  158. * 查询是否加入了企业微信
  159. */
  160. @GetMapping("/check/joinCorpWx")
  161. public Result<Boolean> isJoinCorpWx() {
  162. long userId = StpUserUtil.getLoginIdAsLong();
  163. Boolean flag = groupRelationFrontService.isJoinCorpWx(userId, false, false);
  164. return GatewayResponse.SUCCESS.newBuilder().toResult(flag);
  165. }
  166. /**
  167. * 获取全部车票
  168. */
  169. @GetMapping("/get")
  170. public Result<List<UserTicketView>> getUserTicketView() {
  171. long userId = StpUserUtil.getLoginIdAsLong();
  172. List<Long> userIds = userBindRelationService.getRelationUserIdList(userId, null);
  173. List<UserTicketView> ticketViews = beanSearcher.searchAll(UserTicketView.class, MapUtils.flatBuilder(request.getParameterMap())
  174. .field(UserTicketView::getUserId, userIds).op(Operator.InList)
  175. .field(RenewalView::getStatus, List.of("validity", "outside")).op(Operator.InList)
  176. .field(RenewalView::getExpiryTime, DateTime.now()).op(Operator.GreaterThan)
  177. .orderBy(UserTicketView::getRelationId).asc()
  178. .build());
  179. return GatewayResponse.SUCCESS.newBuilder().toResult(ticketViews);
  180. }
  181. /**
  182. * 记录查看ChatGPT车票密码
  183. */
  184. @GetMapping("/recordView/{relationId}")
  185. public Result<String> recordGPTPwdView(@PathVariable Long relationId) {
  186. long userId = StpUserUtil.getLoginIdAsLong();
  187. List<Long> userIds = userBindRelationService.getRelationUserIdList(userId, null);
  188. GroupsRelationView groupsRelationView = beanSearcher.searchFirst(GroupsRelationView.class, MapUtils.builder()
  189. .field(GroupsRelationView::getUserId, userIds).op(Operator.InList)
  190. .field(GroupsRelationView::getId, relationId).build());
  191. if (groupsRelationView == null) {
  192. log.info("userId:{}查看relationId:{}车票不存在", userId, relationId);
  193. throw BusinessRuntimeException.getInstance("该车票已不存在");
  194. }
  195. if (groupsRelationView.getAccountId() == null) throw BusinessRuntimeException.getInstance("该车队未配置账号");
  196. if (groupRelationFrontService == null) throw BusinessRuntimeException.getInstance("车票已不存在");
  197. TicketPwdViewRecord viewRecord = new TicketPwdViewRecord();
  198. viewRecord.setUserId(userId);
  199. viewRecord.setRelationId(relationId);
  200. viewRecord.setSkuId(groupsRelationView.getSkuId());
  201. viewRecord.setOperateLocation(ServletUtil.getClientIP(request));
  202. viewRecord.setAccount(groupsRelationView.getTripsAccount());
  203. viewRecord.setPassword(groupsRelationView.getTripsPassword());
  204. ticketPwdViewRecordMapper.insert(viewRecord);
  205. if (groupsRelationView.getGoodsId() == 18 && StrUtil.isEmpty(groupsRelationView.getApiSecret())) {
  206. THREAD_POOL.execute(() -> {
  207. //车队所有人查看密码
  208. Integer num = groupsRelationView.getGtNum();
  209. Integer viewNum = relationMapper.selectViewPwdCount(groupsRelationView.getGroupsId());
  210. if (num <= viewNum) {
  211. AccountDoubleVerifyRecord exist = accountDoubleVerifyRecordMapper.selectOne(Wrappers.lambdaQuery(AccountDoubleVerifyRecord.class)
  212. .eq(AccountDoubleVerifyRecord::getAccountId, groupsRelationView.getAccountId())
  213. .eq(AccountDoubleVerifyRecord::getDeleted, true).last("limit 1"));
  214. if (exist == null) {
  215. if (redisService.setNx(String.format("%s-%s", groupsRelationView.getAccountId(), groupsRelationView.getId()), groupsRelationView.getId(), 60l)) {
  216. //记录
  217. AccountDoubleVerifyRecord accountDoubleVerifyRecord = new AccountDoubleVerifyRecord();
  218. accountDoubleVerifyRecord.setAccountId(groupsRelationView.getAccountId());
  219. accountDoubleVerifyRecord.setAccount(groupsRelationView.getTripsAccount());
  220. accountDoubleVerifyRecord.setGroupsId(groupsRelationView.getGroupsId());
  221. accountDoubleVerifyRecord.setSkuId(groupsRelationView.getSkuId());
  222. accountDoubleVerifyRecord.setRemark("车队所有人看过密码");
  223. accountDoubleVerifyRecordMapper.insert(accountDoubleVerifyRecord);
  224. }
  225. }
  226. }
  227. });
  228. }
  229. return GatewayResponse.SUCCESS.newBuilder().toResult(groupsRelationView.getTripsPassword());
  230. }
  231. /**
  232. * 获取AI类 ChatGPT产品谷歌验证码
  233. */
  234. @GetMapping("/get/authCode")
  235. public Result<String> getAuthCode(Long relationId) {
  236. long userId = StpUserUtil.getLoginIdAsLong();
  237. List<Long> userIds = userBindRelationService.getRelationUserIdList(userId, null);
  238. if (relationId == null) throw BusinessRuntimeException.getInstance("车票不存在");
  239. GroupsRelationView groupsRelationView = beanSearcher.searchFirst(GroupsRelationView.class, MapUtils.builder()
  240. .field(GroupsRelationView::getId, relationId)
  241. .field(GroupsRelationView::getUserId, userIds).op(Operator.InList).build());
  242. if (groupsRelationView == null) throw BusinessRuntimeException.getInstance("车票不存在");
  243. if (StrUtil.isEmpty(groupsRelationView.getApiSecret())) throw BusinessRuntimeException.getInstance("未开启验证");
  244. DateTime now = DateTime.now();
  245. Integer count = doubleVerifyRecordMapper.selectCount(Wrappers.lambdaQuery(DoubleVerifyClickRecord.class)
  246. .in(DoubleVerifyClickRecord::getUserId, userIds)
  247. .eq(DoubleVerifyClickRecord::getRelationId, relationId)
  248. .eq(DoubleVerifyClickRecord::getAccountId, groupsRelationView.getAccountId())
  249. .between(DoubleVerifyClickRecord::getCreatedTime, DateUtil.beginOfMonth(now), DateUtil.endOfMonth(now)));
  250. //获取双重验证码
  251. Boolean isHasVerifyCode = StrUtil.isNotBlank(groupsRelationView.getVerifyCode()) ? true : false;
  252. //出去亚马逊 获取限制
  253. if (groupsRelationView.getGoodsId() != 6) {
  254. Integer num = groupRelationFrontService.getUserCodeNumBySkuId(userId, groupsRelationView.getSkuId(), isHasVerifyCode);
  255. if (count >= num) throw BusinessRuntimeException.getInstance("获取双重验证码次数上限");
  256. }
  257. //一分钟内 只能一人获取
  258. boolean b = redisService.setNx(RedisService.key.DOUBLE_VERIFY_CODE_VIEW_MINUTES_KEY.getName() + groupsRelationView.getTripsAccount(), relationId, RedisService.key.DOUBLE_VERIFY_CODE_VIEW_MINUTES_KEY.getTimeout());
  259. if (!b) {
  260. throw BusinessRuntimeException.getInstance("一分钟内已有人获取该账号验证码,请稍后获取..");
  261. }
  262. int second = now.second();
  263. if (second < 30 && 30 - second < 3) {
  264. ThreadUtil.sleep(30 - second + 1, TimeUnit.SECONDS);
  265. } else if (second > 30 && 60 - second < 3) {
  266. ThreadUtil.sleep(60 - second + 1, TimeUnit.SECONDS);
  267. }
  268. StringBuilder sb = new StringBuilder();
  269. JSONObject re = new JSONObject();
  270. try {
  271. long code = GoogleGenerator.getCode(groupsRelationView.getApiSecret(), now.getTime());
  272. sb.append(code);
  273. while (sb.length() < 6) {
  274. sb.insert(0, 0);
  275. }
  276. re.putOpt("code", sb.toString());
  277. int nowSecond = DateTime.now().second();
  278. int time = 0;
  279. if (nowSecond < 30) {
  280. time = 30 - nowSecond;
  281. } else {
  282. time = 60 - nowSecond;
  283. }
  284. re.putOpt("time", time);
  285. DoubleVerifyClickRecord doubleVerifyClickRecord = new DoubleVerifyClickRecord();
  286. doubleVerifyClickRecord.setRelationId(relationId);
  287. doubleVerifyClickRecord.setUserId(userId);
  288. doubleVerifyClickRecord.setAccountId(groupsRelationView.getAccountId());
  289. doubleVerifyClickRecord.setAccount(groupsRelationView.getTripsAccount());
  290. doubleVerifyClickRecord.setSkuId(groupsRelationView.getSkuId());
  291. doubleVerifyClickRecord.setCode(sb.toString());
  292. doubleVerifyClickRecord.setRemainTime(time);
  293. doubleVerifyRecordMapper.insert(doubleVerifyClickRecord);
  294. DoubleVerifyDto doubleVerifyDto = new DoubleVerifyDto();
  295. doubleVerifyDto.setClickId(doubleVerifyClickRecord.getId());
  296. doubleVerifyDto.setApiSecret(groupsRelationView.getApiSecret());
  297. redisService.set(String.format("%s-%s", userId, sb.toString()), 0, 60 * 10l);
  298. redisService.set(String.format("%s/%s", userId, sb.toString()), Jsons.toJson(doubleVerifyDto), 60 * 10l);
  299. } catch (Exception e) {
  300. throw BusinessRuntimeException.getInstance("获取双重验证码错误,请联系客服");
  301. }
  302. return GatewayResponse.SUCCESS.newBuilder().toResult(re.toString());
  303. }
  304. /**
  305. * 刷新验证码
  306. */
  307. @GetMapping("/refresh/code")
  308. public Result<String> refreshCode(String code) {
  309. long userId = StpUserUtil.getLoginIdAsLong();
  310. String numKey = String.format("%s-%s", userId, code);
  311. Object num = redisService.get(numKey);
  312. String objKey = String.format("%s/%s", userId, code);
  313. Object objValue = redisService.get(objKey);
  314. if (objValue == null || num == null) {
  315. throw BusinessRuntimeException.getInstance("请重新获取双重验证码");
  316. }
  317. Integer refreshNum = Integer.parseInt(num.toString());
  318. String apiSecret = null;
  319. Long clickId = 0l;
  320. try {
  321. DoubleVerifyDto dto = Jsons.parseObject(objValue.toString(), DoubleVerifyDto.class);
  322. apiSecret = dto.getApiSecret();
  323. clickId = dto.getClickId();
  324. } catch (Exception e) {
  325. apiSecret = objValue.toString();
  326. }
  327. if (refreshNum >= 3) {
  328. redisService.del(numKey);
  329. redisService.del(objKey);
  330. throw BusinessRuntimeException.getInstance("刷新次数已达到3次,请重新获取验证码");
  331. }
  332. if (apiSecret == null) {
  333. throw BusinessRuntimeException.getInstance("请重新获取双重验证码");
  334. }
  335. StringBuilder sb = new StringBuilder();
  336. try {
  337. long c = GoogleGenerator.getCode(apiSecret, DateTime.now().getTime());
  338. sb.append(c);
  339. while (sb.length() < 6) {
  340. sb.insert(0, 0);
  341. }
  342. redisService.incr(numKey, 1l);
  343. } catch (Exception e) {
  344. throw BusinessRuntimeException.getInstance("刷新双重验证码错误,请联系客服");
  345. }
  346. if (clickId != 0) {
  347. int nowSecond = DateTime.now().second();
  348. int time = 0;
  349. if (nowSecond < 30) {
  350. time = 30 - nowSecond;
  351. } else {
  352. time = 60 - nowSecond;
  353. }
  354. //刷新双重验证码记录
  355. DoubleVerifyClickRefreshRecord refreshRecord = new DoubleVerifyClickRefreshRecord();
  356. refreshRecord.setClickId(clickId);
  357. refreshRecord.setUserId(userId);
  358. refreshRecord.setCode(sb.toString());
  359. refreshRecord.setRemainTime(time);
  360. refreshRecordMapper.insert(refreshRecord);
  361. }
  362. return GatewayResponse.SUCCESS.newBuilder().toResult(sb.toString());
  363. }
  364. /**
  365. * 获取双重验证码记录
  366. */
  367. @GetMapping("/get/doubleVerify/codeList")
  368. public Result<List<DoubleVerifyCodeView>> getDoubleVerifyCodeList(Long relationId) {
  369. long userId = StpUserUtil.getLoginIdAsLong();
  370. List<DoubleVerifyCodeView> views = doubleVerifyRecordMapper.getDoubleVerifyCodeList(userId, relationId);
  371. return GatewayResponse.SUCCESS.newBuilder().toResult(views);
  372. }
  373. /**
  374. * 用户是不是自然流量渠道
  375. * 且未回答答题
  376. */
  377. @GetMapping("/natural/channel")
  378. public Result<Boolean> isNaturalChannel() {
  379. long userId = StpUserUtil.getLoginIdAsLong();
  380. String question_key = RedisService.key.QUESTION_RESPONSE_KEY.getNameFormat(userId);
  381. if (redisService.get(question_key) != null) {
  382. return GatewayResponse.SUCCESS.newBuilder().toResult(false);
  383. }
  384. User user = userService.getById(userId);
  385. if (user.getPopularizeId() != 0) {
  386. redisService.set(question_key, userId, RedisService.key.QUESTION_RESPONSE_KEY.getTimeout());
  387. return GatewayResponse.SUCCESS.newBuilder().toResult(false);
  388. }
  389. if (user.getPopularizeId() == 0) {
  390. QuestionResponseRecord record = questionResponseRecordMapper.selectOne(Wrappers.lambdaQuery(QuestionResponseRecord.class)
  391. .eq(QuestionResponseRecord::getUserId, userId).select(QuestionResponseRecord::getId).last("limit 1"));
  392. if (record != null) {
  393. redisService.set(question_key, userId, RedisService.key.QUESTION_RESPONSE_KEY.getTimeout());
  394. return GatewayResponse.SUCCESS.newBuilder().toResult(false);
  395. }
  396. return GatewayResponse.SUCCESS.newBuilder().toResult(true);
  397. }
  398. return GatewayResponse.SUCCESS.newBuilder().toResult(false);
  399. }
  400. /**
  401. * 问卷记录
  402. */
  403. @PostMapping("/record/replyQuestion")
  404. public Result<String> recordReplyQuestion(@RequestBody @Validated QuestionResponseRecord record) {
  405. long userId = StpUserUtil.getLoginIdAsLong();
  406. User user = userService.getById(userId);
  407. String nickname = user.getNickname();
  408. String question_key = RedisService.key.QUESTION_RESPONSE_KEY.getNameFormat(userId);
  409. QuestionResponseRecord dbRecord = questionResponseRecordMapper.selectOne(Wrappers.lambdaQuery(QuestionResponseRecord.class)
  410. .eq(QuestionResponseRecord::getUserId, userId).select(QuestionResponseRecord::getId).last("limit 1"));
  411. if (dbRecord == null) {
  412. if (redisService.setNx(String.format("%s-%s", userId, nickname), userId, 10l)) {
  413. record.setUserId(userId);
  414. record.setNickname(nickname);
  415. questionResponseRecordMapper.insert(record);
  416. //发放优惠券
  417. couponCommonService.sendCouponToUser(userId, 100l, 0l, 0l, 0l, CouponUser.Channel.ques_response);
  418. redisService.set(question_key, userId, RedisService.key.QUESTION_RESPONSE_KEY.getTimeout());
  419. }
  420. }
  421. return GatewayResponse.SUCCESS.newBuilder().toResult();
  422. }
  423. /**
  424. * 获取对应的动态问卷
  425. */
  426. @GetMapping("/get/questionnaire")
  427. public Result<List<QuestionnaireView>> getQuestionnaireView(Long promotionId) {
  428. QuestionnairePromotion promotion = questionnairePromotionMapper.selectById(promotionId);
  429. if (promotion == null || !promotion.getDeleted()) throw BusinessRuntimeException.getInstance("问卷不存在");
  430. Long templateId = promotion.getTemplateId();
  431. List<QuestionnaireView> questionnaireViews = beanSearcher.searchAll(QuestionnaireView.class, MapUtils.builder()
  432. .field(QuestionnaireView::getPromotionId, promotionId)
  433. .orderBy(QuestionnaireView::getSorted).asc()
  434. .orderBy(QuestionnaireView::getFieldsId).asc()
  435. .build());
  436. return GatewayResponse.SUCCESS.newBuilder().toResult(questionnaireViews);
  437. }
  438. /**
  439. * 记录问卷
  440. */
  441. @PostMapping("/record/questionnaire/{promotionId}")
  442. @Transactional(rollbackFor = Exception.class)
  443. @NoSubmit
  444. public Result<String> recordQuestionnaire(@PathVariable Long promotionId, String showId, @RequestBody List<FormFieldsData> answers) {
  445. Long userId = StpUserUtil.getUserIdAfterLogin();
  446. Long groupsId = SEQUENCE.nextId();
  447. List<QuestionnairePromotionFieldsListView> promotionFieldsListViews = beanSearcher.searchAll(QuestionnairePromotionFieldsListView.class, MapUtils.builder().field(QuestionnairePromotionFieldsListView::getPromotionId, promotionId).build());
  448. if (CollUtil.isEmpty(promotionFieldsListViews)) throw BusinessRuntimeException.getInstance("问卷已结束");
  449. if (promotionFieldsListViews.size() != answers.size()) throw BusinessRuntimeException.getInstance("请完成所有问题");
  450. log.info("开始记录问卷:{}", promotionId);
  451. answers.forEach(answer -> {
  452. // if (StringUtil.isNotBlank(showId)) {
  453. // answer.setUserId(userService.getUserIdByShowId(showId));
  454. // }
  455. answer.setUserId(userId);
  456. Long fieldsId = answer.getFieldsId();
  457. String content = answer.getContent();
  458. if (fieldsId == null || StrUtil.isBlank(content)) {
  459. throw BusinessRuntimeException.getInstance("必填项为空");
  460. }
  461. answer.setPromotionId(promotionId);
  462. answer.setGroupsId(groupsId);
  463. formFieldsDataMapper.insert(answer);
  464. });
  465. return GatewayResponse.SUCCESS.newBuilder().toResult();
  466. }
  467. /**
  468. * 查询用户是否填写问卷
  469. */
  470. @GetMapping("/check/questionnaire/{promotionId}")
  471. public Result<Boolean> checkQuestionnaire(@PathVariable Long promotionId) {
  472. long userId = StpUserUtil.getLoginIdAsLong();
  473. List<Long> userIdList = userBindRelationService.getRelationUserIdList(userId, null);
  474. Integer count = formFieldsDataMapper.selectCount(Wrappers.lambdaQuery(FormFieldsData.class).in(FormFieldsData::getUserId, userIdList).eq(FormFieldsData::getPromotionId, promotionId));
  475. return GatewayResponse.SUCCESS.newBuilder().toResult(count > 0);
  476. }
  477. /**
  478. * 对应平台车票 广告配置列表
  479. */
  480. @GetMapping("/get/advertise/{goodsId}")
  481. public Result<List<TicketAdvertiseConfigFrontView>> getTicketAdvertiseConfig(@PathVariable Long goodsId) {
  482. long userId = StpUserUtil.getLoginIdAsLong();
  483. log.info("userId:{}获取广告位配置", userId);
  484. List<TicketAdvertiseConfigFrontView> views = beanSearcher.searchAll(TicketAdvertiseConfigFrontView.class, MapUtils.flatBuilder(request.getParameterMap())
  485. .field(TicketAdvertiseConfig::getGoodsId, goodsId)
  486. .orderBy(TicketAdvertiseConfig::getSorted).desc()
  487. .orderBy(TicketAdvertiseConfig::getId).desc()
  488. .build());
  489. return GatewayResponse.SUCCESS.newBuilder().toResult(views);
  490. }
  491. /**
  492. * 记录用户点击车票广告
  493. */
  494. @PostMapping("/click/ticket/advertise/record/{configId}")
  495. public Result<String> recordClickTicketAdvertise(@PathVariable Long configId) {
  496. long userId = StpUserUtil.getLoginIdAsLong();
  497. ticketAdvertiseConfigClickRecordService.recordUserClickTicketAdvertise(userId, configId);
  498. return GatewayResponse.SUCCESS.newBuilder().toResult();
  499. }
  500. /**
  501. * 推荐平台
  502. */
  503. @GetMapping("/get/recommend/goods")
  504. public Result<Page<UserRecommendGoodsFrontView>> getRecommendGoodsViews(@RequestParam(defaultValue = "0") Integer start, @RequestParam(defaultValue = "5") Integer limit) {
  505. //推荐用户未购买的车票平台 优先展示ai类平台 然后是影视流媒体
  506. long userId = StpUserUtil.getLoginIdAsLong();
  507. List<Long> userIds = userBindRelationService.getRelationUserIdList(userId, null);
  508. List<Long> filter_goods_id = relationMapper.getTicketGoodsId(userIds, List.of("validity", "overdue", "outside"));
  509. //用户是否购买过奈飞产品
  510. Boolean isPayNf = false;
  511. if (filter_goods_id.contains(1l)) {
  512. isPayNf = true;
  513. } else {
  514. int count = orderDonService.count(Wrappers.lambdaQuery(OrderDon.class)
  515. .eq(OrderDon::getGoodsId, 1)
  516. .eq(OrderDon::getUserId, userId)
  517. .notIn(OrderDon::getStatus, Constant.noOrderAllStatus));
  518. if (count > 0) {
  519. //优先展示路由器、ai、流媒体
  520. isPayNf = true;
  521. }
  522. }
  523. Boolean filterCourseGoods = false;
  524. //GPT Plus基础2月 课程不展示
  525. Integer orders = orderDonMapper.selectCount(Wrappers.lambdaQuery(OrderDon.class)
  526. .in(OrderDon::getUserId, userIds)
  527. .eq(OrderDon::getSkuId, 444)
  528. .notIn(OrderDon::getStatus, Constant.noOrderStatus));
  529. if (orders > 0) {
  530. filterCourseGoods = true;
  531. }
  532. Page<UserRecommendGoodsFrontView> page = groupRelationFrontService.getRecommendGoodsViews(isPayNf, filter_goods_id, filterCourseGoods, start, limit);
  533. return GatewayResponse.SUCCESS.newBuilder().toResult(page);
  534. }
  535. /**
  536. * 查看GPT token
  537. */
  538. @GetMapping("/get/gptAccessToken")
  539. public Result<String> getGptAccessToken(Long relationId) throws Exception {
  540. long userId = StpUserUtil.getLoginIdAsLong();
  541. List<Long> userIds = userBindRelationService.getRelationUserIdList(userId, null);
  542. //存在该车票
  543. RenewalView renewalView = beanSearcher.searchFirst(RenewalView.class, MapUtils.builder()
  544. .field(RenewalView::getRelationId, relationId)
  545. .field(RenewalView::getUserId, userIds).op(Operator.InList).build());
  546. Assert.notNull(renewalView, "您的车票不存在");
  547. if (renewalView.getGoodsId() != 42) {
  548. throw BusinessRuntimeException.getInstance("该平台类型车票无法获取GPT直连token");
  549. }
  550. String account = renewalView.getAccount();
  551. String accessToken = chatGptAuthService.getAccessToken(account);
  552. return GatewayResponse.SUCCESS.newBuilder().toResult(accessToken);
  553. }
  554. /**
  555. * 获取特殊类型课程 通过邮件发送课程
  556. * 领取课件
  557. */
  558. @PostMapping("/courseware")
  559. public Result<String> getCourseWare(@RequestBody SpecialGoodsTicketReq request) throws Exception {
  560. long userId = StpUserUtil.getLoginIdAsLong();
  561. request.setUserId(userId);
  562. groupRelationFrontService.sendCourseWare(request);
  563. return GatewayResponse.SUCCESS.newBuilder().toResult();
  564. }
  565. //获取课程云盘链接
  566. @GetMapping("/get/courseware")
  567. public Result<GoodsCoursewareFile> getGoodsCourseware(Long relationId) {
  568. long userId = StpUserUtil.getLoginIdAsLong();
  569. List<Long> userIdList = userBindRelationService.getRelationUserIdList(userId, null);
  570. RenewalView relationView = beanSearcher.searchFirst(RenewalView.class, MapUtils.builder()
  571. .field(RenewalView::getUserId, userIdList).op(Operator.InList)
  572. .field(RenewalView::getRelationId, relationId).build());
  573. if (relationView == null) {
  574. throw BusinessRuntimeException.getInstance("您的车票不存在");
  575. }
  576. GoodsCoursewareFile goodsCoursewareFile = goodsCoursewareFileMapper.selectOne(Wrappers.lambdaQuery(GoodsCoursewareFile.class)
  577. .eq(GoodsCoursewareFile::getGoodsId, relationView.getGoodsId())
  578. .eq(GoodsCoursewareFile::getStatus, true)
  579. .select(GoodsCoursewareFile::getLink, GoodsCoursewareFile::getCode)
  580. .last("limit 1"));
  581. if (goodsCoursewareFile == null) {
  582. throw BusinessRuntimeException.getInstance("暂未配置课件链接地址,请联系客服");
  583. }
  584. return GatewayResponse.SUCCESS.newBuilder().toResult(goodsCoursewareFile);
  585. }
  586. /**
  587. * 读取车票账号登录验证码
  588. */
  589. @PostMapping("/get/verifyCode")
  590. public Result<String> getAiVerifyCode(@RequestBody TicketLoginReq loginReq) throws Exception {
  591. long userId = StpUserUtil.getLoginIdAsLong();
  592. loginReq.setUserId(userId);
  593. return GatewayResponse.SUCCESS.newBuilder().toResult(groupRelationFrontService.getAiVerifyCode(loginReq));
  594. }
  595. /**
  596. * 车票后台登录
  597. */
  598. @PostMapping("/ticket/login")
  599. public Result<GroupsRelation> ticketLogin(@RequestBody TicketLoginReq loginReq) {
  600. GroupsRelation relation = groupRelationFrontService.ticketLogin(loginReq);
  601. return GatewayResponse.SUCCESS.newBuilder().toResult(relation);
  602. }
  603. /**
  604. * 奈飞验证校验
  605. */
  606. @PostMapping("/ticket/verify")
  607. public Result<String> outsideTicketVerify(@RequestBody TicketLoginReq loginReq) {
  608. return GatewayResponse.SUCCESS.newBuilder().toResult(groupRelationFrontService.outsideTicketVerify(loginReq));
  609. }
  610. /**
  611. * 是否有mid车票可候补
  612. */
  613. @GetMapping("/get/standby")
  614. public Result<GptStandbyResp> getGptStandby() {
  615. long userId = StpUserUtil.getLoginIdAsLong();
  616. List<Long> relationUserIdList = userBindRelationService.getRelationUserIdList(userId, null);
  617. String condition = "(a.account like '%@yinhe.ac.cn%' or exists (select id from account_blocked_replace_record abrr where abrr.account = a.account and abrr.goods_id = g.id limit 1))";
  618. List<RenewalView> renewalViewList = beanSearcher.searchAll(RenewalView.class, MapUtils.builder()
  619. .field(RenewalView::getUserId, relationUserIdList).op(Operator.InList)
  620. .field(RenewalView::getGoodsId, 26)
  621. .put("condition", condition)
  622. .field(RenewalView::getExpiryTime).op(Operator.NotNull)
  623. .onlySelect(RenewalView::getAccount, RenewalView::getExpiryTime)
  624. .build());
  625. GptStandbyResp gptStandbyResp = new GptStandbyResp();
  626. if (renewalViewList.isEmpty()) {
  627. gptStandbyResp.setIsHasAccount(false);
  628. return GatewayResponse.SUCCESS.newBuilder().toResult(gptStandbyResp);
  629. }
  630. List<RenewalView> overTen = new ArrayList<>();
  631. List<RenewalView> underTen = new ArrayList<>();
  632. DateTime now = DateTime.now();
  633. renewalViewList.forEach(e -> {
  634. if (e.getExpiryTime().compareTo(DateUtil.offsetDay(now, 10)) > 0) {
  635. overTen.add(e);
  636. } else underTen.add(e);
  637. });
  638. Integer accountBlockedCount = 1;
  639. if (overTen.size() > 1) {
  640. List<String> accountList = overTen.stream().map(RenewalView::getAccount).distinct().collect(Collectors.toList());
  641. accountBlockedCount = accountBlockedReplaceRecordMapper.selectCount(Wrappers.lambdaQuery(AccountBlockedReplaceRecord.class)
  642. .eq(AccountBlockedReplaceRecord::getGoodsId, 26)
  643. .in(AccountBlockedReplaceRecord::getAccount, accountList));
  644. }
  645. if (accountBlockedCount > 1) {
  646. gptStandbyResp.setIsHasAccount(false);
  647. return GatewayResponse.SUCCESS.newBuilder().toResult(gptStandbyResp);
  648. }
  649. gptStandbyResp.setIsHasAccount(true);
  650. gptStandbyResp.setOverTen(overTen);
  651. gptStandbyResp.setUnderTen(underTen);
  652. Integer count = gptTicketStandbyMapper.selectCount(Wrappers.lambdaQuery(GptTicketStandby.class)
  653. .in(GptTicketStandby::getUserId, relationUserIdList));
  654. gptStandbyResp.setIsApply(count > 0 ? true : false);
  655. return GatewayResponse.SUCCESS.newBuilder().toResult(gptStandbyResp);
  656. }
  657. /**
  658. * 申请候补
  659. */
  660. @PostMapping("/apply/standby")
  661. @NoSubmit
  662. public Result<Boolean> applyGptStandby() {
  663. long userId = StpUserUtil.getLoginIdAsLong();
  664. List<Long> relationUserIdList = userBindRelationService.getRelationUserIdList(userId, null);
  665. String condition = "(a.account like '%@yinhe.ac.cn%' or exists (select id from account_blocked_replace_record abrr where abrr.account = a.account and abrr.goods_id = g.id limit 1))";
  666. List<RenewalView> renewalViewList = beanSearcher.searchAll(RenewalView.class, MapUtils.builder()
  667. .field(RenewalView::getUserId, relationUserIdList).op(Operator.InList)
  668. .field(RenewalView::getGoodsId, 26)
  669. .put("condition", condition)
  670. .field(RenewalView::getExpiryTime, DateUtil.offsetDay(DateTime.now(), 10)).op(Operator.GreaterThan)
  671. .onlySelect(RenewalView::getAccount)
  672. .build());
  673. if (renewalViewList.isEmpty()) {
  674. throw BusinessRuntimeException.getInstance("你未有车票账号");
  675. }
  676. Integer count = gptTicketStandbyMapper.selectCount(Wrappers.lambdaQuery(GptTicketStandby.class)
  677. .in(GptTicketStandby::getUserId, relationUserIdList));
  678. if (count > 0) {
  679. throw BusinessRuntimeException.getInstance("你已申请车票账号候补");
  680. }
  681. if (renewalViewList.size() > 1) {
  682. Set<String> accountSet = renewalViewList.stream().map(RenewalView::getAccount).collect(Collectors.toSet());
  683. Integer accountBlockedCount = accountBlockedReplaceRecordMapper.selectCount(Wrappers.lambdaQuery(AccountBlockedReplaceRecord.class)
  684. .eq(AccountBlockedReplaceRecord::getGoodsId, 26)
  685. .in(AccountBlockedReplaceRecord::getAccount, accountSet));
  686. if (accountBlockedCount > 1) {
  687. return GatewayResponse.SUCCESS.newBuilder().toResult(true);
  688. }
  689. }
  690. GptTicketStandby gptTicketStandby = new GptTicketStandby();
  691. gptTicketStandby.setUserId(userId);
  692. gptTicketStandbyMapper.insert(gptTicketStandby);
  693. return GatewayResponse.SUCCESS.newBuilder().toResult(true);
  694. }
  695. /**
  696. * midjourney车票退款
  697. */
  698. @PutMapping("/refund/ticketOrder/{relationId}")
  699. @NoSubmit
  700. public Result<String> ticketRefundOrders(@PathVariable Long relationId) throws Exception {
  701. long userId = StpUserUtil.getLoginIdAsLong();
  702. List<Long> relationUserIdList = userBindRelationService.getRelationUserIdList(userId, null);
  703. String condition = "(a.account like '%@yinhe.ac.cn%' or exists (select id from account_blocked_replace_record abrr where abrr.account = a.account and abrr.goods_id = g.id limit 1))";
  704. RenewalView renewalView = beanSearcher.searchFirst(RenewalView.class, MapUtils.builder()
  705. .field(RenewalView::getRelationId, relationId)
  706. .field(RenewalView::getUserId, relationUserIdList).op(Operator.InList)
  707. .put("condition", condition)
  708. .field(RenewalView::getGoodsId, 26)
  709. .field(RenewalView::getExpiryTime, DateUtil.offsetDay(DateTime.now(), 10)).op(Operator.LessEqual)
  710. .build());
  711. if (renewalView == null) {
  712. throw BusinessRuntimeException.getInstance("你车票不存在或不符合退款要求");
  713. }
  714. OrderDon orderDon = orderDonService.getOne(Wrappers.lambdaQuery(OrderDon.class)
  715. .in(OrderDon::getUserId, relationUserIdList)
  716. .eq(OrderDon::getRelationId, relationId)
  717. .notIn(OrderDon::getStatus, Constant.noOrderAllStatus)
  718. .orderByDesc(OrderDon::getId)
  719. .last("limit 1"));
  720. if (orderDon == null) {
  721. throw BusinessRuntimeException.getInstance("你对应车票的订单不存在");
  722. }
  723. GoodsDonSku sku = goodsDonSkuMapper.selectById(orderDon.getSkuId());
  724. if (sku == null) {
  725. throw BusinessRuntimeException.getInstance("该车票规格不存在,请联系客服进行人工退款..");
  726. }
  727. Date expiryTime = renewalView.getExpiryTime();
  728. long remainDay = DateUtil.between(DateTime.now(), expiryTime, DateUnit.DAY) + 1;
  729. BigDecimal money = orderDon.getMoney();
  730. BigDecimal refundMoney = null;
  731. BigDecimal refundBalance= null;
  732. String refundType = null;
  733. if (money.compareTo(BigDecimal.ZERO) > 0) {
  734. BigDecimal dayMoney = money.divide(BigDecimal.valueOf(sku.getMonths()).multiply(BigDecimal.valueOf(30)), 2, RoundingMode.HALF_DOWN);
  735. refundMoney = BigDecimal.valueOf(remainDay).multiply(dayMoney);
  736. refundType = "money";
  737. }
  738. OrderRefundReq refundReq = new OrderRefundReq();
  739. if (orderDon.getBalance().compareTo(BigDecimal.ZERO) > 0) {
  740. BigDecimal dayMoney = orderDon.getBalance().divide(BigDecimal.valueOf(sku.getMonths()).multiply(BigDecimal.valueOf(30)), 2, RoundingMode.HALF_DOWN);
  741. refundBalance = BigDecimal.valueOf(remainDay).multiply(dayMoney);
  742. refundReq.setIsOnly(true);
  743. }
  744. refundReq.setOrderId(orderDon.getId());
  745. refundReq.setRefundDesc("失效车票退款");
  746. refundReq.setRefundMoney(Optional.ofNullable(refundMoney).orElse(BigDecimal.ZERO));
  747. refundReq.setRefundBalance(Optional.ofNullable(refundBalance).orElse(BigDecimal.ZERO));
  748. refundReq.setRefundType(Optional.ofNullable(refundType).orElse("balance"));
  749. cmsOrderDonService.unifiedRefund(refundReq);
  750. return GatewayResponse.SUCCESS.newBuilder().toResult();
  751. }
  752. /**
  753. * 每日车票到期弹窗
  754. */
  755. @GetMapping("/get/expiry/notify")
  756. public Result<List<RenewalView>> getExpiryRenewalNotify() {
  757. Long userId = StpUserUtil.getLoginIdAsLong();
  758. List<RenewalView> expiryRenewals = groupRelationFrontService.getExpiryRenewalNotify(userId);
  759. return GatewayResponse.SUCCESS.newBuilder().toResult(expiryRenewals);
  760. }
  761. /**
  762. * 车票详情
  763. */
  764. @GetMapping("/get/detail")
  765. public Result<RenewalView> getTicketDetail(Long relationId) {
  766. if (relationId == null) {
  767. return GatewayResponse.SUCCESS.newBuilder().toResult();
  768. }
  769. long userId = StpUserUtil.getLoginIdAsLong();
  770. RenewalView ticketDetail = groupRelationFrontService.getTicketDetail(userId, relationId);
  771. return GatewayResponse.SUCCESS.newBuilder().toResult(ticketDetail);
  772. }
  773. /**
  774. * 车票售后常见问题
  775. */
  776. @GetMapping("/get/questions/{goodsId}")
  777. public Result<List<GoodsDonQaFrontView>> getTicketQuestions(@PathVariable Long goodsId, @RequestParam(defaultValue = "1") Integer type) {
  778. long userId = StpUserUtil.getLoginIdAsLong();
  779. log.info("userId:{}查看车票:{}售后问题", userId, goodsId);
  780. if (type < 1 || type > 2) {
  781. return GatewayResponse.SUCCESS.newBuilder().toResult();
  782. }
  783. String key = RedisService.key.YH_GOODS_QUESTIONS_DETAIL.getNameFormat(type, goodsId);
  784. Object o = redisService.get(key);
  785. if (o == null) {
  786. List<GoodsDonQaFrontView> donQaFrontViews = beanSearcher.searchAll(GoodsDonQaFrontView.class, MapUtils.builder().field(GoodsDonQaFrontView::getGoodsId, goodsId).field(GoodsDonQaFrontView::getType, type).build());
  787. if (CollUtil.isEmpty(donQaFrontViews)) {
  788. return GatewayResponse.SUCCESS.newBuilder().toResult();
  789. }
  790. redisService.setNx(key, donQaFrontViews, RedisService.key.YH_GOODS_QUESTIONS_DETAIL.getTimeout());
  791. o = redisService.get(key);
  792. }
  793. List<GoodsDonQaFrontView> donQaFrontViews = Jsons.parseList(o, GoodsDonQaFrontView.class);
  794. return GatewayResponse.SUCCESS.newBuilder().toResult(donQaFrontViews);
  795. }
  796. /**
  797. * 是否首次购买车票
  798. */
  799. @GetMapping("/get/first/pay/{goodsId}")
  800. public Result<Boolean> getFirstPay(@PathVariable Long goodsId) {
  801. long userId = StpUserUtil.getLoginIdAsLong();
  802. List<Long> userIdList = userBindRelationService.getRelationUserIdList(userId, null);
  803. Number number = beanSearcher.searchCount(OrderDon.class, MapUtils.builder()
  804. .field(OrderDon::getGoodsId, goodsId)
  805. .field(OrderDon::getCreatedTime, new DateTime().toDateStr()).op(Operator.LessEqual)
  806. .field(OrderDon::getUserId, userIdList).op(Operator.InList)
  807. .field(OrderDon::getStatus, Constant.noOrderStatus).op(Operator.NotIn)
  808. .build());
  809. if (number.intValue() == 0) {
  810. UserGoodsNewbieGuideRecord userGoodsNewbieGuideRecord = new UserGoodsNewbieGuideRecord();
  811. userGoodsNewbieGuideRecord.setGoodsId(goodsId);
  812. userGoodsNewbieGuideRecord.setUserId(userId);
  813. userGoodsNewbieGuideRecordMapper.insert(userGoodsNewbieGuideRecord);
  814. return GatewayResponse.SUCCESS.newBuilder().toResult(true);
  815. }
  816. return GatewayResponse.SUCCESS.newBuilder().toResult(false);
  817. }
  818. /**
  819. * 设置pin码
  820. */
  821. @PutMapping("/set/pin/{relationId}")
  822. public Result<String> setPin(@PathVariable Long relationId, String code) {
  823. long userId = StpUserUtil.getLoginIdAsLong();
  824. JSONObject data = groupsRelationNetflixService.setNetflixPin(relationId, userId, code);
  825. return GatewayResponse.SUCCESS.newBuilder().toResult(data.toString());
  826. }
  827. /**
  828. * 查询是否设置成功
  829. */
  830. @GetMapping("/get/pin/status/{taskId}")
  831. public Result<Integer> getPinStatus(@PathVariable String taskId) throws Exception {
  832. long userId = StpUserUtil.getLoginIdAsLong();
  833. log.info("userId:{}查看设置pin码状态", userId);
  834. return GatewayResponse.SUCCESS.newBuilder().toResult(groupsRelationNetflixService.getPinStatus(taskId));
  835. }
  836. /**
  837. * 踢出奈飞设备
  838. */
  839. @PostMapping("/kickOut/nf/{relationId}")
  840. public Result<String> nfKickOut(@PathVariable Long relationId) {
  841. long userId = StpUserUtil.getLoginIdAsLong();
  842. JSONObject data = groupsRelationNetflixService.nfKickOut(userId, relationId);
  843. return GatewayResponse.SUCCESS.newBuilder().toResult(data.toString());
  844. }
  845. /**
  846. * 奈飞同户装置链接
  847. */
  848. @GetMapping("/get/nf/household/device")
  849. public Result<String> getNfHouseholdDevice(@NotNull Long relationId) throws Exception {
  850. long userId = StpUserUtil.getLoginIdAsLong();
  851. String url = groupRelationFrontService.getNfHouseholdDevice(userId, relationId);
  852. return GatewayResponse.SUCCESS.newBuilder().toResult(url);
  853. }
  854. /**
  855. * 代点奈飞同户装置
  856. */
  857. @PostMapping("/click/nf/household/device")
  858. public void clickNfHouseholdDevice(@RequestBody NfDeviceReq nfDeviceReq) {
  859. groupsRelationNetflixService.clickNfHouseholdDevice(nfDeviceReq);
  860. }
  861. /**
  862. * 可选 续费升级车票
  863. */
  864. @GetMapping("/get/renew/skus/{relationId}/{skuId}")
  865. public Result<List<RenewUpgradePackageFrontView>> getRenewSkus(@PathVariable Long relationId, @PathVariable Long skuId) {
  866. long userId = StpUserUtil.getLoginIdAsLong();
  867. List<Long> userIdList = userBindRelationService.getRelationUserIdList(userId, null);
  868. ChatgptUser chatgptUser = chatgptUserMapper.selectOne(Wrappers.lambdaQuery(ChatgptUser.class)
  869. .eq(ChatgptUser::getRelationId, relationId));
  870. if (chatgptUser == null) return GatewayResponse.SUCCESS.newBuilder().toResult();
  871. //目前续费升级的规格
  872. Long renewSkuId = chatgptUser.getRenewSkuId();
  873. GoodsDonSku sku = goodsDonSkuMapper.selectById(skuId);
  874. AtomicInteger minMonths = new AtomicInteger(sku.getMonths());
  875. AtomicInteger minNum = new AtomicInteger(chatgptUser.getLimitNum());
  876. AtomicLong minTime = new AtomicLong(chatgptUser.getLimitTime());
  877. if (renewSkuId != null) {
  878. GoodsDonSku presentRenew = goodsDonSkuMapper.selectById(renewSkuId);
  879. minMonths.set(presentRenew.getMonths());
  880. }
  881. if (chatgptUser.getPackageId() != 0) {
  882. Long packageId = chatgptUser.getPackageId();
  883. UpgradeOrderDon upgradeOrderDon = upgradeOrderDonMapper.selectOne(Wrappers.lambdaQuery(UpgradeOrderDon.class)
  884. .eq(UpgradeOrderDon::getPackageId, packageId)
  885. .eq(UpgradeOrderDon::getRelationId, relationId)
  886. .in(UpgradeOrderDon::getUserId, userIdList)
  887. .last("limit 1"));
  888. Long upgradeOrderDonSkuId = upgradeOrderDon.getSkuId();
  889. GoodsDonSku upgradeSku = goodsDonSkuMapper.selectById(upgradeOrderDonSkuId);
  890. if (upgradeSku != null) {
  891. if (upgradeSku.getMonths() > minMonths.get()) {
  892. minMonths.set(upgradeSku.getMonths());
  893. }
  894. }
  895. }
  896. List<RenewUpgradePackageFrontView> renewUpgradePackageFrontViews = beanSearcher.searchAll(RenewUpgradePackageFrontView.class, MapUtils.builder().field(RenewUpgradePackageFrontView::getSkuId, skuId).build());
  897. renewUpgradePackageFrontViews.forEach(renew -> {
  898. try {
  899. List<Long> upgradeSkuIds = Jsons.parseList(renew.getUpgradeSkuIds(), Long.class);
  900. //年付展示
  901. MapBuilder builder = MapUtils.builder();
  902. // if (minMonths.get() == 12) {
  903. // builder.field(RenewUpgradePackageFrontView.RenewSkuView::getMonths, minMonths.get()).op(Operator.GreaterEqual);
  904. // if (renewSkuId != null) {
  905. // upgradeSkuIds.remove(renewSkuId);
  906. // }
  907. // } else {
  908. // builder.field(RenewUpgradePackageFrontView.RenewSkuView::getMonths, minMonths.get()).op(Operator.GreaterEqual);
  909. // }
  910. //GPT镜像2月规格 特殊处理
  911. if (sku.getGoodsId() == 18 && sku.getMonths() == 2) {
  912. } else {
  913. //同续费时间规格
  914. builder.field(RenewUpgradePackageFrontView.RenewSkuView::getMonths, minMonths.get()).op(Operator.GreaterEqual);
  915. }
  916. if (renewSkuId != null) {
  917. upgradeSkuIds.remove(renewSkuId);
  918. }
  919. List<RenewUpgradePackageFrontView.RenewSkuView> renewSkuViews = new ArrayList<>();
  920. if (CollUtil.isNotEmpty(upgradeSkuIds)) {
  921. renewSkuViews = beanSearcher.searchAll(RenewUpgradePackageFrontView.RenewSkuView.class, builder
  922. .field(RenewUpgradePackageFrontView.RenewSkuView::getGptLimitNum, minNum.get()).op(Operator.GreaterEqual)
  923. .field(RenewUpgradePackageFrontView.RenewSkuView::getGptLimitTime, minTime.get()).op(LessEqual.class)
  924. .field(RenewUpgradePackageFrontView.RenewSkuView::getSkuId, upgradeSkuIds).op(Operator.InList)
  925. .build());
  926. }
  927. renew.setRenewSkus(renewSkuViews);
  928. } catch (Exception e) {
  929. }
  930. });
  931. return GatewayResponse.SUCCESS.newBuilder().toResult(renewUpgradePackageFrontViews);
  932. }
  933. /**
  934. * 独立规格续费套餐列表
  935. */
  936. @GetMapping("/get/independent/renew/skus/{skuId}")
  937. public Result<List<RenewUpgradePackageFrontView>> getRenewSkus(@PathVariable Long skuId) {
  938. long userId = StpUserUtil.getLoginIdAsLong();
  939. List<RenewUpgradePackageFrontView> renewUpgradePackageFrontViews = beanSearcher.searchAll(RenewUpgradePackageFrontView.class, MapUtils.builder().field(RenewUpgradePackageFrontView::getSkuId, skuId).build());
  940. renewUpgradePackageFrontViews.forEach(renew -> {
  941. try {
  942. List<Long> upgradeSkuIds = Jsons.parseList(renew.getUpgradeSkuIds(), Long.class);
  943. MapBuilder builder = MapUtils.builder();
  944. List<RenewUpgradePackageFrontView.RenewSkuView> renewSkuViews = beanSearcher.searchAll(RenewUpgradePackageFrontView.RenewSkuView.class, builder
  945. .field(RenewUpgradePackageFrontView.RenewSkuView::getSkuId, upgradeSkuIds).op(Operator.InList)
  946. .build());
  947. renew.setRenewSkus(renewSkuViews);
  948. } catch (Exception e) {
  949. }
  950. });
  951. return GatewayResponse.SUCCESS.newBuilder().toResult(renewUpgradePackageFrontViews);
  952. }
  953. /**
  954. * 获取GPT PLUS登录验证码
  955. */
  956. @GetMapping("/get/verify/code")
  957. public Result<String> getVerifyCode(@NotEmpty String account) throws Exception {
  958. String code = groupRelationFrontService.getVerifyCode(account);
  959. if (StrUtil.isEmpty(code)) {
  960. throw BusinessRuntimeException.getInstance("请重新发送验证码");
  961. }
  962. return GatewayResponse.SUCCESS.newBuilder().toResult(code);
  963. }
  964. /**
  965. * 独立规格续费减免
  966. */
  967. @GetMapping("/get/renew/reduce")
  968. public Result<UserBenefitsFrontView> getRenewReduce(Long skuId, Long relationId) {
  969. long userId = StpUserUtil.getLoginIdAsLong();
  970. List<Long> userIdList = userBindRelationService.getRelationUserIdList(userId, null);
  971. UserBenefitsFrontView data = beanSearcher.searchFirst(UserBenefitsFrontView.class, MapUtils.builder().field(UserBenefitsFrontView::getSkuId, skuId).field(UserBenefitsFrontView::getType, UserBenefits.Type.RENEW.name()).build());
  972. if (data == null) {
  973. return GatewayResponse.SUCCESS.newBuilder().toResult();
  974. }
  975. Date startTime = null;
  976. if (relationId != null) {
  977. GroupsRelation relation = relationMapper.selectOne(Wrappers.lambdaQuery(GroupsRelation.class)
  978. .eq(GroupsRelation::getId, relationId)
  979. .in(GroupsRelation::getUserId, userIdList));
  980. if (relation == null) {
  981. throw BusinessRuntimeException.getInstance("车票不存在");
  982. }
  983. startTime = relation.getStartTime();
  984. }
  985. Integer renewCount = userBenefitsOrderRecordMapper.selectUseComboRecordByUid(userIdList, data.getType(), data.getGoodsId(), data.getSkuId(), Constant.noOrderAllStatus, null, startTime, relationId);
  986. data.setRenewCount(renewCount);
  987. return GatewayResponse.SUCCESS.newBuilder().toResult(data);
  988. }
  989. /**
  990. * 申请更换车票
  991. */
  992. @PostMapping("/change/ticket")
  993. public Result<String> changeTicket(@RequestBody ChangeTicketReq changeTicketReq) {
  994. long userId = StpUserUtil.getLoginIdAsLong();
  995. List<Long> relationIds = changeTicketReq.getRelationIds();
  996. if (CollUtil.isEmpty(relationIds)) {
  997. return GatewayResponse.SUCCESS.newBuilder().toResult();
  998. }
  999. List<Long> userIdList = userBindRelationService.getRelationUserIdList(userId, null);
  1000. //奈飞超过3帐车票不给看
  1001. Number number = beanSearcher.searchCount(RenewalView.class, MapUtils.builder()
  1002. .field(RenewalView::getUserId, userIdList).op(Operator.InList)
  1003. .field(RenewalView::getGoodsId, 1)
  1004. .field(RenewalView::getExpiryTime, DateTime.now()).op(Operator.GreaterThan)
  1005. .build());
  1006. if (number.intValue() > 2) {
  1007. return GatewayResponse.SUCCESS.newBuilder().toResult();
  1008. }
  1009. relationIds.forEach(relationId -> {
  1010. try {
  1011. groupRelationFrontService.changeTicket(userId, relationId);
  1012. } catch (Exception e) {
  1013. log.error("更换车票失败:{}", StringUtil.getErrorText(e));
  1014. if (relationIds.size() == 1) {
  1015. throw BusinessRuntimeException.getInstance(e.getMessage());
  1016. }
  1017. }
  1018. });
  1019. return GatewayResponse.SUCCESS.newBuilder().toResult();
  1020. }
  1021. /**
  1022. * 查看临时账号
  1023. */
  1024. @GetMapping("/get/temp/account/{relationId}")
  1025. public Result<AccountView> getTempAccount(@PathVariable Long relationId) {
  1026. long userId = StpUserUtil.getLoginIdAsLong();
  1027. AccountView accountView = groupRelationFrontService.getTempAccount(userId, relationId);
  1028. return GatewayResponse.SUCCESS.newBuilder().toResult(accountView);
  1029. }
  1030. /**
  1031. * 申请提交记录
  1032. */
  1033. @GetMapping("/get/netflix/get/error/submit/record")
  1034. public Result<List<NetflixUserAccountStatusRecord>> getUserNetflixSubmitRecord() {
  1035. long userId = StpUserUtil.getLoginIdAsLong();
  1036. List<NetflixUserAccountStatusRecord> netflixUserAccountStatusRecords = groupRelationFrontService.getUserNetflixSubmitRecord(userId);
  1037. return GatewayResponse.SUCCESS.newBuilder().toResult(netflixUserAccountStatusRecords);
  1038. }
  1039. /**
  1040. * 奈飞账号异常检测提交
  1041. */
  1042. @PostMapping("/netflix/error/account/submit/{relationId}")
  1043. public Result<String> nfErrorAccountSubmit(@PathVariable Long relationId) {
  1044. long userId = StpUserUtil.getLoginIdAsLong();
  1045. groupRelationFrontService.nfErrorAccountSubmit(userId, relationId);
  1046. return GatewayResponse.SUCCESS.newBuilder().toResult();
  1047. }
  1048. /**
  1049. * 奈飞账号检测结果
  1050. */
  1051. @GetMapping("/get/netflix/error/account/status/{relationId}")
  1052. public Result<Integer> getNetflixErrorAccountStatus(@PathVariable Long relationId) {
  1053. long userId = StpUserUtil.getLoginIdAsLong();
  1054. Integer state = groupRelationFrontService.getNetflixErrorAccountStatus(userId, relationId);
  1055. return GatewayResponse.SUCCESS.newBuilder().toResult(state);
  1056. }
  1057. }