VipFrontServiceImpl.java 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510
  1. package com.cyksj.service.vip.impl;
  2. import cn.hutool.core.collection.CollUtil;
  3. import cn.hutool.core.date.DateTime;
  4. import cn.hutool.core.date.DateUtil;
  5. import cn.hutool.core.util.ObjectUtil;
  6. import cn.hutool.core.util.StrUtil;
  7. import com.baomidou.mybatisplus.core.toolkit.Wrappers;
  8. import com.cyksj.common.constant.Constant;
  9. import com.cyksj.common.exception.BusinessRuntimeException;
  10. import com.cyksj.mapper.*;
  11. import com.cyksj.mapper.sys.SysConfigMapper;
  12. import com.cyksj.mapper.vip.VipGoodsSkuMapper;
  13. import com.cyksj.model.dto.VipDeductDto;
  14. import com.cyksj.model.entity.*;
  15. import com.cyksj.model.manage.views.GroupsRelationView;
  16. import com.cyksj.model.response.VipUserPageResp;
  17. import com.cyksj.service.chatgpt.ChatGptAccountService;
  18. import com.cyksj.service.claude.ClaudeService;
  19. import com.cyksj.service.user.UserBindRelationService;
  20. import com.cyksj.service.vip.VipFrontService;
  21. import com.ejlchina.searcher.BeanSearcher;
  22. import com.ejlchina.searcher.param.Operator;
  23. import com.ejlchina.searcher.util.MapUtils;
  24. import lombok.RequiredArgsConstructor;
  25. import lombok.extern.slf4j.Slf4j;
  26. import org.springframework.stereotype.Service;
  27. import java.math.BigDecimal;
  28. import java.math.RoundingMode;
  29. import java.util.*;
  30. import java.util.stream.Collectors;
  31. /**
  32. * 项目名: yhlxj2
  33. * 文件名: VipFrontServiceImpl
  34. * 创建者: JavaZou
  35. * 创建时间:2025/5/15 16:00
  36. */
  37. @Service
  38. @RequiredArgsConstructor
  39. @Slf4j
  40. public class VipFrontServiceImpl implements VipFrontService {
  41. private final SysConfigMapper sysConfigMapper;
  42. private final VipGoodsSkuMapper vipGoodsSkuMapper;
  43. private final UserBindRelationService userBindRelationService;
  44. private final BeanSearcher beanSearcher;
  45. private final GoodsDonSkuMapper skuMapper;
  46. private final ChatgptUserMapper chatgptUserMapper;
  47. private final OrderDonRenewRecordMapper orderDonRenewRecordMapper;
  48. private final ClaudeUserMapper claudeUserMapper;
  49. private final OrderDonMapper orderDonMapper;
  50. private final GoodsDonSkuMapper goodsDonSkuMapper;
  51. private final ChatGptAccountService chatGptAccountService;
  52. private final ClaudeService claudeService;
  53. private final LumaUserMapper lumaUserMapper;
  54. private final UpgradeOrderDonMapper upgradeOrderDonMapper;
  55. private final NanoUserQuotaMapper nanoUserQuotaMapper;
  56. private final MidjourneyUserMapper midjourneyUserMapper;
  57. @Override
  58. public void fillVipInfo(Long userId, VipUserPageResp vipUserPageResp) {
  59. SysConfig sysConfig = sysConfigMapper.selectOne(Wrappers.lambdaQuery(SysConfig.class).eq(SysConfig::getSysKey, Constant.VIP_FEE_KEY).last("limit 1"));
  60. if (sysConfig != null && StrUtil.isNotBlank(sysConfig.getSysValue())) {
  61. vipUserPageResp.setVipFee(BigDecimal.valueOf(Integer.parseInt(sysConfig.getSysValue())));
  62. }
  63. if (userId == null) {
  64. return;
  65. }
  66. //可抵扣价格
  67. BigDecimal deductMoney = BigDecimal.ZERO;
  68. List<Long> userIdList = userBindRelationService.getRelationUserIdList(userId, null);
  69. List<Long> vipSkuIds = vipGoodsSkuMapper.selectList(null).stream().map(VipGoodsSku::getSkuId).collect(Collectors.toList());
  70. //可有抵扣车票
  71. DateTime now = DateTime.now();
  72. //会员规格
  73. Set<Long> goodsIds = goodsDonSkuMapper.selectList(Wrappers.lambdaQuery(GoodsDonSku.class)
  74. .in(GoodsDonSku::getId, vipSkuIds)).stream().map(GoodsDonSku::getGoodsId).collect(Collectors.toSet());
  75. //todo 临时处理 nano先不参与抵扣
  76. goodsIds.remove(Constant.NANO_GOODS_ID);
  77. Number count = beanSearcher.searchCount(GroupsRelationView.class, MapUtils.builder().field(GroupsRelationView::getUserId, userIdList).op(Operator.InList).field(GroupsRelationView::getGoodsId, goodsIds).op(Operator.InList).field(GroupsRelationView::getIsMirror, Boolean.TRUE).field(GroupsRelationView::getExpiryTime, now).op(Operator.GreaterThan).build());
  78. //可抵扣车票
  79. if (count.intValue() > 0) {
  80. Integer months = vipUserPageResp.getMonths();
  81. //处理vip抵扣金额
  82. VipDeductDto vipDeductDto = commonHandleVipDeductMoney(userIdList, goodsIds, months);
  83. vipUserPageResp.setRelationUserViews(vipDeductDto.getRelationUserViews());
  84. vipUserPageResp.setExtendsDays(vipDeductDto.getExtendsDays());
  85. if (months != 12) {
  86. //取出最大可抵扣info
  87. vipDeductDto = commonHandleVipDeductMoney(userIdList, goodsIds, 12);
  88. }
  89. deductMoney = vipDeductDto.getDeductMoney();
  90. }
  91. vipUserPageResp.setDeductMoney(deductMoney);
  92. }
  93. /**
  94. * 检查用户并获取订单抵扣金额
  95. */
  96. @Override
  97. public VipDeductDto checkAndGetOrderDeductMoney(Long userId, Integer months) {
  98. List<Long> userIdList = userBindRelationService.getRelationUserIdList(userId, null);
  99. List<Long> vipSkuIds = vipGoodsSkuMapper.selectList(null).stream().map(VipGoodsSku::getSkuId).collect(Collectors.toList());
  100. //会员规格
  101. Set<Long> goodsIds = goodsDonSkuMapper.selectList(Wrappers.lambdaQuery(GoodsDonSku.class)
  102. .in(GoodsDonSku::getId, vipSkuIds)).stream().map(GoodsDonSku::getGoodsId).collect(Collectors.toSet());
  103. Number count = beanSearcher.searchCount(GroupsRelationView.class, MapUtils.builder()
  104. .field(GroupsRelationView::getUserId, userIdList).op(Operator.InList)
  105. .field(GroupsRelationView::getGoodsId, goodsIds).op(Operator.InList)
  106. .field(GroupsRelationView::getExpiryTime, DateTime.now()).op(Operator.GreaterThan)
  107. .field(GroupsRelationView::getIsVip, false)
  108. .build());
  109. if (count.intValue() == 0) {
  110. throw BusinessRuntimeException.getInstance("暂无可抵扣AI车票");
  111. }
  112. VipDeductDto vipDeductDto = commonHandleVipDeductMoney(userIdList, goodsIds, months);
  113. return vipDeductDto;
  114. }
  115. private BigDecimal getVipMoney(Integer months) {
  116. SysConfig sysConfig = sysConfigMapper.selectOne(Wrappers.lambdaQuery(SysConfig.class).eq(SysConfig::getSysKey, Constant.VIP_FEE_KEY).last("limit 1"));
  117. if (sysConfig == null || StrUtil.isEmpty(sysConfig.getSysValue())) {
  118. throw BusinessRuntimeException.getInstance("系统异常");
  119. }
  120. BigDecimal vipFee = BigDecimal.valueOf(Long.valueOf(sysConfig.getSysValue()));
  121. return vipFee.multiply(BigDecimal.valueOf(months));
  122. }
  123. /**
  124. * 统一处理vip抵扣金额
  125. */
  126. public VipDeductDto commonHandleVipDeductMoney(List<Long> userIdList, Set<Long> goodsIds, Integer months) {
  127. VipDeductDto vipDeductDto = new VipDeductDto();
  128. DateTime now = DateTime.now();
  129. List<Long> deductRelationIds = new ArrayList<>();
  130. BigDecimal deductMoney = BigDecimal.ZERO;
  131. BigDecimal vipMoney = getVipMoney(months);
  132. List<GroupsRelationView> relations = beanSearcher.searchAll(GroupsRelationView.class, MapUtils.builder()
  133. .field(GroupsRelationView::getGoodsId, goodsIds).op(Operator.InList)
  134. .field(GroupsRelationView::getIsMirror, Boolean.TRUE)
  135. .field(GroupsRelationView::getUserId, userIdList).op(Operator.InList)
  136. .field(GroupsRelationView::getIsVip, false)
  137. .field(GroupsRelationView::getExpiryTime, DateTime.now()).op(Operator.GreaterThan)
  138. .field(GroupsRelationView::getAqType, 1)
  139. .orderBy(GroupsRelationView::getExpiryTime).desc()
  140. .build());
  141. Set<Long> deductGoodsIds = null;
  142. List<GroupsRelationView> deductRelations = null;
  143. for (GroupsRelationView relation : relations) {
  144. if (deductGoodsIds == null) {
  145. deductGoodsIds = new HashSet<>();
  146. }
  147. if (deductRelations == null) {
  148. deductRelations = new ArrayList<>();
  149. }
  150. Long goodsId = relation.getGoodsId();
  151. if (deductGoodsIds.contains(goodsId)) {
  152. continue;
  153. }
  154. Long skuId = relation.getSkuId();
  155. deductGoodsIds.add(goodsId);
  156. Long relationId = relation.getId();
  157. Date relationExpiryTime = relation.getExpiryTime();
  158. //GPT
  159. if (goodsId == Constant.GPT_PLUS_GID) {
  160. ChatgptUser chatgptUser = chatgptUserMapper.selectOne(Wrappers.lambdaQuery(ChatgptUser.class).eq(ChatgptUser::getRelationId, relationId).last("limit 1"));
  161. if (chatgptUser == null) {
  162. chatGptAccountService.getUserInfo(relation.getUserId(), relation.getId());
  163. chatgptUser = chatgptUserMapper.selectOne(Wrappers.lambdaQuery(ChatgptUser.class).eq(ChatgptUser::getRelationId, relationId).last("limit 1"));
  164. }
  165. if (chatgptUser != null) {
  166. //获取抵扣金额
  167. deductMoney = deductMoney.add(getFinalDeductMoney(relationId, relation.getSkuId(), chatgptUser.getRenewSkuId(), chatgptUser.getRenewOrderId(), chatgptUser.getRenewExpiryTime(), relation.getStartTime(), relationExpiryTime, now, userIdList));
  168. }
  169. } else if (goodsId == Constant.CLAUDE_PRO_GID) {
  170. ClaudeUser claudeUser = claudeUserMapper.selectOne(Wrappers.lambdaQuery(ClaudeUser.class).eq(ClaudeUser::getRelationId, relationId).last("limit 1"));
  171. if (claudeUser == null) {
  172. claudeService.getUserInfo(relation.getUserId(), relation.getId());
  173. claudeUser = claudeUserMapper.selectOne(Wrappers.lambdaQuery(ClaudeUser.class).eq(ClaudeUser::getRelationId, relationId).last("limit 1"));
  174. }
  175. if (claudeUser != null) {
  176. //获取抵扣金额
  177. deductMoney = deductMoney.add(getFinalDeductMoney(relationId, relation.getSkuId(), claudeUser.getRenewSkuId(), claudeUser.getRenewOrderId(), claudeUser.getRenewExpiryTime(), relation.getStartTime(), relationExpiryTime, now, userIdList));
  178. }
  179. } else if (goodsId == Constant.LUMA_GOODS_ID || goodsId == Constant.NANO_GOODS_ID) {
  180. //luma、nano
  181. deductMoney = deductMoney.add(getGeneralRemainNumDeductMoney(relationId, goodsId, skuId, userIdList));
  182. } else if (goodsId == Constant.MIDJOURNEY_GOODS_ID) {
  183. //mj
  184. deductMoney = deductMoney.add(getMjRemainNumDeductMoney(relationId, skuId, userIdList));
  185. } else {
  186. //该车票抵扣金额
  187. deductMoney = deductMoney.add(getDeductMoneyFromTicket(relationId, userIdList, skuId, now, relation.getStartTime(), relationExpiryTime));
  188. }
  189. deductRelationIds.add(relationId);
  190. //可抵扣车票
  191. deductRelations.add(relation);
  192. }
  193. //实际可抵扣金额
  194. vipDeductDto.setActuallyDeDuctMoney(deductMoney);
  195. vipDeductDto.setDeductMoney(deductMoney);
  196. //超出可抵扣的金额 直接返回
  197. if (deductMoney.compareTo(vipMoney) >= 0) {
  198. BigDecimal overMoney = deductMoney.subtract(vipMoney);
  199. //超过抵扣金额可换延长会员多少天
  200. //每天单价
  201. BigDecimal daySingle = vipMoney.divide(BigDecimal.valueOf(months)).divide(BigDecimal.valueOf(30), 0, RoundingMode.DOWN);
  202. //超出部分可换取多少天 低于每天单价为0天
  203. BigDecimal extendsDays = overMoney.divide(daySingle, 0, RoundingMode.UP);
  204. vipDeductDto.setExtendsDays(extendsDays.intValue());
  205. vipDeductDto.setDeductMoney(vipMoney);
  206. }
  207. vipDeductDto.setDeductRelationIds(deductRelationIds);
  208. vipDeductDto.setRelationUserViews(deductRelations);
  209. return vipDeductDto;
  210. }
  211. /**
  212. * 获取最终抵扣金额
  213. */
  214. public BigDecimal getFinalDeductMoney(Long relationId, Long relationSkuId, Long renewSkuId, Long renewOrderId, Date renewExpiryTime, Date relationStartTime, Date relationExpiryTime, DateTime now, List<Long> userIdList) {
  215. BigDecimal deductMoney = BigDecimal.ZERO;
  216. //一个月当30天算单价 往上取整
  217. //续费规格
  218. if (renewSkuId != null && renewExpiryTime.compareTo(now) > 0) {
  219. OrderDon renewOrderDon = orderDonMapper.selectById(renewOrderId);
  220. BigDecimal orderMoney = renewOrderDon.getMoney().add(Optional.ofNullable(renewOrderDon.getBalance()).orElse(BigDecimal.ZERO));
  221. GoodsDonSku presentSku = skuMapper.selectById(renewSkuId);
  222. if (orderMoney.compareTo(BigDecimal.ZERO) == 0) {
  223. orderMoney = presentSku.getPrice();
  224. }
  225. Long betweenDay = DateUtil.betweenDay(now, renewExpiryTime, false) + 1;
  226. //当天购买的按规格原价抵扣
  227. BigDecimal renewDeductMoney;
  228. if (now.toDateStr().equals(DateUtil.format(renewOrderDon.getCreatedTime(), "yyyy-MM-dd"))) {
  229. renewDeductMoney = orderMoney;
  230. deductMoney = deductMoney.add(renewDeductMoney);
  231. if (presentSku.getDays() != null) {
  232. relationExpiryTime = DateUtil.offsetDay(relationExpiryTime, -presentSku.getDays());
  233. } else {
  234. relationExpiryTime = DateUtil.offsetMonth(relationExpiryTime, -presentSku.getMonths());
  235. }
  236. } else {
  237. //此次续费规格单价
  238. BigDecimal single = getPayOrderSingle(orderMoney, presentSku);
  239. //该车票抵扣金额
  240. renewDeductMoney = single.multiply(BigDecimal.valueOf(betweenDay));
  241. log.info("车票id:{}目前续费升级规格可抵扣的金额为:{}", relationId, renewDeductMoney);
  242. deductMoney = deductMoney.add(renewDeductMoney);
  243. relationExpiryTime = DateUtil.offsetDay(relationExpiryTime, -betweenDay.intValue());
  244. }
  245. //上一个续费升级规格
  246. List<OrderDon> orderDOns = orderDonRenewRecordMapper.getOtherRenewSkus(renewOrderId, relationId, userIdList);
  247. OrderDon presentRenewOrderDon = renewOrderDon;
  248. for (OrderDon thisRenewOrderDon : orderDOns) {
  249. Long skuId = thisRenewOrderDon.getSkuId();
  250. GoodsDonSku thisRenewSku = skuMapper.selectById(skuId);
  251. BigDecimal thisOrderMoney = thisRenewOrderDon.getMoney().add(Optional.ofNullable(thisRenewOrderDon.getBalance()).orElse(BigDecimal.ZERO));
  252. if (thisOrderMoney.compareTo(BigDecimal.ZERO) == 0) {
  253. thisOrderMoney = thisRenewSku.getPrice();
  254. }
  255. //当天购买的按规格原价抵扣
  256. BigDecimal thisRenewDeductMoney = BigDecimal.ZERO;
  257. if (now.toDateStr().equals(DateUtil.format(thisRenewOrderDon.getCreatedTime(), "yyyy-MM-dd"))) {
  258. thisRenewDeductMoney = thisOrderMoney;
  259. deductMoney = deductMoney.add(thisRenewDeductMoney);
  260. if (thisRenewSku.getDays() != null) {
  261. relationExpiryTime = DateUtil.offsetDay(relationExpiryTime, -thisRenewSku.getDays());
  262. } else {
  263. relationExpiryTime = DateUtil.offsetMonth(relationExpiryTime, -thisRenewSku.getMonths());
  264. }
  265. } else {
  266. //此次续费订单过期时间
  267. Date thisOrderExpiryTime;
  268. if (thisRenewSku.getDays() != null) {
  269. thisOrderExpiryTime = DateUtil.offsetDay(thisRenewOrderDon.getCreatedTime(), thisRenewSku.getDays());
  270. } else {
  271. thisOrderExpiryTime = DateUtil.offsetMonth(thisRenewOrderDon.getCreatedTime(), thisRenewSku.getMonths());
  272. }
  273. //续费同规格不处理
  274. if (!ObjectUtil.equal(thisRenewOrderDon.getSkuId(), presentRenewOrderDon.getSkuId())) {
  275. //先扣除已使用的天数
  276. //相差多少天
  277. Long thisRenewBetDay = DateUtil.betweenDay(thisRenewOrderDon.getCreatedTime(), presentRenewOrderDon.getCreatedTime(), false);
  278. //扣除已使用的
  279. thisOrderExpiryTime = DateUtil.offsetDay(thisOrderExpiryTime, -thisRenewBetDay.intValue());
  280. }
  281. //此订单过期时间
  282. if (thisOrderExpiryTime.compareTo(now) > 0) {
  283. //距离过期还剩多少天
  284. Long thisDeductBetweenDay = DateUtil.betweenDay(now, thisOrderExpiryTime, false) + 1;
  285. if (thisDeductBetweenDay != 0) {
  286. //此次续费规格单价
  287. BigDecimal single = getPayOrderSingle(thisOrderMoney, thisRenewSku);
  288. //该车票抵扣金额
  289. thisRenewDeductMoney = single.multiply(BigDecimal.valueOf(thisDeductBetweenDay));
  290. deductMoney = deductMoney.add(thisRenewDeductMoney);
  291. }
  292. //目前级别续费订单
  293. presentRenewOrderDon = thisRenewOrderDon;
  294. relationExpiryTime = DateUtil.offsetDay(relationExpiryTime, -thisDeductBetweenDay.intValue());
  295. }
  296. }
  297. log.info("车票id:{}目前次一级规格:{}可抵扣的金额为:{}", relationId, thisRenewSku.getSpecVal(), thisRenewDeductMoney);
  298. }
  299. }
  300. if (relationExpiryTime.after(now)) {
  301. //该车票抵扣金额
  302. BigDecimal deductMoneyFromTicket = getDeductMoneyFromTicket(relationId, userIdList, relationSkuId, now, relationStartTime, relationExpiryTime);
  303. deductMoney = deductMoney.add(deductMoneyFromTicket);
  304. }
  305. log.info("车票id:{}最终到期时间为:{}车票可返回 抵扣金额:{}", relationId, DateUtil.format(relationExpiryTime, "yyyy-MM-dd HH:mm:ss"), deductMoney);
  306. return deductMoney;
  307. }
  308. /**
  309. * 获取车票可抵扣金额
  310. */
  311. public BigDecimal getDeductMoneyFromTicket(Long relationId, List<Long> userIdList, Long skuId, DateTime now, Date relationStartTime, Date relationExpiryTime) {
  312. List<OrderDon> orderDonList = orderDonMapper.selectList(Wrappers.lambdaQuery(OrderDon.class)
  313. .eq(OrderDon::getRelationId, relationId)
  314. .in(OrderDon::getUserId, userIdList)
  315. .eq(OrderDon::getSkuId, skuId)
  316. .notIn(OrderDon::getStatus, Constant.noOrderAllStatus)
  317. .orderByDesc(OrderDon::getId));
  318. //部分退款
  319. if (orderDonList.isEmpty()) {
  320. orderDonList = orderDonMapper.selectList(Wrappers.lambdaQuery(OrderDon.class)
  321. .eq(OrderDon::getRelationId, relationId)
  322. .in(OrderDon::getUserId, userIdList)
  323. .eq(OrderDon::getSkuId, skuId)
  324. .notIn(OrderDon::getStatus, Constant.noOrderStatus)
  325. .orderByDesc(OrderDon::getId));
  326. }
  327. //原车票订单总实付金额
  328. BigDecimal totalOrderMoney = BigDecimal.ZERO;
  329. //原车票订单总天数
  330. Integer totalDays = 0;
  331. for (OrderDon orderDon : orderDonList) {
  332. GoodsDonSku sku = skuMapper.selectById(skuId);
  333. BigDecimal thisOrderMoney = orderDon.getMoney().add(Optional.ofNullable(orderDon.getBalance()).orElse(BigDecimal.ZERO)).subtract(Optional.ofNullable(orderDon.getRefundMoney()).orElse(BigDecimal.ZERO));
  334. if (thisOrderMoney.compareTo(BigDecimal.ZERO) == 0) {
  335. thisOrderMoney = sku.getPrice();
  336. }
  337. totalOrderMoney = totalOrderMoney.add(thisOrderMoney);
  338. //总时间
  339. if (sku.getDays() != null) {
  340. totalDays += sku.getDays();
  341. } else {
  342. totalDays += sku.getMonths() * 30;
  343. }
  344. //原订单数
  345. if (orderDonList.size() == 1) {
  346. //此次订单过期时间
  347. Date thisOrderExpiryTime;
  348. if (sku.getDays() != null) {
  349. thisOrderExpiryTime = DateUtil.offsetDay(orderDon.getCreatedTime(), sku.getDays());
  350. } else {
  351. thisOrderExpiryTime = DateUtil.offsetMonth(orderDon.getCreatedTime(), sku.getMonths());
  352. }
  353. //当天购买的按规格原价抵扣
  354. if (now.toDateStr().equals(DateUtil.format(relationStartTime, "yyyy-MM-dd")) && (DateUtil.betweenDay(thisOrderExpiryTime, relationExpiryTime, true) == 0)) {
  355. return thisOrderMoney;
  356. }
  357. }
  358. }
  359. Long thisDeductBetweenDay = DateUtil.betweenDay(now, relationExpiryTime, false) + 1;
  360. BigDecimal single = totalOrderMoney.divide(BigDecimal.valueOf(totalDays), 0, RoundingMode.HALF_UP);
  361. //该车票抵扣金额
  362. BigDecimal deductMoney = single.multiply(BigDecimal.valueOf(thisDeductBetweenDay));
  363. return deductMoney;
  364. }
  365. /**
  366. * 获取订单单价
  367. */
  368. public BigDecimal getPayOrderSingle(BigDecimal orderMoney, GoodsDonSku sku) {
  369. //此次续费规格单价
  370. BigDecimal single;
  371. //区分天/月
  372. if (sku.getDays() != null) {
  373. single = orderMoney.divide(BigDecimal.valueOf(sku.getDays()), 0, RoundingMode.HALF_UP);
  374. } else {
  375. single = orderMoney.divide(BigDecimal.valueOf(sku.getMonths()).multiply(BigDecimal.valueOf(30)), 0, RoundingMode.HALF_UP);
  376. }
  377. return single;
  378. }
  379. /**
  380. * 获取普通剩余次数可抵扣金额
  381. */
  382. private BigDecimal getGeneralRemainNumDeductMoney(Long relationId,Long goodsId,Long skuId,List<Long> userIdList) {
  383. BigDecimal deductMoney = BigDecimal.ZERO;
  384. BigDecimal orderTotalMoney = BigDecimal.ZERO;
  385. //总次数
  386. Integer totalNum = 0;
  387. List<OrderDon> orderDonList = orderDonMapper.selectList(Wrappers.lambdaQuery(OrderDon.class).eq(OrderDon::getRelationId, relationId).in(OrderDon::getUserId, userIdList).notIn(OrderDon::getStatus, Constant.noOrderAllStatus));
  388. for (OrderDon orderDon : orderDonList) {
  389. GoodsDonSku sku = skuMapper.selectById(skuId);
  390. if (orderDon.getMoney().compareTo(BigDecimal.ZERO) >= 0) {
  391. orderTotalMoney = orderTotalMoney.add(orderDon.getMoney());
  392. } else {
  393. //兑换码订单使用规格价格
  394. orderTotalMoney = orderTotalMoney.add(sku.getPrice());
  395. }
  396. if (goodsId == Constant.LUMA_GOODS_ID) {
  397. totalNum += sku.getLumaNum();
  398. } else {
  399. totalNum += sku.getNanoQuota();
  400. }
  401. }
  402. //加量包订单
  403. List<UpgradeOrderDon> upgradeOrderDons = upgradeOrderDonMapper.selectList(Wrappers.lambdaQuery(UpgradeOrderDon.class).eq(UpgradeOrderDon::getRelationId, relationId).in(UpgradeOrderDon::getUserId, userIdList).notIn(UpgradeOrderDon::getStatus, Constant.noOrderAllStatus));
  404. for (UpgradeOrderDon upgradeOrderDon : upgradeOrderDons) {
  405. orderTotalMoney = orderTotalMoney.add(upgradeOrderDon.getMoney());
  406. totalNum = totalNum + upgradeOrderDon.getNum();
  407. }
  408. Integer remainNum = null;
  409. if (goodsId == Constant.LUMA_GOODS_ID) {
  410. LumaUser lumaUser = lumaUserMapper.selectOne(Wrappers.lambdaQuery(LumaUser.class).eq(LumaUser::getRelationId, relationId).last("limit 1"));
  411. if (lumaUser != null) {
  412. remainNum = lumaUser.getNum();
  413. }
  414. }else {
  415. NanoUserQuota nanoUserQuota = nanoUserQuotaMapper.selectOne(Wrappers.lambdaQuery(NanoUserQuota.class).eq(NanoUserQuota::getRelationId, relationId).last("limit 1"));
  416. if (nanoUserQuota != null) {
  417. remainNum = nanoUserQuota.getRemainingQuota();
  418. }
  419. }
  420. //若未使用
  421. if (remainNum == null) {
  422. deductMoney = deductMoney.add(orderTotalMoney);
  423. } else {
  424. BigDecimal remainMoney = BigDecimal.valueOf(remainNum).divide(BigDecimal.valueOf(totalNum), 2, RoundingMode.UP).multiply(orderTotalMoney);
  425. deductMoney = deductMoney.add(remainMoney);
  426. }
  427. return deductMoney;
  428. }
  429. /**
  430. * 获取mj剩余次数可抵扣金额
  431. */
  432. private BigDecimal getMjRemainNumDeductMoney(Long relationId, Long skuId, List<Long> userIdList) {
  433. BigDecimal deductMoney = BigDecimal.ZERO;
  434. BigDecimal orderTotalMoney = BigDecimal.ZERO;
  435. //总次数
  436. Integer fastTotalNum = 0;
  437. Integer relaxTotalNum = 0;
  438. List<OrderDon> orderDonList = orderDonMapper.selectList(Wrappers.lambdaQuery(OrderDon.class).eq(OrderDon::getRelationId, relationId).in(OrderDon::getUserId, userIdList).notIn(OrderDon::getStatus, Constant.noOrderAllStatus));
  439. for (OrderDon orderDon : orderDonList) {
  440. GoodsDonSku sku = skuMapper.selectById(skuId);
  441. if (orderDon.getMoney().compareTo(BigDecimal.ZERO) >= 0) {
  442. orderTotalMoney = orderTotalMoney.add(orderDon.getMoney());
  443. } else {
  444. //兑换码订单使用规格价格
  445. orderTotalMoney = orderTotalMoney.add(sku.getPrice());
  446. }
  447. fastTotalNum += sku.getMjFastNum();
  448. relaxTotalNum += sku.getMjRelaxNum();
  449. }
  450. Integer upgradeNum = 0;
  451. BigDecimal upgradeOrderMoney = BigDecimal.ZERO;
  452. //加量包订单
  453. List<UpgradeOrderDon> upgradeOrderDons = upgradeOrderDonMapper.selectList(Wrappers.lambdaQuery(UpgradeOrderDon.class).eq(UpgradeOrderDon::getRelationId, relationId).in(UpgradeOrderDon::getUserId, userIdList).notIn(UpgradeOrderDon::getStatus, Constant.noOrderAllStatus));
  454. for (UpgradeOrderDon upgradeOrderDon : upgradeOrderDons) {
  455. upgradeNum += upgradeOrderDon.getNum();
  456. upgradeOrderMoney = upgradeOrderMoney.add(upgradeOrderDon.getMoney());
  457. }
  458. MidjourneyUser midjourneyUser = midjourneyUserMapper.selectOne(Wrappers.lambdaQuery(MidjourneyUser.class).eq(MidjourneyUser::getRelationId, relationId).last("limit 1"));
  459. if (midjourneyUser == null) {
  460. deductMoney = deductMoney.add(orderTotalMoney).add(upgradeOrderMoney);
  461. } else {
  462. Integer remainFastNum = midjourneyUser.getMjFastNum();
  463. Integer remainRelaxNum = midjourneyUser.getMjRelaxNum();
  464. if (CollUtil.isNotEmpty(orderDonList)) {
  465. BigDecimal fastMoney = BigDecimal.valueOf(remainFastNum).divide(BigDecimal.valueOf(fastTotalNum), 2, RoundingMode.UP).multiply(orderTotalMoney);
  466. BigDecimal relaxMoney = BigDecimal.valueOf(remainRelaxNum).divide(BigDecimal.valueOf(relaxTotalNum), 2, RoundingMode.UP).multiply(orderTotalMoney);
  467. deductMoney = deductMoney.add(fastMoney).add(relaxMoney);
  468. }
  469. //加量包
  470. Integer remainUpgradeNum = midjourneyUser.getMjUpgradeNum();
  471. if (CollUtil.isNotEmpty(upgradeOrderDons)) {
  472. BigDecimal upgradeMoney = BigDecimal.valueOf(remainUpgradeNum).divide(BigDecimal.valueOf(upgradeNum), 2, RoundingMode.UP).multiply(upgradeOrderMoney);
  473. deductMoney = deductMoney.add(upgradeMoney);
  474. }
  475. }
  476. return deductMoney;
  477. }
  478. }