Browse Source

Merge branch 'ai-quota' of wangfan/adweb3-server into master

wangfan 2 months ago
parent
commit
6115a89a8b

+ 3 - 3
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/adweb/gpt/cache/LocalCache.java → jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/adweb/gpt/cache/SseEmitterCache.java

@@ -12,16 +12,16 @@ import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
  * @author chenrui
  * @date 2024/1/26 20:06
  */
-public class LocalCache {
+public class SseEmitterCache {
 
     /** 缓存时长 */
-    public static final long TIMEOUT = 5 * DateUnit.MINUTE.getMillis();
+    private static final long TIMEOUT = 5 * DateUnit.MINUTE.getMillis();
 
     /** 清理间隔 */
     private static final long CLEAN_TIMEOUT = 5 * DateUnit.MINUTE.getMillis();
 
     /** 缓存对象 */
-    public static final TimedCache<String, Object> CACHE = CacheUtil.newTimedCache(TIMEOUT);
+    public static final TimedCache<String, SseEmitter> CACHE = CacheUtil.newTimedCache(TIMEOUT);
 
     static {
         // 启动定时任务

+ 9 - 6
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/adweb/gpt/entity/ChatHistory.java

@@ -15,9 +15,10 @@ import org.jeecgframework.poi.excel.annotation.Excel;
 import org.springframework.format.annotation.DateTimeFormat;
 
 import java.io.Serializable;
+import java.util.Date;
 
 /**
- * @Description: chatGPT聊天历史记录表
+ * @Description: ChatGPT聊天历史记录表
  * @Author: jeecg-boot
  * @Date: 2025-01-07
  * @Version: V1.0
@@ -26,7 +27,7 @@ import java.io.Serializable;
 @TableName("adweb_ai_chat_history")
 @Accessors(chain = true)
 @EqualsAndHashCode(callSuper = false)
-@Schema(description = "chatGPT聊天历史记录表")
+@Schema(description = "ChatGPT聊天历史记录表")
 public class ChatHistory implements Serializable {
     private static final long serialVersionUID = 1L;
 
@@ -40,10 +41,12 @@ public class ChatHistory implements Serializable {
     @Schema(description = "用户ID,与用户表关联")
     private String uid;
 
-    /** 角色 */
-    @Excel(name = "角色", width = 15)
-    @Schema(description = "角色")
-    private String role;
+    /** 对话时间,如每周或每月第一天 */
+    @Excel(name = "对话时间,如每周或每月第一天", width = 15, format = "yyyy-MM-dd")
+    @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd")
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
+    @Schema(description = "对话时间,如每周或每月第一天")
+    private Date date;
 
     /** 内容 */
     @Excel(name = "内容", width = 15)

+ 1 - 5
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/adweb/gpt/listeners/OpenAISSEEventSourceListener.java

@@ -120,11 +120,7 @@ public class OpenAISSEEventSourceListener extends EventSourceListener {
         return errMsg;
     }
 
-    /**
-     * tokens
-     *
-     * @return
-     */
+    /** tokens */
     public long tokens() {
         return tokens;
     }

+ 4 - 5
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/adweb/gpt/mapper/ChatHistoryMapper.java

@@ -1,14 +1,13 @@
 package org.jeecg.modules.adweb.gpt.mapper;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
 import org.jeecg.modules.adweb.gpt.entity.ChatHistory;
 
 /**
- * @Description: chatGPT聊天历史记录表
+ * @Description: ChatGPT聊天历史记录表
  * @Author: jeecg-boot
- * @Date:   2025-01-07
+ * @Date: 2025-01-07
  * @Version: V1.0
  */
-public interface ChatHistoryMapper extends BaseMapper<ChatHistory> {
-
-}
+public interface ChatHistoryMapper extends BaseMapper<ChatHistory> {}

+ 2 - 11
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/adweb/gpt/service/ChatService.java

@@ -4,8 +4,6 @@ import org.jeecg.common.api.vo.Result;
 import org.jeecg.modules.adweb.gpt.vo.ChatHistoryVO;
 import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
 
-// update-begin---author:chenrui ---date:20240126  for:【QQYUN-7932】AI助手------------
-
 /**
  * AI助手聊天Service
  *
@@ -13,11 +11,8 @@ import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
  * @date 2024/1/26 20:08
  */
 public interface ChatService {
-    /**
-     * 创建SSE
-     *
-     * @return
-     */
+
+    /** 创建SSE */
     SseEmitter createChat();
 
     /** 关闭SSE */
@@ -33,7 +28,6 @@ public interface ChatService {
      */
     void sendMessage(String topicId, String message);
 
-    // update-begin---author:chenrui ---date:20240223  for:[QQYUN-8225]聊天记录保存------------
     /**
      * 保存聊天记录
      *
@@ -52,7 +46,4 @@ public interface ChatService {
      * @date 2024/2/22 13:59
      */
     Result<ChatHistoryVO> getHistoryByTopic();
-    // update-end---author:chenrui ---date:20240223  for:[QQYUN-8225]聊天记录保存------------
 }
-
-// update-end---author:chenrui ---date:20240126  for:【QQYUN-7932】AI助手------------

+ 10 - 1
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/adweb/gpt/service/IChatHistoryService.java

@@ -4,10 +4,19 @@ import com.baomidou.mybatisplus.extension.service.IService;
 
 import org.jeecg.modules.adweb.gpt.entity.ChatHistory;
 
+import java.util.List;
+
 /**
  * @Description: adweb_ai_chat_history
  * @Author: jeecg-boot
  * @Date: 2025-12-09
  * @Version: V1.0
  */
-public interface IChatHistoryService extends IService<ChatHistory> {}
+public interface IChatHistoryService extends IService<ChatHistory> {
+
+    /** 获取用户本周的{@link ChatHistory}记录 */
+    ChatHistory getChatHistoryOfWeek(String uid);
+
+    /** 获取用户所有的{@link ChatHistory}记录 */
+    List<ChatHistory> getChatHistoriesByUid(String uid);
+}

+ 38 - 1
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/adweb/gpt/service/impl/ChatHistoryServiceImpl.java

@@ -1,14 +1,20 @@
 package org.jeecg.modules.adweb.gpt.service.impl;
 
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 
 import lombok.extern.slf4j.Slf4j;
 
+import org.jeecg.modules.adweb.common.util.DateUtil;
 import org.jeecg.modules.adweb.gpt.entity.ChatHistory;
 import org.jeecg.modules.adweb.gpt.mapper.ChatHistoryMapper;
 import org.jeecg.modules.adweb.gpt.service.IChatHistoryService;
 import org.springframework.stereotype.Service;
 
+import java.util.Date;
+import java.util.List;
+import java.util.Objects;
+
 /**
  * @Description: adweb_ai_chat_history
  * @Author: jeecg-boot
@@ -18,4 +24,35 @@ import org.springframework.stereotype.Service;
 @Slf4j
 @Service
 public class ChatHistoryServiceImpl extends ServiceImpl<ChatHistoryMapper, ChatHistory>
-        implements IChatHistoryService {}
+        implements IChatHistoryService {
+
+    /** 获取用户本周的{@link ChatHistory}记录 */
+    @Override
+    public ChatHistory getChatHistoryOfWeek(String uid) {
+        // 1. 根据uid查询 - 每周对话存储为一条DB记录,date为每周第一天(默认为周日)
+        Date firstDayOfWeek = DateUtil.getDateRangeByType(DateUtil.DATE_TYPE_THIS_WEEK).getLeft();
+        ChatHistory chatHistory =
+                this.getOne(
+                        new LambdaQueryWrapper<ChatHistory>()
+                                .eq(ChatHistory::getUid, uid)
+                                .ge(ChatHistory::getDate, firstDayOfWeek));
+        if (Objects.nonNull(chatHistory)) {
+            return chatHistory;
+        }
+
+        // 2. 初始化DB entity
+        log.info("用户 {} 本周没有对话记录", uid);
+        chatHistory = new ChatHistory();
+        chatHistory.setUid(uid);
+        chatHistory.setDate(firstDayOfWeek);
+
+        // 3. 更新数据库
+        this.save(chatHistory);
+        return chatHistory;
+    }
+
+    /** 获取用户所有的{@link ChatHistory}记录 */
+    public List<ChatHistory> getChatHistoriesByUid(String uid) {
+        return this.list(new LambdaQueryWrapper<ChatHistory>().eq(ChatHistory::getUid, uid));
+    }
+}

+ 44 - 57
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/adweb/gpt/service/impl/ChatServiceImpl.java

@@ -1,6 +1,5 @@
 package org.jeecg.modules.adweb.gpt.service.impl;
 
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.google.common.collect.Lists;
 import com.unfbx.chatgpt.OpenAiStreamClient;
 import com.unfbx.chatgpt.entity.chat.ChatCompletion;
@@ -14,11 +13,10 @@ import org.apache.shiro.SecurityUtils;
 import org.jeecg.common.api.vo.Result;
 import org.jeecg.common.exception.JeecgBootException;
 import org.jeecg.common.system.vo.LoginUser;
-import org.jeecg.common.util.FastJsonUtil;
 import org.jeecg.common.util.SpringContextUtils;
 import org.jeecg.common.util.UUIDGenerator;
 import org.jeecg.modules.adweb.common.util.AdwebRedisUtil;
-import org.jeecg.modules.adweb.gpt.cache.LocalCache;
+import org.jeecg.modules.adweb.gpt.cache.SseEmitterCache;
 import org.jeecg.modules.adweb.gpt.entity.ChatHistory;
 import org.jeecg.modules.adweb.gpt.listeners.OpenAISSEEventSourceListener;
 import org.jeecg.modules.adweb.gpt.service.ChatService;
@@ -33,27 +31,26 @@ import java.util.*;
 import java.util.stream.Collectors;
 
 /**
- * AI助手聊天Service
+ * AI聊天助手Service
  *
  * @author chenrui
  * @date 2024/1/26 20:07
  */
-@Service
 @Slf4j
+@Service
 public class ChatServiceImpl implements ChatService {
 
-    @Autowired private IChatHistoryService chatHistoryService;
-
     // private static final String CACHE_KEY_PREFIX = "ai:chat:";
-
     // private static final String CACHE_KEY_MSG_HISTORY = "msg_history";
 
-    private static final String REDIS_KEY_PREFIX_MSG_CONTEXT = "ai:chat:msg_content";
+    private static final String REDIS_KEY_PREFIX_TOPIC_CONTEXT = "ai:chat:topic-context";
 
     @Autowired AdwebRedisUtil adwebRedisUtil;
 
     @Autowired private OpenAiStreamClient openAiStreamClient;
 
+    @Autowired private IChatHistoryService chatHistoryService;
+
     /** 防止client不能成功注入 */
     private OpenAiStreamClient ensureClient() {
         if (Objects.isNull(this.openAiStreamClient)) {
@@ -64,14 +61,14 @@ public class ChatServiceImpl implements ChatService {
 
     @Override
     public SseEmitter createChat() {
-        String uid = getUserId();
+        String uid = this.getUserId();
         // 默认30秒超时,设置为0L则永不超时
         SseEmitter sseEmitter = new SseEmitter(-0L);
         // 完成后回调
         sseEmitter.onCompletion(
                 () -> {
                     log.info("[{}]结束连接...................", uid);
-                    LocalCache.CACHE.remove(uid);
+                    SseEmitterCache.CACHE.remove(uid);
                 });
         // 超时回调
         sseEmitter.onTimeout(
@@ -89,7 +86,7 @@ public class ChatServiceImpl implements ChatService {
                                         .name("发生异常!")
                                         .data(Message.builder().content("发生异常请重试!").build())
                                         .reconnectTime(3000));
-                        LocalCache.CACHE.put(uid, sseEmitter);
+                        SseEmitterCache.CACHE.put(uid, sseEmitter);
                     } catch (IOException e) {
                         log.error(e.getMessage(), e);
                     }
@@ -99,25 +96,25 @@ public class ChatServiceImpl implements ChatService {
         } catch (IOException e) {
             log.error(e.getMessage(), e);
         }
-        LocalCache.CACHE.put(uid, sseEmitter);
+        SseEmitterCache.CACHE.put(uid, sseEmitter);
         log.info("[{}]创建sse连接成功!", uid);
         return sseEmitter;
     }
 
     @Override
     public void closeChat() {
-        String uid = getUserId();
-        SseEmitter sse = (SseEmitter) LocalCache.CACHE.get(uid);
-        if (sse != null) {
+        String uid = this.getUserId();
+        SseEmitter sse = SseEmitterCache.CACHE.get(uid);
+        if (Objects.nonNull(sse)) {
             sse.complete();
             // 移除
-            LocalCache.CACHE.remove(uid);
+            SseEmitterCache.CACHE.remove(uid);
         }
     }
 
     @Override
     public void sendMessage(String topicId, String message) {
-        String uid = getUserId();
+        String uid = this.getUserId();
         if (StringUtils.isBlank(message)) {
             log.info("参数异常,message为null");
             throw new BaseException("参数异常,message不能为空~");
@@ -127,40 +124,41 @@ public class ChatServiceImpl implements ChatService {
         }
 
         log.info("话题id:{}", topicId);
-        // 1. 获取当前话题下的message context
-        String contextKey = String.format("%s:%s:%s", REDIS_KEY_PREFIX_MSG_CONTEXT, uid, topicId);
-        String contextValue = adwebRedisUtil.getString(contextKey);
-        List<Message> messageContext =
-                StringUtils.isNotEmpty(contextValue)
-                        ? FastJsonUtil.parseList(contextValue, Message.class)
-                        : Lists.newArrayList();
+        // 1. 获取当前话题的context - 最近100条用户message
+        String contextKey = String.format("%s:%s:%s", REDIS_KEY_PREFIX_TOPIC_CONTEXT, uid, topicId);
+        List<Message> topicContext =
+                Optional.ofNullable(adwebRedisUtil.lGet(contextKey, 0, -1))
+                        .orElse(Lists.newArrayList())
+                        .stream()
+                        .map(Message.class::cast)
+                        .collect(Collectors.toList());
         // 1.1 添加当前message到context
-        messageContext.add(Message.builder().content(message).role(Message.Role.USER).build());
+        topicContext.add(Message.builder().content(message).role(Message.Role.USER).build());
 
         // 2. 发送GPT请求
-        SseEmitter sseEmitter = (SseEmitter) LocalCache.CACHE.get(uid);
-        if (sseEmitter == null) {
-            log.info("聊天消息推送失败uid:[{}],没有创建连接,请重试。", uid);
-            throw new JeecgBootException("聊天消息推送失败uid:[{}],没有创建连接,请重试。~");
+        SseEmitter sseEmitter = SseEmitterCache.CACHE.get(uid);
+        if (Objects.isNull(sseEmitter)) {
+            log.info("聊天消息推送失败uid:[{}]没有创建连接,请重试。", uid);
+            throw new JeecgBootException("聊天消息推送失败uid:[{}],没有创建连接,请重试~");
         }
         OpenAISSEEventSourceListener openAIEventSourceListener =
                 new OpenAISSEEventSourceListener(topicId, sseEmitter);
         ChatCompletion completion =
                 ChatCompletion.builder()
-                        .messages(messageContext)
+                        .messages(topicContext)
                         .model(ChatCompletion.Model.GPT_3_5_TURBO.getName())
                         .build();
         ensureClient().streamChatCompletion(completion, openAIEventSourceListener);
 
-        // 3. 将message context保存到Redis
-        adwebRedisUtil.set(
+        // 3. 将当前话题的context保存到Redis
+        adwebRedisUtil.del(contextKey);
+        adwebRedisUtil.lSet(
                 contextKey,
-                FastJsonUtil.toJSONString(
-                        messageContext.stream()
-                                // 每个话题仅保存最后100条message
-                                .skip(Math.max(0, messageContext.size() - 100))
-                                .collect(Collectors.toList())),
-                // 话题 TTL设置为3小时
+                topicContext.stream()
+                        // 每个话题仅保存最后100条message
+                        .skip(Math.max(0, topicContext.size() - 100))
+                        .collect(Collectors.toList()),
+                // 话题context TTL设置为3小时
                 3 * 60 * 60);
 
         Result.ok(completion.tokens());
@@ -173,20 +171,10 @@ public class ChatServiceImpl implements ChatService {
         // redisTemplate.opsForValue().set(cacheKey, chatHistoryVO.getContent());
         // return Result.OK("保存成功");
 
-        // AdWeb重构 - 聊天记录保存到DB,不存Redis
-        String uid = getUserId();
-        ChatHistory chatHistory =
-                chatHistoryService.getOne(
-                        new LambdaQueryWrapper<ChatHistory>().eq(ChatHistory::getUid, uid));
-
-        if (Objects.isNull(chatHistory)) {
-            chatHistory = new ChatHistory();
-            chatHistory.setUid(uid);
-            chatHistory.setRole(Message.Role.USER.getName());
-        }
-
+        // AdWeb重构 - 聊天记录按周保存到DB,不存Redis
+        ChatHistory chatHistory = chatHistoryService.getChatHistoryOfWeek(this.getUserId());
         chatHistory.setContent(chatHistoryVO.getContent());
-        chatHistoryService.saveOrUpdate(chatHistory);
+        chatHistoryService.updateById(chatHistory);
 
         return Result.OK("保存成功");
     }
@@ -200,17 +188,16 @@ public class ChatServiceImpl implements ChatService {
         // chatHistoryVO.setContent(historyContent);
         // return Result.OK(chatHistoryVO);
 
-        // AdWeb重构 - 聊天记录保存到DB,不存Redis
-        String uid = getUserId();
-        ChatHistory chatHistory =
-                chatHistoryService.getOne(
-                        new LambdaQueryWrapper<ChatHistory>().eq(ChatHistory::getUid, uid));
+        // AdWeb重构 - 聊天记录按周保存到DB,不存Redis
+        ChatHistory chatHistory = chatHistoryService.getChatHistoryOfWeek(this.getUserId());
 
         ChatHistoryVO chatHistoryVO = new ChatHistoryVO();
         chatHistoryVO.setContent(Objects.nonNull(chatHistory) ? chatHistory.getContent() : null);
+
         return Result.OK(chatHistoryVO);
     }
 
+    /** 获取当前登陆用户ID */
     private String getUserId() {
         LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
         return sysUser.getId();

+ 65 - 11
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/adweb/gpt/vo/ChatHistoryVO.java

@@ -1,25 +1,79 @@
 package org.jeecg.modules.adweb.gpt.vo;
 
+import com.fasterxml.jackson.annotation.JsonProperty;
+
 import lombok.Data;
 
 import java.io.Serializable;
+import java.util.Collections;
+import java.util.List;
 
 /**
- * @Description: 聊天记录
- * @Author: chenrui
- * @Date: 2024/2/22 13:36
+ * 聊天记录
+ *
+ * @author: chenrui
+ * @date: 2024/2/22 13:36
  */
 @Data
 public class ChatHistoryVO implements Serializable {
     private static final long serialVersionUID = 3238429500037511283L;
 
-    /**
-     * 话题id
-     */
-    String topicId;
+    /** 话题id */
+    private String topicId;
+
+    /** 聊天记录内容 */
+    private String content;
+
+    @Data
+    public static class Content {
+        private String active;
+        private boolean usingContext;
+        private List<History> history = Collections.emptyList();
+        private List<Chat> chat = Collections.emptyList();
+
+        @Data
+        public static class History {
+            private String uuid;
+            private String title;
+
+            @JsonProperty("isEdit")
+            private boolean isEdit;
+        }
+
+        @Data
+        public static class Chat {
+            private String uuid;
+            private List<ChatData> data;
+
+            @Data
+            public static class ChatData {
+                private String dateTime;
+                // 不解析 - 节省内存
+                // private String text;
+                private boolean inversion;
+                private boolean error;
+                private boolean loading;
+
+                // 不解析 - 节省内存
+                // private ConversationOptions conversationOptions;
+                // private RequestOptions requestOptions;
+
+                @Data
+                public static class ConversationOptions {
+                    private String parentMessageId;
+                }
+
+                @Data
+                public static class RequestOptions {
+                    private String prompt;
+                    private Options options;
 
-    /**
-     * 聊天记录内容
-     */
-    String content;
+                    @Data
+                    public static class Options {
+                        private String parentMessageId;
+                    }
+                }
+            }
+        }
+    }
 }

+ 32 - 4
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/adweb/quota/service/impl/ResourceQuotaServiceImpl.java

@@ -9,11 +9,15 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 
 import lombok.extern.slf4j.Slf4j;
 
+import org.apache.commons.lang3.BooleanUtils;
 import org.apache.commons.lang3.tuple.Pair;
 import org.apache.ibatis.reflection.property.PropertyNamer;
 import org.apache.shiro.SecurityUtils;
 import org.jeecg.common.system.vo.LoginUser;
 import org.jeecg.common.util.FastJsonUtil;
+import org.jeecg.modules.adweb.gpt.entity.ChatHistory;
+import org.jeecg.modules.adweb.gpt.service.IChatHistoryService;
+import org.jeecg.modules.adweb.gpt.vo.ChatHistoryVO;
 import org.jeecg.modules.adweb.quota.entity.ResourceQuota;
 import org.jeecg.modules.adweb.quota.mapper.ResourceQuotaMapper;
 import org.jeecg.modules.adweb.quota.service.IResourceQuotaService;
@@ -23,6 +27,7 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 
+import java.util.List;
 import java.util.Objects;
 
 /**
@@ -54,6 +59,8 @@ public class ResourceQuotaServiceImpl extends ServiceImpl<ResourceQuotaMapper, R
 
     @Autowired private IAdwebSiteService adwebSiteService;
 
+    @Autowired private IChatHistoryService chatHistoryService;
+
     @Override
     public ResourceQuotaVO getResourceQuotaByUid(String uid) {
         ResourceQuota resourceQuota = this.getResourceQuota(uid);
@@ -103,8 +110,28 @@ public class ResourceQuotaServiceImpl extends ServiceImpl<ResourceQuotaMapper, R
 
     @Override
     public Pair<Integer, Integer> getAIPowerQuota(String uid) {
-        // TODO
-        return Pair.of(this.getResourceQuota(uid).getAiPowerQuota(), 0);
+        long aiPowerUsage =
+                chatHistoryService.getChatHistoriesByUid(uid).stream()
+                        .map(ChatHistory::getContent)
+                        .filter(StringUtils::isNotBlank)
+                        .map(
+                                content ->
+                                        FastJsonUtil.parseObject(
+                                                content, ChatHistoryVO.Content.class))
+                        .filter(Objects::nonNull)
+                        .map(content -> content.getChat())
+                        .flatMap(List::stream)
+                        .map(ChatHistoryVO.Content.Chat::getData)
+                        .flatMap(List::stream)
+                        .filter(
+                                chatData ->
+                                        BooleanUtils.isFalse(chatData.isError())
+                                                &&
+                                                // AI生成的消息
+                                                BooleanUtils.isFalse(chatData.isInversion()))
+                        .count();
+
+        return Pair.of(this.getResourceQuota(uid).getAiPowerQuota(), (int) aiPowerUsage);
     }
 
     @Override
@@ -134,13 +161,14 @@ public class ResourceQuotaServiceImpl extends ServiceImpl<ResourceQuotaMapper, R
      * @return
      */
     private ResourceQuota getResourceQuota(String uid) {
+        // 1. 根据uid查询
         ResourceQuota resourceQuota =
                 this.getOne(new LambdaQueryWrapper<ResourceQuota>().eq(ResourceQuota::getUid, uid));
         if (Objects.nonNull(resourceQuota)) {
             return resourceQuota;
         }
 
-        // 1. 初始化DB entity
+        // 2. 初始化DB entity
         log.info("用户 {} 未配置资源额度", uid);
         resourceQuota = new ResourceQuota();
         resourceQuota.setUid(uid);
@@ -149,7 +177,7 @@ public class ResourceQuotaServiceImpl extends ServiceImpl<ResourceQuotaMapper, R
         resourceQuota.setCustomsDataQuota(defaultCustomsDataQuota);
         resourceQuota.setCustomsDataUsage(0);
 
-        // 2. 更新数据库
+        // 3. 更新数据库
         this.save(resourceQuota);
         log.info(
                 "管理员 {} 为用户 {} 配置资源额度 {}",