TASK: 对话 扣除积分

This commit is contained in:
2025-06-30 12:03:23 +08:00
parent dcd63668bd
commit de5da5b299
6 changed files with 91 additions and 11 deletions

View File

@@ -57,6 +57,8 @@ public enum CreditsEventsEnum {
LOCAL_TEXT2IMG_HIGH("Local_text2img_high","5"), LOCAL_TEXT2IMG_HIGH("Local_text2img_high","5"),
LOCAL_IMG2IMG_HIGH("Local_img2img_high","5"), LOCAL_IMG2IMG_HIGH("Local_img2img_high","5"),
LOCAL_ANIMATION("Local_Animation","15"), LOCAL_ANIMATION("Local_Animation","15"),
LLM_CONVERSATION("LLM_Conversation", "0")
; ;
private final String name; private final String name;

View File

@@ -39,6 +39,22 @@ public class ChatMessage implements Serializable {
@ApiModelProperty("0对话内容1颜色2图片") @ApiModelProperty("0对话内容1颜色2图片")
private Integer isImage; private Integer isImage;
/**
* 输入
*/
private Long inputTokens;
/**
* 输出
*/
private Long outputTokens;
/**
* 思考
*/
private Long reasoningTokens;
/**
* 本次输出消耗的总金额
*/
private String totalCost;
@ApiModelProperty("创建时间") @ApiModelProperty("创建时间")
private LocalDateTime createTime; private LocalDateTime createTime;

View File

@@ -9,10 +9,10 @@ import java.io.Serializable;
@Data @Data
@TableName("workspace_rel_style") @TableName("workspace_rel_style")
public class WorkspaceRelStyle implements Serializable { public class WorkspaceRelStyle extends BaseEntity implements Serializable {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@TableId(value = "id", type = IdType.AUTO) // @TableId(value = "id", type = IdType.AUTO)
private Long id; // private Long id;
private Long workspaceId; private Long workspaceId;
private Long styleId; private Long styleId;
} }

View File

@@ -7,6 +7,8 @@ import com.ai.da.mapper.primary.entity.CreditsDetail;
import com.ai.da.model.dto.QueryIncomeOrExpenditureDTO; import com.ai.da.model.dto.QueryIncomeOrExpenditureDTO;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
import java.math.BigDecimal;
public interface CreditsService extends IService<CreditsDetail> { public interface CreditsService extends IService<CreditsDetail> {
Boolean buyCredits(Long accountId, Float quantity); Boolean buyCredits(Long accountId, Float quantity);
@@ -40,4 +42,6 @@ public interface CreditsService extends IService<CreditsDetail> {
void updateChangedCredits(String accountId, String taskId); void updateChangedCredits(String accountId, String taskId);
CreditsDetail queryDetailByTaskId(String taskId); CreditsDetail queryDetailByTaskId(String taskId);
void tokenUsage(Long accountId, BigDecimal totalTokenUsage);
} }

View File

@@ -26,12 +26,10 @@ import org.springframework.util.CollectionUtils;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.util.List; import java.util.*;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
@Service @Service
@Slf4j @Slf4j
@@ -368,4 +366,23 @@ public class CreditsServiceImpl extends ServiceImpl<CreditsDetailMapper, Credits
return baseMapper.selectOne(queryWrapper); return baseMapper.selectOne(queryWrapper);
} }
public void tokenUsage(Long accountId, BigDecimal totalTokenUsage){
Account account = accountService.getById(accountId);
BigDecimal changeCredits = totalTokenUsage.setScale(0, RoundingMode.CEILING);
BigDecimal subtracted = account.getCredits().subtract(changeCredits);
account.setCredits(subtracted);
account.setUpdateDate(new Date());
accountService.updateById(account);
CreditsDetail creditsDetail = new CreditsDetail();
creditsDetail.setAccountId(accountId);
creditsDetail.setChangeEvent(CreditsEventsEnum.LLM_CONVERSATION.getName());
creditsDetail.setChangedCredits("-" + changeCredits);
creditsDetail.setCredits(subtracted);
creditsDetail.setCreateTime(LocalDateTime.now());
baseMapper.insert(creditsDetail);
log.info("对话扣除积分,原始积分消耗量:{} 取整:{} 剩余积分:{}", totalTokenUsage, changeCredits, subtracted);
}
} }

View File

@@ -18,10 +18,7 @@ import com.ai.da.model.enums.*;
import com.ai.da.model.vo.AuthPrincipalVo; import com.ai.da.model.vo.AuthPrincipalVo;
import com.ai.da.model.vo.UserLikeGroupVO; import com.ai.da.model.vo.UserLikeGroupVO;
import com.ai.da.python.PythonService; import com.ai.da.python.PythonService;
import com.ai.da.service.DesignService; import com.ai.da.service.*;
import com.ai.da.service.LLMService;
import com.ai.da.service.SysFileService;
import com.ai.da.service.WorkspaceService;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
@@ -42,6 +39,8 @@ import javax.annotation.Resource;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.io.OutputStream; import java.io.OutputStream;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.HttpURLConnection; import java.net.HttpURLConnection;
import java.net.URL; import java.net.URL;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
@@ -81,6 +80,8 @@ public class LLMServiceImpl implements LLMService {
private CollectionElementRelModelMapper collectionElementRelModelMapper; private CollectionElementRelModelMapper collectionElementRelModelMapper;
@Value("${minio.bucketName.sysImage}") @Value("${minio.bucketName.sysImage}")
private String sysImage; private String sysImage;
@Resource
private CreditsService creditsService;
@Override @Override
public SseEmitter stream(String prompt, Long projectParamId, String fileUrl, List<String> imageUrlList, String token, Boolean enableThinking, String process) { public SseEmitter stream(String prompt, Long projectParamId, String fileUrl, List<String> imageUrlList, String token, Boolean enableThinking, String process) {
@@ -295,6 +296,14 @@ public class LLMServiceImpl implements LLMService {
systemMessage.setAccountId(accountId); systemMessage.setAccountId(accountId);
StringBuilder responseContentBuilder = new StringBuilder(); StringBuilder responseContentBuilder = new StringBuilder();
String contentType = ""; String contentType = "";
BigDecimal totalTokenUsage = BigDecimal.ZERO;
// 需要存input_token output_token reasoning_tokens total_cost
Long inputToken = 0L;
Long outputToken = 0L;
Long reasoningToken = 0L;
String totalCost = "0";
boolean tokenUsageFlag = false;
try (BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8))) { try (BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8))) {
String line; String line;
while ((line = reader.readLine()) != null) { while ((line = reader.readLine()) != null) {
@@ -334,6 +343,13 @@ public class LLMServiceImpl implements LLMService {
systemMessage.setSeq(getNextSeq(projectId)); systemMessage.setSeq(getNextSeq(projectId));
systemMessage.setCreateTime(LocalDateTime.now()); systemMessage.setCreateTime(LocalDateTime.now());
systemMessage.setContent(responseContentBuilder.toString()); systemMessage.setContent(responseContentBuilder.toString());
if (tokenUsageFlag){
systemMessage.setInputTokens(inputToken);
systemMessage.setOutputTokens(outputToken);
systemMessage.setReasoningTokens(reasoningToken);
systemMessage.setTotalCost(totalCost);
tokenUsageFlag = false;
}
chatMessageMapper.insert(systemMessage); chatMessageMapper.insert(systemMessage);
systemMessage.setId(null); systemMessage.setId(null);
responseContentBuilder = new StringBuilder(); responseContentBuilder = new StringBuilder();
@@ -368,6 +384,13 @@ public class LLMServiceImpl implements LLMService {
systemImage.setCreateTime(LocalDateTime.now()); systemImage.setCreateTime(LocalDateTime.now());
systemImage.setContent(contentSave); systemImage.setContent(contentSave);
systemImage.setAccountId(accountId); systemImage.setAccountId(accountId);
if (tokenUsageFlag){
systemImage.setInputTokens(inputToken);
systemImage.setOutputTokens(outputToken);
systemImage.setReasoningTokens(reasoningToken);
systemImage.setTotalCost(totalCost);
tokenUsageFlag = false;
}
chatMessageMapper.insert(systemImage); chatMessageMapper.insert(systemImage);
} else if (Objects.nonNull(toolsName) && toolsName.equals("search_sketch_img")) { } else if (Objects.nonNull(toolsName) && toolsName.equals("search_sketch_img")) {
json.put("content", processSearchSketchToolCon(projectId, toolsData)); json.put("content", processSearchSketchToolCon(projectId, toolsData));
@@ -376,6 +399,16 @@ public class LLMServiceImpl implements LLMService {
updateProjectParams(projectId, toolsData); updateProjectParams(projectId, toolsData);
} }
emitter.send(json.toJSONString()); emitter.send(json.toJSONString());
}else if ("cost".equals(type)) {
JSONObject contentObj = json.getJSONObject("content");
log.info("token usage: {}", contentObj);
inputToken = contentObj.getLong("input_tokens");
outputToken = contentObj.getLong("output_tokens");
reasoningToken = contentObj.getLong("reasoning_tokens");
totalCost = contentObj.getString("total_cost");
totalTokenUsage = totalTokenUsage.add(new BigDecimal(totalCost).divide(new BigDecimal("0.03"), 6, RoundingMode.CEILING));
log.info("totalTokenUsage: {}", totalTokenUsage);
tokenUsageFlag = true;
} }
} }
} }
@@ -384,8 +417,16 @@ public class LLMServiceImpl implements LLMService {
systemMessage.setSeq(getNextSeq(projectId)); systemMessage.setSeq(getNextSeq(projectId));
systemMessage.setCreateTime(LocalDateTime.now()); systemMessage.setCreateTime(LocalDateTime.now());
systemMessage.setContent(responseContentBuilder.toString()); systemMessage.setContent(responseContentBuilder.toString());
if (tokenUsageFlag){
systemMessage.setInputTokens(inputToken);
systemMessage.setOutputTokens(outputToken);
systemMessage.setReasoningTokens(reasoningToken);
systemMessage.setTotalCost(totalCost);
}
chatMessageMapper.insert(systemMessage); chatMessageMapper.insert(systemMessage);
} }
// 扣积分
creditsService.tokenUsage(accountId, totalTokenUsage);
} }
} }
emitter.complete(); emitter.complete();