generate 添加积分扣除

This commit is contained in:
2024-06-20 15:26:22 +08:00
parent e7f9b77fe5
commit 8457a61ded
6 changed files with 59 additions and 127 deletions

View File

@@ -7,20 +7,22 @@ import lombok.Getter;
@Getter
public enum CreditsEventsEnum {
// PRICE("price","6"),
PRICE("price","0.1"),
PRICE("price","6"),
// PRICE("price","0.1"),
// BUY_CREDITS("Buy Credits","600"),
BUY_CREDITS("Buy Credits","10"),
BUY_CREDITS("Buy Credits","60"),
// BUY_CREDITS("Buy Credits","10"),
INIT("init", "500"),
// 每月更新
INIT_YEARLY("init", "6000"),
INIT_MONTHLY("init", "5000"),
INIT_TRIAL("init", "100"),
DAILY_CHECKIN("Daily Check-In", "20"),
SOCIAL_MEDIA_SHARING("Social Media Sharing","20"),
// SUPER_RESOLUTION("Super Resolution","300"),
SUPER_RESOLUTION("Super Resolution","5"),
// SUPER_RESOLUTION("Super Resolution","30"),
SUPER_RESOLUTION("Super Resolution","10"),
SLOGAN("Slogan","10"),
NORMAL_GENERATE("Normal_Generate","5"),
QUESTIONNAIRE("Questionnaire","100"),
OTHER("Other","10");

View File

@@ -27,11 +27,11 @@ public class ThirdPartyController {
@Resource
private AccountService accountService;
@ApiOperation(value = "Add user information")
/*@ApiOperation(value = "Add user information")
@PostMapping("/addUser")
public Response<Boolean> addUser(@Valid @RequestBody AccountAddDTO accountAddDTO) {
return Response.success(accountService.addUser(accountAddDTO));
}
}*/
@ApiOperation(value = "Edit user information")
@PostMapping("/editUser")

View File

@@ -9,8 +9,6 @@ import com.baomidou.mybatisplus.extension.service.IService;
public interface CreditsService extends IService<CreditsDetail> {
void initCredits();
Boolean buyCredits(Long accountId, Float quantity);
void creditsIncrease(Long accountId, String event);
@@ -29,6 +27,8 @@ public interface CreditsService extends IService<CreditsDetail> {
Boolean creditsPreDeduction(CreditsEventsEnum event, Integer num);
void addRecordToCreditsDeduction(Long accountId, String taskId, CreditsEventsEnum creditsEventsEnum);
void taskCreditsDeduction(Long accountId, String taskId);
CreditsDetail getByAccountIdAndChangeEvent(Long accountId, String changeEvent, String changedCredits);

View File

@@ -1,6 +1,7 @@
package com.ai.da.service.impl;
import com.ai.da.common.config.exception.BusinessException;
import com.ai.da.common.constant.CommonConstant;
import com.ai.da.common.context.UserContext;
import com.ai.da.common.enums.CreditsEventsEnum;
import com.ai.da.common.response.PageBaseResponse;
@@ -42,11 +43,6 @@ public class CreditsServiceImpl extends ServiceImpl<CreditsDetailMapper, Credits
@Resource
private RedisUtil redisUtil;
@Override
public void initCredits() {
accountService.updateCredits(UserContext.getUserHolder().getId(), CreditsEventsEnum.INIT.getValue());
}
@Override
public Boolean buyCredits(Long accountId, Float quantity) {
BigDecimal existingCredits = accountMapper.selectById(accountId).getCredits();
@@ -61,12 +57,6 @@ public class CreditsServiceImpl extends ServiceImpl<CreditsDetailMapper, Credits
CreditsEventsEnum event = null;
switch (creditsEvent) {
case "Daily Check-In":
event = CreditsEventsEnum.DAILY_CHECKIN;
break;
case "Social Media Sharing":
event = CreditsEventsEnum.SOCIAL_MEDIA_SHARING;
break;
case "Other":
event = CreditsEventsEnum.OTHER;
break;
@@ -200,12 +190,15 @@ public class CreditsServiceImpl extends ServiceImpl<CreditsDetailMapper, Credits
*/
/** 积分预扣除 */
public Boolean creditsPreDeduction(CreditsEventsEnum event, Integer num){
Long accountId = UserContext.getUserHolder().getId();
// 1、获取当前需要预扣除的积分
// 1、获取当前在积分预扣除区,未来需要预扣除的积分总和
Set<String> keys = redisUtil.getKeysFromString(creditsDeduction + ":" + accountId + ":*");
List<String> multiValue = redisUtil.getMultiValue(keys);
// 1.1 预扣除区 积分总和
int sum = multiValue.stream().mapToInt(Integer::parseInt).sum();
// 1.2 加上本次操作需要扣除的积分
sum += Integer.parseInt(event.getValue()) * num;
// 2、获取当前积分
@@ -221,6 +214,12 @@ public class CreditsServiceImpl extends ServiceImpl<CreditsDetailMapper, Credits
return Boolean.TRUE;
}
@Override
public void addRecordToCreditsDeduction(Long accountId, String taskId, CreditsEventsEnum creditsEventsEnum){
// 5、添加当前任务的预扣积分到redis 任务有效期一天,若待扣积分两天还没被移除,说明任务已经失败,待扣积分自动失效
redisUtil.addToString(creditsDeduction + ":" + accountId + ":" + taskId, creditsEventsEnum.getValue(), CommonConstant.CREDITS_EXPIRE_TIME);
}
/** 执行扣除积分,更新数据库 */
@Override
@Transactional(rollbackFor = Exception.class)

View File

@@ -4,6 +4,7 @@ import com.ai.da.common.config.exception.BusinessException;
import com.ai.da.common.constant.CommonConstant;
import com.ai.da.common.context.UserContext;
import com.ai.da.common.enums.CollectionLevel2TypeEnum;
import com.ai.da.common.enums.CreditsEventsEnum;
import com.ai.da.common.enums.GenerateModeEnum;
import com.ai.da.common.enums.ModelNameEnum;
import com.ai.da.common.utils.*;
@@ -14,10 +15,7 @@ import com.ai.da.model.dto.GenerateThroughImageTextDTO;
import com.ai.da.model.dto.GenerateToPythonDTO;
import com.ai.da.model.vo.*;
import com.ai.da.python.PythonService;
import com.ai.da.service.CollectionElementService;
import com.ai.da.service.GenerateService;
import com.ai.da.service.LibraryService;
import com.ai.da.service.RabbitMQService;
import com.ai.da.service.*;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
@@ -45,28 +43,22 @@ public class GenerateServiceImpl extends ServiceImpl<GenerateMapper, Generate> i
@Resource
private CollectionElementMapper collectionElementMapper;
@Resource
private GenerateDetailMapper generateDetailMapper;
@Resource
private LibraryService libraryService;
@Resource
private PythonService pythonService;
@Resource
private CollectionElementService collectionElementService;
@Resource
private CreditsService creditsService;
@Resource
private MinioUtil minioUtil;
@Resource
private RabbitMQService rabbitMQService;
@Resource
private RedisUtil redisUtil;
@Resource
private GenerateCancelMapper generateCancelMapper;
@@ -196,41 +188,12 @@ public class GenerateServiceImpl extends ServiceImpl<GenerateMapper, Generate> i
GenerateResultVO generateResultVO = new GenerateResultVO(generateThroughImageTextDTO.getUniqueId(), null, null, status);
redisUtil.addToString(key, new Gson().toJson(generateResultVO), CommonConstant.GENERATE_RESULT_EXPIRE_TIME);
// 5、处理模型返回的数据
// 5.1 将相应的url保存到数据库
/*List<GenerateCollectionItemVO> generatedCollectionItems = new ArrayList<>();
generatedSketchUrl.forEach(item -> {
GenerateDetail generateDetail = new GenerateDetail();
GenerateCollectionItemVO generateCollectionItemVO = new GenerateCollectionItemVO();
String md5 = MD5Utils.encryptFile(minioUtil.getPresignedUrl(item, 24 * 60), Boolean.FALSE);
// 通过MD5值和level1Type,判断不同level1Type下相同的图片是否被like过
List<Map<String, Long>> libraryIdList = generateDetailMapper.getLibraryIdThroughMD5(md5, generateThroughImageTextDTO.getLevel1Type());
if (!libraryIdList.isEmpty()) {
generateDetail.setIsLike((byte) 1);
generateDetail.setLibraryId(libraryIdList.get(0).get("library_id"));
generateCollectionItemVO.setIsLiked(Boolean.TRUE);
}
generateDetail.setUrl(item);
generateDetail.setGenerateId(generate.getId());
generateDetail.setCreateDate(DateUtil.getByTimeZone(generateThroughImageTextDTO.getTimeZone()));
generateDetail.setMd5(md5);
generateDetailMapper.insert(generateDetail);
generateCollectionItemVO.setGenerateItemId(generateDetail.getId());
generateCollectionItemVO.setGenerateItemUrl(minioUtil.getPresignedUrl(item, 24 * 60));
generatedCollectionItems.add(generateCollectionItemVO);
});
// 6、将模型返回的图片地址返回给前端
Long collectionId = Objects.isNull(collectionElement) ? null : collectionElement.getCollectionId();
return new GenerateCollectionVO(generate.getId(), collectionId, generatedCollectionItems);*/
}
@Override
@Transactional(rollbackFor = Exception.class)
public void processGenerateResult(String taskId, String url, String category) {
// 5、处理模型返回的数据
// 5.1 将相应的url保存到数据库
// 1、处理模型返回的数据
GenerateDetail generateDetail = new GenerateDetail();
GenerateCollectionItemVO generateCollectionItemVO = new GenerateCollectionItemVO();
Generate generate;
@@ -243,7 +206,6 @@ public class GenerateServiceImpl extends ServiceImpl<GenerateMapper, Generate> i
} else {
throw new BusinessException("There are some problems with database query, please try again.");
}
}
// Generate generate = selectByUniqueId(taskId);
String md5 = MD5Utils.encryptFile(minioUtil.getPresignedUrl(url, 24 * 60), Boolean.FALSE);
@@ -258,13 +220,20 @@ public class GenerateServiceImpl extends ServiceImpl<GenerateMapper, Generate> i
generateDetail.setGenerateId(generate.getId());
generateDetail.setCreateDate(LocalDateTime.now());
generateDetail.setMd5(md5);
// 将相应的url保存到数据库
generateDetailMapper.insert(generateDetail);
String key = generateResultKey + ":" + taskId;
String imageName = url.substring(url.lastIndexOf("/") + 1);
String status = imageName.equals("white_image.jpg") ? "Invalid" : "Success";
GenerateResultVO generateResultVO = new GenerateResultVO(taskId, generateDetail.getId(), url, status, category);
// 更新redis
redisUtil.addToString(key, new Gson().toJson(generateResultVO), CommonConstant.GENERATE_RESULT_EXPIRE_TIME);
// 执行积分扣除
String accountId = taskId.substring(taskId.lastIndexOf("-") + 1);
String uuid = taskId.substring(0,taskId.substring(0, taskId.lastIndexOf("-")).lastIndexOf("-"));
creditsService.taskCreditsDeduction(Long.parseLong(accountId), uuid);
}
@Resource
@@ -506,7 +475,7 @@ public class GenerateServiceImpl extends ServiceImpl<GenerateMapper, Generate> i
return new PrepareForGenerateVO(0);
}
}
CreditsEventsEnum creditsEventsEnum = null;
int times = 4;
// 当level1Type为Print_board时level2Type为pattern时需要确定generateType
if (generateThroughImageTextDTO.getLevel1Type().equals(PRINT_BOARD.getRealName())){
@@ -524,6 +493,7 @@ public class GenerateServiceImpl extends ServiceImpl<GenerateMapper, Generate> i
validateGeneraType(generate, text, elementId);
// 校验后获取
generateThroughImageTextDTO.setGenerateType(generate.getGenerateType());
creditsEventsEnum = CreditsEventsEnum.NORMAL_GENERATE;
}
// Slogan 参数校验
if (generateThroughImageTextDTO.getLevel2Type().equals(CollectionLevel2TypeEnum.SLOGAN.getRealName())){
@@ -559,6 +529,7 @@ public class GenerateServiceImpl extends ServiceImpl<GenerateMapper, Generate> i
generateThroughImageTextDTO.setCollectionElementId(collectionElement.getId());
generateThroughImageTextDTO.setSloganBase64(null);
generateThroughImageTextDTO.setDesignType("collection");
creditsEventsEnum = CreditsEventsEnum.SLOGAN;
}
// Logo参数校验
@@ -575,10 +546,17 @@ public class GenerateServiceImpl extends ServiceImpl<GenerateMapper, Generate> i
if (seed < 0 || seed > 99999){
throw new BusinessException("the.value.range.of.seed");
}
creditsEventsEnum = CreditsEventsEnum.NORMAL_GENERATE;
}
}
// 2、生成唯一id 使用uuid,由于uuid重复的几率很小故取消对uuid重复性的校验
// 2、判断用户当前积分是否够本次生成消耗
Boolean preDeduction = creditsService.creditsPreDeduction(creditsEventsEnum, 1);
if (!preDeduction) {
throw new BusinessException("Not enough Credits");
}
// 3、生成唯一id 使用uuid,由于uuid重复的几率很小故取消对uuid重复性的校验
String uuid = UUID.randomUUID().toString();
ArrayList<String> taskIdList = new ArrayList<>();
@@ -589,7 +567,7 @@ public class GenerateServiceImpl extends ServiceImpl<GenerateMapper, Generate> i
generateThroughImageTextDTO.setUniqueId(temp);
String jsonString = JSON.toJSONString(generateThroughImageTextDTO);
// 3、加入redis排队便于获取实时排队信息
// 4、加入redis排队便于获取实时排队信息
Double maxScore = redisUtil.getMaxScore(consumptionOrderKey);
redisUtil.addToZSet(consumptionOrderKey, temp, maxScore);
@@ -598,11 +576,14 @@ public class GenerateServiceImpl extends ServiceImpl<GenerateMapper, Generate> i
GenerateResultVO generateResultVO = new GenerateResultVO(generateThroughImageTextDTO.getUniqueId(), null, null, "Waiting");
redisUtil.addToString(key, new Gson().toJson(generateResultVO), CommonConstant.GENERATE_RESULT_EXPIRE_TIME);
// 4、将消息发布到MQ消息队列
// 5、将消息发布到MQ消息队列
rabbitMQService.publishMessageToGenerate(jsonString);
}
// 5、返回唯一id
// 6、添加预扣除积分到redis
creditsService.addRecordToCreditsDeduction(generateThroughImageTextDTO.getUserId(), uuid, creditsEventsEnum);
// 7、返回唯一id
return new PrepareForGenerateVO(taskIdList, 2 - trialsCount);
}
@@ -612,57 +593,6 @@ public class GenerateServiceImpl extends ServiceImpl<GenerateMapper, Generate> i
return redisUtil.getRank(consumptionOrderKey, uniqueId);
}
/*@Override
public GenerateCollectionVO getGenerateResult(String uniqueId) {
// 1、判断该请求是否已经异常
Boolean isMember = redisUtil.isElementExistsInMap(exceptionMapKey, uniqueId);
if (isMember) {
throw new BusinessException("generate.interface.error");
}
// 2、判断该请求是否还在排队
Boolean existsInZSet = redisUtil.isElementExistsInZSet(consumptionOrderKey, uniqueId);
if (existsInZSet) {
// 排队中,给出当前排序位置,rank从0开始
Long rankPosition = getRankPosition(uniqueId);
// 有9个消费者所以当rank>8即当前请求至少排在第九位时其实际排队位置为9-8+1当rank <=8请求均在处理中
return new GenerateCollectionVO(rankPosition > 8L ? rankPosition - 8 + 1 : 1L);
}
// 3、判断redis中有没有
boolean hasHashKey = redisUtil.isElementExistsInMap(resultMapKey, uniqueId);
if (hasHashKey) {
// 3.1 有直接从redis中拿
String resultString = redisUtil.getMapValue(resultMapKey, uniqueId);
return JSONObject.parseObject(resultString, GenerateCollectionVO.class);
}
// 3.2 判断数据库中有没有
Generate generate = selectByUniqueId(uniqueId);
if (Objects.isNull(generate)) {
// 3.3 还没执行完,给出当前位置
return new GenerateCollectionVO(1L);
}
Long generateId = generate.getId();
QueryWrapper<GenerateDetail> qw = new QueryWrapper<>();
qw.eq("generate_id", generateId);
List<GenerateDetail> generateDetails = generateDetailMapper.selectList(qw);
if (CollectionUtils.isEmpty(generateDetails)) {
// 会有这种情况吗存到generate中但是还没存到generateDetail中
return new GenerateCollectionVO(1L);
}
List<GenerateCollectionItemVO> generatedCollectionItems = new ArrayList<>();
generateDetails.forEach(item -> {
GenerateCollectionItemVO generateCollectionItemVO = new GenerateCollectionItemVO();
generateCollectionItemVO.setGenerateItemId(item.getId());
generateCollectionItemVO.setGenerateItemUrl(minioUtil.getPresignedUrl(item.getUrl(), 24 * 60));
generatedCollectionItems.add(generateCollectionItemVO);
});
return new GenerateCollectionVO(generateId, null, generatedCollectionItems);
}*/
@Override
public List<GenerateResultVO> getGenerateResultList(List<String> taskIdList) {
List<GenerateResultVO> results = new ArrayList<>();

View File

@@ -109,7 +109,8 @@ public class SuperResolutionServiceImpl extends ServiceImpl<TaskListMapper, Task
baseMapper.insert(taskList);
// 5、添加当前任务的预扣积分到redis 任务有效期一天,若待扣积分两天还没被移除,说明任务已经失败,待扣积分自动失效
redisUtil.addToString(creditsDeduction + ":" + accountId + ":" + uuid, CreditsEventsEnum.SUPER_RESOLUTION.getValue(), CommonConstant.CREDITS_EXPIRE_TIME);
creditsService.addRecordToCreditsDeduction(accountId, uuid, CreditsEventsEnum.SUPER_RESOLUTION);
// redisUtil.addToString(creditsDeduction + ":" + accountId + ":" + uuid, CreditsEventsEnum.SUPER_RESOLUTION.getValue(), CommonConstant.CREDITS_EXPIRE_TIME);
// 6、加入任务列表 设置状态为 等待中
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");