|
@@ -1,5 +1,6 @@
|
|
|
package com.cyksj.service.vip.impl;
|
|
package com.cyksj.service.vip.impl;
|
|
|
|
|
|
|
|
|
|
+import cn.hutool.core.collection.CollUtil;
|
|
|
import cn.hutool.core.date.DateTime;
|
|
import cn.hutool.core.date.DateTime;
|
|
|
import cn.hutool.core.date.DateUtil;
|
|
import cn.hutool.core.date.DateUtil;
|
|
|
import cn.hutool.core.util.ObjectUtil;
|
|
import cn.hutool.core.util.ObjectUtil;
|
|
@@ -14,6 +15,7 @@ import com.cyksj.model.dto.VipDeductDto;
|
|
|
import com.cyksj.model.entity.*;
|
|
import com.cyksj.model.entity.*;
|
|
|
import com.cyksj.model.manage.views.GroupsRelationView;
|
|
import com.cyksj.model.manage.views.GroupsRelationView;
|
|
|
import com.cyksj.model.response.VipUserPageResp;
|
|
import com.cyksj.model.response.VipUserPageResp;
|
|
|
|
|
+import com.cyksj.model.views.RenewalView;
|
|
|
import com.cyksj.service.chatgpt.ChatGptAccountService;
|
|
import com.cyksj.service.chatgpt.ChatGptAccountService;
|
|
|
import com.cyksj.service.claude.ClaudeService;
|
|
import com.cyksj.service.claude.ClaudeService;
|
|
|
import com.cyksj.service.user.UserBindRelationService;
|
|
import com.cyksj.service.user.UserBindRelationService;
|
|
@@ -64,6 +66,14 @@ public class VipFrontServiceImpl implements VipFrontService {
|
|
|
|
|
|
|
|
private final ClaudeService claudeService;
|
|
private final ClaudeService claudeService;
|
|
|
|
|
|
|
|
|
|
+ private final LumaUserMapper lumaUserMapper;
|
|
|
|
|
+
|
|
|
|
|
+ private final UpgradeOrderDonMapper upgradeOrderDonMapper;
|
|
|
|
|
+
|
|
|
|
|
+ private final NanoUserQuotaMapper nanoUserQuotaMapper;
|
|
|
|
|
+
|
|
|
|
|
+ private final MidjourneyUserMapper midjourneyUserMapper;
|
|
|
|
|
+
|
|
|
@Override
|
|
@Override
|
|
|
public void fillVipInfo(Long userId, VipUserPageResp vipUserPageResp) {
|
|
public void fillVipInfo(Long userId, VipUserPageResp vipUserPageResp) {
|
|
|
SysConfig sysConfig = sysConfigMapper.selectOne(Wrappers.lambdaQuery(SysConfig.class).eq(SysConfig::getSysKey, Constant.VIP_FEE_KEY).last("limit 1"));
|
|
SysConfig sysConfig = sysConfigMapper.selectOne(Wrappers.lambdaQuery(SysConfig.class).eq(SysConfig::getSysKey, Constant.VIP_FEE_KEY).last("limit 1"));
|
|
@@ -82,8 +92,6 @@ public class VipFrontServiceImpl implements VipFrontService {
|
|
|
//会员规格
|
|
//会员规格
|
|
|
Set<Long> goodsIds = goodsDonSkuMapper.selectList(Wrappers.lambdaQuery(GoodsDonSku.class)
|
|
Set<Long> goodsIds = goodsDonSkuMapper.selectList(Wrappers.lambdaQuery(GoodsDonSku.class)
|
|
|
.in(GoodsDonSku::getId, vipSkuIds)).stream().map(GoodsDonSku::getGoodsId).collect(Collectors.toSet());
|
|
.in(GoodsDonSku::getId, vipSkuIds)).stream().map(GoodsDonSku::getGoodsId).collect(Collectors.toSet());
|
|
|
- //todo 临时处理 nano先不参与抵扣
|
|
|
|
|
- goodsIds.remove(Constant.NANO_GOODS_ID);
|
|
|
|
|
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());
|
|
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());
|
|
|
//可抵扣车票
|
|
//可抵扣车票
|
|
|
if (count.intValue() > 0) {
|
|
if (count.intValue() > 0) {
|
|
@@ -165,6 +173,25 @@ public class VipFrontServiceImpl implements VipFrontService {
|
|
|
if (deductGoodsIds.contains(goodsId)) {
|
|
if (deductGoodsIds.contains(goodsId)) {
|
|
|
continue;
|
|
continue;
|
|
|
}
|
|
}
|
|
|
|
|
+ if (goodsId == Constant.NANO_GOODS_ID) {
|
|
|
|
|
+ NanoUserQuota nanoUserQuota = nanoUserQuotaMapper.selectOne(Wrappers.lambdaQuery(NanoUserQuota.class).in(NanoUserQuota::getUid, userIdList).orderByDesc(NanoUserQuota::getRemainingQuota).last("limit 1"));
|
|
|
|
|
+ if (nanoUserQuota != null) {
|
|
|
|
|
+ if (!ObjectUtil.equal(nanoUserQuota.getRelationId(), relation.getId())) {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ //规格最高
|
|
|
|
|
+ RenewalView renewalView = beanSearcher.searchFirst(RenewalView.class, MapUtils.builder()
|
|
|
|
|
+ .field(RenewalView::getGoodsId, goodsId)
|
|
|
|
|
+ .field(RenewalView::getUserId, userIdList).op(Operator.InList)
|
|
|
|
|
+ .orderBy(RenewalView::getSkuNanoQuota).desc()
|
|
|
|
|
+ .onlySelect(RenewalView::getRelationId)
|
|
|
|
|
+ .build());
|
|
|
|
|
+ if (renewalView != null && !ObjectUtil.equal(renewalView.getRelationId(), relation.getId())) {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
Long skuId = relation.getSkuId();
|
|
Long skuId = relation.getSkuId();
|
|
|
deductGoodsIds.add(goodsId);
|
|
deductGoodsIds.add(goodsId);
|
|
|
Long relationId = relation.getId();
|
|
Long relationId = relation.getId();
|
|
@@ -190,6 +217,12 @@ public class VipFrontServiceImpl implements VipFrontService {
|
|
|
//获取抵扣金额
|
|
//获取抵扣金额
|
|
|
deductMoney = deductMoney.add(getFinalDeductMoney(relationId, relation.getSkuId(), claudeUser.getRenewSkuId(), claudeUser.getRenewOrderId(), claudeUser.getRenewExpiryTime(), relation.getStartTime(), relationExpiryTime, now, userIdList));
|
|
deductMoney = deductMoney.add(getFinalDeductMoney(relationId, relation.getSkuId(), claudeUser.getRenewSkuId(), claudeUser.getRenewOrderId(), claudeUser.getRenewExpiryTime(), relation.getStartTime(), relationExpiryTime, now, userIdList));
|
|
|
}
|
|
}
|
|
|
|
|
+ } else if (goodsId == Constant.LUMA_GOODS_ID || goodsId == Constant.NANO_GOODS_ID) {
|
|
|
|
|
+ //luma、nano
|
|
|
|
|
+ deductMoney = deductMoney.add(getGeneralRemainNumDeductMoney(relationId, goodsId, skuId, userIdList, relation.getStartTime()));
|
|
|
|
|
+ } else if (goodsId == Constant.MIDJOURNEY_GOODS_ID) {
|
|
|
|
|
+ //mj
|
|
|
|
|
+ deductMoney = deductMoney.add(getMjRemainNumDeductMoney(relationId, skuId, userIdList, relation.getStartTime(), relation.getExpiryTime()));
|
|
|
} else {
|
|
} else {
|
|
|
//该车票抵扣金额
|
|
//该车票抵扣金额
|
|
|
deductMoney = deductMoney.add(getDeductMoneyFromTicket(relationId, userIdList, skuId, now, relation.getStartTime(), relationExpiryTime));
|
|
deductMoney = deductMoney.add(getDeductMoneyFromTicket(relationId, userIdList, skuId, now, relation.getStartTime(), relationExpiryTime));
|
|
@@ -388,4 +421,153 @@ public class VipFrontServiceImpl implements VipFrontService {
|
|
|
}
|
|
}
|
|
|
return single;
|
|
return single;
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 获取普通剩余次数可抵扣金额
|
|
|
|
|
+ */
|
|
|
|
|
+ private BigDecimal getGeneralRemainNumDeductMoney(Long relationId, Long goodsId, Long skuId, List<Long> userIdList, Date relationStartTime) {
|
|
|
|
|
+ BigDecimal deductMoney = BigDecimal.ZERO;
|
|
|
|
|
+ BigDecimal orderTotalMoney = BigDecimal.ZERO;
|
|
|
|
|
+ //总次数
|
|
|
|
|
+ Integer totalNum = 0;
|
|
|
|
|
+ DateTime now = DateTime.now();
|
|
|
|
|
+
|
|
|
|
|
+ List<OrderDon> orderDonList = orderDonMapper.selectList(Wrappers.lambdaQuery(OrderDon.class).eq(OrderDon::getRelationId, relationId).in(OrderDon::getUserId, userIdList).notIn(OrderDon::getStatus, Constant.noOrderAllStatus));
|
|
|
|
|
+ for (OrderDon orderDon : orderDonList) {
|
|
|
|
|
+ GoodsDonSku sku = skuMapper.selectById(skuId);
|
|
|
|
|
+ Date orderCreatedTime = orderDon.getCreatedTime();
|
|
|
|
|
+ Integer months = sku.getMonths();
|
|
|
|
|
+ Integer days = sku.getDays();
|
|
|
|
|
+ Date orderExpiryTime;
|
|
|
|
|
+ if (days != null) {
|
|
|
|
|
+ orderExpiryTime = DateUtil.offsetDay(orderCreatedTime, days);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ orderExpiryTime = DateUtil.offsetMonth(orderCreatedTime, months);
|
|
|
|
|
+ }
|
|
|
|
|
+ //过期的订单不算入
|
|
|
|
|
+ if (orderExpiryTime.before(now)) {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (orderDon.getMoney().compareTo(BigDecimal.ZERO) > 0) {
|
|
|
|
|
+ orderTotalMoney = orderTotalMoney.add(orderDon.getMoney().add(Optional.ofNullable(orderDon.getBalance()).orElse(BigDecimal.ZERO)));
|
|
|
|
|
+ } else {
|
|
|
|
|
+ //兑换码订单使用规格价格
|
|
|
|
|
+ orderTotalMoney = orderTotalMoney.add(sku.getPrice());
|
|
|
|
|
+ }
|
|
|
|
|
+ if (goodsId == Constant.LUMA_GOODS_ID) {
|
|
|
|
|
+ totalNum += sku.getLumaNum();
|
|
|
|
|
+ } else {
|
|
|
|
|
+ totalNum += sku.getNanoQuota();
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ //加量包订单
|
|
|
|
|
+ List<UpgradeOrderDon> upgradeOrderDons = upgradeOrderDonMapper.selectList(Wrappers.lambdaQuery(UpgradeOrderDon.class).eq(UpgradeOrderDon::getRelationId, relationId).in(UpgradeOrderDon::getUserId, userIdList).notIn(UpgradeOrderDon::getStatus, Constant.noOrderAllStatus).gt(UpgradeOrderDon::getCreatedTime, relationStartTime));
|
|
|
|
|
+ for (UpgradeOrderDon upgradeOrderDon : upgradeOrderDons) {
|
|
|
|
|
+ orderTotalMoney = orderTotalMoney.add(upgradeOrderDon.getMoney().add(Optional.ofNullable(upgradeOrderDon.getBalance()).orElse(BigDecimal.ZERO)));
|
|
|
|
|
+ totalNum = totalNum + upgradeOrderDon.getNum();
|
|
|
|
|
+ }
|
|
|
|
|
+ Integer remainNum = null;
|
|
|
|
|
+ if (goodsId == Constant.LUMA_GOODS_ID) {
|
|
|
|
|
+ LumaUser lumaUser = lumaUserMapper.selectOne(Wrappers.lambdaQuery(LumaUser.class).eq(LumaUser::getRelationId, relationId).last("limit 1"));
|
|
|
|
|
+ if (lumaUser != null) {
|
|
|
|
|
+ remainNum = lumaUser.getNum();
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ NanoUserQuota nanoUserQuota = nanoUserQuotaMapper.selectOne(Wrappers.lambdaQuery(NanoUserQuota.class).eq(NanoUserQuota::getRelationId, relationId).last("limit 1"));
|
|
|
|
|
+ if (nanoUserQuota != null) {
|
|
|
|
|
+ remainNum = nanoUserQuota.getRemainingQuota();
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ //若未使用
|
|
|
|
|
+ if (remainNum == null) {
|
|
|
|
|
+ deductMoney = deductMoney.add(orderTotalMoney);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ BigDecimal remainMoney = BigDecimal.valueOf(remainNum).divide(BigDecimal.valueOf(totalNum), 2, RoundingMode.DOWN).multiply(orderTotalMoney);
|
|
|
|
|
+ deductMoney = deductMoney.add(remainMoney);
|
|
|
|
|
+ }
|
|
|
|
|
+ return deductMoney;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 获取mj剩余次数可抵扣金额
|
|
|
|
|
+ */
|
|
|
|
|
+ private BigDecimal getMjRemainNumDeductMoney(Long relationId, Long skuId, List<Long> userIdList, Date relationStartTime, Date relationExpiryTime) {
|
|
|
|
|
+ BigDecimal deductMoney = BigDecimal.ZERO;
|
|
|
|
|
+ BigDecimal orderTotalMoney = BigDecimal.ZERO;
|
|
|
|
|
+ //总次数
|
|
|
|
|
+ Integer totalNum = null;
|
|
|
|
|
+ //原车票订单总天数
|
|
|
|
|
+ Integer totalDays = 0;
|
|
|
|
|
+ DateTime now = DateTime.now();
|
|
|
|
|
+
|
|
|
|
|
+ List<OrderDon> orderDonList = orderDonMapper.selectList(Wrappers.lambdaQuery(OrderDon.class).eq(OrderDon::getRelationId, relationId).in(OrderDon::getUserId, userIdList).notIn(OrderDon::getStatus, Constant.noOrderAllStatus));
|
|
|
|
|
+ for (OrderDon orderDon : orderDonList) {
|
|
|
|
|
+ GoodsDonSku sku = skuMapper.selectById(skuId);
|
|
|
|
|
+ Date orderCreatedTime = orderDon.getCreatedTime();
|
|
|
|
|
+ Integer months = sku.getMonths();
|
|
|
|
|
+ Integer days = sku.getDays();
|
|
|
|
|
+ //订单过期时间
|
|
|
|
|
+ Date orderExpiryTime;
|
|
|
|
|
+ if (days != null) {
|
|
|
|
|
+ orderExpiryTime = DateUtil.offsetDay(orderCreatedTime, days);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ orderExpiryTime = DateUtil.offsetMonth(orderCreatedTime, months);
|
|
|
|
|
+ }
|
|
|
|
|
+ //总时间
|
|
|
|
|
+ totalDays += sku.getMonths() * 30;
|
|
|
|
|
+ //过期的订单不算入
|
|
|
|
|
+ if (orderExpiryTime.before(now)) {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (orderDon.getMoney().compareTo(BigDecimal.ZERO) > 0) {
|
|
|
|
|
+ orderTotalMoney = orderTotalMoney.add(orderDon.getMoney().add(Optional.ofNullable(orderDon.getBalance()).orElse(BigDecimal.ZERO)));
|
|
|
|
|
+ } else {
|
|
|
|
|
+ //兑换码订单使用规格价格
|
|
|
|
|
+ orderTotalMoney = orderTotalMoney.add(sku.getPrice());
|
|
|
|
|
+ }
|
|
|
|
|
+ if (totalNum == null) {
|
|
|
|
|
+ totalNum = sku.getMjFastNum() + sku.getMjRelaxNum();
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ Integer upgradeNum = 0;
|
|
|
|
|
+ BigDecimal upgradeOrderMoney = BigDecimal.ZERO;
|
|
|
|
|
+ //加量包订单
|
|
|
|
|
+ List<UpgradeOrderDon> upgradeOrderDons = upgradeOrderDonMapper.selectList(Wrappers.lambdaQuery(UpgradeOrderDon.class).eq(UpgradeOrderDon::getRelationId, relationId).in(UpgradeOrderDon::getUserId, userIdList).notIn(UpgradeOrderDon::getStatus, Constant.noOrderAllStatus).gt(UpgradeOrderDon::getCreatedTime, relationStartTime));
|
|
|
|
|
+ for (UpgradeOrderDon upgradeOrderDon : upgradeOrderDons) {
|
|
|
|
|
+ upgradeNum += upgradeOrderDon.getNum();
|
|
|
|
|
+ upgradeOrderMoney = upgradeOrderMoney.add(upgradeOrderDon.getMoney().add(Optional.ofNullable(upgradeOrderDon.getBalance()).orElse(BigDecimal.ZERO)));
|
|
|
|
|
+ }
|
|
|
|
|
+ MidjourneyUser midjourneyUser = midjourneyUserMapper.selectOne(Wrappers.lambdaQuery(MidjourneyUser.class).eq(MidjourneyUser::getRelationId, relationId).last("limit 1"));
|
|
|
|
|
+ if (midjourneyUser == null) {
|
|
|
|
|
+ deductMoney = deductMoney.add(orderTotalMoney).add(upgradeOrderMoney);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ if (CollUtil.isNotEmpty(orderDonList)) {
|
|
|
|
|
+ Integer remainFastNum = midjourneyUser.getMjFastNum();
|
|
|
|
|
+ Integer remainRelaxNum = midjourneyUser.getMjRelaxNum();
|
|
|
|
|
+ Integer usedNum = totalNum - remainFastNum - remainRelaxNum;
|
|
|
|
|
+ if (usedNum == 0 && now.toDateStr().equals(DateUtil.format(relationStartTime, "yyyy-MM-dd"))) {
|
|
|
|
|
+ deductMoney = deductMoney.add(orderTotalMoney);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ //每天单价
|
|
|
|
|
+ BigDecimal single = orderTotalMoney.divide(BigDecimal.valueOf(totalDays), 0, RoundingMode.HALF_UP);
|
|
|
|
|
+ BigDecimal consumeRate = BigDecimal.valueOf(usedNum).divide(BigDecimal.valueOf(totalNum), 2, RoundingMode.DOWN);
|
|
|
|
|
+ //消耗的次数当月 值多少钱
|
|
|
|
|
+ BigDecimal consumeMoney = consumeRate.multiply(single.multiply(BigDecimal.valueOf(30)));
|
|
|
|
|
+ //该车票多长时间
|
|
|
|
|
+ Long thisDeductBetweenDay = DateUtil.betweenDay(now, relationExpiryTime, false) + 1;
|
|
|
|
|
+ //该车票抵扣金额
|
|
|
|
|
+ BigDecimal orderRemainMoney = single.multiply(BigDecimal.valueOf(thisDeductBetweenDay));
|
|
|
|
|
+ //最终可抵扣
|
|
|
|
|
+ deductMoney = deductMoney.add(orderRemainMoney.subtract(consumeMoney));
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ //加量包
|
|
|
|
|
+ Integer remainUpgradeNum = midjourneyUser.getMjUpgradeNum();
|
|
|
|
|
+ if (CollUtil.isNotEmpty(upgradeOrderDons)) {
|
|
|
|
|
+ BigDecimal upgradeMoney = BigDecimal.valueOf(remainUpgradeNum).divide(BigDecimal.valueOf(upgradeNum), 2, RoundingMode.DOWN).multiply(upgradeOrderMoney);
|
|
|
|
|
+ deductMoney = deductMoney.add(upgradeMoney);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return deductMoney;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|