TASK:订阅计划,测试修改
This commit is contained in:
@@ -289,7 +289,7 @@ public class AccountController {
|
|||||||
|
|
||||||
@PostMapping("organizationNameSearch")
|
@PostMapping("organizationNameSearch")
|
||||||
@ApiOperation(value = "组织名模糊查询")
|
@ApiOperation(value = "组织名模糊查询")
|
||||||
public Response<Set<String>> organizationNameSearch(@RequestParam("type") String type, @RequestParam("name") String name) {
|
public Response<Set<String>> organizationNameSearch(@RequestParam("type") String type, @RequestParam(value = "name", required = false) String name) {
|
||||||
return Response.success(accountService.organizationNameSearch(type, name));
|
return Response.success(accountService.organizationNameSearch(type, name));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -58,5 +58,19 @@ public class SubscriptionPlanController {
|
|||||||
return Response.success();
|
return Response.success();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ApiOperation("activeSubscriptionPlan")
|
||||||
|
@GetMapping("/activeSubscriptionPlan")
|
||||||
|
public Response<String> activeSubscriptionPlan() {
|
||||||
|
subscriptionPlanService.activeSubscriptionPlan();
|
||||||
|
return Response.success();
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation("expireSubscription")
|
||||||
|
@GetMapping("/expireSubscription")
|
||||||
|
public Response<String> expireSubscription() {
|
||||||
|
subscriptionPlanService.expireSubscription();
|
||||||
|
return Response.success();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,4 +19,8 @@ public interface SubscriptionPlanService extends IService<SubscriptionPlan> {
|
|||||||
void deletePlan(Long id);
|
void deletePlan(Long id);
|
||||||
|
|
||||||
void switchSubscriptionPlan(Long subscriptionPlanId, Long adminAccId);
|
void switchSubscriptionPlan(Long subscriptionPlanId, Long adminAccId);
|
||||||
|
|
||||||
|
void activeSubscriptionPlan();
|
||||||
|
|
||||||
|
void expireSubscription();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3593,7 +3593,7 @@ public class AccountServiceImpl extends ServiceImpl<AccountMapper, Account> impl
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<String> organizationNameSearch(String type, String name) {
|
public Set<String> organizationNameSearch(String type, String name) {
|
||||||
QueryWrapper<Account> qw = new QueryWrapper<>();
|
/*QueryWrapper<Account> qw = new QueryWrapper<>();
|
||||||
qw.lambda().ne(Account::getOrganizationName, "").isNotNull(Account::getOrganizationName);
|
qw.lambda().ne(Account::getOrganizationName, "").isNotNull(Account::getOrganizationName);
|
||||||
if (!StringUtil.isNullOrEmpty(name)) {
|
if (!StringUtil.isNullOrEmpty(name)) {
|
||||||
qw.lambda().like(Account::getOrganizationName, name);
|
qw.lambda().like(Account::getOrganizationName, name);
|
||||||
@@ -3615,6 +3615,20 @@ public class AccountServiceImpl extends ServiceImpl<AccountMapper, Account> impl
|
|||||||
if (CollectionUtil.isNotEmpty(accountList)) {
|
if (CollectionUtil.isNotEmpty(accountList)) {
|
||||||
return accountList.stream().map(Account::getOrganizationName).collect(Collectors.toSet());
|
return accountList.stream().map(Account::getOrganizationName).collect(Collectors.toSet());
|
||||||
}
|
}
|
||||||
|
return new HashSet<>();*/
|
||||||
|
|
||||||
|
QueryWrapper<Organization> queryWrapper = new QueryWrapper<>();
|
||||||
|
if (StringUtils.isNotBlank(type)){
|
||||||
|
type = type.equals("Enterprise") ? "Enterprise" : "Education";
|
||||||
|
queryWrapper.lambda().eq(Organization::getType, type);
|
||||||
|
}
|
||||||
|
if (StringUtils.isNotBlank(name)) {
|
||||||
|
queryWrapper.lambda().like(Organization::getName, name);
|
||||||
|
}
|
||||||
|
List<Organization> organizations = organizationMapper.selectList(queryWrapper);
|
||||||
|
if (CollectionUtil.isNotEmpty(organizations)) {
|
||||||
|
return organizations.stream().map(Organization::getName).collect(Collectors.toSet());
|
||||||
|
}
|
||||||
return new HashSet<>();
|
return new HashSet<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1101,9 +1101,9 @@ public class StripeServiceImpl implements StripeService {
|
|||||||
setSubscriptionParams(paymentInfo, subscriptionInfo, orderByOrderNo, emailParamsDTO, language);
|
setSubscriptionParams(paymentInfo, subscriptionInfo, orderByOrderNo, emailParamsDTO, language);
|
||||||
|
|
||||||
log.info("SEND EMAIL: type={}, params={}, language={}, receiver={}", type, JSONObject.toJSON(emailParamsDTO), language, account.getUserEmail());
|
log.info("SEND EMAIL: type={}, params={}, language={}, receiver={}", type, JSONObject.toJSON(emailParamsDTO), language, account.getUserEmail());
|
||||||
// boolean b = SendEmailUtil.subscriptionEmailReminder(type, emailParamsDTO, language, account.getUserEmail());
|
boolean b = SendEmailUtil.subscriptionEmailReminder(type, emailParamsDTO, language, account.getUserEmail());
|
||||||
// boolean b = emailService.subscriptionEmailReminder(type, emailParamsDTO, language, account.getUserEmail());
|
// boolean b = emailService.subscriptionEmailReminder(type, emailParamsDTO, language, account.getUserEmail());
|
||||||
// if (!b) return false;
|
if (!b) return false;
|
||||||
|
|
||||||
// 邮件通知成功后,更新标志
|
// 邮件通知成功后,更新标志
|
||||||
if (!type.startsWith("reminder") && !type.equals("cancel")){
|
if (!type.startsWith("reminder") && !type.equals("cancel")){
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package com.ai.da.service.impl;
|
|||||||
|
|
||||||
import com.ai.da.common.config.exception.BusinessException;
|
import com.ai.da.common.config.exception.BusinessException;
|
||||||
import com.ai.da.common.context.UserContext;
|
import com.ai.da.common.context.UserContext;
|
||||||
|
import com.ai.da.common.response.ResultEnum;
|
||||||
import com.ai.da.common.utils.CopyUtil;
|
import com.ai.da.common.utils.CopyUtil;
|
||||||
import com.ai.da.common.utils.RedisUtil;
|
import com.ai.da.common.utils.RedisUtil;
|
||||||
import com.ai.da.mapper.primary.AccountMapper;
|
import com.ai.da.mapper.primary.AccountMapper;
|
||||||
@@ -51,7 +52,7 @@ public class SubscriptionPlanServiceImpl extends ServiceImpl<SubscriptionPlanMap
|
|||||||
|
|
||||||
// 创建
|
// 创建
|
||||||
@Override
|
@Override
|
||||||
public void createPlan(SubscriptionPlanDTO subscriptionPlanDTO){
|
public void createPlan(SubscriptionPlanDTO subscriptionPlanDTO) {
|
||||||
SubscriptionPlan subscriptionPlan = CopyUtil.copyObject(subscriptionPlanDTO, SubscriptionPlan.class);
|
SubscriptionPlan subscriptionPlan = CopyUtil.copyObject(subscriptionPlanDTO, SubscriptionPlan.class);
|
||||||
subscriptionPlan.setStatus(SubscriptionPlan.SubscriptionStatus.PENDING.name());
|
subscriptionPlan.setStatus(SubscriptionPlan.SubscriptionStatus.PENDING.name());
|
||||||
subscriptionPlan.setName("DEFAULT_NAME");
|
subscriptionPlan.setName("DEFAULT_NAME");
|
||||||
@@ -66,7 +67,7 @@ public class SubscriptionPlanServiceImpl extends ServiceImpl<SubscriptionPlanMap
|
|||||||
|
|
||||||
// 更新 到期时间、积分总量、已使用积分量
|
// 更新 到期时间、积分总量、已使用积分量
|
||||||
@Override
|
@Override
|
||||||
public void updatePlan(UpdateSubscriptionPlanDTO updateDTO){
|
public void updatePlan(UpdateSubscriptionPlanDTO updateDTO) {
|
||||||
if (Objects.isNull(updateDTO.getId())) {
|
if (Objects.isNull(updateDTO.getId())) {
|
||||||
throw new BusinessException("id.cannot.be.empty");
|
throw new BusinessException("id.cannot.be.empty");
|
||||||
}
|
}
|
||||||
@@ -101,7 +102,7 @@ public class SubscriptionPlanServiceImpl extends ServiceImpl<SubscriptionPlanMap
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updatePlan(){
|
public void updatePlan() {
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -120,7 +121,7 @@ public class SubscriptionPlanServiceImpl extends ServiceImpl<SubscriptionPlanMap
|
|||||||
IPage<SubscriptionPlan> resultPage = baseMapper.selectPage(page, queryWrapper);
|
IPage<SubscriptionPlan> resultPage = baseMapper.selectPage(page, queryWrapper);
|
||||||
|
|
||||||
// 4. 转换为VO并返回
|
// 4. 转换为VO并返回
|
||||||
return resultPage.convert((Function<SubscriptionPlan, SubscriptionPlanVO>) plan -> CopyUtil.copyObject(plan, SubscriptionPlanVO.class)) ;
|
return resultPage.convert((Function<SubscriptionPlan, SubscriptionPlanVO>) plan -> CopyUtil.copyObject(plan, SubscriptionPlanVO.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -129,10 +130,10 @@ public class SubscriptionPlanServiceImpl extends ServiceImpl<SubscriptionPlanMap
|
|||||||
private void validatePageQuery(SubscriptionPlanPageQuery query) {
|
private void validatePageQuery(SubscriptionPlanPageQuery query) {
|
||||||
// 基本分页参数校验(JSR-303已校验,这里做额外业务校验)
|
// 基本分页参数校验(JSR-303已校验,这里做额外业务校验)
|
||||||
if (query.getPage() <= 0) {
|
if (query.getPage() <= 0) {
|
||||||
throw new BusinessException("页码必须大于0");
|
throw new BusinessException("page.num.limit");
|
||||||
}
|
}
|
||||||
if (query.getSize() <= 0 || query.getSize() > 100) {
|
if (query.getSize() <= 0 || query.getSize() > 100) {
|
||||||
throw new BusinessException("每页数量必须在1-100之间");
|
throw new BusinessException("page.size.limit");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 时间格式校验
|
// 时间格式校验
|
||||||
@@ -142,10 +143,10 @@ public class SubscriptionPlanServiceImpl extends ServiceImpl<SubscriptionPlanMap
|
|||||||
LocalDateTime end = parseDateTime(query.getEndTime());
|
LocalDateTime end = parseDateTime(query.getEndTime());
|
||||||
assert start != null;
|
assert start != null;
|
||||||
if (start.isAfter(end)) {
|
if (start.isAfter(end)) {
|
||||||
throw new BusinessException("开始时间不能晚于结束时间");
|
throw new BusinessException("the.start.time.cannot.be.later.than.the.end.time");
|
||||||
}
|
}
|
||||||
} catch (DateTimeParseException e) {
|
} catch (DateTimeParseException e) {
|
||||||
throw new BusinessException("时间格式错误,请使用yyyy-MM-dd HH:mm:ss格式");
|
throw new BusinessException("invalid.time.format");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -154,7 +155,8 @@ public class SubscriptionPlanServiceImpl extends ServiceImpl<SubscriptionPlanMap
|
|||||||
try {
|
try {
|
||||||
SubscriptionPlan.SubscriptionStatus.valueOf(status.toUpperCase());
|
SubscriptionPlan.SubscriptionStatus.valueOf(status.toUpperCase());
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
throw new BusinessException("未知订阅状态:" + status);
|
log.error("未知订阅状态:{}", status);
|
||||||
|
throw new BusinessException("unknown.subscription.status");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -229,18 +231,18 @@ public class SubscriptionPlanServiceImpl extends ServiceImpl<SubscriptionPlanMap
|
|||||||
Long adminAccountId = UserContext.getUserHolder().getId();
|
Long adminAccountId = UserContext.getUserHolder().getId();
|
||||||
// 1. 参数基础校验
|
// 1. 参数基础校验
|
||||||
if (id == null || id <= 0) {
|
if (id == null || id <= 0) {
|
||||||
throw new BusinessException("ID不能为空且必须大于0");
|
throw new BusinessException("ID.cannot.be.empty.and.must.be.greater.than.0");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. 检查数据是否存在
|
// 2. 检查数据是否存在
|
||||||
SubscriptionPlan plan = baseMapper.selectById(id);
|
SubscriptionPlan plan = baseMapper.selectById(id);
|
||||||
if (plan == null) {
|
if (plan == null) {
|
||||||
throw new BusinessException("订阅计划不存在");
|
throw new BusinessException("subscription.plan.does.not.exist");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. 检查是否已被删除(防止重复删除) 一般情况下走不到,逻辑删除的数据通过mybatis-plus查不到
|
// 3. 检查是否已被删除(防止重复删除) 一般情况下走不到,逻辑删除的数据通过mybatis-plus查不到
|
||||||
if (plan.getIsDeleted() == 1) {
|
if (plan.getIsDeleted() == 1) {
|
||||||
throw new BusinessException("该订阅计划已被删除");
|
throw new BusinessException("subscription.plan.has.been.deleted");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4. 检查业务约束条件(例如:是否有正在使用的订单等)
|
// 4. 检查业务约束条件(例如:是否有正在使用的订单等)
|
||||||
@@ -254,7 +256,7 @@ public class SubscriptionPlanServiceImpl extends ServiceImpl<SubscriptionPlanMap
|
|||||||
|
|
||||||
int rows = baseMapper.update(null, wrapper);
|
int rows = baseMapper.update(null, wrapper);
|
||||||
if (rows == 0) {
|
if (rows == 0) {
|
||||||
throw new BusinessException("删除失败,请稍后重试");
|
throw new BusinessException("deletion.failed.please.try.again.later");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 6. 记录操作日志
|
// 6. 记录操作日志
|
||||||
@@ -269,12 +271,12 @@ public class SubscriptionPlanServiceImpl extends ServiceImpl<SubscriptionPlanMap
|
|||||||
// 检查是否有活跃的用户关联
|
// 检查是否有活跃的用户关联
|
||||||
Long activeSubAcc = countActiveSubAccByPlanId(plan.getId());
|
Long activeSubAcc = countActiveSubAccByPlanId(plan.getId());
|
||||||
if (activeSubAcc > 0) {
|
if (activeSubAcc > 0) {
|
||||||
throw new BusinessException("存在" + activeSubAcc + "个用户使用此计划,无法删除");
|
throw new BusinessException("users.currently.using.this.plan");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查是否在有效期内
|
// 检查是否在有效期内
|
||||||
if (plan.getCurrentPeriodEnd() != null && isExpired(plan.getCurrentPeriodEnd())) {
|
if (plan.getCurrentPeriodEnd() != null && isExpired(plan.getCurrentPeriodEnd())) {
|
||||||
throw new BusinessException("计划仍在有效期内,请到期后再删除");
|
throw new BusinessException("valid.subscription.period");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -321,6 +323,10 @@ public class SubscriptionPlanServiceImpl extends ServiceImpl<SubscriptionPlanMap
|
|||||||
for (SubscriptionPlan plan : todayActivePlans) {
|
for (SubscriptionPlan plan : todayActivePlans) {
|
||||||
try {
|
try {
|
||||||
processActiveSubscriptionPlan(plan);
|
processActiveSubscriptionPlan(plan);
|
||||||
|
// 3. 修改订阅状态
|
||||||
|
plan.setStatus(SubscriptionPlan.SubscriptionStatus.ACTIVE.name());
|
||||||
|
plan.setUpdateTime(LocalDateTime.now());
|
||||||
|
baseMapper.updateById(plan);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("处理订阅计划失败,ID: {}, 错误: {}", plan.getId(), e.getMessage(), e);
|
log.error("处理订阅计划失败,ID: {}, 错误: {}", plan.getId(), e.getMessage(), e);
|
||||||
// 继续处理其他计划,不中断整体流程
|
// 继续处理其他计划,不中断整体流程
|
||||||
@@ -366,14 +372,12 @@ public class SubscriptionPlanServiceImpl extends ServiceImpl<SubscriptionPlanMap
|
|||||||
// 3. 检查管理员当前是否处于其他有效订阅中
|
// 3. 检查管理员当前是否处于其他有效订阅中
|
||||||
if (isAccountInActiveSubscription(adminAccount, plan.getId())) {
|
if (isAccountInActiveSubscription(adminAccount, plan.getId())) {
|
||||||
log.info("管理员ID: {} 已处于有效订阅中,本次不修改账户信息", adminAccount.getId());
|
log.info("管理员ID: {} 已处于有效订阅中,本次不修改账户信息", adminAccount.getId());
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4. 更新管理员账号信息
|
// 4. 更新管理员账号信息
|
||||||
updateAdminAccount(adminAccount, plan);
|
updateAdminAccount(adminAccount, plan);
|
||||||
|
|
||||||
// 5. 修改订阅状态
|
|
||||||
plan.setStatus(SubscriptionPlan.SubscriptionStatus.ACTIVE.name());
|
|
||||||
|
|
||||||
log.info("订阅计划处理完成,ID: {}", plan.getId());
|
log.info("订阅计划处理完成,ID: {}", plan.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -385,14 +389,19 @@ public class SubscriptionPlanServiceImpl extends ServiceImpl<SubscriptionPlanMap
|
|||||||
updateAccount.setId(account.getId());
|
updateAccount.setId(account.getId());
|
||||||
|
|
||||||
// ① 根据订阅结束时间延长管理员账号有效期validEndTime
|
// ① 根据订阅结束时间延长管理员账号有效期validEndTime
|
||||||
Long newValidEndTime = calculateNewValidEndTime(account, plan);
|
// Long newValidEndTime = calculateNewValidEndTime(account, plan);
|
||||||
updateAccount.setValidEndTime(newValidEndTime);
|
updateAccount.setValidEndTime(plan.getCurrentPeriodEnd() * 1000);
|
||||||
|
|
||||||
// ② 根据积分上限更新管理员的积分credits和身份systemUser
|
// ② 根据积分上限更新管理员的积分credits和身份systemUser
|
||||||
// 暂时保留管理员自己购买的积分
|
// 暂时保留管理员自己购买的积分
|
||||||
if (Objects.nonNull(account.getCreditsUsageLimit())) {
|
if ((account.getSystemUser() == 5 || account.getSystemUser() == 7)
|
||||||
|
&& Objects.nonNull(account.getCreditsUsageLimit())) {
|
||||||
BigDecimal leftCredits = account.getCredits().add(account.getCreditsUsage()).subtract(account.getCreditsUsageLimit());
|
BigDecimal leftCredits = account.getCredits().add(account.getCreditsUsage()).subtract(account.getCreditsUsageLimit());
|
||||||
updateAccount.setCredits(plan.getCreditLimit().add(leftCredits));
|
if (leftCredits.compareTo(BigDecimal.ZERO) > 0) {
|
||||||
|
updateAccount.setCredits(plan.getCreditLimit().add(leftCredits));
|
||||||
|
} else {
|
||||||
|
updateAccount.setCredits(plan.getCreditLimit());
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
updateAccount.setCredits(plan.getCreditLimit().add(account.getCredits()));
|
updateAccount.setCredits(plan.getCreditLimit().add(account.getCredits()));
|
||||||
}
|
}
|
||||||
@@ -422,7 +431,7 @@ public class SubscriptionPlanServiceImpl extends ServiceImpl<SubscriptionPlanMap
|
|||||||
if (rows > 0) {
|
if (rows > 0) {
|
||||||
log.info("管理员账号更新成功,ID: {}, 有效期至: {}, 用户类型: {}, 积分: {}",
|
log.info("管理员账号更新成功,ID: {}, 有效期至: {}, 用户类型: {}, 积分: {}",
|
||||||
account.getId(),
|
account.getId(),
|
||||||
formatTimestamp(newValidEndTime),
|
formatTimestamp(plan.getCurrentPeriodEnd()),
|
||||||
newSystemUser,
|
newSystemUser,
|
||||||
plan.getCreditLimit());
|
plan.getCreditLimit());
|
||||||
|
|
||||||
@@ -461,7 +470,8 @@ public class SubscriptionPlanServiceImpl extends ServiceImpl<SubscriptionPlanMap
|
|||||||
Organization organization = organizationMapper.selectById(orgId);
|
Organization organization = organizationMapper.selectById(orgId);
|
||||||
|
|
||||||
if (Objects.isNull(organization)) {
|
if (Objects.isNull(organization)) {
|
||||||
throw new BusinessException("未知组织id: " + orgId);
|
log.error("未知组织id: {}", orgId);
|
||||||
|
throw new BusinessException("unknown.organization");
|
||||||
}
|
}
|
||||||
if (organization.getType().equals("Enterprise")) {
|
if (organization.getType().equals("Enterprise")) {
|
||||||
return 5; // 学校管理员
|
return 5; // 学校管理员
|
||||||
@@ -525,9 +535,20 @@ public class SubscriptionPlanServiceImpl extends ServiceImpl<SubscriptionPlanMap
|
|||||||
public void expireSubscription() {
|
public void expireSubscription() {
|
||||||
// 1. 查询有哪些已过期订阅
|
// 1. 查询有哪些已过期订阅
|
||||||
List<SubscriptionPlan> recentlyExpiredPlans = findRecentlyExpiredPlans();
|
List<SubscriptionPlan> recentlyExpiredPlans = findRecentlyExpiredPlans();
|
||||||
|
if (CollectionUtils.isEmpty(recentlyExpiredPlans)) {
|
||||||
|
log.info("过去24h没有过期的订阅计划");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info("发现{}个过去24h过期的订阅计划", recentlyExpiredPlans.size());
|
||||||
|
|
||||||
// 2. 更新与订阅相关账号的状态
|
// 2. 更新与订阅相关账号的状态
|
||||||
for (SubscriptionPlan subscriptionPlan : recentlyExpiredPlans) {
|
for (SubscriptionPlan subscriptionPlan : recentlyExpiredPlans) {
|
||||||
processExpiringSubscriptionPlan(subscriptionPlan);
|
processExpiringSubscriptionPlan(subscriptionPlan);
|
||||||
|
// 6. 修改订阅状态
|
||||||
|
subscriptionPlan.setStatus(SubscriptionPlan.SubscriptionStatus.EXPIRED.name());
|
||||||
|
subscriptionPlan.setUpdateTime(LocalDateTime.now());
|
||||||
|
baseMapper.updateById(subscriptionPlan);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -538,6 +559,8 @@ public class SubscriptionPlanServiceImpl extends ServiceImpl<SubscriptionPlanMap
|
|||||||
long now = System.currentTimeMillis() / 1000;
|
long now = System.currentTimeMillis() / 1000;
|
||||||
long yesterday = now - (24 * 60 * 60); // 24小时前
|
long yesterday = now - (24 * 60 * 60); // 24小时前
|
||||||
|
|
||||||
|
log.debug("扫描时间范围: {} - {} (过去24h)", formatTimestamp(yesterday), formatTimestamp(now));
|
||||||
|
|
||||||
QueryWrapper<SubscriptionPlan> queryWrapper = new QueryWrapper<>();
|
QueryWrapper<SubscriptionPlan> queryWrapper = new QueryWrapper<>();
|
||||||
queryWrapper.eq("is_deleted", 0)
|
queryWrapper.eq("is_deleted", 0)
|
||||||
.between("current_period_end", yesterday, now) // 过去24小时内到期
|
.between("current_period_end", yesterday, now) // 过去24小时内到期
|
||||||
@@ -577,9 +600,6 @@ public class SubscriptionPlanServiceImpl extends ServiceImpl<SubscriptionPlanMap
|
|||||||
// 5. 管理员当前未使用这个订阅,只处理订阅关系状态
|
// 5. 管理员当前未使用这个订阅,只处理订阅关系状态
|
||||||
log.info("订阅{}已过期,但管理员{}未激活此订阅", plan.getId(), adminAccount.getId());
|
log.info("订阅{}已过期,但管理员{}未激活此订阅", plan.getId(), adminAccount.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
// 6. 修改订阅状态
|
|
||||||
plan.setStatus(SubscriptionPlan.SubscriptionStatus.EXPIRED.name());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -595,11 +615,6 @@ public class SubscriptionPlanServiceImpl extends ServiceImpl<SubscriptionPlanMap
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
long now = System.currentTimeMillis() / 1000;
|
|
||||||
if (plan.getCurrentPeriodStart() > now || plan.getCurrentPeriodEnd() < now) {
|
|
||||||
return null; // 不在有效期内
|
|
||||||
}
|
|
||||||
|
|
||||||
return plan;
|
return plan;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -623,6 +638,11 @@ public class SubscriptionPlanServiceImpl extends ServiceImpl<SubscriptionPlanMap
|
|||||||
// 3. 切换到开始最早的订阅
|
// 3. 切换到开始最早的订阅
|
||||||
updateAdminAccount(adminAccount, earliestActivePlan);
|
updateAdminAccount(adminAccount, earliestActivePlan);
|
||||||
|
|
||||||
|
// 4. 修改订阅状态
|
||||||
|
earliestActivePlan.setStatus(SubscriptionPlan.SubscriptionStatus.ACTIVE.name());
|
||||||
|
earliestActivePlan.setUpdateTime(LocalDateTime.now());
|
||||||
|
baseMapper.updateById(earliestActivePlan);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// 5. 没有其他活跃订阅,将管理员降级为游客
|
// 5. 没有其他活跃订阅,将管理员降级为游客
|
||||||
log.info("管理员{}没有其他活跃订阅,降级为游客", adminAccount.getId());
|
log.info("管理员{}没有其他活跃订阅,降级为游客", adminAccount.getId());
|
||||||
@@ -692,6 +712,9 @@ public class SubscriptionPlanServiceImpl extends ServiceImpl<SubscriptionPlanMap
|
|||||||
if (Objects.isNull(subscriptionPlan)) {
|
if (Objects.isNull(subscriptionPlan)) {
|
||||||
throw new BusinessException("unknown.subscription.plan");
|
throw new BusinessException("unknown.subscription.plan");
|
||||||
}
|
}
|
||||||
|
if (subscriptionPlan.getStatus().equals(SubscriptionPlan.SubscriptionStatus.EXPIRED.name())) {
|
||||||
|
throw new BusinessException("subscription.has.expired");
|
||||||
|
}
|
||||||
if (!accountId.equals(subscriptionPlan.getAdminAccId()) && !accountId.equals(87L)) {
|
if (!accountId.equals(subscriptionPlan.getAdminAccId()) && !accountId.equals(87L)) {
|
||||||
throw new BusinessException("have.no.permission");
|
throw new BusinessException("have.no.permission");
|
||||||
}
|
}
|
||||||
@@ -702,7 +725,15 @@ public class SubscriptionPlanServiceImpl extends ServiceImpl<SubscriptionPlanMap
|
|||||||
}
|
}
|
||||||
Account account = accountMapper.selectById(adminAccId);
|
Account account = accountMapper.selectById(adminAccId);
|
||||||
if (Objects.isNull(account)) {
|
if (Objects.isNull(account)) {
|
||||||
throw new BusinessException("切换失败,未知管理员用户");
|
throw new BusinessException("unknown.administrator.user");
|
||||||
|
}
|
||||||
|
if (!adminAccId.equals(subscriptionPlan.getAdminAccId())) {
|
||||||
|
log.info("用户:{} 没有权限管理订阅:{}", adminAccId, subscriptionPlanId);
|
||||||
|
throw new BusinessException("no.permission.manage.subscription", ResultEnum.PROMPT.getCode());
|
||||||
|
}
|
||||||
|
if (account.getSubscriptionPlanId().equals(subscriptionPlanId)) {
|
||||||
|
log.info("用户:{} 当前正在管理订阅 {}", adminAccId, subscriptionPlanId);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
updateAdminAccount(account, subscriptionPlan);
|
updateAdminAccount(account, subscriptionPlan);
|
||||||
|
|||||||
@@ -26,7 +26,8 @@
|
|||||||
<update id="toVisitor">
|
<update id="toVisitor">
|
||||||
update t_account
|
update t_account
|
||||||
set is_trial = 0, credits = 0, system_user = 0,
|
set is_trial = 0, credits = 0, system_user = 0,
|
||||||
organization_name = null, credits_usage = null, credits_usage_limit = null, sub_account_num = null
|
organization_name = null, organization_id = null, credits_usage = null, credits_usage_limit = null, sub_account_num = null,
|
||||||
|
parent_id = null, subscription_plan_id = null
|
||||||
where id = #{id}
|
where id = #{id}
|
||||||
</update>
|
</update>
|
||||||
|
|
||||||
|
|||||||
@@ -190,6 +190,21 @@ unknow.affiliate=Unknown affiliate id.
|
|||||||
unknown.operationType=Unknown operationType.
|
unknown.operationType=Unknown operationType.
|
||||||
unknown.mode=unknown mode
|
unknown.mode=unknown mode
|
||||||
unknown.subscription.plan=unknown subscription plan
|
unknown.subscription.plan=unknown subscription plan
|
||||||
|
unknown.subscription.status=Unknown subscription status.
|
||||||
|
subscription.has.expired=Switch failed. The subscription has expired.
|
||||||
|
unknown.administrator.user=Switch failed. Unknown administrator user.
|
||||||
|
no.permission.manage.subscription=Switch failed. You do not have permission to manage this subscription.
|
||||||
|
unknown.organization=Unknown organization.
|
||||||
|
valid.subscription.period=The plan is still within its valid period. Please delete it after it expires.
|
||||||
|
users.currently.using.this.plan=There are users currently using this plan, so it cannot be deleted.
|
||||||
|
deletion.failed.please.try.again.later=Deletion failed. Please try again later.
|
||||||
|
subscription.plan.has.been.deleted=This subscription plan has been deleted.
|
||||||
|
subscription.plan.does.not.exist=The subscription plan does not exist.
|
||||||
|
ID.cannot.be.empty.and.must.be.greater.than.0=ID cannot be empty and must be greater than 0.
|
||||||
|
invalid.time.format=Invalid time format. Please use the yyyy-MM-dd HH:mm:ss format.
|
||||||
|
the.start.time.cannot.be.later.than.the.end.time=The start time cannot be later than the end time.
|
||||||
|
page.size.limit=The number of items per page must be between 1 and 100.
|
||||||
|
page.num.limit=The page number must be greater than 0.
|
||||||
|
|
||||||
# 可能会报异常
|
# 可能会报异常
|
||||||
# Informative:
|
# Informative:
|
||||||
|
|||||||
@@ -186,6 +186,21 @@ unknow.affiliate=未知推广者id
|
|||||||
unknown.operationType=未知操作类型
|
unknown.operationType=未知操作类型
|
||||||
unknown.mode=未知模式
|
unknown.mode=未知模式
|
||||||
unknown.subscription.plan=未知订阅计划
|
unknown.subscription.plan=未知订阅计划
|
||||||
|
unknown.subscription.status=未知订阅状态
|
||||||
|
subscription.has.expired=切换失败,订阅已过期
|
||||||
|
unknown.administrator.user=切换失败,未知管理员用户
|
||||||
|
no.permission.manage.subscription=切换失败,您没有权限管理该订阅
|
||||||
|
unknown.organization=未知组织
|
||||||
|
valid.subscription.period=计划仍在有效期内,请到期后再删除
|
||||||
|
users.currently.using.this.plan=存在用户正在使用此计划,无法删除
|
||||||
|
deletion.failed.please.try.again.later=删除失败,请稍后重试
|
||||||
|
subscription.plan.has.been.deleted=该订阅计划已被删除
|
||||||
|
subscription.plan.does.not.exist=订阅计划不存在
|
||||||
|
ID.cannot.be.empty.and.must.be.greater.than.0=ID不能为空且必须大于0
|
||||||
|
invalid.time.format=时间格式错误,请使用yyyy-MM-dd HH:mm:ss格式
|
||||||
|
the.start.time.cannot.be.later.than.the.end.time=开始时间不能晚于结束时间
|
||||||
|
page.size.limit=每页数量必须在1-100之间
|
||||||
|
page.num.limit=页码必须大于0
|
||||||
|
|
||||||
# 可能会报异常
|
# 可能会报异常
|
||||||
# Informative:
|
# Informative:
|
||||||
|
|||||||
@@ -27,20 +27,20 @@ paypal.webhook_id=1D107312EX592781K
|
|||||||
##### Stripe
|
##### Stripe
|
||||||
|
|
||||||
# developer
|
# developer
|
||||||
stripe.private-key=sk_test_51P4ZZL02n1TEydyN8qQHjOA9imsFU7Oxs2HMHGy2urHnnQgSHnZuu5vVP6pKhEACwUpsKNyrbZpdcg5TJWJLRHcY008dEO1fn2
|
#stripe.private-key=sk_test_51P4ZZL02n1TEydyN8qQHjOA9imsFU7Oxs2HMHGy2urHnnQgSHnZuu5vVP6pKhEACwUpsKNyrbZpdcg5TJWJLRHcY008dEO1fn2
|
||||||
# dev 端点
|
# dev 端点
|
||||||
stripe.webhook-sign-secret=whsec_e0dBiJngx6qqgJj6yPyJ2A9ouh1Cjv5w
|
#stripe.webhook-sign-secret=whsec_e0dBiJngx6qqgJj6yPyJ2A9ouh1Cjv5w
|
||||||
# local 端点
|
# local 端点
|
||||||
#stripe.webhook-sign-secret=whsec_TJcMSnAkh4uktrNY1M6Iy8XaVze4Rzqm
|
#stripe.webhook-sign-secret=whsec_TJcMSnAkh4uktrNY1M6Iy8XaVze4Rzqm
|
||||||
|
|
||||||
# kim - test
|
# kim - test
|
||||||
#stripe.private-key=sk_test_51LwPrxH7nPZ8bkrNj67TFD7sxucaTANs1lf0KGSu1QSJfxYXcnigq2wTaZyZzST7y0fMbhhvaJZ4LjjFhr95M83a00eXrmOTL0
|
stripe.private-key=sk_test_51LwPrxH7nPZ8bkrNj67TFD7sxucaTANs1lf0KGSu1QSJfxYXcnigq2wTaZyZzST7y0fMbhhvaJZ4LjjFhr95M83a00eXrmOTL0
|
||||||
# prod 端点
|
# prod 端点
|
||||||
#stripe.webhook-sign-secret=whsec_GoyVEAaBtuGD5Rt55z83JnPnLDAZTN3u
|
#stripe.webhook-sign-secret=whsec_GoyVEAaBtuGD5Rt55z83JnPnLDAZTN3u
|
||||||
# local 端点
|
# local 端点
|
||||||
#stripe.webhook-sign-secret=whsec_NvwM3hDQiN5GXclYOYekE9IKHLjmROF8
|
#stripe.webhook-sign-secret=whsec_NvwM3hDQiN5GXclYOYekE9IKHLjmROF8
|
||||||
# dev 端点
|
# dev 端点
|
||||||
#stripe.webhook-sign-secret=whsec_pX0pPMQm85PaUSWnFMEzoccb3MGNkjoL
|
stripe.webhook-sign-secret=whsec_pX0pPMQm85PaUSWnFMEzoccb3MGNkjoL
|
||||||
|
|
||||||
# kim - live
|
# kim - live
|
||||||
#stripe.private-key=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
|
#stripe.private-key=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
|
||||||
|
|||||||
Reference in New Issue
Block a user