会话
This commit is contained in:
@@ -175,6 +175,8 @@ type UserContact struct {
|
||||
UserID string `gorm:"type:varchar(100);index;comment:用户ID" json:"user_id"`
|
||||
// 联系人ID - 好友的用户ID
|
||||
ContactID string `gorm:"type:varchar(100);index;comment:联系人ID" json:"contact_id"`
|
||||
// 房间ID - 关联的房间ID
|
||||
RoomID string `gorm:"type:varchar(100);index;comment:房间ID" json:"room_id"`
|
||||
// 备注名称 - 用户自定义的好友备注
|
||||
RemarkName string `gorm:"type:varchar(100);comment:备注名称" json:"remark_name"`
|
||||
// 分组ID - 好友所属分组
|
||||
@@ -241,8 +243,10 @@ type ChatRoom struct {
|
||||
RoomName string `gorm:"type:varchar(200);comment:房间名称" json:"room_name"`
|
||||
// 房间头像 - 群聊时显示
|
||||
RoomAvatar string `gorm:"type:varchar(500);comment:房间头像" json:"room_avatar"`
|
||||
// 成员列表 - JSON数组
|
||||
Members string `gorm:"type:text;comment:成员列表JSON" json:"members"`
|
||||
// 群主ID - 群聊必填,单聊为0
|
||||
OwnerID string `gorm:"type:varchar(100);index;default:0;comment:群主ID(群聊必填,单聊为0)" json:"owner_id"`
|
||||
// 管理员ID列表 - 逗号分隔
|
||||
AdminIDs string `gorm:"type:varchar(500);comment:管理员ID列表(逗号分隔)" json:"admin_ids"`
|
||||
// 创建者ID
|
||||
CreatorID string `gorm:"type:varchar(100);index;comment:创建者ID" json:"creator_id"`
|
||||
// 最后消息时间
|
||||
@@ -260,6 +264,25 @@ func (ChatRoom) TableName() string {
|
||||
return "chat_rooms"
|
||||
}
|
||||
|
||||
/**
|
||||
* RoomMember
|
||||
* 对应数据库表:room_members
|
||||
* 作用:房间成员表,存储房间与用户的关联关系
|
||||
*/
|
||||
type RoomMember struct {
|
||||
// 房间ID
|
||||
RoomID string `gorm:"type:varchar(100);primaryKey;comment:房间ID" json:"room_id"`
|
||||
// 用户ID
|
||||
UserID string `gorm:"type:varchar(100);primaryKey;comment:用户ID" json:"user_id"`
|
||||
// 加入时间
|
||||
JoinedAt time.Time `gorm:"type:datetime;autoCreateTime;comment:加入时间" json:"joined_at"`
|
||||
}
|
||||
|
||||
// TableName 指定表名和注释
|
||||
func (RoomMember) TableName() string {
|
||||
return "room_members"
|
||||
}
|
||||
|
||||
/**
|
||||
* FriendRequest
|
||||
* 对应数据库表:friend_requests
|
||||
@@ -416,6 +439,8 @@ type ChatConversation struct {
|
||||
CreatedAt time.Time `gorm:"autoCreateTime;comment:创建时间" json:"created_at"`
|
||||
// 更新时间
|
||||
UpdatedAt time.Time `gorm:"autoUpdateTime;comment:更新时间" json:"updated_at"`
|
||||
// 目标用户信息(关联查询,不存储在数据库中)
|
||||
TargetUser *User `gorm:"foreignKey:TargetID;references:ID" json:"target_user,omitempty"`
|
||||
}
|
||||
|
||||
// TableName 指定表名和注释
|
||||
|
||||
@@ -5,8 +5,12 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
"xk-websocket-v2/internal/model"
|
||||
"xk-websocket-v2/internal/utils"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
@@ -69,10 +73,14 @@ func (s *ContactService) AddFriend(fromUserID, toUserID, message string) error {
|
||||
/**
|
||||
* GetFriendRequests
|
||||
* 功能:获取好友申请列表
|
||||
* 包括:
|
||||
* 1. 发送给当前用户的待处理申请 (to_user_id = userID AND status = 'pending')
|
||||
* 2. 当前用户发送的被拒绝的申请 (from_user_id = userID AND status = 'rejected')
|
||||
*/
|
||||
func (s *ContactService) GetFriendRequests(userID string) ([]model.FriendRequest, error) {
|
||||
var requests []model.FriendRequest
|
||||
result := s.DB.Where("to_user_id = ? AND status = ?", userID, "pending").
|
||||
result := s.DB.Where("(to_user_id = ? AND status = ?) OR (from_user_id = ? AND status = ?)",
|
||||
userID, "pending", userID, "rejected").
|
||||
Order("created_at DESC").
|
||||
Find(&requests)
|
||||
return requests, result.Error
|
||||
@@ -96,6 +104,11 @@ func (s *ContactService) AcceptFriendRequest(requestID uint, userID string) erro
|
||||
|
||||
// 开始事务
|
||||
tx := s.DB.Begin()
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
tx.Rollback()
|
||||
}
|
||||
}()
|
||||
|
||||
// 更新申请状态
|
||||
if err := tx.Model(&request).Update("status", "accepted").Error; err != nil {
|
||||
@@ -103,14 +116,53 @@ func (s *ContactService) AcceptFriendRequest(requestID uint, userID string) erro
|
||||
return err
|
||||
}
|
||||
|
||||
// 创建双向好友关系
|
||||
// 使用雪花ID生成唯一的房间ID
|
||||
roomID, err := utils.NextIDString()
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
return fmt.Errorf("生成房间ID失败: %v", err)
|
||||
}
|
||||
|
||||
// 创建房间(p2p类型)
|
||||
room := model.ChatRoom{
|
||||
RoomID: roomID,
|
||||
RoomType: "p2p",
|
||||
OwnerID: "0", // 单聊群主为0
|
||||
CreatorID: request.ToUserID, // 接受者为创建者
|
||||
}
|
||||
if err := tx.Create(&room).Error; err != nil {
|
||||
tx.Rollback()
|
||||
return err
|
||||
}
|
||||
|
||||
// 创建房间成员记录(两个用户)
|
||||
member1 := model.RoomMember{
|
||||
RoomID: roomID,
|
||||
UserID: request.FromUserID,
|
||||
}
|
||||
member2 := model.RoomMember{
|
||||
RoomID: roomID,
|
||||
UserID: request.ToUserID,
|
||||
}
|
||||
if err := tx.Create(&member1).Error; err != nil {
|
||||
tx.Rollback()
|
||||
return err
|
||||
}
|
||||
if err := tx.Create(&member2).Error; err != nil {
|
||||
tx.Rollback()
|
||||
return err
|
||||
}
|
||||
|
||||
// 创建双向好友关系,并绑定房间ID
|
||||
contact1 := model.UserContact{
|
||||
UserID: request.FromUserID,
|
||||
ContactID: request.ToUserID,
|
||||
RoomID: roomID,
|
||||
}
|
||||
contact2 := model.UserContact{
|
||||
UserID: request.ToUserID,
|
||||
ContactID: request.FromUserID,
|
||||
RoomID: roomID,
|
||||
}
|
||||
|
||||
if err := tx.Create(&contact1).Error; err != nil {
|
||||
@@ -122,7 +174,76 @@ func (s *ContactService) AcceptFriendRequest(requestID uint, userID string) erro
|
||||
return err
|
||||
}
|
||||
|
||||
return tx.Commit().Error
|
||||
// 为双方创建会话记录
|
||||
now := time.Now()
|
||||
conv1 := model.ChatConversation{
|
||||
UserID: request.FromUserID,
|
||||
TargetID: request.ToUserID,
|
||||
RoomID: roomID,
|
||||
Type: 1, // 私聊
|
||||
LastTime: now,
|
||||
}
|
||||
conv2 := model.ChatConversation{
|
||||
UserID: request.ToUserID,
|
||||
TargetID: request.FromUserID,
|
||||
RoomID: roomID,
|
||||
Type: 1, // 私聊
|
||||
LastTime: now,
|
||||
}
|
||||
|
||||
if err := tx.Create(&conv1).Error; err != nil {
|
||||
tx.Rollback()
|
||||
return err
|
||||
}
|
||||
if err := tx.Create(&conv2).Error; err != nil {
|
||||
tx.Rollback()
|
||||
return err
|
||||
}
|
||||
|
||||
// 提交事务
|
||||
if err := tx.Commit().Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 发送欢迎消息(在事务外执行,避免影响主流程)
|
||||
go s.sendWelcomeMessage(request.ToUserID, request.FromUserID, roomID)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
/**
|
||||
* sendWelcomeMessage
|
||||
* 功能:发送欢迎消息
|
||||
*/
|
||||
func (s *ContactService) sendWelcomeMessage(senderID, receiverID, roomID string) {
|
||||
// 创建消息记录
|
||||
msg := model.ChatMessage{
|
||||
RoomID: roomID,
|
||||
SenderUserID: senderID,
|
||||
ReceiverUserID: receiverID,
|
||||
MessageType: 0, // 文本消息
|
||||
Content: "我已经通过了你的好友申请,开始和我聊天吧~",
|
||||
}
|
||||
|
||||
if err := s.DB.Create(&msg).Error; err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// 更新会话列表
|
||||
if ConversationSvc != nil {
|
||||
_ = ConversationSvc.UpsertConversationOnMessage(senderID, receiverID, roomID, msg, true)
|
||||
_ = ConversationSvc.UpsertConversationOnMessage(receiverID, senderID, roomID, msg, false)
|
||||
}
|
||||
|
||||
// 通过 WebSocket 推送消息
|
||||
if ChatSvc != nil {
|
||||
pushMsg := model.WsPayload{
|
||||
RequestType: "receive_message",
|
||||
Data: msg,
|
||||
}
|
||||
msgBytes, _ := json.Marshal(pushMsg)
|
||||
ChatSvc.DispatchMessage(receiverID, msgBytes)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -288,19 +409,24 @@ func (s *ContactService) GetContactsWithUserInfo(userID string) ([]map[string]in
|
||||
}
|
||||
user.Password = ""
|
||||
|
||||
// 组合数据
|
||||
// 组合数据,包含 user 对象
|
||||
item := map[string]interface{}{
|
||||
"id": contact.ContactID,
|
||||
"name": user.Name,
|
||||
"avatar": user.Avatar,
|
||||
"desc": user.Desc,
|
||||
"remark_name": contact.RemarkName,
|
||||
"group_id": contact.GroupID,
|
||||
"is_top": contact.IsTop,
|
||||
"is_muted": contact.IsMuted,
|
||||
"id": contact.ContactID,
|
||||
"user_id": contact.ContactID,
|
||||
"contact_user_id": contact.ContactID,
|
||||
"user": user, // 包含完整的用户信息对象
|
||||
"remark_name": contact.RemarkName,
|
||||
"room_id": contact.RoomID,
|
||||
"group_id": contact.GroupID,
|
||||
"is_top": contact.IsTop,
|
||||
"is_muted": contact.IsMuted,
|
||||
"is_special_care": contact.IsSpecialCare,
|
||||
"is_blocked": contact.IsBlocked,
|
||||
"last_chat_time": contact.LastChatTime,
|
||||
"last_message": contact.LastMessage,
|
||||
"unread_count": contact.UnreadCount,
|
||||
"last_message": contact.LastMessage,
|
||||
"last_msg": contact.LastMessage,
|
||||
"unread_count": contact.UnreadCount,
|
||||
"unread": contact.UnreadCount,
|
||||
}
|
||||
result = append(result, item)
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ func InitConversationService(db *gorm.DB) {
|
||||
func (s *ConversationService) GetConversations(userID string) ([]model.ChatConversation, error) {
|
||||
var list []model.ChatConversation
|
||||
err := s.DB.Where("user_id = ?", userID).
|
||||
Preload("TargetUser").
|
||||
Order("is_top DESC, last_time DESC, id DESC").
|
||||
Find(&list).Error
|
||||
return list, err
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"time"
|
||||
"xk-websocket-v2/internal/model"
|
||||
@@ -62,6 +61,8 @@ func GenerateGroupRoomID() string {
|
||||
*/
|
||||
func (s *RoomService) CreateRoom(roomType string, members []string, creatorID string) (*model.ChatRoom, error) {
|
||||
var roomID string
|
||||
var ownerID string = "0" // 单聊默认为0
|
||||
|
||||
if roomType == "p2p" {
|
||||
if len(members) != 2 {
|
||||
return nil, fmt.Errorf("点对点房间需要2个成员")
|
||||
@@ -69,6 +70,8 @@ func (s *RoomService) CreateRoom(roomType string, members []string, creatorID st
|
||||
roomID = GenerateP2PRoomID(members[0], members[1])
|
||||
} else {
|
||||
roomID = GenerateGroupRoomID()
|
||||
// 群聊时,创建者就是群主
|
||||
ownerID = creatorID
|
||||
}
|
||||
|
||||
// 检查房间是否已存在
|
||||
@@ -77,16 +80,19 @@ func (s *RoomService) CreateRoom(roomType string, members []string, creatorID st
|
||||
return &existingRoom, nil
|
||||
}
|
||||
|
||||
// 序列化成员列表
|
||||
membersJSON, err := json.Marshal(members)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// 开始事务
|
||||
tx := s.DB.Begin()
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
tx.Rollback()
|
||||
}
|
||||
}()
|
||||
|
||||
// 创建房间
|
||||
room := model.ChatRoom{
|
||||
RoomID: roomID,
|
||||
RoomType: roomType,
|
||||
Members: string(membersJSON),
|
||||
RoomID: roomID,
|
||||
RoomType: roomType,
|
||||
OwnerID: ownerID,
|
||||
CreatorID: creatorID,
|
||||
}
|
||||
|
||||
@@ -94,7 +100,24 @@ func (s *RoomService) CreateRoom(roomType string, members []string, creatorID st
|
||||
room.RoomName = "群聊"
|
||||
}
|
||||
|
||||
if err := s.DB.Create(&room).Error; err != nil {
|
||||
if err := tx.Create(&room).Error; err != nil {
|
||||
tx.Rollback()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 创建房间成员记录
|
||||
for _, userID := range members {
|
||||
member := model.RoomMember{
|
||||
RoomID: roomID,
|
||||
UserID: userID,
|
||||
}
|
||||
if err := tx.Create(&member).Error; err != nil {
|
||||
tx.Rollback()
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if err := tx.Commit().Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -146,3 +169,41 @@ func (s *RoomService) UpdateRoomLastMessage(roomID, message string) error {
|
||||
}).Error
|
||||
}
|
||||
|
||||
/**
|
||||
* GetRoomMembers
|
||||
* 功能:获取房间成员列表
|
||||
*/
|
||||
func (s *RoomService) GetRoomMembers(roomID string) ([]string, error) {
|
||||
var members []model.RoomMember
|
||||
if err := s.DB.Where("room_id = ?", roomID).Find(&members).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
userIDs := make([]string, len(members))
|
||||
for i, member := range members {
|
||||
userIDs[i] = member.UserID
|
||||
}
|
||||
return userIDs, nil
|
||||
}
|
||||
|
||||
/**
|
||||
* AddRoomMember
|
||||
* 功能:添加房间成员
|
||||
*/
|
||||
func (s *RoomService) AddRoomMember(roomID, userID string) error {
|
||||
member := model.RoomMember{
|
||||
RoomID: roomID,
|
||||
UserID: userID,
|
||||
}
|
||||
return s.DB.Create(&member).Error
|
||||
}
|
||||
|
||||
/**
|
||||
* RemoveRoomMember
|
||||
* 功能:移除房间成员
|
||||
*/
|
||||
func (s *RoomService) RemoveRoomMember(roomID, userID string) error {
|
||||
return s.DB.Where("room_id = ? AND user_id = ?", roomID, userID).
|
||||
Delete(&model.RoomMember{}).Error
|
||||
}
|
||||
|
||||
|
||||
@@ -107,7 +107,8 @@ CREATE TABLE `chat_rooms` (
|
||||
`room_type` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '房间类型',
|
||||
`room_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '房间名称',
|
||||
`room_avatar` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '房间头像',
|
||||
`members` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL COMMENT '成员列表JSON',
|
||||
`owner_id` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '0' COMMENT '群主ID(群聊必填,单聊为0)',
|
||||
`admin_ids` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '管理员ID列表(逗号分隔)',
|
||||
`creator_id` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '创建者ID',
|
||||
`last_message_time` datetime NULL DEFAULT NULL COMMENT '最后消息时间',
|
||||
`last_message` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL COMMENT '最后消息内容',
|
||||
@@ -115,6 +116,7 @@ CREATE TABLE `chat_rooms` (
|
||||
`updated_at` datetime(3) NULL DEFAULT NULL COMMENT '更新时间',
|
||||
PRIMARY KEY (`room_id`) USING BTREE,
|
||||
INDEX `idx_chat_rooms_room_type`(`room_type` ASC) USING BTREE,
|
||||
INDEX `idx_chat_rooms_owner_id`(`owner_id` ASC) USING BTREE,
|
||||
INDEX `idx_chat_rooms_creator_id`(`creator_id` ASC) USING BTREE,
|
||||
INDEX `idx_chat_rooms_last_message_time`(`last_message_time` ASC) USING BTREE
|
||||
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '聊天房间表,支持点对点和群聊' ROW_FORMAT = Dynamic;
|
||||
@@ -123,6 +125,26 @@ CREATE TABLE `chat_rooms` (
|
||||
-- Records of chat_rooms
|
||||
-- ----------------------------
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for room_members
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `room_members`;
|
||||
CREATE TABLE `room_members` (
|
||||
`room_id` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '房间ID',
|
||||
`user_id` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '用户ID',
|
||||
`joined_at` datetime(3) NULL DEFAULT NULL COMMENT '加入时间',
|
||||
PRIMARY KEY (`room_id`, `user_id`) USING BTREE,
|
||||
INDEX `idx_room_members_user_id`(`user_id` ASC) USING BTREE
|
||||
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '房间成员表,存储房间与用户的关联关系' ROW_FORMAT = Dynamic;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of room_members
|
||||
-- ----------------------------
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of chat_rooms
|
||||
-- ----------------------------
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for contact_groups
|
||||
-- ----------------------------
|
||||
@@ -195,10 +217,13 @@ CREATE TABLE `user_contacts` (
|
||||
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键ID',
|
||||
`user_id` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '用户ID',
|
||||
`contact_id` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '联系人ID',
|
||||
`room_id` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '房间ID',
|
||||
`remark_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '备注名称',
|
||||
`group_id` bigint NULL DEFAULT NULL COMMENT '分组ID',
|
||||
`is_top` tinyint(1) NULL DEFAULT 0 COMMENT '是否置顶',
|
||||
`is_muted` tinyint(1) NULL DEFAULT 0 COMMENT '是否免打扰',
|
||||
`is_special_care` tinyint(1) NULL DEFAULT 0 COMMENT '是否特别关心',
|
||||
`is_blocked` tinyint(1) NULL DEFAULT 0 COMMENT '是否拉黑',
|
||||
`last_chat_time` datetime NULL DEFAULT NULL COMMENT '最后聊天时间',
|
||||
`last_message` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL COMMENT '最后一条消息',
|
||||
`unread_count` bigint NULL DEFAULT 0 COMMENT '未读消息数',
|
||||
@@ -207,6 +232,7 @@ CREATE TABLE `user_contacts` (
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
INDEX `idx_user_contacts_user_id`(`user_id` ASC) USING BTREE,
|
||||
INDEX `idx_user_contacts_contact_id`(`contact_id` ASC) USING BTREE,
|
||||
INDEX `idx_user_contacts_room_id`(`room_id` ASC) USING BTREE,
|
||||
INDEX `idx_user_contacts_group_id`(`group_id` ASC) USING BTREE
|
||||
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '用户联系人表,存储好友关系、分组、备注等信息' ROW_FORMAT = Dynamic;
|
||||
|
||||
@@ -237,7 +263,7 @@ CREATE TABLE `users` (
|
||||
-- ----------------------------
|
||||
-- Records of users
|
||||
-- ----------------------------
|
||||
INSERT INTO `users` VALUES ('10001', 'user001@example.com', '13800138001', '$2a$10$OsVRHKowu.mVT4GNxzZ3/eo8xEABkWsUGAt4nV5nalzOXW47vtBmC', '张三', '张', 'Golang 开发工程师', '北京', '2025-12-03 09:53:49.000', '2025-12-03 09:53:49.000');
|
||||
INSERT INTO `users` VALUES ('10001', 'workerqi@163.com', '13800138001', '$2a$10$OsVRHKowu.mVT4GNxzZ3/eo8xEABkWsUGAt4nV5nalzOXW47vtBmC', '张三', '张', 'Golang 开发工程师', '北京', '2025-12-03 09:53:49.000', '2025-12-03 09:53:49.000');
|
||||
INSERT INTO `users` VALUES ('10002', 'user002@example.com', '13800138002', '$2a$10$OsVRHKowu.mVT4GNxzZ3/eo8xEABkWsUGAt4nV5nalzOXW47vtBmC', '李四', '李', '前端开发工程师', '上海', '2025-12-03 09:53:49.000', '2025-12-03 09:53:49.000');
|
||||
INSERT INTO `users` VALUES ('10003', 'user003@example.com', '13800138003', '$2a$10$OsVRHKowu.mVT4GNxzZ3/eo8xEABkWsUGAt4nV5nalzOXW47vtBmC', '王五', '王', '产品经理', '深圳', '2025-12-03 09:53:49.000', '2025-12-03 09:53:49.000');
|
||||
INSERT INTO `users` VALUES ('10004', 'user004@example.com', '13800138004', '$2a$10$OsVRHKowu.mVT4GNxzZ3/eo8xEABkWsUGAt4nV5nalzOXW47vtBmC', '赵六', '赵', 'UI设计师', '广州', '2025-12-03 09:53:49.000', '2025-12-03 09:53:49.000');
|
||||
|
||||
Reference in New Issue
Block a user