!27 fix: 文件消息类型回显时新增空格

Merge pull request !27 from Dawn/dev
This commit is contained in:
Dawn
2025-07-04 12:57:06 +00:00
committed by Gitee
14 changed files with 148 additions and 58 deletions

View File

@@ -9,7 +9,6 @@ import com.hula.core.chat.domain.vo.request.contact.ContactNotificationReq;
import com.hula.core.chat.domain.vo.request.contact.ContactShieldReq;
import com.hula.core.chat.domain.vo.request.contact.ContactTopReq;
import com.hula.core.chat.domain.vo.response.ChatRoomResp;
import com.hula.core.chat.service.ChatService;
import com.hula.core.chat.service.RoomAppService;
import com.hula.domain.vo.res.ApiResult;
import com.hula.utils.RequestHolder;
@@ -33,8 +32,6 @@ import org.springframework.web.bind.annotation.RestController;
@Tag(name = "聊天室相关接口")
@Slf4j
public class ContactController {
@Resource
private ChatService chatService;
@Resource
private RoomAppService roomService;

View File

@@ -16,6 +16,7 @@ import jakarta.annotation.Resource;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@@ -52,13 +53,11 @@ public class GroupMemberDao extends ServiceImpl<GroupMemberMapper, GroupMember>
return wrapper.list().stream().map(GroupMember::getUid).collect(Collectors.toList());
}
public List<Long> getMemberBatch(Long groupId, List<Long> uidList) {
List<GroupMember> list = lambdaQuery()
public List<GroupMember> getMemberBatch(Long groupId, Collection<Long> uidList) {
return lambdaQuery()
.eq(GroupMember::getGroupId, groupId)
.in(GroupMember::getUid, uidList)
.select(GroupMember::getUid)
.list();
return list.stream().map(GroupMember::getUid).collect(Collectors.toList());
}
/**

View File

@@ -29,6 +29,7 @@ public class ChatMessageResp extends BaseEntity {
public static class UserInfo {
@Schema(description ="用户id")
private String uid;
private String nickname;
}
@Data

View File

@@ -1,6 +1,7 @@
package com.hula.core.chat.service.adapter;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import com.hula.common.enums.YesOrNoEnum;
import com.hula.core.chat.domain.entity.Announcements;
import com.hula.core.chat.domain.entity.Message;
@@ -34,6 +35,8 @@ public class MessageAdapter {
.roomId(request.getRoomId())
.type(request.getMsgType())
.status(MessageStatusEnum.NORMAL.getStatus())
.createTime(DateUtil.date())
.updateTime(DateUtil.date())
.build();
}

View File

@@ -16,6 +16,7 @@ import com.hula.core.chat.domain.dto.MsgReadInfoDTO;
import com.hula.core.chat.domain.entity.*;
import com.hula.core.chat.domain.enums.MessageMarkActTypeEnum;
import com.hula.core.chat.domain.enums.MessageTypeEnum;
import com.hula.core.chat.domain.enums.RoomTypeEnum;
import com.hula.core.chat.domain.vo.request.*;
import com.hula.core.chat.domain.vo.request.member.MemberReq;
import com.hula.core.chat.domain.vo.response.ChatMemberListResp;
@@ -36,7 +37,9 @@ import com.hula.core.chat.service.strategy.msg.AbstractMsgHandler;
import com.hula.core.chat.service.strategy.msg.MsgHandlerFactory;
import com.hula.core.chat.service.strategy.msg.RecallMsgHandler;
import com.hula.core.user.dao.UserDao;
import com.hula.core.user.dao.UserFriendDao;
import com.hula.core.user.domain.entity.User;
import com.hula.core.user.domain.entity.UserFriend;
import com.hula.core.user.domain.enums.ChatActiveStatusEnum;
import com.hula.core.user.domain.enums.RoleTypeEnum;
import com.hula.core.user.domain.vo.resp.ws.ChatMemberResp;
@@ -47,6 +50,7 @@ import com.hula.utils.AssertUtil;
import jakarta.annotation.Nullable;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.context.ApplicationEventPublisher;
@@ -55,6 +59,7 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import static com.hula.common.config.ThreadPoolConfig.HULA_EXECUTOR;
@@ -70,6 +75,9 @@ import static com.hula.common.config.ThreadPoolConfig.HULA_EXECUTOR;
@AllArgsConstructor
public class ChatServiceImpl implements ChatService {
public static final long ROOM_GROUP_ID = 1L;
private final RoomDao roomDao;
private final UserFriendDao userFriendDao;
private final RoomGroupDao roomGroupDao;
private MessageDao messageDao;
private UserDao userDao;
@@ -91,7 +99,7 @@ public class ChatServiceImpl implements ChatService {
@Override
@Transactional
public Long sendMsg(ChatMessageReq request, Long uid) {
check(request.getSkip(), request.getRoomId(), uid);
check(request.getSkip(), request.getRoomId(), uid);
AbstractMsgHandler<?> msgHandler = MsgHandlerFactory.getStrategyNoNull(request.getMsgType());
Long msgId = msgHandler.checkAndSaveMsg(request, uid);
// 发布消息发送事件
@@ -99,37 +107,37 @@ public class ChatServiceImpl implements ChatService {
return msgId;
}
private void checkDeFriend(Long roomId, Long uid) {
Room room = roomCache.get(roomId);
Assert.notNull(room, "房间不存在!");
if (room.isRoomGroup()) {
RoomGroup roomGroup = roomGroupCache.get(roomId);
GroupMember member = groupMemberDao.getMember(roomGroup.getId(), uid);
Assert.notNull(member, "您已经被移除该群");
Assert.isFalse(member.getDeFriend(), "您已经屏蔽群聊!");
} else {
RoomFriend roomFriend = roomFriendDao.getByRoomId(roomId);
boolean u1State = uid.equals(roomFriend.getUid1());
boolean u2State = uid.equals(roomFriend.getUid2());
private void checkDeFriend(Long roomId, Long uid) {
Room room = roomCache.get(roomId);
Assert.notNull(room, "房间不存在!");
if (room.isRoomGroup()) {
RoomGroup roomGroup = roomGroupCache.get(roomId);
GroupMember member = groupMemberDao.getMember(roomGroup.getId(), uid);
Assert.notNull(member, "您已经被移除该群");
Assert.isFalse(member.getDeFriend(), "您已经屏蔽群聊!");
} else {
RoomFriend roomFriend = roomFriendDao.getByRoomId(roomId);
boolean u1State = uid.equals(roomFriend.getUid1());
boolean u2State = uid.equals(roomFriend.getUid2());
if (roomFriend.getDeFriend1() && u1State || roomFriend.getDeFriend2() && u2State){
throw new BizException("已屏蔽对方!");
}
if (roomFriend.getDeFriend1() && u1State || roomFriend.getDeFriend2() && u2State) {
throw new BizException("已屏蔽对方!");
}
Assert.isTrue(u1State || u2State, "消息已发送, 但对方拒收了");
}
}
Assert.isTrue(u1State || u2State, "消息已发送, 但对方拒收了");
}
}
private void check(Boolean skip, Long roomId, Long uid) {
if(skip){
return;
}
checkDeFriend(roomId, uid);
if (skip) {
return;
}
checkDeFriend(roomId, uid);
}
@Override
public ChatMessageResp getMsgResp(Message message, Long receiveUid) {
return CollUtil.getFirst(getMsgRespBatch(Collections.singletonList(message), receiveUid));
return CollUtil.getFirst(getMsgRespBatch(message.getRoomId(), Collections.singletonList(message), receiveUid));
}
@Override
@@ -181,15 +189,16 @@ public class ChatServiceImpl implements ChatService {
@Override
public CursorPageBaseResp<ChatMessageResp> getMsgPage(ChatMessagePageReq request, Long receiveUid) {
// 1. 用最后一条消息id来限制被踢出的人能看见的最大一条消息
// 1. 用最后一条消息id来限制被踢出的人能看见的最大一条消息
Long lastMsgId = getLastMsgId(request.getRoomId(), receiveUid);
// 2. 判断我屏蔽会话没有权限
check(request.getSkip(), request.getRoomId(), receiveUid);
// 2. 判断我屏蔽会话没有权限
check(request.getSkip(), request.getRoomId(), receiveUid);
CursorPageBaseResp<Message> cursorPage = messageDao.getCursorPage(request.getRoomId(), request, lastMsgId);
if (cursorPage.isEmpty()) {
return CursorPageBaseResp.empty();
}
return CursorPageBaseResp.init(cursorPage, getMsgRespBatch(cursorPage.getList(), receiveUid), cursorPage.getTotal());
return CursorPageBaseResp.init(cursorPage, getMsgRespBatch(request.getRoomId(), cursorPage.getList(), receiveUid), cursorPage.getTotal());
}
private Long getLastMsgId(Long roomId, Long receiveUid) {
@@ -289,17 +298,17 @@ public class ChatServiceImpl implements ChatService {
update.setReadTime(new Date());
contactDao.updateById(update);
} else {
log.error("uid --> ", uid, "roomId --> ", request.getRoomId());
log.error("uid --> ", uid, "roomId --> ", request.getRoomId());
// contactDao.save(uid, request.getRoomId());
}
}
@Override
public List<Message> getMsgByIds(List<Long> msgIds) {
return messageDao.listByIds(msgIds);
}
@Override
public List<Message> getMsgByIds(List<Long> msgIds) {
return messageDao.listByIds(msgIds);
}
private void checkRecall(Long uid, Message message) {
private void checkRecall(Long uid, Message message) {
AssertUtil.isNotEmpty(message, "消息有误");
AssertUtil.notEqual(message.getType(), MessageTypeEnum.RECALL.getType(), "消息无法撤回");
boolean isChatManager = roleService.hasRole(uid, RoleTypeEnum.CHAT_MANAGER);
@@ -312,13 +321,50 @@ public class ChatServiceImpl implements ChatService {
AssertUtil.isTrue(between < 2, "超过2分钟的消息不能撤回");
}
public List<ChatMessageResp> getMsgRespBatch(List<Message> messages, Long receiveUid) {
public List<ChatMessageResp> getMsgRespBatch(Long roomId, List<Message> messages, Long receiveUid) {
if (CollectionUtil.isEmpty(messages)) {
return new ArrayList<>();
}
// 查询消息标志
List<MessageMark> msgMark = messageMarkDao.getValidMarkByMsgIdBatch(messages.stream().map(Message::getId).collect(Collectors.toList()));
return MessageAdapter.buildMsgResp(messages, msgMark, receiveUid);
List<ChatMessageResp> chatMessageResp = MessageAdapter.buildMsgResp(messages, msgMark, receiveUid);
Room room = roomDao.getById(roomId);
// 如果是群聊,设置消息的发送人的名称显示
if (Objects.equals(room.getType(), RoomTypeEnum.GROUP.getType())) {
Set<Long> uidSet = messages.stream().map(Message::getFromUid).collect(Collectors.toSet());
RoomGroup roomGroup = roomGroupDao.getByRoomId(roomId);
Map<Long, GroupMember> groupMemberMap = groupMemberDao.getMemberBatch(roomGroup.getId(), uidSet).stream().collect(Collectors.toMap(GroupMember::getUid, Function.identity()));
Map<Long, User> userMap = userDao.getByIds(uidSet).stream().collect(Collectors.toMap(User::getId, Function.identity()));
Map<Long, String> userFriendMapByFriendUid = userFriendDao.getByFriends(receiveUid, uidSet)
.stream()
.filter(item -> item.getDeleteStatus() == 0 && StringUtils.isNotEmpty(item.getRemark()))
.collect(Collectors.toMap(UserFriend::getFriendUid, UserFriend::getRemark));
// 设置 user 名称
chatMessageResp.forEach(item -> {
ChatMessageResp.UserInfo fromUser = item.getFromUser();
long uid = Long.parseLong(fromUser.getUid());
GroupMember groupMember = groupMemberMap.get(uid);
String friendRemark = userFriendMapByFriendUid.get(uid);
// 优先显示好友备注
if (StringUtils.isNotEmpty(friendRemark)){
fromUser.setNickname(friendRemark);
}
else if (groupMember != null){
String myName = groupMember.getMyName();
if (StringUtils.isNotEmpty(myName)){
fromUser.setNickname(myName);
}else {
User user = userMap.get(uid);
fromUser.setNickname(user.getName());
}
}
});
}
return chatMessageResp;
}
}

View File

@@ -14,6 +14,7 @@ import com.hula.common.event.GroupMemberAddEvent;
import com.hula.core.chat.dao.ContactDao;
import com.hula.core.chat.dao.GroupMemberDao;
import com.hula.core.chat.dao.MessageDao;
import com.hula.core.chat.dao.RoomGroupDao;
import com.hula.core.chat.domain.dto.RoomBaseInfo;
import com.hula.core.chat.domain.entity.*;
import com.hula.core.chat.domain.entity.msg.MergeMsg;
@@ -43,8 +44,10 @@ import com.hula.core.chat.service.adapter.RoomAdapter;
import com.hula.core.chat.service.cache.*;
import com.hula.core.chat.service.strategy.msg.AbstractMsgHandler;
import com.hula.core.chat.service.strategy.msg.MsgHandlerFactory;
import com.hula.core.user.dao.UserBackpackDao;
import com.hula.core.user.dao.UserDao;
import com.hula.core.user.domain.entity.User;
import com.hula.core.user.domain.entity.UserBackpack;
import com.hula.core.user.domain.enums.RoleTypeEnum;
import com.hula.core.user.domain.enums.WsBaseResp;
import com.hula.core.user.domain.vo.req.MergeMessageReq;
@@ -77,8 +80,10 @@ import java.util.stream.Collectors;
@Service
@AllArgsConstructor
public class RoomAppServiceImpl implements RoomAppService {
private ContactDao contactDao;
private final UserBackpackDao userBackpackDao;
private final RoomGroupDao roomGroupDao;
private ContactDao contactDao;
private RoomCache roomCache;
private RoomGroupCache roomGroupCache;
private RoomFriendCache roomFriendCache;
@@ -374,7 +379,9 @@ public class RoomAppServiceImpl implements RoomAppService {
RoomGroup roomGroup = roomGroupCache.get(resp.getRoomId());
GroupMember groupMember = verifyGroupPermissions(uid, roomGroup);
if(GroupRoleEnum.MEMBER.getType().equals(groupMember.getRole())) {
long count = userBackpackDao.countByUidAndItemId(uid, "HuLa项目贡献者专属徽章");
if(count == 0 && GroupRoleEnum.MEMBER.getType().equals(groupMember.getRole())) {
return false;
}
@@ -572,8 +579,8 @@ public class RoomAppServiceImpl implements RoomAppService {
AssertUtil.isNotEmpty(roomGroup, "房间号有误");
GroupMember self = groupMemberDao.getMember(roomGroup.getId(), uid);
AssertUtil.isNotEmpty(self, "您不是群成员");
List<Long> memberBatch = groupMemberDao.getMemberBatch(roomGroup.getId(), request.getUidList());
Set<Long> existUid = new HashSet<>(memberBatch);
List<Long> memberBatch = groupMemberDao.getMemberBatch(roomGroup.getId(), request.getUidList()).stream().map(GroupMember::getUid).toList();
Set<Long> existUid = new HashSet<>(memberBatch);
List<Long> waitAddUidList = request.getUidList().stream().filter(a -> !existUid.contains(a)).distinct().collect(Collectors.toList());
if (CollectionUtils.isEmpty(waitAddUidList)) {
return;
@@ -673,7 +680,9 @@ public class RoomAppServiceImpl implements RoomAppService {
Map<Long, User> lastMsgUidMap = userInfoCache.getBatch(messages.stream().map(Message::getFromUid).collect(Collectors.toList()));
// 消息未读数
Map<Long, Integer> unReadCountMap = getUnReadCountMap(uid, roomIds);
return roomBaseInfoMap.values().stream().map(room -> {
Map<Long, RoomGroup> roomGroupMapByRoomId = roomGroupDao.listByRoomIds(roomIds).stream().collect(Collectors.toMap(RoomGroup::getRoomId, Function.identity()));
return roomBaseInfoMap.values().stream().map(room -> {
ChatRoomResp resp = new ChatRoomResp();
Long roomId = room.getRoomId();
RoomBaseInfo roomBaseInfo = roomBaseInfoMap.get(roomId);
@@ -705,8 +714,14 @@ public class RoomAppServiceImpl implements RoomAppService {
AbstractMsgHandler strategyNoNull = MsgHandlerFactory.getStrategyNoNull(message.getType());
// 判断是群聊还是单聊
if (Objects.equals(roomBaseInfo.getType(), RoomTypeEnum.GROUP.getType())) {
GroupMember messageUser = groupMemberCache.getMemberDetail(roomBaseInfo.getRoomId(), message.getFromUid());
resp.setText(ObjectUtil.isNotNull(messageUser) && StrUtil.isNotEmpty(messageUser.getMyName())? messageUser.getMyName(): (lastMsgUidMap.get(message.getFromUid()).getName()) + ":" + strategyNoNull.showContactMsg(message));
RoomGroup roomGroup = roomGroupMapByRoomId.get(roomId);
GroupMember messageUser = groupMemberCache.getMemberDetail(roomGroup.getId(), message.getFromUid());
if (ObjectUtil.isNotNull(messageUser) && StrUtil.isNotEmpty(messageUser.getMyName())){
resp.setText(messageUser.getMyName() + ":" + strategyNoNull.showContactMsg(message));
}else {
resp.setText((lastMsgUidMap.get(message.getFromUid()).getName()) + ":" + strategyNoNull.showContactMsg(message));
}
} else {
resp.setText(strategyNoNull.showContactMsg(message));
}

View File

@@ -50,6 +50,6 @@ public class FileMsgHandler extends AbstractMsgHandler<FileMsgDTO> {
@Override
public String showContactMsg(Message msg) {
return "[文件]" + msg.getExtra().getFileMsg().getFileName();
return "[文件] " + msg.getExtra().getFileMsg().getFileName();
}
}

View File

@@ -1,5 +1,6 @@
package com.hula.core.user.dao;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hula.core.user.domain.entity.ItemConfig;
import com.hula.core.user.mapper.ItemConfigMapper;
@@ -22,4 +23,9 @@ public class ItemConfigDao extends ServiceImpl<ItemConfigMapper, ItemConfig> {
.eq(ItemConfig::getType, type)
.list();
}
public ItemConfig getByDesc(String desc) {
return baseMapper.selectOne(new LambdaQueryWrapper<ItemConfig>()
.eq(ItemConfig::getDescribe, desc));
}
}

View File

@@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hula.common.enums.YesOrNoEnum;
import com.hula.core.user.domain.entity.ItemConfig;
import com.hula.core.user.domain.entity.UserBackpack;
import com.hula.core.user.mapper.UserBackpackMapper;
import org.springframework.stereotype.Service;
@@ -20,6 +21,12 @@ import java.util.List;
@Service
public class UserBackpackDao extends ServiceImpl<UserBackpackMapper, UserBackpack> {
private final ItemConfigDao itemConfigDao;
public UserBackpackDao(ItemConfigDao itemConfigDao) {
this.itemConfigDao = itemConfigDao;
}
public Integer getCountByValidItemId(Long uid, Long itemId) {
return Math.toIntExact(lambdaQuery().eq(UserBackpack::getUid, uid)
.eq(UserBackpack::getItemId, itemId)
@@ -60,4 +67,12 @@ public class UserBackpackDao extends ServiceImpl<UserBackpackMapper, UserBackpac
public UserBackpack getByIdp(String idempotent) {
return lambdaQuery().eq(UserBackpack::getIdempotent, idempotent).one();
}
public long countByUidAndItemId(Long uid, String desc) {
ItemConfig itemConfig = itemConfigDao.getByDesc(desc);
return baseMapper.selectCount(new LambdaQueryWrapper<UserBackpack>()
.eq(UserBackpack::getUid, uid)
.eq(UserBackpack::getItemId, itemConfig.getId())
);
}
}

View File

@@ -16,6 +16,7 @@ import com.hula.core.user.mapper.UserMapper;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Set;
/**
* <p>
@@ -104,4 +105,8 @@ public class UserDao extends ServiceImpl<UserMapper, User> {
}
return baseMapper.selectCount(wrapper) > 0;
}
public List<User> getByIds(Set<Long> uidSet) {
return baseMapper.selectBatchIds(uidSet);
}
}

View File

@@ -12,6 +12,7 @@ import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
@@ -24,7 +25,7 @@ import java.util.stream.Collectors;
*/
@Service
public class UserFriendDao extends ServiceImpl<UserFriendMapper, UserFriend> {
public List<UserFriend> getByFriends(Long uid, List<Long> uidList) {
public List<UserFriend> getByFriends(Long uid, Collection<Long> uidList) {
return lambdaQuery().eq(UserFriend::getUid, uid)
.in(UserFriend::getFriendUid, uidList)
.list();

View File

@@ -1,4 +1,4 @@
version: 2.6.12
version: 2.6.13
HuLa-IM:
HOST: 127.0.0.1 #域名
MYSQL_PORT: 3306 #端口

View File

@@ -15,7 +15,7 @@
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<revision>v2.6.12</revision>
<revision>v2.6.13</revision>
<java.version>21</java.version>
<spring-boot.version>3.4.4</spring-boot.version>
<hutool.version>5.8.27</hutool.version>

View File

@@ -11,7 +11,7 @@
Target Server Version : 80031 (8.0.31)
File Encoding : 65001
Date: 27/04/2025 16:00:45
Date: 28/05/2025 14:53:35
*/
SET NAMES utf8mb4;
@@ -175,6 +175,7 @@ CREATE TABLE `ai_gpt_chat_message` (
-- Records of ai_gpt_chat_message
-- ----------------------------
INSERT INTO `ai_gpt_chat_message` VALUES (78095167005053952, 78094677378781184, 'f34e52b5-c853-4355-b70d-f0186fe2d356', '', 'LocalLM', 'chatglm3-6b', '32131', 'text', 'user', '', 1, '', 0, NULL, '', 3, '2025-03-06 10:49:40', NULL, NULL, 0);
-- ----------------------------
-- Table structure for ai_gpt_comb
-- ----------------------------
@@ -188,8 +189,8 @@ CREATE TABLE `ai_gpt_comb` (
`price` decimal(10, 2) NULL DEFAULT 0.00 COMMENT '价格',
`status` smallint NULL DEFAULT 1 COMMENT '状态 0 禁用 1 启用',
`remark` varchar(250) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT '' COMMENT '备注',
`created_by` bigint DEFAULT 0 NOT NULL COMMENT '创建者',
`created_time` datetime DEFAULT (now()) NOT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '创建时间',
`created_by` bigint NOT NULL DEFAULT 0 COMMENT '创建者',
`created_time` datetime NOT NULL DEFAULT (now()) ON UPDATE CURRENT_TIMESTAMP COMMENT '创建时间',
`updated_by` bigint NULL DEFAULT NULL COMMENT '更新者',
`updated_time` datetime NULL DEFAULT NULL COMMENT '更新时间',
`is_del` tinyint(1) NOT NULL DEFAULT 0 COMMENT '是否删除',
@@ -403,6 +404,7 @@ CREATE TABLE `black` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'id',
`type` int NOT NULL COMMENT '拉黑目标类型 1.ip 2uid',
`target` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '拉黑目标',
`deadline` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '截止时间',
`create_time` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间',
`update_time` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3) COMMENT '修改时间',
PRIMARY KEY (`id`) USING BTREE,