|
@@ -12,7 +12,6 @@ import cn.hutool.http.HttpUtil;
|
|
|
import cn.hutool.http.Method;
|
|
import cn.hutool.http.Method;
|
|
|
import cn.hutool.json.JSONObject;
|
|
import cn.hutool.json.JSONObject;
|
|
|
import cn.hutool.json.JSONUtil;
|
|
import cn.hutool.json.JSONUtil;
|
|
|
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
|
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|
|
import com.cyksj.common.constant.Constant;
|
|
import com.cyksj.common.constant.Constant;
|
|
|
import com.cyksj.common.exception.BusinessRuntimeException;
|
|
import com.cyksj.common.exception.BusinessRuntimeException;
|
|
@@ -21,8 +20,6 @@ import com.cyksj.common.util.StringUtil;
|
|
|
import com.cyksj.mapper.*;
|
|
import com.cyksj.mapper.*;
|
|
|
import com.cyksj.mapper.station.CollegeStudentStationUseTicketRecordMapper;
|
|
import com.cyksj.mapper.station.CollegeStudentStationUseTicketRecordMapper;
|
|
|
import com.cyksj.model.entity.*;
|
|
import com.cyksj.model.entity.*;
|
|
|
-import com.cyksj.model.request.gpt.ConversationRequest;
|
|
|
|
|
-import com.cyksj.model.response.ConversationLimitResponse;
|
|
|
|
|
import com.cyksj.model.views.ChatGptUserView;
|
|
import com.cyksj.model.views.ChatGptUserView;
|
|
|
import com.cyksj.model.views.ChatgptCarInfoView;
|
|
import com.cyksj.model.views.ChatgptCarInfoView;
|
|
|
import com.cyksj.redis.RedisService;
|
|
import com.cyksj.redis.RedisService;
|
|
@@ -37,18 +34,19 @@ import lombok.extern.slf4j.Slf4j;
|
|
|
import org.apache.commons.lang3.StringUtils;
|
|
import org.apache.commons.lang3.StringUtils;
|
|
|
import org.springframework.beans.factory.annotation.Value;
|
|
import org.springframework.beans.factory.annotation.Value;
|
|
|
import org.springframework.dao.DuplicateKeyException;
|
|
import org.springframework.dao.DuplicateKeyException;
|
|
|
-import org.springframework.data.redis.core.ZSetOperations;
|
|
|
|
|
import org.springframework.stereotype.Service;
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
|
|
|
-import javax.annotation.PostConstruct;
|
|
|
|
|
import javax.imageio.stream.FileImageOutputStream;
|
|
import javax.imageio.stream.FileImageOutputStream;
|
|
|
import javax.servlet.http.HttpServletRequest;
|
|
import javax.servlet.http.HttpServletRequest;
|
|
|
import java.math.BigDecimal;
|
|
import java.math.BigDecimal;
|
|
|
|
|
+import java.math.RoundingMode;
|
|
|
import java.nio.file.Files;
|
|
import java.nio.file.Files;
|
|
|
import java.nio.file.Path;
|
|
import java.nio.file.Path;
|
|
|
import java.time.LocalDateTime;
|
|
import java.time.LocalDateTime;
|
|
|
-import java.util.*;
|
|
|
|
|
-import java.util.stream.Collectors;
|
|
|
|
|
|
|
+import java.util.Date;
|
|
|
|
|
+import java.util.HashMap;
|
|
|
|
|
+import java.util.List;
|
|
|
|
|
+import java.util.Map;
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
* @author chan
|
|
* @author chan
|
|
@@ -67,13 +65,6 @@ public class ChatGptAccountServiceImpl implements ChatGptAccountService {
|
|
|
|
|
|
|
|
private static final String GPT_PROXY = "https://chat-chan-87jztgkf257d.xyhelper.net";
|
|
private static final String GPT_PROXY = "https://chat-chan-87jztgkf257d.xyhelper.net";
|
|
|
|
|
|
|
|
- private static final int MAX_REQUESTS = 40; // 3小时内最大请求次数
|
|
|
|
|
-
|
|
|
|
|
- private static final long WINDOW_SIZE = 3 * 60 * 60; // 3小时窗口的秒数
|
|
|
|
|
-
|
|
|
|
|
- private static final List<String> LOW_GPT_MODEL = List.of("gpt-4o-mini","text-davinci-002-render-sha");
|
|
|
|
|
-
|
|
|
|
|
- private static final GlobalThreadPoolTaskExecutor TASK_EXECUTOR = GlobalThreadPoolTaskExecutor.getInstance();
|
|
|
|
|
|
|
|
|
|
private final RedisService redisService;
|
|
private final RedisService redisService;
|
|
|
|
|
|
|
@@ -91,18 +82,12 @@ public class ChatGptAccountServiceImpl implements ChatGptAccountService {
|
|
|
|
|
|
|
|
private final UserBindRelationService userBindRelationService;
|
|
private final UserBindRelationService userBindRelationService;
|
|
|
|
|
|
|
|
- private final ChatgptUserConversationRecordMapper chatgptUserConversationRecordMapper;
|
|
|
|
|
-
|
|
|
|
|
- private final ChatgptUserConversationMapper chatgptUserConversationMapper;
|
|
|
|
|
-
|
|
|
|
|
private final AccountMapper accountMapper;
|
|
private final AccountMapper accountMapper;
|
|
|
|
|
|
|
|
private final BeanSearcher beanSearcher;
|
|
private final BeanSearcher beanSearcher;
|
|
|
|
|
|
|
|
private final ChatgptUserTokenPrepareMapper chatgptUserTokenPrepareMapper;
|
|
private final ChatgptUserTokenPrepareMapper chatgptUserTokenPrepareMapper;
|
|
|
|
|
|
|
|
- private final ChatgptUserCarUsedRecordMapper chatgptUserCarUsedRecordMapper;
|
|
|
|
|
-
|
|
|
|
|
private final CollegeStudentStationUseTicketRecordMapper collegeStudentStationUseTicketRecordMapper;
|
|
private final CollegeStudentStationUseTicketRecordMapper collegeStudentStationUseTicketRecordMapper;
|
|
|
|
|
|
|
|
private final UpgradePackageMapper upgradePackageMapper;
|
|
private final UpgradePackageMapper upgradePackageMapper;
|
|
@@ -113,30 +98,6 @@ public class ChatGptAccountServiceImpl implements ChatGptAccountService {
|
|
|
|
|
|
|
|
private final HttpServletRequest request;
|
|
private final HttpServletRequest request;
|
|
|
|
|
|
|
|
- @Override
|
|
|
|
|
- public String addAccount(Account account) {
|
|
|
|
|
- if (isAccountExists(account)) {
|
|
|
|
|
- throw BusinessRuntimeException.getInstance("镜像服务该账号已存在.");
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- String refreshToken = "";
|
|
|
|
|
- String officialSession = "";
|
|
|
|
|
- try {
|
|
|
|
|
- JSONObject loginResult = getLoginResult(account);
|
|
|
|
|
- if (StringUtils.isBlank(loginResult.getStr("accessToken"))) {
|
|
|
|
|
- throw BusinessRuntimeException.getInstance(loginResult.getStr("detail"));
|
|
|
|
|
- }
|
|
|
|
|
- refreshToken = loginResult.getStr("refresh_token");
|
|
|
|
|
- officialSession = loginResult.toString();
|
|
|
|
|
- } catch (Exception e) {
|
|
|
|
|
- throw BusinessRuntimeException.getInstance("登录获取token错误 error:" + e.getMessage());
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- createChatgptSession(account, officialSession);
|
|
|
|
|
-
|
|
|
|
|
- return refreshToken;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
@Override
|
|
@Override
|
|
|
public String getGptSession(String account, String password) {
|
|
public String getGptSession(String account, String password) {
|
|
|
String officialSession = "";
|
|
String officialSession = "";
|
|
@@ -155,16 +116,6 @@ public class ChatGptAccountServiceImpl implements ChatGptAccountService {
|
|
|
return officialSession;
|
|
return officialSession;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- /**
|
|
|
|
|
- * 判断账号是否存在
|
|
|
|
|
- *
|
|
|
|
|
- * @param account 账号
|
|
|
|
|
- * @return 是否存在
|
|
|
|
|
- */
|
|
|
|
|
- private boolean isAccountExists(Account account) {
|
|
|
|
|
- Integer count = chatgptSessionMapper.selectCount(Wrappers.lambdaQuery(ChatgptSession.class).eq(ChatgptSession::getEmail, account.getAccount()));
|
|
|
|
|
- return count > 0;
|
|
|
|
|
- }
|
|
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
* 获取登录结果
|
|
* 获取登录结果
|
|
@@ -182,43 +133,6 @@ public class ChatGptAccountServiceImpl implements ChatGptAccountService {
|
|
|
return new JSONObject(execute.body());
|
|
return new JSONObject(execute.body());
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- /**
|
|
|
|
|
- * 创建chatgptSession
|
|
|
|
|
- *
|
|
|
|
|
- * @param account
|
|
|
|
|
- * @param officialSession
|
|
|
|
|
- */
|
|
|
|
|
- private void createChatgptSession(Account account, String officialSession) {
|
|
|
|
|
- ChatgptSession chatgptSession = new ChatgptSession();
|
|
|
|
|
- chatgptSession.setOfficialSession(officialSession);
|
|
|
|
|
- chatgptSession.setEmail(account.getAccount());
|
|
|
|
|
- chatgptSession.setPassword(account.getPassword());
|
|
|
|
|
- chatgptSession.setIsPlus(1);
|
|
|
|
|
- chatgptSession.setAccountId(account.getId());
|
|
|
|
|
- chatgptSession.setStatus(1);
|
|
|
|
|
- chatgptSessionMapper.insert(chatgptSession);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * 更新账号
|
|
|
|
|
- *
|
|
|
|
|
- * @param account
|
|
|
|
|
- */
|
|
|
|
|
- @Override
|
|
|
|
|
- public void upAccount(Account account) {
|
|
|
|
|
- ChatgptSession chatgptSession = chatgptSessionMapper.selectOne(Wrappers.lambdaQuery(ChatgptSession.class).eq(ChatgptSession::getEmail, account.getAccount()));
|
|
|
|
|
- if (chatgptSession != null) {
|
|
|
|
|
- if (StringUtils.isNotBlank(account.getGptRefreshToken())) {
|
|
|
|
|
- chatgptSession.setOfficialSession(account.getGptRefreshToken());
|
|
|
|
|
- }
|
|
|
|
|
- chatgptSession.setEmail(account.getAccount());
|
|
|
|
|
- chatgptSession.setPassword(account.getPassword());
|
|
|
|
|
- chatgptSession.setIsPlus(1);
|
|
|
|
|
- chatgptSession.setAccountId(account.getId());
|
|
|
|
|
- chatgptSession.setStatus(1);
|
|
|
|
|
- chatgptSessionMapper.updateById(chatgptSession);
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
* 获取登录url
|
|
* 获取登录url
|
|
@@ -344,28 +258,6 @@ public class ChatGptAccountServiceImpl implements ChatGptAccountService {
|
|
|
*/
|
|
*/
|
|
|
private synchronized ChatgptUser createChatgptUser(GroupsRelation groupsRelation, GroupsTrips groupsTrips, User user, GoodsDonSku goodsDonSku) {
|
|
private synchronized ChatgptUser createChatgptUser(GroupsRelation groupsRelation, GroupsTrips groupsTrips, User user, GoodsDonSku goodsDonSku) {
|
|
|
ChatgptUser chatgptUser = new ChatgptUser();
|
|
ChatgptUser chatgptUser = new ChatgptUser();
|
|
|
- if (!goodsDonSku.getIsCar()) {
|
|
|
|
|
- ChatgptSession chatgptSession = chatgptSessionMapper.selectOne(Wrappers.lambdaQuery(ChatgptSession.class).eq(ChatgptSession::getAccountId, groupsTrips.getAccountId()));
|
|
|
|
|
- if (chatgptSession == null) {
|
|
|
|
|
-
|
|
|
|
|
- Account account = accountMapper.selectById(groupsTrips.getAccountId());
|
|
|
|
|
- String officialSession = "";
|
|
|
|
|
- try {
|
|
|
|
|
- JSONObject loginResult = getLoginResult(account);
|
|
|
|
|
- if (StringUtils.isBlank(loginResult.getStr("accessToken"))) {
|
|
|
|
|
- throw BusinessRuntimeException.getInstance(loginResult.getStr("detail"));
|
|
|
|
|
- }
|
|
|
|
|
- officialSession = loginResult.toString();
|
|
|
|
|
- } catch (Exception e) {
|
|
|
|
|
- throw BusinessRuntimeException.getInstance("配置账号错误 msg: " + e.getMessage());
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- createChatgptSession(account, officialSession);
|
|
|
|
|
- chatgptSession = chatgptSessionMapper.selectOne(Wrappers.lambdaQuery(ChatgptSession.class).eq(ChatgptSession::getAccountId, groupsTrips.getAccountId()));
|
|
|
|
|
-
|
|
|
|
|
- }
|
|
|
|
|
- chatgptUser.setSessionId(chatgptSession.getId());
|
|
|
|
|
- }
|
|
|
|
|
if (goodsDonSku.getIsCar()) {
|
|
if (goodsDonSku.getIsCar()) {
|
|
|
chatgptUser.setIsCar(true);
|
|
chatgptUser.setIsCar(true);
|
|
|
chatgptUser.setLimitNum(goodsDonSku.getGptLimitNum());
|
|
chatgptUser.setLimitNum(goodsDonSku.getGptLimitNum());
|
|
@@ -463,106 +355,6 @@ public class ChatGptAccountServiceImpl implements ChatGptAccountService {
|
|
|
return chatgptUserMapper.selectOne(Wrappers.lambdaQuery(ChatgptUser.class).eq(ChatgptUser::getUserToken, userToken).gt(ChatgptUser::getExpireTime, now));
|
|
return chatgptUserMapper.selectOne(Wrappers.lambdaQuery(ChatgptUser.class).eq(ChatgptUser::getUserToken, userToken).gt(ChatgptUser::getExpireTime, now));
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- @Override
|
|
|
|
|
- public void saveConversationRecord(String userToken, ConversationRequest conversationRequest) {
|
|
|
|
|
- LambdaQueryWrapper<ChatgptSession> wrapper = Wrappers.lambdaQuery(ChatgptSession.class);
|
|
|
|
|
- ChatgptUser chatgptUser = chatgptUserMapper.selectOne(Wrappers.lambdaQuery(ChatgptUser.class).eq(ChatgptUser::getUserToken, userToken));
|
|
|
|
|
- if (StringUtils.isNotBlank(conversationRequest.getCarId())) {
|
|
|
|
|
- wrapper.eq(ChatgptSession::getCarId, conversationRequest.getCarId());
|
|
|
|
|
- } else {
|
|
|
|
|
- if (chatgptUser.getSessionId() != null) {
|
|
|
|
|
- wrapper.eq(ChatgptSession::getId, chatgptUser.getSessionId());
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- ChatgptSession chatgptSession = chatgptSessionMapper.selectOne(wrapper);
|
|
|
|
|
- ChatgptUserConversationRecord chatgptUserConversationRecord = new ChatgptUserConversationRecord();
|
|
|
|
|
- chatgptUserConversationRecord.setUserToken(userToken);
|
|
|
|
|
- chatgptUserConversationRecord.setCarId(chatgptSession.getCarId());
|
|
|
|
|
- chatgptUserConversationRecord.setCarName(chatgptSession.getCarName());
|
|
|
|
|
-
|
|
|
|
|
- if (StringUtils.isNotBlank(conversationRequest.getConversation_id())) {
|
|
|
|
|
- chatgptUserConversationRecord.setConversationId(conversationRequest.getConversation_id());
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- chatgptUserConversationRecord.setModel(conversationRequest.getModel());
|
|
|
|
|
- chatgptUserConversationRecordMapper.insert(chatgptUserConversationRecord);
|
|
|
|
|
-
|
|
|
|
|
- if(!LOW_GPT_MODEL.contains(conversationRequest.getModel())){
|
|
|
|
|
- String key = RedisService.key.CHATGPT_CONVERSATION_LIMIT.getName() + ":" + userToken;
|
|
|
|
|
- long currentTimeMillis = System.currentTimeMillis();
|
|
|
|
|
-
|
|
|
|
|
- redisService.del();
|
|
|
|
|
- if(redisService.hasKey("chatgpt:team:clears_in:" + chatgptSession.getCarId())){
|
|
|
|
|
- redisService.del("chatgpt:team:clears_in:" + chatgptSession.getCarId());
|
|
|
|
|
- }
|
|
|
|
|
- if (redisService.hasKey("chatgpt:clears_in:" + chatgptSession.getCarId())) {
|
|
|
|
|
- redisService.del("chatgpt:clears_in:" + chatgptSession.getCarId());
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // 如果未超过限制,记录当前请求的时间戳
|
|
|
|
|
- redisService.zAdd(key, currentTimeMillis, currentTimeMillis);
|
|
|
|
|
- // 设置ZSet的过期时间,窗口大小加上一段冗余时间
|
|
|
|
|
- redisService.expire(key, (chatgptUser.getLimitTime() * 60 * 60) + 20);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- if (StringUtils.isNotBlank(chatgptSession.getCarId())) {
|
|
|
|
|
- updateExperienceAndScore(chatgptSession.getCarId(), !LOW_GPT_MODEL.contains(conversationRequest.getModel()), System.currentTimeMillis());
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
- @Override
|
|
|
|
|
- public ConversationLimitResponse conversationLimit(String userToken, String model, String carId, ChatgptUser chatgptUser, Boolean isCar) {
|
|
|
|
|
- ConversationLimitResponse conversationLimitResponse = new ConversationLimitResponse();
|
|
|
|
|
- conversationLimitResponse.setLimited(false);
|
|
|
|
|
- if (!LOW_GPT_MODEL.contains(model)) {
|
|
|
|
|
- //如果不为车队 直接返回
|
|
|
|
|
- if (chatgptUser.getIsCar()) {
|
|
|
|
|
- conversationLimitResponse = isConversationAllowed(userToken, chatgptUser.getLimitNum(), chatgptUser.getLimitTime());
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- return conversationLimitResponse;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * 检查是否允许进行进行提问
|
|
|
|
|
- *
|
|
|
|
|
- * @param userToken 用户token
|
|
|
|
|
- * @return true 如果允许请求,false 如果请求被限制
|
|
|
|
|
- */
|
|
|
|
|
- public ConversationLimitResponse isConversationAllowed(String userToken, int limit, Long limitTime) {
|
|
|
|
|
- String key = RedisService.key.CHATGPT_CONVERSATION_LIMIT.getName() + ":" + userToken;
|
|
|
|
|
- long currentTimeMillis = System.currentTimeMillis();
|
|
|
|
|
- long windowStartMillis = currentTimeMillis - (limitTime * 60 * 60) * 1000;
|
|
|
|
|
- ConversationLimitResponse conversationLimitResponse = new ConversationLimitResponse();
|
|
|
|
|
- // 清除时间窗口之前的请求记录
|
|
|
|
|
- redisService.zRemoveRangeByScore(key, 0, windowStartMillis);
|
|
|
|
|
-
|
|
|
|
|
- Long currentSize = redisService.zCard(key);
|
|
|
|
|
- if (currentSize != null && currentSize >= limit) {
|
|
|
|
|
- // 如果当前请求次数超过限制,则拒绝请求
|
|
|
|
|
- Set<Object> times = redisService.zRangeByScore(key, 0, currentTimeMillis, 0, 1);
|
|
|
|
|
- Long oldestTime = (Long) times.stream().findFirst().orElse(null);
|
|
|
|
|
- if (oldestTime != null) {
|
|
|
|
|
- // 下一次可用时间是最早请求时间之后的3小时
|
|
|
|
|
- long nextAvailableTime = oldestTime + (limitTime * 60 * 60 * 1000);
|
|
|
|
|
- conversationLimitResponse.setNextAvailableTime(nextAvailableTime);
|
|
|
|
|
- }
|
|
|
|
|
- conversationLimitResponse.setLimited(true);
|
|
|
|
|
- //用户次数使用限制
|
|
|
|
|
- ChatgptUserCarUsedRecord chatgptUserCarUsedRecord = new ChatgptUserCarUsedRecord();
|
|
|
|
|
- chatgptUserCarUsedRecord.setUserToken(userToken);
|
|
|
|
|
- chatgptUserCarUsedRecord.setIsUserLimit(true);
|
|
|
|
|
- chatgptUserCarUsedRecordMapper.insert(chatgptUserCarUsedRecord);
|
|
|
|
|
- return conversationLimitResponse;
|
|
|
|
|
- } else {
|
|
|
|
|
- conversationLimitResponse.setLimited(false);
|
|
|
|
|
- return conversationLimitResponse;
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -573,38 +365,14 @@ public class ChatGptAccountServiceImpl implements ChatGptAccountService {
|
|
|
*/
|
|
*/
|
|
|
@Override
|
|
@Override
|
|
|
public Long getConversationCount(String userToken, Long limitTime) {
|
|
public Long getConversationCount(String userToken, Long limitTime) {
|
|
|
- String key = RedisService.key.CHATGPT_CONVERSATION_LIMIT.getName() + ":" + userToken;
|
|
|
|
|
- long currentTimeMillis = System.currentTimeMillis();
|
|
|
|
|
- long windowStartMillis = currentTimeMillis - (limitTime * 60 * 60) * 1000;
|
|
|
|
|
-
|
|
|
|
|
- // 清除时间窗口之前的请求记录(可选,根据需要决定是否在此处清理过期记录)
|
|
|
|
|
- redisService.zRemoveRangeByScore(key, 0, windowStartMillis);
|
|
|
|
|
-
|
|
|
|
|
- // 获取当前窗口内的请求次数
|
|
|
|
|
- Long currentSize = redisService.zCard(key);
|
|
|
|
|
- return currentSize != null ? currentSize : 0L;
|
|
|
|
|
|
|
+ try {
|
|
|
|
|
+ String res = HttpUtil.get("http://154.198.213.52:9611/getConversationCount?userToken=" + userToken);
|
|
|
|
|
+ return new JSONObject(res).getLong("count");
|
|
|
|
|
+ }catch (Exception e){
|
|
|
|
|
+ return 0L;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- /**
|
|
|
|
|
- * 获取指定车队ID在滑动窗口内的提问次数
|
|
|
|
|
- *
|
|
|
|
|
- * @param carId 车队ID
|
|
|
|
|
- * @return 滑动窗口内的请求次数
|
|
|
|
|
- */
|
|
|
|
|
- private Long getCarConversationCount(String carId, Long limitTime) {
|
|
|
|
|
- // 定义键名
|
|
|
|
|
- String key = RedisService.key.CHATGPT_CAR_HIGH_CHAT.getName() + carId;
|
|
|
|
|
- long timestamp = System.currentTimeMillis();
|
|
|
|
|
-
|
|
|
|
|
- long windowStartMillis = timestamp - (limitTime * 60 * 60 * 1000);
|
|
|
|
|
-
|
|
|
|
|
- // 清除时间窗口之前的请求记录(可选,根据需要决定是否在此处清理过期记录)
|
|
|
|
|
- redisService.zRemoveRangeByScore(key, 0, windowStartMillis);
|
|
|
|
|
-
|
|
|
|
|
- // 获取当前窗口内的请求次数
|
|
|
|
|
- Long currentSize = redisService.zCard(key);
|
|
|
|
|
- return currentSize != null ? currentSize : 0L;
|
|
|
|
|
- }
|
|
|
|
|
|
|
|
|
|
@Override
|
|
@Override
|
|
|
public ChatgptSession checkSession(String carId) {
|
|
public ChatgptSession checkSession(String carId) {
|
|
@@ -690,7 +458,8 @@ public class ChatGptAccountServiceImpl implements ChatGptAccountService {
|
|
|
*/
|
|
*/
|
|
|
@Override
|
|
@Override
|
|
|
public SearchResult<ChatgptCarInfoView> getCarInfoPage(String userToken, Integer limit, Boolean isPlus) {
|
|
public SearchResult<ChatgptCarInfoView> getCarInfoPage(String userToken, Integer limit, Boolean isPlus) {
|
|
|
- SearchResult<ChatgptCarInfoView> chatgptCarInfoViews = beanSearcher.search(ChatgptCarInfoView.class, MapUtils.flatBuilder(request.getParameterMap()).field(ChatgptCarInfoView::getIsPlus, isPlus).orderBy(ChatgptCarInfoView::getScore).asc().build());
|
|
|
|
|
|
|
+ SearchResult<ChatgptCarInfoView> chatgptCarInfoViews = beanSearcher.search(ChatgptCarInfoView.class, MapUtils.flatBuilder(request.getParameterMap())
|
|
|
|
|
+ .field(ChatgptCarInfoView::getIsPlus, isPlus).orderBy(ChatgptCarInfoView::getTeamClearsIn).asc().orderBy(ChatgptCarInfoView::getClearsIn).asc().orderBy(ChatgptCarInfoView::getScore).asc().build());
|
|
|
|
|
|
|
|
chatgptCarInfoViews.getDataList().forEach(this::buildChatgptCarInfoView);
|
|
chatgptCarInfoViews.getDataList().forEach(this::buildChatgptCarInfoView);
|
|
|
return chatgptCarInfoViews;
|
|
return chatgptCarInfoViews;
|
|
@@ -706,46 +475,6 @@ public class ChatGptAccountServiceImpl implements ChatGptAccountService {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
- // 更新体验并计算评分
|
|
|
|
|
- public void updateExperienceAndScore(String carId, boolean isHighLevel, long timestamp) {
|
|
|
|
|
- // 定义键名
|
|
|
|
|
- String key = isHighLevel ? RedisService.key.CHATGPT_CAR_HIGH_CHAT.getName() + carId : RedisService.key.CHATGPT_CAR_LOW_CHAT.getName() + carId;
|
|
|
|
|
- double scoreToAdd = isHighLevel ? 2.0 : 1.0; // 分数更新规则
|
|
|
|
|
-
|
|
|
|
|
- // 更新体验数据
|
|
|
|
|
- redisService.zAdd(key, timestamp, String.valueOf(timestamp));
|
|
|
|
|
-
|
|
|
|
|
- // 清理旧数据(可选)和重新计算评分(根据需要实现)
|
|
|
|
|
- cleanupOldExperiencesAndRecalculateScore(carId, timestamp);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // 清理旧数据和重新计算评分
|
|
|
|
|
- public void cleanupOldExperiencesAndRecalculateScore(String carId, long currentTimestamp) {
|
|
|
|
|
- long threeHoursAgo = currentTimestamp - (3 * 60 * 60 * 1000); // 3小时前的时间戳
|
|
|
|
|
-
|
|
|
|
|
- // 清理高级体验旧数据
|
|
|
|
|
- redisService.zRemoveRangeByScore(RedisService.key.CHATGPT_CAR_HIGH_CHAT.getName() + carId, 0, threeHoursAgo);
|
|
|
|
|
-
|
|
|
|
|
- // 清理低级体验旧数据
|
|
|
|
|
- redisService.zRemoveRangeByScore(RedisService.key.CHATGPT_CAR_LOW_CHAT.getName() + carId, 0, threeHoursAgo);
|
|
|
|
|
-
|
|
|
|
|
- // 重新计算评分
|
|
|
|
|
- recalculateScore(carId, currentTimestamp);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
- // 重新计算指定车队的评分
|
|
|
|
|
- private void recalculateScore(String carId, long currentTimestamp) {
|
|
|
|
|
- // 实际应用中,你需要根据高级体验和低级体验的数量重新计算得分
|
|
|
|
|
- Double highExperienceScore = (double) redisService.zCount(RedisService.key.CHATGPT_CAR_HIGH_CHAT.getName() + carId, currentTimestamp - (3 * 60 * 60 * 1000), currentTimestamp) * 2;
|
|
|
|
|
- Double lowExperienceScore = (double) redisService.zCount(RedisService.key.CHATGPT_CAR_LOW_CHAT.getName() + carId, currentTimestamp - (3 * 60 * 60 * 1000), currentTimestamp);
|
|
|
|
|
- double newScore = highExperienceScore + lowExperienceScore;
|
|
|
|
|
- if(carId.contains("T")){
|
|
|
|
|
- newScore = BigDecimal.valueOf(newScore).divide(BigDecimal.valueOf(5), 2, BigDecimal.ROUND_HALF_UP).doubleValue();
|
|
|
|
|
- }
|
|
|
|
|
- redisService.zAdd(RedisService.key.CHATGPT_CAR_SCORES.getName(), newScore, carId);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
|
|
|
|
|
// 获取得分最低的N个车队的方法
|
|
// 获取得分最低的N个车队的方法
|
|
|
public List<ChatgptCarInfoView> getLowestScoreFleets(int count, Boolean isPlus) {
|
|
public List<ChatgptCarInfoView> getLowestScoreFleets(int count, Boolean isPlus) {
|
|
@@ -755,24 +484,6 @@ public class ChatGptAccountServiceImpl implements ChatGptAccountService {
|
|
|
return chatgptCarInfoViews;
|
|
return chatgptCarInfoViews;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- public void initFleets(Boolean flag) {
|
|
|
|
|
- LambdaQueryWrapper<ChatgptSession> wrapper = Wrappers.lambdaQuery(ChatgptSession.class);
|
|
|
|
|
- if (flag) {
|
|
|
|
|
- Set<ZSetOperations.TypedTuple<Object>> fleets = redisService.zRangeWithScores(RedisService.key.CHATGPT_CAR_SCORES.getName(), 0L, -1);
|
|
|
|
|
- List<Object> collect = fleets.stream().map(ZSetOperations.TypedTuple::getValue).collect(Collectors.toList());
|
|
|
|
|
- wrapper.notIn(collect.size() > 0, ChatgptSession::getCarId, collect);
|
|
|
|
|
- }
|
|
|
|
|
- //如果存在未存在redis中的车辆则同步进 chatgpt:car:scores
|
|
|
|
|
- List<ChatgptSession> chatgptSessions = chatgptSessionMapper.selectList(wrapper.eq(ChatgptSession::getIsCar, true));
|
|
|
|
|
-
|
|
|
|
|
- chatgptSessions.forEach((chatgptSession) -> {
|
|
|
|
|
- if (!redisService.checkValueExistsInZSet(RedisService.key.CHATGPT_CAR_SCORES.getName(), chatgptSession.getCarId())) {
|
|
|
|
|
- redisService.zAdd(RedisService.key.CHATGPT_CAR_SCORES.getName(), 0, chatgptSession.getCarId());
|
|
|
|
|
- }
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
|
|
|
|
|
// 构建ChatgptCarInfoView对象
|
|
// 构建ChatgptCarInfoView对象
|
|
|
private ChatgptCarInfoView buildChatgptCarInfoView(ChatgptCarInfoView view) {
|
|
private ChatgptCarInfoView buildChatgptCarInfoView(ChatgptCarInfoView view) {
|
|
@@ -782,11 +493,11 @@ public class ChatGptAccountServiceImpl implements ChatGptAccountService {
|
|
|
|
|
|
|
|
if(view.getCarName().contains("T") && view.getIsPlus() == 1){
|
|
if(view.getCarName().contains("T") && view.getIsPlus() == 1){
|
|
|
view.setType("Team");
|
|
view.setType("Team");
|
|
|
- Long team = carOaiLimit(view.getCarId(), true);
|
|
|
|
|
|
|
+ Long team = view.getTeamClearsIn();
|
|
|
if (team != 0L) {
|
|
if (team != 0L) {
|
|
|
view.setTeamExpTime(new DateTime(System.currentTimeMillis() + team * 1000));
|
|
view.setTeamExpTime(new DateTime(System.currentTimeMillis() + team * 1000));
|
|
|
}
|
|
}
|
|
|
- Long aLong = carOaiLimit(view.getCarId(), false);
|
|
|
|
|
|
|
+ Long aLong = view.getClearsIn();
|
|
|
if (aLong != 0L) {
|
|
if (aLong != 0L) {
|
|
|
view.setExpTime(new DateTime(System.currentTimeMillis() + aLong * 1000));
|
|
view.setExpTime(new DateTime(System.currentTimeMillis() + aLong * 1000));
|
|
|
}
|
|
}
|
|
@@ -797,15 +508,13 @@ public class ChatGptAccountServiceImpl implements ChatGptAccountService {
|
|
|
}
|
|
}
|
|
|
}else {
|
|
}else {
|
|
|
view.setType(view.getIsPlus() == 1 ? "Plus" : "3.5");
|
|
view.setType(view.getIsPlus() == 1 ? "Plus" : "3.5");
|
|
|
- Long aLong = carOaiLimit(view.getCarId(), false);
|
|
|
|
|
|
|
+ Long aLong = view.getClearsIn();
|
|
|
if (aLong != 0L) {
|
|
if (aLong != 0L) {
|
|
|
view.setStatus("停运");
|
|
view.setStatus("停运");
|
|
|
view.setExpTime(new DateTime(System.currentTimeMillis() + aLong * 1000));
|
|
view.setExpTime(new DateTime(System.currentTimeMillis() + aLong * 1000));
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
- int use = getCarConversationCount(view.getCarId(), 3L).intValue();
|
|
|
|
|
- view.setUse(use);
|
|
|
|
|
- view.setScore(Math.min(view.getScore(), 200));
|
|
|
|
|
|
|
+ view.setScore(Math.min(BigDecimal.valueOf(view.getScore()).multiply(BigDecimal.valueOf(0.5)).setScale(0, RoundingMode.DOWN).doubleValue(), 200));
|
|
|
return view;
|
|
return view;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -875,83 +584,6 @@ public class ChatGptAccountServiceImpl implements ChatGptAccountService {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- @Override
|
|
|
|
|
- public void genTitleSync(String conversationId, String carid, String userToken) {
|
|
|
|
|
- //同步对话
|
|
|
|
|
- if (!StringUtils.isAnyBlank(conversationId, carid, userToken)) {
|
|
|
|
|
- ChatgptUserConversationRecord chatgptUserConversationRecord = chatgptUserConversationRecordMapper.selectOne(Wrappers.lambdaQuery(ChatgptUserConversationRecord.class)
|
|
|
|
|
- .isNull(ChatgptUserConversationRecord::getConversationId)
|
|
|
|
|
- .eq(ChatgptUserConversationRecord::getCarId, carid)
|
|
|
|
|
- .eq(ChatgptUserConversationRecord::getUserToken, userToken)
|
|
|
|
|
- .orderByDesc(ChatgptUserConversationRecord::getId)
|
|
|
|
|
- .last(" limit 1"));
|
|
|
|
|
- if (chatgptUserConversationRecord != null) {
|
|
|
|
|
- chatgptUserConversationRecord.setConversationId(conversationId);
|
|
|
|
|
- chatgptUserConversationRecordMapper.updateById(chatgptUserConversationRecord);
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- @Override
|
|
|
|
|
- public void carLimited(String carId, String userToken, Long expTime, Boolean isTeam) {
|
|
|
|
|
- if (carId == null) {
|
|
|
|
|
- if (StringUtils.isNotBlank(userToken)) {
|
|
|
|
|
- ChatgptUser chatgptUser = chatgptUserMapper.selectOne(Wrappers.lambdaQuery(ChatgptUser.class).eq(ChatgptUser::getUserToken, userToken));
|
|
|
|
|
- if (chatgptUser != null && chatgptUser.getSessionId() != null) {
|
|
|
|
|
- ChatgptSession chatgptSession = chatgptSessionMapper.selectById(chatgptUser.getSessionId());
|
|
|
|
|
- if (chatgptSession != null) {
|
|
|
|
|
- carId = chatgptSession.getCarId();
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- if(isTeam){
|
|
|
|
|
- redisService.set("chatgpt:team:clears_in:" + carId, expTime, expTime);
|
|
|
|
|
- }else {
|
|
|
|
|
- redisService.set("chatgpt:clears_in:" + carId, expTime, expTime);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
- try {
|
|
|
|
|
- //记录用户触发限制
|
|
|
|
|
- ChatgptUserCarUsedRecord chatgptUserCarUsedRecord = new ChatgptUserCarUsedRecord();
|
|
|
|
|
- chatgptUserCarUsedRecord.setUserToken(userToken);
|
|
|
|
|
- chatgptUserCarUsedRecord.setCarId(carId);
|
|
|
|
|
-
|
|
|
|
|
- String highCarChatKey = RedisService.key.CHATGPT_CAR_HIGH_CHAT.getName() + carId;
|
|
|
|
|
- String lowCarChatKey = RedisService.key.CHATGPT_CAR_LOW_CHAT.getName() + carId;
|
|
|
|
|
-
|
|
|
|
|
- Long highCarChatNum = redisService.zCard(highCarChatKey);
|
|
|
|
|
- if (highCarChatNum != null) {
|
|
|
|
|
- chatgptUserCarUsedRecord.setGptFour(Integer.parseInt(highCarChatNum.toString()));
|
|
|
|
|
- }
|
|
|
|
|
- Long lowCarChatNum = redisService.zCard(lowCarChatKey);
|
|
|
|
|
- if (lowCarChatNum != null) {
|
|
|
|
|
- chatgptUserCarUsedRecord.setGpt(Integer.parseInt(lowCarChatNum.toString()));
|
|
|
|
|
- }
|
|
|
|
|
- chatgptUserCarUsedRecordMapper.insert(chatgptUserCarUsedRecord);
|
|
|
|
|
- log.info("记录userToken:{}访问对应镜像车队carId:{}操作成功", userToken, carId);
|
|
|
|
|
- } catch (Exception e) {
|
|
|
|
|
- log.info("记录userToken:{}访问对应镜像车队carId:{}操作失败e:{}", userToken, carId, StringUtil.getErrorText(e));
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- @PostConstruct
|
|
|
|
|
- public void init() {
|
|
|
|
|
- //如果存在未存在redis中的车辆则同步进 chatgpt:car:scores
|
|
|
|
|
- TASK_EXECUTOR.execute(() -> {
|
|
|
|
|
- Set<ZSetOperations.TypedTuple<Object>> lowestScorecarIds = redisService.zRangeWithScores(RedisService.key.CHATGPT_CAR_SCORES.getName(), 0L, -1);
|
|
|
|
|
- List<Object> collect = lowestScorecarIds.stream().map(ZSetOperations.TypedTuple::getValue).collect(Collectors.toList());
|
|
|
|
|
- List<ChatgptSession> chatgptSessions = chatgptSessionMapper.selectList(Wrappers.lambdaQuery(ChatgptSession.class).notIn(collect.size() > 0, ChatgptSession::getCarId, collect).eq(ChatgptSession::getIsPlus, 1).eq(ChatgptSession::getIsCar, true));
|
|
|
|
|
- chatgptSessions.forEach((chatgptSession) -> {
|
|
|
|
|
- if (!redisService.checkValueExistsInZSet(RedisService.key.CHATGPT_CAR_SCORES.getName(), chatgptSession.getCarId())) {
|
|
|
|
|
- redisService.zAdd(RedisService.key.CHATGPT_CAR_SCORES.getName(), 0, chatgptSession.getCarId());
|
|
|
|
|
- }
|
|
|
|
|
- });
|
|
|
|
|
- });
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
public String getGptDomain(String domain, GoodsDonSku goodsDonSku) {
|
|
public String getGptDomain(String domain, GoodsDonSku goodsDonSku) {
|
|
|
String DOMAIN = domain;
|
|
String DOMAIN = domain;
|
|
|
if (StrUtil.isEmpty(DOMAIN)) {
|
|
if (StrUtil.isEmpty(DOMAIN)) {
|