chore: initialize qiming workspace repository
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>app-platform-subscription</artifactId>
|
||||
<groupId>com.xspaceagi</groupId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>app-platform-subscription-application</artifactId>
|
||||
|
||||
<properties>
|
||||
<maven.deploy.skip>true</maven.deploy.skip>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.xspaceagi</groupId>
|
||||
<artifactId>app-platform-subscription-domain</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.xspaceagi</groupId>
|
||||
<artifactId>app-platform-subscription-infra</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.xspaceagi</groupId>
|
||||
<artifactId>app-platform-subscription-sdk</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.xspaceagi</groupId>
|
||||
<artifactId>app-platform-credit-sdk</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-tx</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.xspaceagi.subscription.app.service;
|
||||
|
||||
import com.xspaceagi.subscription.sdk.dto.PlanDTO;
|
||||
import com.xspaceagi.subscription.sdk.dto.PlanQueryRequest;
|
||||
import com.xspaceagi.subscription.spec.enums.BizTypeEnum;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface SubscriptionPlanAppService {
|
||||
|
||||
Long createPlan(PlanDTO dto);
|
||||
|
||||
boolean updatePlan(PlanDTO dto);
|
||||
|
||||
boolean offlinePlan(Long id);
|
||||
|
||||
boolean deletePlan(Long id);
|
||||
|
||||
PlanDTO getPlanById(Long id);
|
||||
|
||||
PlanDTO getPlanById(Long id, boolean showPlanDescItems);
|
||||
|
||||
List<PlanDTO> listPlans(PlanQueryRequest query);
|
||||
|
||||
PlanDTO getFreePlan(BizTypeEnum bizType, String bizId, boolean showPlanDescItems);
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.xspaceagi.subscription.app.service;
|
||||
|
||||
import com.xspaceagi.subscription.sdk.dto.*;
|
||||
import com.xspaceagi.subscription.spec.enums.BizTypeEnum;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface UserSubscriptionAppService {
|
||||
|
||||
List<UserSubscriptionDTO> getUserSubscriptions(SubscriptionQueryRequest query);
|
||||
|
||||
/**
|
||||
* 获取用户当前指定业务(智能体)订阅
|
||||
*/
|
||||
UserSubscriptionDTO getUserCurrentSubscription(Long userId, BizTypeEnum bizType, String bizId);
|
||||
|
||||
/**
|
||||
* 获取用户当前系统订阅
|
||||
*/
|
||||
UserSubscriptionDTO getUserCurrentSystemSubscription(Long userId, boolean showPlanDescItems);
|
||||
|
||||
UserSubscriptionDTO createSubscription(CreateSubscriptionRequest request);
|
||||
|
||||
SubscriptionStatsDTO getSubscriptionStats(SubscriptionStatsQueryRequest request);
|
||||
|
||||
void reset(UserSubscriptionDTO subscriptionDTO);
|
||||
|
||||
int incrementCallCount(Long subscriptionId, Integer count);
|
||||
|
||||
List<UserSubscriptionDTO> getNeedResetSubscriptions();
|
||||
|
||||
List<UserSubscriptionDTO> getExpiredSubscriptions();
|
||||
}
|
||||
@@ -0,0 +1,282 @@
|
||||
package com.xspaceagi.subscription.app.service.impl;
|
||||
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.xspaceagi.agent.core.sdk.IAgentRpcService;
|
||||
import com.xspaceagi.agent.core.sdk.IModelRpcService;
|
||||
import com.xspaceagi.agent.core.sdk.dto.AgentInfoDto;
|
||||
import com.xspaceagi.agent.core.sdk.dto.ModelInfoDto;
|
||||
import com.xspaceagi.knowledge.sdk.response.KnowledgeConfigVo;
|
||||
import com.xspaceagi.knowledge.sdk.sevice.IKnowledgeConfigRpcService;
|
||||
import com.xspaceagi.subscription.app.service.SubscriptionPlanAppService;
|
||||
import com.xspaceagi.subscription.infra.dao.entity.Plan;
|
||||
import com.xspaceagi.subscription.infra.dao.entity.UserSubscription;
|
||||
import com.xspaceagi.subscription.infra.dao.mapper.PlanMapper;
|
||||
import com.xspaceagi.subscription.infra.dao.mapper.UserSubscriptionMapper;
|
||||
import com.xspaceagi.subscription.infra.dao.service.IPlanService;
|
||||
import com.xspaceagi.subscription.sdk.dto.PlanDTO;
|
||||
import com.xspaceagi.subscription.sdk.dto.PlanItemGroupDTO;
|
||||
import com.xspaceagi.subscription.sdk.dto.PlanQueryRequest;
|
||||
import com.xspaceagi.subscription.spec.enums.BizTypeEnum;
|
||||
import com.xspaceagi.subscription.spec.enums.PlanPeriodEnum;
|
||||
import com.xspaceagi.subscription.spec.enums.PlanStatusEnum;
|
||||
import com.xspaceagi.system.sdk.permission.IPermissionCacheRpcSerivce;
|
||||
import com.xspaceagi.system.sdk.permission.IUserDataPermissionRpcService;
|
||||
import com.xspaceagi.system.sdk.service.dto.MergedGroupDataPermissionDto;
|
||||
import com.xspaceagi.system.spec.enums.ErrorCodeEnum;
|
||||
import com.xspaceagi.system.spec.exception.BizException;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
public class SubscriptionPlanAppServiceImpl implements SubscriptionPlanAppService {
|
||||
|
||||
@Resource
|
||||
private IPlanService planService;
|
||||
|
||||
@Resource
|
||||
private PlanMapper planMapper;
|
||||
|
||||
@Resource
|
||||
private UserSubscriptionMapper userSubscriptionMapper;
|
||||
|
||||
@Resource
|
||||
private IUserDataPermissionRpcService iUserDataPermissionRpcService;
|
||||
|
||||
@Resource
|
||||
private IModelRpcService iModelRpcService;
|
||||
|
||||
@Resource
|
||||
private IAgentRpcService iAgentRpcService;
|
||||
|
||||
@Resource
|
||||
private IKnowledgeConfigRpcService iKnowledgeConfigRpcService;
|
||||
|
||||
@Resource
|
||||
private IPermissionCacheRpcSerivce iPermissionCacheRpcSerivce;
|
||||
|
||||
@Override
|
||||
public Long createPlan(PlanDTO dto) {
|
||||
if (dto.getName() == null || dto.getName().isBlank()) {
|
||||
throw new BizException(ErrorCodeEnum.INVALID_PARAM.getCode(), "计划名称不能为空");
|
||||
}
|
||||
if (dto.getBizType() == null) {
|
||||
throw new BizException(ErrorCodeEnum.INVALID_PARAM.getCode(), "业务类型不能为空");
|
||||
}
|
||||
if (!BizTypeEnum.SYSTEM.equals(dto.getBizType()) && (dto.getBizId() == null || dto.getBizId().isBlank())) {
|
||||
throw new BizException(ErrorCodeEnum.INVALID_PARAM.getCode(), "非系统业务类型必须指定业务对象ID");
|
||||
}
|
||||
|
||||
Plan entity = convertToEntity(dto);
|
||||
if (entity.getStatus() == null) {
|
||||
entity.setStatus(PlanStatusEnum.ONLINE.getCode());
|
||||
}
|
||||
if (entity.getIsHot() == null) {
|
||||
entity.setIsHot(false);
|
||||
}
|
||||
if (entity.getCreditAmount() == null) {
|
||||
entity.setCreditAmount(java.math.BigDecimal.ZERO);
|
||||
}
|
||||
if (entity.getCallLimitCount() == null) {
|
||||
entity.setCallLimitCount(-1);
|
||||
}
|
||||
if (entity.getFunctionOnly() == null) {
|
||||
entity.setFunctionOnly(false);
|
||||
}
|
||||
planService.save(entity);
|
||||
return entity.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean updatePlan(PlanDTO dto) {
|
||||
if (dto.getId() == null) {
|
||||
throw new BizException(ErrorCodeEnum.INVALID_PARAM.getCode(), "计划ID不能为空");
|
||||
}
|
||||
PlanDTO oldDto = getPlanById(dto.getId());
|
||||
Plan entity = convertToEntity(dto);
|
||||
try {
|
||||
return planService.updateById(entity);
|
||||
} finally {
|
||||
if (oldDto != null && dto.getGroupIds() != null) {
|
||||
iPermissionCacheRpcSerivce.clearCacheAllByTenant(oldDto.getTenantId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean offlinePlan(Long id) {
|
||||
Plan entity = new Plan();
|
||||
entity.setId(id);
|
||||
entity.setStatus(PlanStatusEnum.OFFLINE.getCode());
|
||||
return planService.updateById(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean deletePlan(Long id) {
|
||||
Long count = userSubscriptionMapper.selectCount(
|
||||
new LambdaQueryWrapper<UserSubscription>()
|
||||
.eq(UserSubscription::getPlanId, id));
|
||||
if (count != null && count > 0) {
|
||||
throw new BizException("PLAN_HAS_SUBSCRIPTION", "该计划已有用户订阅,无法删除");
|
||||
}
|
||||
return planService.removeById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PlanDTO getPlanById(Long id) {
|
||||
Plan entity = planService.getById(id);
|
||||
return entity != null ? convertToDTO(entity, true) : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PlanDTO getPlanById(Long id, boolean showPlanDescItems) {
|
||||
Plan entity = planService.getById(id);
|
||||
return entity != null ? convertToDTO(entity, showPlanDescItems) : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<PlanDTO> listPlans(PlanQueryRequest query) {
|
||||
List<Plan> plans = planMapper.selectListWithFilters(query);
|
||||
return plans.stream().map((Plan entity) -> convertToDTO(entity, true)).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public PlanDTO getFreePlan(BizTypeEnum bizType, String bizId, boolean showPlanDescItems) {
|
||||
Plan freePlan = planService.lambdaQuery()
|
||||
.eq(Plan::getBizType, bizType.getCode())
|
||||
.eq(bizType != BizTypeEnum.SYSTEM, Plan::getBizId, bizId)
|
||||
.eq(Plan::getStatus, PlanStatusEnum.ONLINE.getCode())
|
||||
.eq(Plan::getPrice, BigDecimal.ZERO)
|
||||
.orderByAsc(Plan::getSort)
|
||||
.orderByAsc(Plan::getId)
|
||||
.last("LIMIT 1")
|
||||
.one();
|
||||
return convertToDTO(freePlan, showPlanDescItems);
|
||||
}
|
||||
|
||||
private Plan convertToEntity(PlanDTO dto) {
|
||||
Plan entity = new Plan();
|
||||
BeanUtils.copyProperties(dto, entity);
|
||||
if (dto.getBizType() != null) {
|
||||
entity.setBizType(dto.getBizType().getCode());
|
||||
}
|
||||
|
||||
entity.setPeriod(dto.getPeriod() != null ? dto.getPeriod().getCode() : PlanPeriodEnum.FOREVER.getCode());
|
||||
if (dto.getExtra() != null) {
|
||||
entity.setExtra(JSON.toJSONString(dto.getExtra()));
|
||||
}
|
||||
if (dto.getGroupIds() != null) {
|
||||
entity.setGroupIds(JSON.toJSONString(dto.getGroupIds()));
|
||||
}
|
||||
return entity;
|
||||
}
|
||||
|
||||
private PlanDTO convertToDTO(Plan entity, boolean showPlanDescItems) {
|
||||
if (entity == null) {
|
||||
return null;
|
||||
}
|
||||
PlanDTO dto = new PlanDTO();
|
||||
BeanUtils.copyProperties(entity, dto);
|
||||
dto.setBizType(BizTypeEnum.fromCode(entity.getBizType()));
|
||||
dto.setPeriod(PlanPeriodEnum.getByCode(entity.getPeriod()));
|
||||
|
||||
List<PlanItemGroupDTO> itemGroups = new ArrayList<>();
|
||||
PlanItemGroupDTO itemGroup = new PlanItemGroupDTO();
|
||||
itemGroups.add(itemGroup);
|
||||
itemGroup.setName("基础权限");
|
||||
itemGroup.setDescription("基础权限");
|
||||
itemGroup.setGroupType(PlanItemGroupDTO.GroupType.BASE);
|
||||
itemGroup.setItems(new ArrayList<>());
|
||||
if (dto.getBizType() == BizTypeEnum.SYSTEM) {
|
||||
dto.setItemGroups(itemGroups);
|
||||
}
|
||||
try {
|
||||
if (entity.getExtra() != null) {
|
||||
dto.setExtra(JSON.parseObject(entity.getExtra()));
|
||||
}
|
||||
if (entity.getGroupIds() != null) {
|
||||
dto.setGroupIds(JSON.parseArray(entity.getGroupIds(), Long.class));
|
||||
if (CollectionUtils.isNotEmpty(dto.getGroupIds()) && showPlanDescItems) {
|
||||
MergedGroupDataPermissionDto mergedGroupDataPermission = iUserDataPermissionRpcService.getMergedGroupDataPermission(dto.getGroupIds());
|
||||
if (mergedGroupDataPermission != null) {
|
||||
itemGroup.getItems().add(new PlanItemGroupDTO.ItemDTO("工作空间", "可创建工作空间数量 " + (mergedGroupDataPermission.getMaxSpaceCount() == null || mergedGroupDataPermission.getMaxSpaceCount() < 0 ? "无限制" : mergedGroupDataPermission.getMaxSpaceCount()), "workspace", mergedGroupDataPermission.getMaxSpaceCount() != null && mergedGroupDataPermission.getMaxSpaceCount() != 0));
|
||||
itemGroup.getItems().add(new PlanItemGroupDTO.ItemDTO("智能体", "可创建智能体数量 " + (mergedGroupDataPermission.getMaxAgentCount() == null || mergedGroupDataPermission.getMaxAgentCount() < 0 ? "无限制" : mergedGroupDataPermission.getMaxAgentCount()), "agent", mergedGroupDataPermission.getMaxAgentCount() != null && mergedGroupDataPermission.getMaxAgentCount() != 0));
|
||||
itemGroup.getItems().add(new PlanItemGroupDTO.ItemDTO("网页应用", "可创建网页应用数量 " + (mergedGroupDataPermission.getMaxPageAppCount() == null || mergedGroupDataPermission.getMaxPageAppCount() < 0 ? "无限制" : mergedGroupDataPermission.getMaxPageAppCount()), "pageApp", mergedGroupDataPermission.getMaxPageAppCount() != null && mergedGroupDataPermission.getMaxPageAppCount() != 0));
|
||||
itemGroup.getItems().add(new PlanItemGroupDTO.ItemDTO("知识库", "可创建知识库数量 " + (mergedGroupDataPermission.getMaxKnowledgeCount() == null || mergedGroupDataPermission.getMaxKnowledgeCount() < 0 ? "无限制" : mergedGroupDataPermission.getMaxKnowledgeCount()), "kb", mergedGroupDataPermission.getMaxKnowledgeCount() != null && mergedGroupDataPermission.getMaxKnowledgeCount() != 0));
|
||||
itemGroup.getItems().add(new PlanItemGroupDTO.ItemDTO("知识库", "知识库存储空间上限 " + (mergedGroupDataPermission.getKnowledgeStorageLimitGb() == null || mergedGroupDataPermission.getKnowledgeStorageLimitGb().doubleValue() < 0 ? "无限制" : mergedGroupDataPermission.getKnowledgeStorageLimitGb() + " GB"), "kb", mergedGroupDataPermission.getKnowledgeStorageLimitGb() != null && mergedGroupDataPermission.getKnowledgeStorageLimitGb().doubleValue() != 0));
|
||||
itemGroup.getItems().add(new PlanItemGroupDTO.ItemDTO("数据表", "可创建数据表数量 " + (mergedGroupDataPermission.getMaxDataTableCount() == null || mergedGroupDataPermission.getMaxDataTableCount() < 0 ? "无限制" : mergedGroupDataPermission.getMaxDataTableCount()), "table", mergedGroupDataPermission.getKnowledgeStorageLimitGb() != null && mergedGroupDataPermission.getKnowledgeStorageLimitGb().doubleValue() != 0));
|
||||
itemGroup.getItems().add(new PlanItemGroupDTO.ItemDTO("定时任务", "可创建定时任务数量 " + (mergedGroupDataPermission.getMaxScheduledTaskCount() == null || mergedGroupDataPermission.getMaxScheduledTaskCount() < 0 ? "无限制" : mergedGroupDataPermission.getMaxScheduledTaskCount()), "task", mergedGroupDataPermission.getMaxScheduledTaskCount() != null && mergedGroupDataPermission.getMaxScheduledTaskCount() != 0));
|
||||
itemGroup.getItems().add(new PlanItemGroupDTO.ItemDTO("智能体电脑", "个人智能体电脑内存 " + (mergedGroupDataPermission.getAgentComputerMemoryGb() == null || mergedGroupDataPermission.getAgentComputerMemoryGb().doubleValue() < 0 ? "无限制" : mergedGroupDataPermission.getAgentComputerMemoryGb() + " GB"), "agentComputer", mergedGroupDataPermission.getAgentComputerMemoryGb() != null && mergedGroupDataPermission.getAgentComputerMemoryGb() != 0));
|
||||
|
||||
//模型权限
|
||||
List<ModelInfoDto> modelInfoList = iModelRpcService.getModelInfoList(mergedGroupDataPermission.getModelIds());
|
||||
if (CollectionUtils.isNotEmpty(modelInfoList)) {
|
||||
itemGroup = new PlanItemGroupDTO();
|
||||
itemGroups.add(itemGroup);
|
||||
itemGroup.setName("模型权限");
|
||||
itemGroup.setDescription("模型权限");
|
||||
itemGroup.setGroupType(PlanItemGroupDTO.GroupType.MODEL);
|
||||
itemGroup.setItems(modelInfoList.stream().map(modelInfo -> new PlanItemGroupDTO.ItemDTO(modelInfo.getName(), modelInfo.getDescription(), modelInfo.getIcon(), true)).collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
//智能体权限
|
||||
List<AgentInfoDto> agentInfoList = iAgentRpcService.queryAgentInfoList(mergedGroupDataPermission.getAgentIds()).getData();
|
||||
if (CollectionUtils.isNotEmpty(agentInfoList)) {
|
||||
itemGroup = new PlanItemGroupDTO();
|
||||
itemGroups.add(itemGroup);
|
||||
itemGroup.setName("智能体权限");
|
||||
itemGroup.setDescription("智能体权限");
|
||||
itemGroup.setGroupType(PlanItemGroupDTO.GroupType.AGENT);
|
||||
itemGroup.setItems(agentInfoList.stream().map(agentInfo -> new PlanItemGroupDTO.ItemDTO(agentInfo.getName(), agentInfo.getDescription(), agentInfo.getIcon(), true)).collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
//网页应用权限
|
||||
List<AgentInfoDto> pageAgentInfoList = iAgentRpcService.queryAgentInfoList(mergedGroupDataPermission.getPageAgentIds()).getData();
|
||||
if (CollectionUtils.isNotEmpty(pageAgentInfoList)) {
|
||||
itemGroup = new PlanItemGroupDTO();
|
||||
itemGroups.add(itemGroup);
|
||||
itemGroup.setName("网页应用权限");
|
||||
itemGroup.setDescription("网页应用权限");
|
||||
itemGroup.setGroupType(PlanItemGroupDTO.GroupType.APP);
|
||||
itemGroup.setItems(pageAgentInfoList.stream().map(agentInfo -> new PlanItemGroupDTO.ItemDTO(agentInfo.getName(), agentInfo.getDescription(), agentInfo.getIcon(), true)).collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
//知识库权限
|
||||
List<KnowledgeConfigVo> knowledgeInfoList = iKnowledgeConfigRpcService.listByIds(mergedGroupDataPermission.getKnowledgeIds());
|
||||
if (CollectionUtils.isNotEmpty(knowledgeInfoList)) {
|
||||
itemGroup = new PlanItemGroupDTO();
|
||||
itemGroups.add(itemGroup);
|
||||
itemGroup.setName("知识库权限");
|
||||
itemGroup.setDescription("知识库权限");
|
||||
itemGroup.setGroupType(PlanItemGroupDTO.GroupType.KB);
|
||||
itemGroup.setItems(knowledgeInfoList.stream().map(knowledgeInfo -> new PlanItemGroupDTO.ItemDTO(knowledgeInfo.getName(), knowledgeInfo.getDescription(), knowledgeInfo.getIcon(), true)).collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
//API权限
|
||||
List<MergedGroupDataPermissionDto.OpenApiConfig> openApiConfigs = mergedGroupDataPermission.getOpenApiConfigs();
|
||||
if (CollectionUtils.isNotEmpty(openApiConfigs)) {
|
||||
itemGroup = new PlanItemGroupDTO();
|
||||
itemGroups.add(itemGroup);
|
||||
itemGroup.setName("API权限");
|
||||
itemGroup.setDescription("API权限");
|
||||
itemGroup.setGroupType(PlanItemGroupDTO.GroupType.API);
|
||||
itemGroup.setOpenApiConfigs(openApiConfigs);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// ignore
|
||||
}
|
||||
return dto;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
package com.xspaceagi.subscription.app.service.impl;
|
||||
|
||||
import com.xspaceagi.subscription.app.service.UserSubscriptionAppService;
|
||||
import com.xspaceagi.subscription.infra.dao.entity.UserSubscription;
|
||||
import com.xspaceagi.subscription.infra.dao.service.IUserSubscriptionService;
|
||||
import com.xspaceagi.subscription.spec.enums.BizTypeEnum;
|
||||
import com.xspaceagi.subscription.spec.enums.SubscriptionStatusEnum;
|
||||
import com.xspaceagi.system.sdk.permission.IPermissionCacheRpcSerivce;
|
||||
import com.xspaceagi.system.sdk.service.AbstractTaskExecuteService;
|
||||
import com.xspaceagi.system.sdk.service.ScheduleTaskApiService;
|
||||
import com.xspaceagi.system.sdk.service.dto.ScheduleTaskDto;
|
||||
import com.xspaceagi.system.spec.common.RequestContext;
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
@Slf4j
|
||||
@Service("subscriptionResetTaskService")
|
||||
public class SubscriptionResetTaskServiceImpl extends AbstractTaskExecuteService {
|
||||
|
||||
@Resource
|
||||
private ScheduleTaskApiService scheduleTaskApiService;
|
||||
|
||||
@Resource
|
||||
private UserSubscriptionAppService userSubscriptionAppService;
|
||||
|
||||
@Resource
|
||||
private IUserSubscriptionService userSubscriptionService;
|
||||
|
||||
@Resource
|
||||
private IPermissionCacheRpcSerivce iPermissionCacheRpcSerivce;
|
||||
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
scheduleTaskApiService.start(ScheduleTaskDto.builder()
|
||||
.taskId("subscriptionResetTaskService")
|
||||
.beanId("subscriptionResetTaskService")
|
||||
.maxExecTimes(Long.MAX_VALUE)
|
||||
.cron(ScheduleTaskDto.Cron.EVERY_10_SECOND.getCron())
|
||||
.params(Map.of())
|
||||
.build());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean execute(ScheduleTaskDto scheduleTaskDto) {
|
||||
userSubscriptionAppService.getNeedResetSubscriptions().forEach(subscription -> {
|
||||
try {
|
||||
RequestContext.setThreadTenantId(subscription.getTenantId());
|
||||
userSubscriptionAppService.reset(subscription);
|
||||
} finally {
|
||||
RequestContext.remove();
|
||||
}
|
||||
});
|
||||
userSubscriptionAppService.getExpiredSubscriptions().forEach(subscription -> {
|
||||
try {
|
||||
RequestContext.setThreadTenantId(subscription.getTenantId());
|
||||
UserSubscription update = new UserSubscription();
|
||||
update.setId(subscription.getId());
|
||||
update.setStatus(SubscriptionStatusEnum.EXPIRED.getCode());
|
||||
userSubscriptionService.updateById(update);
|
||||
if (subscription.getBizType() == BizTypeEnum.SYSTEM) {
|
||||
iPermissionCacheRpcSerivce.clearCacheByTenantAndUserIds(subscription.getTenantId(), Collections.singletonList(subscription.getUserId()));
|
||||
log.info("用户订阅已过期,清除用户权限缓存,用户ID:{}", subscription.getUserId());
|
||||
}
|
||||
} finally {
|
||||
RequestContext.remove();
|
||||
}
|
||||
});
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,400 @@
|
||||
package com.xspaceagi.subscription.app.service.impl;
|
||||
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.xspaceagi.credit.sdk.dto.CreditAddRequest;
|
||||
import com.xspaceagi.credit.sdk.rpc.ICreditRpcService;
|
||||
import com.xspaceagi.credit.spec.enums.CreditTypeEnum;
|
||||
import com.xspaceagi.subscription.app.service.SubscriptionPlanAppService;
|
||||
import com.xspaceagi.subscription.app.service.UserSubscriptionAppService;
|
||||
import com.xspaceagi.subscription.infra.dao.entity.Plan;
|
||||
import com.xspaceagi.subscription.infra.dao.entity.UserSubscription;
|
||||
import com.xspaceagi.subscription.infra.dao.mapper.UserSubscriptionMapper;
|
||||
import com.xspaceagi.subscription.infra.dao.service.IPlanService;
|
||||
import com.xspaceagi.subscription.infra.dao.service.IUserSubscriptionService;
|
||||
import com.xspaceagi.subscription.sdk.dto.*;
|
||||
import com.xspaceagi.subscription.spec.enums.BizTypeEnum;
|
||||
import com.xspaceagi.subscription.spec.enums.PlanPeriodEnum;
|
||||
import com.xspaceagi.subscription.spec.enums.SubscriptionStatusEnum;
|
||||
import com.xspaceagi.system.sdk.permission.IPermissionCacheRpcSerivce;
|
||||
import com.xspaceagi.system.sdk.server.IUserRpcService;
|
||||
import com.xspaceagi.system.spec.common.UserContext;
|
||||
import com.xspaceagi.system.spec.exception.BizException;
|
||||
import com.xspaceagi.system.spec.tenant.thread.TenantFunctions;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
public class UserSubscriptionAppServiceImpl implements UserSubscriptionAppService {
|
||||
|
||||
@Resource
|
||||
private IUserSubscriptionService userSubscriptionService;
|
||||
|
||||
@Resource
|
||||
private UserSubscriptionMapper userSubscriptionMapper;
|
||||
|
||||
@Resource
|
||||
private SubscriptionPlanAppService subscriptionPlanAppService;
|
||||
|
||||
@Resource
|
||||
private IPlanService planService;
|
||||
|
||||
@Resource
|
||||
private ICreditRpcService iCreditRpcService;
|
||||
|
||||
@Resource
|
||||
private IUserRpcService iUserRpcService;
|
||||
|
||||
@Resource
|
||||
private IPermissionCacheRpcSerivce iPermissionCacheRpcSerivce;
|
||||
|
||||
@Override
|
||||
public List<UserSubscriptionDTO> getUserSubscriptions(SubscriptionQueryRequest query) {
|
||||
if (query.getBizType() == null) {
|
||||
query.setBizType(BizTypeEnum.SYSTEM);
|
||||
}
|
||||
List<UserSubscription> subscriptions = userSubscriptionService.lambdaQuery()
|
||||
.eq(UserSubscription::getUserId, query.getUserId())
|
||||
.eq(query.getBizType() != null, UserSubscription::getBizType, query.getBizType())
|
||||
.eq(query.getStatus() != null, UserSubscription::getStatus, SubscriptionStatusEnum.getByCode(query.getStatus()))
|
||||
.eq(query.getBizId() != null, UserSubscription::getBizId, query.getBizId())
|
||||
.list();
|
||||
|
||||
List<UserSubscriptionDTO> result = subscriptions.stream().map((UserSubscription entity) -> convertToDTO(entity, query.isShowPlanDescItems())).collect(Collectors.toCollection(ArrayList::new));
|
||||
|
||||
//是否包含可用订阅
|
||||
boolean hasActiveSubscription = result.stream().anyMatch(sub -> sub.getPlan() != null && sub.getStatus() == SubscriptionStatusEnum.ACTIVE);
|
||||
boolean shouldAddFreePlan = (BizTypeEnum.SYSTEM.equals(query.getBizType()) && !hasActiveSubscription)
|
||||
|| (!BizTypeEnum.SYSTEM.equals(query.getBizType()) && query.getBizId() != null && !hasActiveSubscription);
|
||||
if (shouldAddFreePlan) {
|
||||
PlanDTO freePlan = subscriptionPlanAppService.getFreePlan(query.getBizType(), query.getBizId(), query.isShowPlanDescItems());
|
||||
if (freePlan != null) {
|
||||
result.add(buildFreePlanDTO(freePlan));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserSubscriptionDTO getUserCurrentSubscription(Long userId, BizTypeEnum bizType, String bizId) {
|
||||
SubscriptionQueryRequest request = new SubscriptionQueryRequest();
|
||||
request.setUserId(userId);
|
||||
request.setBizType(bizType);
|
||||
request.setBizId(bizId);
|
||||
request.setStatus(SubscriptionStatusEnum.ACTIVE.getCode());
|
||||
return getUserSubscriptions(request).stream().findFirst().orElse(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserSubscriptionDTO getUserCurrentSystemSubscription(Long userId, boolean showPlanDescItems) {
|
||||
SubscriptionQueryRequest request = new SubscriptionQueryRequest();
|
||||
request.setUserId(userId);
|
||||
request.setBizType(BizTypeEnum.SYSTEM);
|
||||
request.setStatus(SubscriptionStatusEnum.ACTIVE.getCode());
|
||||
return getUserSubscriptions(request).stream().findFirst().orElse(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SubscriptionStatsDTO getSubscriptionStats(SubscriptionStatsQueryRequest request) {
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.set(Calendar.HOUR_OF_DAY, 0);
|
||||
cal.set(Calendar.MINUTE, 0);
|
||||
cal.set(Calendar.SECOND, 0);
|
||||
cal.set(Calendar.MILLISECOND, 0);
|
||||
Date todayStart = cal.getTime();
|
||||
|
||||
cal.set(Calendar.DAY_OF_MONTH, 1);
|
||||
Date monthStart = cal.getTime();
|
||||
|
||||
Map<String, Object> stats = userSubscriptionMapper.selectStatsByPlanBiz(
|
||||
request.getBizType().getCode(), request.getBizId(), todayStart, monthStart);
|
||||
|
||||
SubscriptionStatsDTO dto = new SubscriptionStatsDTO();
|
||||
dto.setTotalCount(toLong(stats.get("totalCount")));
|
||||
dto.setTodayCount(toLong(stats.get("todayCount")));
|
||||
dto.setMonthCount(toLong(stats.get("monthCount")));
|
||||
|
||||
Long total = userSubscriptionMapper.countByPlanBiz(
|
||||
request.getBizType().getCode(), request.getBizId());
|
||||
int offset = (request.getPageNum() - 1) * request.getPageSize();
|
||||
List<UserSubscription> subscribers = userSubscriptionMapper.selectByPlanBiz(
|
||||
request.getBizType().getCode(), request.getBizId(), offset, request.getPageSize());
|
||||
|
||||
dto.setSubscribers(subscribers.stream().map((UserSubscription entity) -> convertToDTO(entity, true)).collect(Collectors.toList()));
|
||||
dto.setTotal(total);
|
||||
dto.setPageNum(request.getPageNum());
|
||||
dto.setPageSize(request.getPageSize());
|
||||
|
||||
//补充用户信息
|
||||
List<Long> userIds = dto.getSubscribers().stream().map(UserSubscriptionDTO::getUserId).toList();
|
||||
List<UserContext> userContexts = iUserRpcService.queryUserListByIds(userIds);
|
||||
Map<Long, UserContext> userContextMap = userContexts.stream().collect(Collectors.toMap(UserContext::getUserId, userContext -> userContext, (a, b) -> a));
|
||||
dto.getSubscribers().forEach(subscriber -> {
|
||||
UserContext userContext = userContextMap.get(subscriber.getUserId());
|
||||
if (userContext != null) {
|
||||
String userName = StringUtils.isNotBlank(userContext.getNickName()) ? userContext.getNickName() : userContext.getUserName();
|
||||
subscriber.setSubscriber(new UserSubscriptionDTO.Subscriber(userContext.getUserId(), userName, userContext.getAvatar()));
|
||||
}
|
||||
});
|
||||
return dto;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public UserSubscriptionDTO createSubscription(CreateSubscriptionRequest request) {
|
||||
Plan plan = planService.getById(request.getPlanId());
|
||||
if (plan == null) {
|
||||
throw new BizException("PLAN_NOT_FOUND", "订阅计划不存在");
|
||||
}
|
||||
if (plan.getStatus() == null || plan.getStatus() == 0) {
|
||||
throw new BizException("PLAN_NOT_AVAILABLE", "订阅计划已下线");
|
||||
}
|
||||
|
||||
UserSubscription existingSub = userSubscriptionMapper.selectByUserIdAndPlanId(
|
||||
request.getUserId(), request.getPlanId());
|
||||
|
||||
if (existingSub == null) {
|
||||
// Check if user has a subscription to a different plan (switch plan)
|
||||
UserSubscription otherSub = userSubscriptionService.lambdaQuery()
|
||||
.eq(UserSubscription::getBizType, plan.getBizType())
|
||||
.eq(!plan.getBizType().equals(BizTypeEnum.SYSTEM.getCode()), UserSubscription::getBizId, plan.getBizId())
|
||||
.eq(UserSubscription::getUserId, request.getUserId())
|
||||
.one();
|
||||
if (otherSub == null) {
|
||||
return handleNewSubscription(request, plan);
|
||||
}
|
||||
existingSub = otherSub;
|
||||
}
|
||||
|
||||
boolean isSamePlan = existingSub.getPlanId().equals(request.getPlanId());
|
||||
existingSub.setExtra(request.getExtraJsonString());
|
||||
if (isSamePlan) {
|
||||
if (request.getExtraJsonString() != null) {
|
||||
existingSub.setPeriod(plan.getPeriod());
|
||||
userSubscriptionService.updateById(existingSub);
|
||||
}
|
||||
if (SubscriptionStatusEnum.ACTIVE.getCode().equals(existingSub.getStatus()) && existingSub.getEndTime() != null
|
||||
&& existingSub.getEndTime().getTime() > System.currentTimeMillis()) {
|
||||
return handleRenewActive(existingSub, plan);
|
||||
} else {
|
||||
return handleRenewExpired(existingSub, plan);
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
return handleChangePlan(existingSub, plan);
|
||||
} finally {
|
||||
//清除用户权限缓存
|
||||
if (plan.getBizType().equals(BizTypeEnum.SYSTEM.getCode())) {
|
||||
iPermissionCacheRpcSerivce.clearCacheByTenantAndUserIds(plan.getTenantId(), List.of(request.getUserId()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private UserSubscriptionDTO handleNewSubscription(CreateSubscriptionRequest request, Plan plan) {
|
||||
Date startTime = new Date();
|
||||
Date endTime = PlanPeriodEnum.FOREVER.getCode().equals(plan.getPeriod()) ? addMonths(startTime, 1200) : addMonths(startTime, plan.getPeriod());
|
||||
UserSubscription sub = UserSubscription.builder()
|
||||
.userId(request.getUserId())
|
||||
.tenantId(plan.getTenantId())
|
||||
.planId(plan.getId())
|
||||
.bizType(BizTypeEnum.valueOf(plan.getBizType()))
|
||||
.bizId(plan.getBizId())
|
||||
.period(plan.getPeriod())
|
||||
.startTime(startTime)
|
||||
.endTime(endTime)
|
||||
.status(SubscriptionStatusEnum.ACTIVE.getCode())
|
||||
.callUsedCount(0)
|
||||
.nextResetTime(startTime)
|
||||
.extra(request.getExtraJsonString())
|
||||
.build();
|
||||
userSubscriptionService.save(sub);
|
||||
UserSubscriptionDTO userSubscriptionDTO = convertToDTO(sub, false);
|
||||
reset(userSubscriptionDTO);//积分发放
|
||||
log.info("新建订阅, userId={}, planId={}, endTime={}", request.getUserId(), plan.getId(), endTime);
|
||||
return convertToDTO(sub, false);
|
||||
}
|
||||
|
||||
private UserSubscriptionDTO handleRenewActive(UserSubscription sub, Plan plan) {
|
||||
Date newEndTime = PlanPeriodEnum.FOREVER.getCode().equals(plan.getPeriod()) ? addMonths(sub.getEndTime(), 1200) : addMonths(sub.getEndTime(), plan.getPeriod());
|
||||
userSubscriptionMapper.updateEndTime(sub.getId(), newEndTime);
|
||||
sub.setEndTime(newEndTime);
|
||||
|
||||
log.info("续费(生效中), userId={}, planId={}, newEndTime={}", sub.getUserId(), plan.getId(), newEndTime);
|
||||
return convertToDTO(sub, false);
|
||||
}
|
||||
|
||||
private UserSubscriptionDTO handleRenewExpired(UserSubscription sub, Plan plan) {
|
||||
Date startTime = new Date();
|
||||
Date endTime = PlanPeriodEnum.FOREVER.getCode().equals(plan.getPeriod()) ? addMonths(startTime, 1200) : addMonths(startTime, plan.getPeriod());
|
||||
userSubscriptionMapper.updatePeriod(sub.getId(), startTime, endTime,
|
||||
SubscriptionStatusEnum.ACTIVE.getCode());
|
||||
sub.setStartTime(startTime);
|
||||
sub.setEndTime(endTime);
|
||||
sub.setStatus(SubscriptionStatusEnum.ACTIVE.getCode());
|
||||
|
||||
log.info("续费(已过期/已取消), userId={}, planId={}, endTime={}", sub.getUserId(), plan.getId(), endTime);
|
||||
UserSubscriptionDTO userSubscriptionDTO = convertToDTO(sub, false);
|
||||
reset(userSubscriptionDTO);//积分发放
|
||||
return userSubscriptionDTO;
|
||||
}
|
||||
|
||||
//更新计划,降级不退,升级补差价
|
||||
private UserSubscriptionDTO handleChangePlan(UserSubscription oldSub, Plan newPlan) {
|
||||
userSubscriptionMapper.deleteById(oldSub.getId());
|
||||
Date startTime = new Date();
|
||||
Date endTime = PlanPeriodEnum.FOREVER.getCode().equals(newPlan.getPeriod()) ? addMonths(startTime, 1200) : addMonths(startTime, newPlan.getPeriod());
|
||||
UserSubscription sub = UserSubscription.builder()
|
||||
.userId(oldSub.getUserId())
|
||||
.tenantId(newPlan.getTenantId())
|
||||
.planId(newPlan.getId())
|
||||
.bizType(BizTypeEnum.valueOf(newPlan.getBizType()))
|
||||
.bizId(newPlan.getBizId())
|
||||
.period(newPlan.getPeriod())
|
||||
.startTime(startTime)
|
||||
.endTime(endTime)
|
||||
.status(SubscriptionStatusEnum.ACTIVE.getCode())
|
||||
.callUsedCount(0)
|
||||
.nextResetTime(startTime) // 后台任务会执行初始化积分发放以及更新下次重置时间
|
||||
.extra(oldSub.getExtra())
|
||||
.build();
|
||||
userSubscriptionService.save(sub);
|
||||
UserSubscriptionDTO userSubscriptionDTO = convertToDTO(sub, false);
|
||||
reset(userSubscriptionDTO);// 积分发放
|
||||
return userSubscriptionDTO;
|
||||
}
|
||||
|
||||
private UserSubscriptionDTO buildFreePlanDTO(PlanDTO plan) {
|
||||
UserSubscriptionDTO dto = new UserSubscriptionDTO();
|
||||
dto.setId(0L);
|
||||
dto.setTenantId(plan.getTenantId());
|
||||
dto.setPlanId(plan.getId());
|
||||
dto.setPlanName(plan.getName());
|
||||
dto.setBizType(plan.getBizType());
|
||||
dto.setBizId(plan.getBizId());
|
||||
dto.setPeriod(plan.getPeriod());
|
||||
dto.setStartTime(new Date());
|
||||
dto.setEndTime(addMonths(dto.getStartTime(), plan.getPeriod().getCode() == 0 ? 1200 : plan.getPeriod().getCode()));
|
||||
dto.setStatus(SubscriptionStatusEnum.ACTIVE);
|
||||
dto.setPlan(plan);
|
||||
return dto;
|
||||
}
|
||||
|
||||
private Date addMonths(Date from, int months) {
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.setTime(from);
|
||||
cal.add(Calendar.MONTH, months);
|
||||
return cal.getTime();
|
||||
}
|
||||
|
||||
private Long toLong(Object val) {
|
||||
if (val == null) return 0L;
|
||||
if (val instanceof Long) return (Long) val;
|
||||
if (val instanceof Number) return ((Number) val).longValue();
|
||||
return Long.parseLong(val.toString());
|
||||
}
|
||||
|
||||
private UserSubscriptionDTO convertToDTO(UserSubscription entity, boolean showPlanDescItems) {
|
||||
UserSubscriptionDTO dto = new UserSubscriptionDTO();
|
||||
dto.setId(entity.getId());
|
||||
dto.setUserId(entity.getUserId());
|
||||
dto.setPlanId(entity.getPlanId());
|
||||
dto.setStartTime(entity.getStartTime());
|
||||
dto.setEndTime(entity.getEndTime());
|
||||
dto.setStatus(SubscriptionStatusEnum.getByCode(entity.getStatus()));
|
||||
dto.setCreated(entity.getCreated());
|
||||
dto.setModified(entity.getModified());
|
||||
if (dto.getStatus() == SubscriptionStatusEnum.ACTIVE && entity.getEndTime().getTime() < System.currentTimeMillis()) {
|
||||
dto.setStatus(SubscriptionStatusEnum.EXPIRED);
|
||||
if (entity.getId() != null) {
|
||||
UserSubscription update = new UserSubscription();
|
||||
update.setId(entity.getId());
|
||||
update.setStatus(SubscriptionStatusEnum.EXPIRED.getCode());
|
||||
userSubscriptionService.updateById(update);
|
||||
iPermissionCacheRpcSerivce.clearCacheByTenantAndUserIds(entity.getTenantId(), Collections.singletonList(entity.getUserId()));
|
||||
}
|
||||
}
|
||||
|
||||
dto.setCallUsedCount(entity.getCallUsedCount());
|
||||
dto.setNextResetTime(entity.getNextResetTime());
|
||||
PlanDTO plan = subscriptionPlanAppService.getPlanById(entity.getPlanId(), showPlanDescItems);
|
||||
dto.setPlan(plan);
|
||||
if (dto.getPlan() == null && JSON.isValidObject(entity.getExtra())) {
|
||||
JSONObject jsonObject = JSON.parseObject(entity.getExtra());
|
||||
plan = jsonObject.getObject("plan", PlanDTO.class);
|
||||
dto.setPlan(plan);
|
||||
}
|
||||
dto.setPlanName(dto.getPlan().getName());
|
||||
dto.setPeriod(PlanPeriodEnum.getByCode(entity.getPeriod()));
|
||||
dto.setBizType(entity.getBizType());
|
||||
dto.setBizId(entity.getBizId());
|
||||
dto.setTenantId(entity.getTenantId());
|
||||
return dto;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void reset(UserSubscriptionDTO subscriptionDTO) {
|
||||
if (subscriptionDTO.getEndTime() != null && subscriptionDTO.getEndTime().getTime() < System.currentTimeMillis()) {
|
||||
log.info("用户订阅已过期, userId={}, planId={}", subscriptionDTO.getUserId(), subscriptionDTO.getPlanId());
|
||||
return;
|
||||
}
|
||||
if (subscriptionDTO.getNextResetTime() != null && subscriptionDTO.getNextResetTime().getTime() > System.currentTimeMillis()) {
|
||||
log.info("用户订阅未到重置时间, userId={}, planId={}", subscriptionDTO.getUserId(), subscriptionDTO.getPlanId());
|
||||
return;
|
||||
}
|
||||
log.info("用户订阅重置, userId={}, planId={}", subscriptionDTO.getUserId(), subscriptionDTO.getPlanId());
|
||||
Date nextResetTime = addMonths(subscriptionDTO.getStartTime(), 1);
|
||||
while (nextResetTime.getTime() < System.currentTimeMillis()) {
|
||||
nextResetTime = addMonths(nextResetTime, 1);
|
||||
}
|
||||
if (subscriptionDTO.getBizType() == BizTypeEnum.SYSTEM && subscriptionDTO.getPlan() != null && subscriptionDTO.getPlan().getCreditAmount().compareTo(BigDecimal.ZERO) > 0) {
|
||||
CreditAddRequest creditAddRequest = new CreditAddRequest();
|
||||
creditAddRequest.setUserId(subscriptionDTO.getUserId());
|
||||
creditAddRequest.setAmount(subscriptionDTO.getPlan().getCreditAmount());
|
||||
creditAddRequest.setCreditType(CreditTypeEnum.SUBSCRIPTION);
|
||||
creditAddRequest.setRemark("订阅积分发放");
|
||||
creditAddRequest.setBizNo("sub" + UUID.randomUUID().toString().replace("-", ""));
|
||||
creditAddRequest.setTenantId(subscriptionDTO.getTenantId());
|
||||
iCreditRpcService.addCredit(creditAddRequest);
|
||||
}
|
||||
userSubscriptionMapper.resetCallCount(subscriptionDTO.getId(), nextResetTime);
|
||||
log.info("用户订阅重置成功, userId={}, planId={}", subscriptionDTO.getUserId(), subscriptionDTO.getPlanId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int incrementCallCount(Long subscriptionId, Integer count) {
|
||||
int actualCount = count != null ? count : 1;
|
||||
userSubscriptionMapper.incrementCallCount(subscriptionId, actualCount);
|
||||
return actualCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<UserSubscriptionDTO> getNeedResetSubscriptions() {
|
||||
List<UserSubscription> subscriptions = TenantFunctions.callWithIgnoreCheck(() -> userSubscriptionService.lambdaQuery()
|
||||
.in(UserSubscription::getBizType, BizTypeEnum.SYSTEM.getCode(), BizTypeEnum.AGENT.getCode())
|
||||
.le(UserSubscription::getNextResetTime, new Date())
|
||||
.last("limit 1000")
|
||||
.list());
|
||||
|
||||
return TenantFunctions.callWithIgnoreCheck(() -> subscriptions.stream().map((UserSubscription entity) -> convertToDTO(entity, false)).collect(Collectors.toCollection(ArrayList::new)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<UserSubscriptionDTO> getExpiredSubscriptions() {
|
||||
List<UserSubscription> subscriptions = TenantFunctions.callWithIgnoreCheck(() -> userSubscriptionService.lambdaQuery()
|
||||
.ne(UserSubscription::getStatus, SubscriptionStatusEnum.EXPIRED.getCode())
|
||||
.le(UserSubscription::getEndTime, new Date())
|
||||
.last("limit 1000")
|
||||
.list());
|
||||
return TenantFunctions.callWithIgnoreCheck(() -> subscriptions.stream().map((UserSubscription entity) -> convertToDTO(entity, false)).collect(Collectors.toCollection(ArrayList::new)));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user