TASK:默认积分分配改为平均分配;超级管理员可新增教育、企业管理员账户;组织成员使用积分时需要记录creditsUsage;试用用户初始50积分

This commit is contained in:
2025-08-26 23:53:40 +08:00
parent 6e9213ec5a
commit 18c38b020e
9 changed files with 121 additions and 97 deletions

View File

@@ -182,21 +182,21 @@ public class AccountController {
* 填写调查问卷
* @return
*/
@ApiOperation(value = "填写调查问卷")
/* @ApiOperation(value = "填写调查问卷")
@PostMapping("/questionnaire")
public Response<Boolean> questionnaire(@Valid @RequestBody String questionnaireInfo){
return Response.success(accountService.collectQuestionnaires(questionnaireInfo));
}
}*/
/**
* 参与活动 获取福利
* @return
*/
@ApiOperation(value = "参与活动 获取福利")
/* @ApiOperation(value = "参与活动 获取福利")
@GetMapping("/activity")
public Response<String> getActivityBenefits(){
return Response.success(accountService.getActivityBenefits());
}
}*/
@ApiOperation(value = "将用户账号过期时间设置为过期当天的235959")
@GetMapping("/setUserValidToDayEnd")

View File

@@ -37,4 +37,18 @@ public class AccountAddDTO {
private Integer systemUser;
private String organizationName;
private Integer subAccountNum;
public AccountAddDTO(String userEmail, String userName, String country, String validStartTime, String validEndTime, Integer isTrial, BigDecimal credits, Integer systemUser) {
this.userEmail = userEmail;
this.userName = userName;
this.country = country;
this.validStartTime = validStartTime;
this.validEndTime = validEndTime;
this.isTrial = isTrial;
this.credits = credits;
this.systemUser = systemUser;
}
}

View File

@@ -16,6 +16,7 @@ import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -140,8 +141,7 @@ public interface AccountService extends IService<Account> {
void moveLibraryDate();
void updateCreditsAndEndTime(Long accountId, String value);
void updateCreditsAndEndTime(Long accountId, String value, Long endTime);
void updateCreditsAndEndTime(Long accountId, String value, Long endTime, BigDecimal creditsUsage);
Boolean designWorksRegister(AccountDesignWorksRegisterDTO accountDesignWorksRegisterDTO);

View File

@@ -13,10 +13,6 @@ public interface CreditsService extends IService<CreditsDetail> {
Boolean buyCredits(Long accountId, Float quantity);
void creditsIncrease(Long accountId, String event);
void creditsDecrease(Long accountId, String event);
String getCredits(Long accountId);
void creditsRefund(Long accountId, Integer quantity, String orderNo);

View File

@@ -59,6 +59,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.security.GeneralSecurityException;
@@ -1145,20 +1146,21 @@ public class AccountServiceImpl extends ServiceImpl<AccountMapper, Account> impl
// 未迁移过的进行迁移,注意模特数据迁移打点信息以及转换模特格式
}
public void updateCreditsAndEndTime(Long accountId, String value) {
public void updateCreditsAndEndTime(Long accountId, String value, Long endTime, BigDecimal creditsUsage) {
Account account = new Account();
account.setId(accountId);
account.setCredits(new BigDecimal(value));
accountMapper.updateById(account);
}
// todo 将其与上一个合并
public void updateCreditsAndEndTime(Long accountId, String value, Long endTime) {
Account account = new Account();
account.setId(accountId);
account.setCredits(new BigDecimal(value));
if (!Objects.isNull(endTime)){
if (Objects.nonNull(endTime)){
account.setValidEndTime(toDayEnd(endTime));
}
if (Objects.nonNull(creditsUsage)){
// 机构的积分使用量不会超过上限
if (creditsUsage.compareTo(account.getCreditsUsageLimit()) > 0){
account.setCreditsUsage(account.getCreditsUsageLimit());
} else {
account.setCreditsUsage(creditsUsage);
}
}
account.setUpdateDate(new Date());
accountMapper.updateById(account);
}
@@ -1206,7 +1208,7 @@ public class AccountServiceImpl extends ServiceImpl<AccountMapper, Account> impl
}
account.setSystemUser(3);
account.setIsTrial(1);
account.setCredits(BigDecimal.valueOf(100));
account.setCredits(BigDecimal.valueOf(50));
account.setValidEndTime(toDayEnd(Instant.now().plus(5, ChronoUnit.DAYS).toEpochMilli()));
account.setIsBeginner(1);
account.setValidStartTime(Instant.now().toEpochMilli());
@@ -1253,15 +1255,15 @@ public class AccountServiceImpl extends ServiceImpl<AccountMapper, Account> impl
static {
HikariConfig config = new HikariConfig();
config.setJdbcUrl("jdbc:mysql://code-create.com.hk:3306/db1nfvsgmjp3b8");
config.setUsername("uafqtz4gsvfrw");
config.setPassword("aida123456.");
// config.setJdbcUrl("jdbc:mysql://code-create.com.hk:3306/db1nfvsgmjp3b8");
// config.setUsername("uafqtz4gsvfrw");
// config.setPassword("aida123456.");
// config.setJdbcUrl("jdbc:mysql://18.167.251.121:33008/aida");
// config.setUsername("aida_con");
// config.setPassword("123456");
// config.setJdbcUrl("jdbc:mysql://localhost:3306/code-create-local?serverTimezone=UTC");
// config.setUsername("root");
// config.setPassword("root");
config.setJdbcUrl("jdbc:mysql://localhost:3306/code-create-local?serverTimezone=UTC");
config.setUsername("root");
config.setPassword("root");
config.addDataSourceProperty("cachePrepStmts", "true");
config.addDataSourceProperty("prepStmtCacheSize", "250");
config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");
@@ -1329,11 +1331,11 @@ public class AccountServiceImpl extends ServiceImpl<AccountMapper, Account> impl
// 不管是不是新用户 都要更新用户角色和积分
String credits = "0";
if (totalSales == 5000.0){
log.info("年付用户,初始积分6000");
credits = CreditsEventsEnum.INIT_MONTHLY.getValue();
log.info("年付用户,初始积分50000");
credits = CreditsEventsEnum.INIT_YEARLY.getValue();
systemUserType = 1;
}else if (totalSales == 500.0){
log.info("月付用户初始积分5000");
log.info("月付用户,初始积分3500");
credits = CreditsEventsEnum.INIT_MONTHLY.getValue();
systemUserType = 2;
}else if (totalSales == 0.0){
@@ -1591,7 +1593,7 @@ public class AccountServiceImpl extends ServiceImpl<AccountMapper, Account> impl
// 3.3、更新 t_account 表
if (account.getValidEndTime() != null && account.getValidEndTime() < 1720972799000L){
updateCreditsAndEndTime(account.getId(), added.toString(), 1720972799000L);
updateCreditsAndEndTime(account.getId(), added.toString(), 1720972799000L, null);
}
}
@@ -1658,16 +1660,20 @@ public class AccountServiceImpl extends ServiceImpl<AccountMapper, Account> impl
// 获取该管理员的所有子账号
List<Account> subAccounts = getSubAccountsByAdmin(adminAccount);
if (CollectionUtils.isEmpty(subAccounts)) {
if (CollectionUtils.isEmpty(subAccounts)
|| Objects.isNull(adminAccount.getSubAccountNum())
|| adminAccount.getSubAccountNum() == 0) {
log.debug("管理员 {} 没有子账号", adminAccount.getId());
continue;
}
BigDecimal averageCredits = adminAccount.getCreditsUsageLimit().divide(new BigDecimal(adminAccount.getSubAccountNum()), RoundingMode.FLOOR);
// 批量更新子账号积分
int processedCount = batchUpdateSubAccountsCredits(subAccounts);
int processedCount = batchUpdateSubAccountsCredits(subAccounts, averageCredits);
totalProcessed += processedCount;
adminAccount.setCreditsUsage(new BigDecimal(3500).multiply(new BigDecimal(processedCount)));
adminAccount.setCreditsUsage(averageCredits.multiply(new BigDecimal(processedCount)));
adminAccount.setCredits(adminAccount.getCreditsUsageLimit().subtract(adminAccount.getCreditsUsage()));
adminAccount.setUpdateDate(new Date());
updateById(adminAccount);
@@ -1696,13 +1702,13 @@ public class AccountServiceImpl extends ServiceImpl<AccountMapper, Account> impl
/**
* 批量更新子账号积分
*/
private int batchUpdateSubAccountsCredits(List<Account> subAccounts) {
private int batchUpdateSubAccountsCredits(List<Account> subAccounts, BigDecimal averageCredits) {
List<Account> accountsToUpdate = new ArrayList<>();
Date now = new Date();
for (Account subAcc : subAccounts) {
try {
Account updatedAccount = calculateNewCredits(subAcc, now);
Account updatedAccount = calculateNewCredits(subAcc, now, averageCredits);
accountsToUpdate.add(updatedAccount);
} catch (Exception e) {
@@ -1720,8 +1726,9 @@ public class AccountServiceImpl extends ServiceImpl<AccountMapper, Account> impl
/**
* 计算新的积分值
* 默认积分为学校总积分数 / 学校可使用子账号数
*/
private Account calculateNewCredits(Account subAcc, Date updateTime) {
private Account calculateNewCredits(Account subAcc, Date updateTime, BigDecimal averageCredits) {
BigDecimal creditsUsageLimit = subAcc.getCreditsUsageLimit();
// 使用 Optional 替代 ObjectUtils.defaultIfNull
BigDecimal creditsUsage = Optional.ofNullable(subAcc.getCreditsUsage()).orElse(BigDecimal.ZERO);
@@ -1739,8 +1746,8 @@ public class AccountServiceImpl extends ServiceImpl<AccountMapper, Account> impl
// 确保个人积分不为负数
personalCredits = personalCredits.max(BigDecimal.ZERO);
// 新的总积分 = 个人积分 + 学校分配的新积分额度 todo 重新分配的积分是使用上个月分配的积分还是默认积分,暂时使用默认积分 3500
BigDecimal newTotalCredits = personalCredits.add(new BigDecimal(3500));
// 新的总积分 = 个人积分 + 学校分配的新积分额度 重新分配的积分是使用上个月分配的积分还是默认积分,暂时使用平均积分)
BigDecimal newTotalCredits = personalCredits.add(averageCredits);
// 记录积分变更日志(可选)
logCreditChange(subAcc, currentCredits, newTotalCredits, creditsUsage);
@@ -1750,7 +1757,7 @@ public class AccountServiceImpl extends ServiceImpl<AccountMapper, Account> impl
updatedAccount.setId(subAcc.getId());
updatedAccount.setCredits(newTotalCredits);
updatedAccount.setCreditsUsage(BigDecimal.ZERO); // 重置已使用积分
updatedAccount.setCreditsUsageLimit(new BigDecimal(3500)); // 重置为默认积分
updatedAccount.setCreditsUsageLimit(averageCredits); // 重置为默认积分
updatedAccount.setUpdateDate(updateTime);
return updatedAccount;
@@ -2117,7 +2124,7 @@ public class AccountServiceImpl extends ServiceImpl<AccountMapper, Account> impl
newUser.setCreateDate(new Date());
newUser.setIsTrial(1);
newUser.setIsBeginner(1);
newUser.setCredits(BigDecimal.valueOf(100));
newUser.setCredits(BigDecimal.valueOf(50));
newUser.setSystemUser(3);
accountMapper.insert(newUser);
session.setAttribute("user", newUser);
@@ -2424,6 +2431,7 @@ public class AccountServiceImpl extends ServiceImpl<AccountMapper, Account> impl
adminAcc.setCreditsUsage(adminAcc.getCreditsUsage().add(subAccount.getCreditsUsageLimit()));
adminAcc.setCredits(adminAcc.getCreditsUsageLimit().subtract(adminAcc.getCreditsUsage()));
adminAcc.setUpdateDate(new Date());
log.debug("分配积分: remainingCredits={}, subAccId={}, setCredits={}", remainingCredits, subAccount.getId(), addSubAccountDTO.getCreditsUsageLimit());
}else {
handleSubAccCredits(subAccount, adminAcc);
}
@@ -2457,6 +2465,7 @@ public class AccountServiceImpl extends ServiceImpl<AccountMapper, Account> impl
adminAcc.setCreditsUsage(adminAcc.getCreditsUsage().add(subAccount.getCreditsUsageLimit()));
adminAcc.setCredits(adminAcc.getCreditsUsageLimit().subtract(adminAcc.getCreditsUsage()));
adminAcc.setUpdateDate(new Date());
log.debug("分配积分: remainingCredits={}, subAccId={}, setCredits={}", remainingCredits, subAccount.getId(), addSubAccountDTO.getCreditsUsageLimit());
}
// 未指定积分使用上限
else {
@@ -2584,8 +2593,8 @@ public class AccountServiceImpl extends ServiceImpl<AccountMapper, Account> impl
}
if (Objects.nonNull(adminAcc.getCreditsUsageLimit()) && (Objects.isNull(subAcc.getCreditsUsageLimit()) || subAcc.getCreditsUsageLimit().compareTo(BigDecimal.ZERO) == 0)) {
// todo 需要先判断管理员的订阅类型 年付 -> 4200 月付 -> 3500
BigDecimal defaultCredits = BigDecimal.valueOf(3500L);
// 默认使用平均积分
BigDecimal defaultCredits = adminAcc.getCreditsUsageLimit().divide(new BigDecimal(adminAcc.getSubAccountNum()), RoundingMode.FLOOR);;
if (remainingCredits.compareTo(defaultCredits) >= 0) {
subAcc.setCreditsUsageLimit(defaultCredits);
@@ -2597,7 +2606,7 @@ public class AccountServiceImpl extends ServiceImpl<AccountMapper, Account> impl
adminAcc.setCreditsUsage(adminAcc.getCreditsUsage().add(subAcc.getCreditsUsageLimit()));
adminAcc.setCredits(adminAcc.getCreditsUsageLimit().subtract(adminAcc.getCreditsUsage()));
adminAcc.setUpdateDate(new Date());
log.debug("分配积分: subAccId={}, defaultCredits={}, remainingCredits={}", subAcc.getId(), defaultCredits, remainingCredits);
log.debug("分配积分: remainingCredits={}, subAccId={}, defaultCredits={}", remainingCredits, subAcc.getId(), defaultCredits);
if (Objects.nonNull(subAcc.getCredits())) {
subAcc.setCredits(subAcc.getCreditsUsageLimit().add(subAcc.getCredits()));
@@ -2782,7 +2791,7 @@ public class AccountServiceImpl extends ServiceImpl<AccountMapper, Account> impl
newUser.setCreateDate(new Date());
newUser.setIsTrial(1);
newUser.setIsBeginner(1);
newUser.setCredits(BigDecimal.valueOf(100));
newUser.setCredits(BigDecimal.valueOf(50));
newUser.setSystemUser(3);
accountMapper.insert(newUser);
@@ -2886,7 +2895,7 @@ public class AccountServiceImpl extends ServiceImpl<AccountMapper, Account> impl
newUser.setCreateDate(new Date());
newUser.setIsTrial(1);
newUser.setIsBeginner(1);
newUser.setCredits(BigDecimal.valueOf(100));
newUser.setCredits(BigDecimal.valueOf(50));
newUser.setSystemUser(3);
accountMapper.insert(newUser);
@@ -3417,6 +3426,7 @@ public class AccountServiceImpl extends ServiceImpl<AccountMapper, Account> impl
}
@Override
@Transactional
public Boolean subAccountImport(MultipartFile file) {
AuthPrincipalVo vo = UserContext.getUserHolder();
Account parent = accountMapper.selectById(vo.getId());
@@ -3443,14 +3453,13 @@ public class AccountServiceImpl extends ServiceImpl<AccountMapper, Account> impl
AddSubAccountDTO addSubAccountDTO = new AddSubAccountDTO();
addSubAccountDTO.setUserEmail(dto.getEmail());
if (Objects.nonNull(dto.getCredisUsageLimit())) {
addSubAccountDTO.setCreditsUsageLimit(BigDecimal.valueOf(dto.getCredisUsageLimit()));
}
addSubAccountDTO.setUserName(dto.getEmail().substring(0, dto.getEmail().indexOf("@")));
addSubAccountDTO.setUserPassword(md5(parent.getOrganizationName().toLowerCase() + "abc"));
// 添加用户
try {
addSubAccount(addSubAccountDTO);
} catch (BusinessException e){
log.warn("批量导入业务报错, {}", e.getMsg());
}
addSubAccount(addSubAccountDTO);
}
return true;

View File

@@ -479,6 +479,15 @@ public class ConvenientInquiryServiceImpl extends ServiceImpl<QuestionnaireMappe
// 新增用户
@Transactional(rollbackFor = Exception.class)
public Boolean addUser(AccountAddDTO accountAddDTO) {
if (Objects.isNull(accountAddDTO.getSystemUser())){
throw new BusinessException("Please choose an user type.");
}
// 如果是学校或者企业身份,组织名不能为空
if (Arrays.asList(5,6,7,8).contains(accountAddDTO.getSystemUser())
&& StringUtil.isNullOrEmpty(accountAddDTO.getOrganizationName())){
throw new BusinessException("The organization name cannot be empty.");
}
// 需要给的数据 用户邮箱、用户名、账号有效期截止时间、账号类型
Account account = CopyUtil.copyObject(accountAddDTO, Account.class);
QueryWrapper<Account> queryWrapper = new QueryWrapper<>();
@@ -489,8 +498,7 @@ public class ConvenientInquiryServiceImpl extends ServiceImpl<QuestionnaireMappe
throw new BusinessException("The email address already exists. One email address can only register one AiDA account");
}
// 添加正式用户
assert accountAddDTO != null;
// 添加正式用户或企业/教育版的管理员
if (Objects.isNull(accountAddDTO.getSystemUser())) {
throw new BusinessException("you have to choose user type");
} else {
@@ -511,8 +519,30 @@ public class ConvenientInquiryServiceImpl extends ServiceImpl<QuestionnaireMappe
account.setCredits(new BigDecimal(CreditsEventsEnum.INIT_TRIAL.getValue()));
account.setIsTrial(1);
break;
case 5:
account.setCreditsUsageLimit(BigDecimal.ZERO);
account.setCredits(BigDecimal.ZERO);
account.setSystemUser(5);
account.setSubAccountNum(0);
break;
case 7:
account.setCreditsUsageLimit(BigDecimal.ZERO);
account.setCredits(BigDecimal.ZERO);
account.setSystemUser(7);
account.setSubAccountNum(0);
break;
}
}
if (Objects.nonNull(accountAddDTO.getCredits())){
account.setCredits(accountAddDTO.getCredits());
}
if (Objects.nonNull(accountAddDTO.getSubAccountNum())){
account.setSubAccountNum(accountAddDTO.getSubAccountNum());
}
if (!StringUtil.isNullOrEmpty(accountAddDTO.getOrganizationName())){
account.setOrganizationName(accountAddDTO.getOrganizationName());
}
account.setValidStartTime(Long.parseLong(accountAddDTO.getValidStartTime()));
account.setValidEndTime(Long.parseLong(accountAddDTO.getValidEndTime()));
account.setUserPassword("Third-000000");
@@ -566,6 +596,8 @@ public class ConvenientInquiryServiceImpl extends ServiceImpl<QuestionnaireMappe
account.setCredits(new BigDecimal(credits));
log.info("管理员:{},修改用户 {} 信息,将账号积分置为:{}", username, accountId, credits);
}
// todo 如果修改管理员账号的积分上限或子账号数量,则其所有子账号的积分上限需要重新计算
account.setId(accountId);
account.setUpdateDate(new Date());
return accountMapper.updateById(account) == 1;

View File

@@ -50,49 +50,10 @@ public class CreditsServiceImpl extends ServiceImpl<CreditsDetailMapper, Credits
BigDecimal existingCredits = accountMapper.selectById(accountId).getCredits();
BigDecimal newCredits = new BigDecimal(CreditsEventsEnum.BUY_CREDITS.getValue()).multiply(new BigDecimal(quantity));
BigDecimal added = existingCredits.add(newCredits);
accountService.updateCreditsAndEndTime(accountId, added.toString(), null);
accountService.updateCreditsAndEndTime(accountId, added.toString(), null, null);
return Boolean.TRUE;
}
@Override
public void creditsIncrease(Long accountId, String creditsEvent) {
CreditsEventsEnum event = null;
switch (creditsEvent) {
case "Other":
event = CreditsEventsEnum.OTHER;
break;
case "Super Resolution":
event = CreditsEventsEnum.SUPER_RESOLUTION;
break;
default:
throw new BusinessException("UNKNOWN TYPE");
}
BigDecimal existingCredits = accountMapper.selectById(accountId).getCredits();
BigDecimal add = new BigDecimal(event.getValue()).add(existingCredits);
accountService.updateCreditsAndEndTime(accountId, add.toString(), null);
}
@Override
public void creditsDecrease(Long accountId, String creditsEvent) {
CreditsEventsEnum event;
switch (creditsEvent) {
case "Super Resolution":
event = CreditsEventsEnum.SUPER_RESOLUTION;
break;
case "Other":
event = CreditsEventsEnum.OTHER;
break;
default:
log.error("UNKNOWN TYPE");
throw new BusinessException("UNKNOWN TYPE");
}
BigDecimal existingCredits = accountMapper.selectById(accountId).getCredits();
BigDecimal subtract = existingCredits.subtract(new BigDecimal(event.getValue()));
accountService.updateCreditsAndEndTime(accountId, subtract.toString(), null);
}
@Override
public String getCredits(Long accountId) {
Account account = accountMapper.selectById(accountId);
@@ -104,7 +65,7 @@ public class CreditsServiceImpl extends ServiceImpl<CreditsDetailMapper, Credits
BigDecimal newCredits = new BigDecimal(CreditsEventsEnum.BUY_CREDITS.getValue()).multiply(new BigDecimal(quantity));
BigDecimal subtracted = existingCredits.subtract(newCredits);
// 更新t_account表
accountService.updateCreditsAndEndTime(accountId, subtracted.toString(), null);
accountService.updateCreditsAndEndTime(accountId, subtracted.toString(), null, null);
// 更新t_credits_details表
// 添加积分变更记录
insertToCreditsDetail(accountId,
@@ -294,9 +255,15 @@ public class CreditsServiceImpl extends ServiceImpl<CreditsDetailMapper, Credits
}
// 2、操作数据库扣除积分
BigDecimal existingCredits = accountMapper.selectById(accountId).getCredits();
Account account = accountMapper.selectById(accountId);
BigDecimal existingCredits = account.getCredits();
BigDecimal subtract = existingCredits.subtract(new BigDecimal(value));
accountService.updateCreditsAndEndTime(accountId, subtract.toString(), null);
BigDecimal creditsUsage = null;
if (!StringUtil.isNullOrEmpty(account.getOrganizationName())){
creditsUsage = Objects.isNull(account.getCreditsUsage()) ? BigDecimal.ZERO : account.getCreditsUsage();
creditsUsage = creditsUsage.add(new BigDecimal(value));
}
accountService.updateCreditsAndEndTime(accountId, subtract.toString(), null, creditsUsage);
// 3、从redis中移除当前待扣积分
redisUtil.removeFromString(key);

View File

@@ -1237,9 +1237,15 @@ public class GenerateServiceImpl extends ServiceImpl<GenerateMapper, Generate> i
}
public void doCreditsSubtract(Long accountId, CreditsEventsEnum event) {
BigDecimal existingCredits = accountService.getById(accountId).getCredits();
Account account = accountService.getById(accountId);
BigDecimal existingCredits = account.getCredits();
BigDecimal subtract = existingCredits.subtract(new BigDecimal(event.getValue()));
accountService.updateCreditsAndEndTime(accountId, subtract.toString(), null);
BigDecimal creditsUsage = null;
if (!StringUtil.isNullOrEmpty(account.getOrganizationName())){
creditsUsage = Objects.isNull(account.getCreditsUsage()) ? BigDecimal.ZERO : account.getCreditsUsage();
creditsUsage = creditsUsage.add(new BigDecimal(event.getValue()));
}
accountService.updateCreditsAndEndTime(accountId, subtract.toString(), null, creditsUsage);
creditsService.preInsert(accountId, event.getName(), null, Boolean.FALSE, event.getValue());
}