!24 优化ai消息的校验

Merge pull request !24 from Dawn/dev
This commit is contained in:
Dawn
2025-05-16 02:50:46 +00:00
committed by Gitee
13 changed files with 91 additions and 22 deletions

View File

@@ -127,11 +127,15 @@ Thanks to the following sponsors for their support!
| Date | Sponsor | Amount | Platform |
|------|---------|---------|----------|
| 2025-04-25 | 上官俊斌 | ¥200 | 微信赞赏码 |
| 2025-04-20 | 姜兴(Simon) | ¥188 | 微信赞赏码 |
| 2025-02-17 | 禾硕 | ¥168 | 支付宝赞赏 |
| 2025-02-8 | Boom.... | ¥100 | 微信赞赏码 |
| 2025-05-09 | 犹豫,就会败北。| ¥88.00 | 微信红包 |
| 2025-04-01 | 墨 | ¥88.88 | 微信转账 |
| 2025-02-8 | 邓伟 | ¥88 | 微信赞赏码 |
| 2025-02-7 | dennis | ¥80 | gitee码云赞赏 |
| 2025-05-15 | 孤鸿影 | ¥56 | 微信红包 |
| 2025-02-6 | 小二 | ¥62 | 微信转账 |
> Note: This list is manually updated. If you have sponsored but are not shown in the list, please contact us through:

View File

@@ -128,12 +128,16 @@ HuLa-Server 是一款基于 SpringBoot3、Netty、MyBatis-Plus 和 RocketMQ 构
| 日期 | 赞助者 | 金额 | 平台 |
|------------|---------|--------|------|
| 2025-02-17 | 禾硕 | ¥168 | 支付宝赞赏 |
| 2025-02-8 | Boom.... | ¥100 | 微信赞赏码 |
| 2025-04-25 | 上官俊斌 | ¥200 | 微信赞赏 |
| 2025-04-20 | 姜兴(Simon) | ¥188 | 微信赞赏码 |
| 2025-02-17 | 禾硕 | ¥168 | 支付宝赞赏 |
| 2025-02-8 | Boom.... | ¥100 | 微信赞赏码 |
| 2025-05-09 | 犹豫,就会败北。| ¥88.00 | 微信红包 |
| 2025-04-01 | 墨 | ¥88.88 | 微信转账 |
| 2025-02-8 | 邓伟 | ¥88 | 微信赞赏码 |
| 2025-02-7 | dennis | ¥80 | gitee码云赞赏 |
| 2025-02-6 | 小二 | ¥62 | 微信转账 |
| 2025-02-8 | 邓伟 | ¥88 | 微信赞赏码 |
| 2025-02-7 | dennis | ¥80 | gitee码云赞赏 |
| 2025-05-15 | 孤鸿影 | ¥56 | 微信红包 |
| 2025-02-6 | 小二 | ¥62 | 微信转账 |
> 注:该名单为手动更新。如果您已赞助但未显示在列表中,请通过以下方式联系我们:
1. 在GitHub上提交Issue

View File

@@ -1,13 +1,13 @@
package com.hula.utils;
import cn.hutool.extra.spring.SpringUtil;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.Cursor;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisConnectionUtils;
import org.springframework.data.redis.core.ScanOptions;
import org.springframework.data.redis.core.StringRedisTemplate;
@@ -274,7 +274,51 @@ public class RedisUtils {
return list.stream().map(o -> toBeanOrNull(o, tClass)).collect(Collectors.toList());
}
static <T> T toBeanOrNull(String json, Class<T> tClass) {
/**
* 查询key下面的所有key值
* @param keyPattern
* @return
*/
public static List<String> multiGet(String keyPattern) {
Set<String> keys = stringRedisTemplate.execute((RedisCallback<Set<String>>) connection -> {
Set<String> result = new HashSet<>();
Cursor<byte[]> cursor = connection.scan(ScanOptions.scanOptions().match(keyPattern).count(100).build());
while (cursor.hasNext()) {
result.add(new String(cursor.next()));
}
return result;
});
return stringRedisTemplate.opsForValue().multiGet(keys);
}
/**
* 匹配所有key并删除
* @param keyPattern
*/
public static void multiDelete(String keyPattern) {
// 1. 使用SCAN获取所有匹配的键
Set<String> keys = stringRedisTemplate.execute((RedisCallback<Set<String>>) connection -> {
Set<String> result = new HashSet<>();
Cursor<byte[]> cursor = connection.scan(
ScanOptions.scanOptions()
.match(keyPattern)
.count(100)
.build()
);
while (cursor.hasNext()) {
result.add(new String(cursor.next()));
}
return result;
});
// 2. 批量删除所有键
if (keys != null && !keys.isEmpty()) {
stringRedisTemplate.delete(keys);
}
}
static <T> T toBeanOrNull(String json, Class<T> tClass) {
return json == null ? null : JsonUtils.toObj(json, tClass);
}
@@ -285,9 +329,7 @@ public class RedisUtils {
public static <T> void multiSet(Map<String, T> map, long time) {
Map<String, String> collect = map.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, (e) -> objToStr(e.getValue())));
stringRedisTemplate.opsForValue().multiSet(collect);
map.forEach((key, value) -> {
expire(key, time);
});
map.forEach((key, value) -> expire(key, time));
}

View File

@@ -108,6 +108,7 @@ public class ChatServiceImpl extends ServiceImpl<ChatMapper, Chat> implements IC
chat.setUid(command.getUid());
chat.setCreatedBy(command.getUid());
chat.setCreatedTime(LocalDateTime.now());
chat.setId(null);
chatMapper.insert(chat);
return ChatVO.builder().chatNumber(chat.getChatNumber()).prompt(command.getPrompt()).build();
}

View File

@@ -21,6 +21,7 @@ import com.hula.ai.gpt.pojo.entity.Assistant;
import com.hula.ai.gpt.pojo.vo.ChatVO;
import com.hula.ai.gpt.service.IChatMessageService;
import com.hula.ai.gpt.service.IChatService;
import com.hula.core.user.domain.entity.User;
import com.hula.core.user.domain.vo.resp.user.UserInfoResp;
import com.hula.core.user.service.ConfigService;
import com.hula.core.user.service.UserService;
@@ -160,7 +161,7 @@ public class GptServiceImpl implements GptService {
* @param command
*/
private void validateUser(ChatCommand command) {
UserInfoResp user = userService.getUserInfo(command.getUid());
User user = userService.getUserById(command.getUid());
if (ObjectUtil.isNull(user)) {
throw new BizException("用户不存在!");
}

View File

@@ -90,9 +90,7 @@ public class TongYiServiceImpl implements ModelService {
throw new BizException("未加载到密钥信息");
}
MessageManager msgManager = new MessageManager(20);
chatMessages.stream().forEach(v -> {
msgManager.add(Message.builder().role(v.getRole()).content(v.getContent()).build());
});
chatMessages.stream().forEach(v -> msgManager.add(Message.builder().role(v.getRole()).content(v.getContent()).build()));
Generation gen = new Generation();
QwenParam param = QwenParam.builder().apiKey(tongYiClient.getAppKey())
.model(ObjectUtil.isNotNull(version) ? version : Generation.Models.QWEN_TURBO)

View File

@@ -71,6 +71,11 @@ public class RedisKey {
*/
public static final String GROUP_ANNOUNCEMENTS_FORMAT = "groupInfo:announcements_%d";
/**
* 用户token存放 格式:终端:uid
*/
public static final String USER_TOKEN_UID_FORMAT = "userToken:%s:uid_%d";
/**
* 用户token存放 格式:终端:uid:uuid
*/

View File

@@ -24,5 +24,5 @@ public class UploadUrlReq extends BaseEntity {
private String fileName;
@ApiModelProperty(value = "上传场景chat.聊天室,emoji.表情包,avatar.头像")
@NotNull
private Integer scene;
private String scene;
}

View File

@@ -21,7 +21,7 @@ import java.util.List;
@NoArgsConstructor
public class SummeryInfoReq extends BaseEntity {
@ApiModelProperty(value = "用户信息入参")
@Size(max = 50)
@Size(max = 50, message = "一次最多查询50个用户数据")
private List<infoReq> reqList;
@Data

View File

@@ -2,6 +2,7 @@ package com.hula.core.user.service;
import com.hula.core.user.domain.dto.ItemInfoDTO;
import com.hula.core.user.domain.dto.SummeryInfoDTO;
import com.hula.core.user.domain.entity.User;
import com.hula.core.user.domain.vo.req.user.*;
import com.hula.core.user.domain.vo.resp.user.BadgeResp;
import com.hula.core.user.domain.vo.resp.user.UserInfoResp;
@@ -17,6 +18,13 @@ import java.util.List;
*/
public interface UserService {
/**
* 获取用户基础信息 [DB]
*
* @param uid
*
*/
User getUserById(Long uid);
/**
* 获取前端展示信息

View File

@@ -215,7 +215,7 @@ public class FriendServiceImpl implements FriendService {
AssertUtil.equal(userApply.getStatus(), WAIT_APPROVAL.getCode(), "已同意好友申请");
// 同意申请
userApplyDao.agree(request.getApplyId());
//创建双方好友关系
// 创建双方好友关系
createFriend(uid, userApply.getUid());
// 创建一个聊天房间
RoomFriend roomFriend = roomService.createFriendRoom(Arrays.asList(uid, userApply.getUid()));

View File

@@ -1,5 +1,6 @@
package com.hula.core.user.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.StrUtil;
import com.auth0.jwt.interfaces.Claim;
@@ -55,17 +56,17 @@ public class TokenServiceImpl implements TokenService {
String uuid = UUID.randomUUID().toString(true);
String tokenKey = RedisKey.getKey(RedisKey.USER_TOKEN_FORMAT, loginType, uid, uuid);
String refreshTokenKey = RedisKey.getKey(RedisKey.USER_REFRESH_TOKEN_FORMAT, loginType, uid, uuid);
String token = RedisUtils.getStr(tokenKey), refreshToken;
String key = RedisKey.getKey(RedisKey.USER_REFRESH_TOKEN_UID_FORMAT, loginType, uid);
RedisUtils.del(tokenKey, key);
String key = RedisKey.getKey(RedisKey.USER_REFRESH_TOKEN_UID_FORMAT, loginType, uid) + "*";
RedisUtils.multiDelete(RedisKey.getKey(RedisKey.USER_TOKEN_UID_FORMAT, loginType, uid) + "*");
// 1.2 token存在 旧设备下线
if (StrUtil.isNotBlank(token)) {
if (CollUtil.isNotEmpty(RedisUtils.multiGet(key))) {
RedisUtils.multiDelete(key);
applicationEventPublisher.publishEvent(new TokenExpireEvent(this, new OffLineResp(uid, loginType, RequestHolder.get().getIp(), uuid)));
}
// 2. 创建用户token
token = JwtUtils.createToken(uid, loginType, uuid, TOKEN_EXPIRE_DAYS);
String token = JwtUtils.createToken(uid, loginType, uuid, TOKEN_EXPIRE_DAYS), refreshToken;
refreshToken = JwtUtils.createToken(uid, loginType, uuid, TOKEN_RENEWAL_DAYS);
// 3. 刷新存放时间

View File

@@ -58,6 +58,11 @@ public class UserServiceImpl implements UserService {
private UserSummaryCache userSummaryCache;
private SensitiveWordBs sensitiveWordBs;
@Override
public User getUserById(Long uid) {
return userDao.getById(uid);
}
@Override
public UserInfoResp getUserInfo(Long uid) {
User userInfo = userCache.getUserInfo(uid);