From 99114d330198327507aeae5776a41f59375eb107 Mon Sep 17 00:00:00 2001 From: Administratos-User <53223786+Administratos-User@users.noreply.github.com> Date: Fri, 11 Jul 2025 11:59:20 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dtoken=E4=B8=8D=E6=89=A3?= =?UTF-8?q?=E8=B4=B9=E5=92=8C=E6=89=A3=E8=B4=B9=E5=BC=82=E5=B8=B8=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1.本次提交的token数+未付费token数 判断大于100token的时候就进行扣费,当然这里还可以改成更多,我觉得100合适。 2.不需要进行扣费的地方屏蔽了相关代码。 3.SessionId传递异常 建议前端传递uuid,也就是每次会话的id。 --- .../common/chat/request/ChatRequest.java | 6 ++ .../chat/impl/ChatCostServiceImpl.java | 81 ++++++++++++++----- .../service/chat/impl/SseServiceImpl.java | 20 +++++ 3 files changed, 87 insertions(+), 20 deletions(-) diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/request/ChatRequest.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/request/ChatRequest.java index 16710ec8..20a021de 100644 --- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/request/ChatRequest.java +++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/request/ChatRequest.java @@ -61,4 +61,10 @@ public class ChatRequest { */ private String role; + + /** + * 对话id(每个聊天窗口都不一样) + */ + private Long uuid; + } diff --git a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/impl/ChatCostServiceImpl.java b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/impl/ChatCostServiceImpl.java index 035f5133..c460bba4 100644 --- a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/impl/ChatCostServiceImpl.java +++ b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/impl/ChatCostServiceImpl.java @@ -47,46 +47,57 @@ public class ChatCostServiceImpl implements IChatCostService { */ @Override public void deductToken(ChatRequest chatRequest) { + + if(chatRequest.getUserId()==null || chatRequest.getSessionId()==null){ return; } + int tokens = TikTokensUtil.tokens(chatRequest.getModel(), chatRequest.getPrompt()); + System.out.println("deductToken->本次提交token数 : "+tokens); + String modelName = chatRequest.getModel(); ChatMessageBo chatMessageBo = new ChatMessageBo(); // 设置用户id chatMessageBo.setUserId(chatRequest.getUserId()); - // 设置对话角色 - chatMessageBo.setRole(chatRequest.getRole()); // 设置会话id chatMessageBo.setSessionId(chatRequest.getSessionId()); + + // 设置对话角色 + chatMessageBo.setRole(chatRequest.getRole()); + // 设置对话内容 chatMessageBo.setContent(chatRequest.getPrompt()); - // 计算总token数 + // 设置模型名字 + chatMessageBo.setModelName(chatRequest.getModel()); + + // 获得记录的累计token数 ChatUsageToken chatToken = chatTokenService.queryByUserId(chatMessageBo.getUserId(), modelName); + + if (chatToken == null) { chatToken = new ChatUsageToken(); chatToken.setToken(0); } + + // 计算总token数 int totalTokens = chatToken.getToken() + tokens; - // 如果总token数大于等于1000,进行费用扣除 - if (totalTokens >= 1000) { - // 计算费用 - int token1 = totalTokens / 1000; - int token2 = totalTokens % 1000; - if (token2 > 0) { - // 保存剩余tokens - chatToken.setModelName(modelName); - chatToken.setUserId(chatMessageBo.getUserId()); - chatToken.setToken(token2); - chatTokenService.editToken(chatToken); - } else { - chatTokenService.resetToken(chatMessageBo.getUserId(), modelName); - } + + //当前未付费token + int token = chatToken.getToken(); + + System.out.println("deductToken->未付费的token数 : "+token); + System.out.println("deductToken->本次提交+未付费token数 : "+totalTokens); + + + //扣费核心逻辑(总token大于100就要对未结清的token进行扣费) + if (totalTokens >= 100) {// 如果总token数大于等于100,进行费用扣除 + ChatModelVo chatModelVo = chatModelService.selectModelByName(modelName); double cost = chatModelVo.getModelPrice(); if (BillingType.TIMES.getCode().equals(chatModelVo.getModelType())) { @@ -95,22 +106,42 @@ public class ChatCostServiceImpl implements IChatCostService { chatMessageBo.setDeductCost(cost); }else { // 按token扣费 - Double numberCost = token1 * cost; + Double numberCost = totalTokens * cost; + System.out.println("deductToken->按token扣费 计算token数量: "+totalTokens); + System.out.println("deductToken->按token扣费 每token的价格: "+cost); + deductUserBalance(chatMessageBo.getUserId(), numberCost); chatMessageBo.setDeductCost(numberCost); + + // 保存剩余tokens + chatToken.setModelName(modelName); + chatToken.setUserId(chatMessageBo.getUserId()); + chatToken.setToken(0);//因为判断大于100token直接全部计算扣除了所以这里直接=0就可以了 + chatTokenService.editToken(chatToken); } + + } else { - deductUserBalance(chatMessageBo.getUserId(), 0.0); + //不满100Token,不需要进行扣费啊啊啊 + //deductUserBalance(chatMessageBo.getUserId(), 0.0); chatMessageBo.setDeductCost(0d); - chatMessageBo.setRemark("不满1kToken,计入下一次!"); + chatMessageBo.setRemark("不满100Token,计入下一次!"); + System.out.println("deductToken->不满100Token,计入下一次!"); chatToken.setToken(totalTokens); chatToken.setModelName(chatMessageBo.getModelName()); chatToken.setUserId(chatMessageBo.getUserId()); chatTokenService.editToken(chatToken); } + + + + // 保存消息记录 chatMessageService.insertByBo(chatMessageBo); + + System.out.println("deductToken->chatMessageService.insertByBo(: "+chatMessageBo); + System.out.println("----------------------------------------"); } /** @@ -121,15 +152,25 @@ public class ChatCostServiceImpl implements IChatCostService { */ @Override public void deductUserBalance(Long userId, Double numberCost) { + SysUser sysUser = sysUserMapper.selectById(userId); if (sysUser == null) { return; } Double userBalance = sysUser.getUserBalance(); + + + System.out.println("deductUserBalance->准备扣除:numberCost: "+numberCost); + System.out.println("deductUserBalance->剩余金额:userBalance: "+userBalance); + + if (userBalance < numberCost || userBalance == 0) { throw new ServiceException("余额不足, 请充值"); } + + + sysUserMapper.update(null, new LambdaUpdateWrapper() .set(SysUser::getUserBalance, Math.max(userBalance - numberCost, 0)) diff --git a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/impl/SseServiceImpl.java b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/impl/SseServiceImpl.java index d8c61a9c..269fcac0 100644 --- a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/impl/SseServiceImpl.java +++ b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/impl/SseServiceImpl.java @@ -81,6 +81,26 @@ public class SseServiceImpl implements ISseService { chatRequest.setRole(Message.Role.USER.getName()); if(LoginHelper.isLogin()){ + + // 设置用户id + chatRequest.setUserId(LoginHelper.getUserId()); + + + //待优化的地方 (这里请前端提交send的时候传递uuid进来或者sessionId) + //待优化的地方 (这里请前端提交send的时候传递uuid进来或者sessionId) + //待优化的地方 (这里请前端提交send的时候传递uuid进来或者sessionId) + { + // 设置会话id + if (chatRequest.getUuid() == null){ + //暂时随机生成会话id + chatRequest.setSessionId(System.currentTimeMillis()); + }else{ + //这里或许需要修改一下,这里应该用uuid 或者 前端传递 sessionId + chatRequest.setSessionId(chatRequest.getUuid()); + } + } + + // 保存消息记录 并扣除费用 chatCostService.deductToken(chatRequest); chatRequest.setUserId(chatCostService.getUserId());