您的位置:首页 > 健康 > 美食 > 用uniapp 及socket.io做一个简单聊天app 3

用uniapp 及socket.io做一个简单聊天app 3

2024/12/26 17:47:12 来源:https://blog.csdn.net/hzether/article/details/140895504  浏览:    关键词:用uniapp 及socket.io做一个简单聊天app 3

一直正开发时,又优化了相关的表,现在的表结构为:

/*Navicat Premium Data TransferSource Server         : localhostSource Server Type    : MySQLSource Server Version : 80012 (8.0.12)Source Host           : localhost:3306Source Schema         : chatTarget Server Type    : MySQLTarget Server Version : 80012 (8.0.12)File Encoding         : 65001Date: 03/08/2024 19:27:31
*/SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;-- ----------------------------
-- Table structure for blacklists
-- ----------------------------
DROP TABLE IF EXISTS `blacklists`;
CREATE TABLE `blacklists`  (`user_id` int(11) NULL DEFAULT NULL,`blocked_user_id` int(11) NULL DEFAULT NULL,`created_at` datetime NULL DEFAULT NULL,INDEX `user_id`(`user_id` ASC) USING BTREE,INDEX `blocked_user_id`(`blocked_user_id` ASC) USING BTREE,CONSTRAINT `blacklists_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT,CONSTRAINT `blacklists_ibfk_2` FOREIGN KEY (`blocked_user_id`) REFERENCES `users` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;-- ----------------------------
-- Table structure for chatgroups
-- ----------------------------
DROP TABLE IF EXISTS `chatgroups`;
CREATE TABLE `chatgroups`  (`id` int(11) NOT NULL AUTO_INCREMENT,`name` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,`description` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL,`avatar_url` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,`owner_id` int(11) NULL DEFAULT NULL,`created_at` datetime NULL DEFAULT NULL,PRIMARY KEY (`id`) USING BTREE,INDEX `owner_id`(`owner_id` ASC) USING BTREE,CONSTRAINT `chatgroups_ibfk_1` FOREIGN KEY (`owner_id`) REFERENCES `users` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE = InnoDB AUTO_INCREMENT = 10 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;-- ----------------------------
-- Table structure for friends
-- ----------------------------
DROP TABLE IF EXISTS `friends`;
CREATE TABLE `friends`  (`id` int(11) NOT NULL AUTO_INCREMENT,`user_id` int(11) NULL DEFAULT NULL,`group_friend_id` int(11) NULL DEFAULT NULL,`type` enum('user','group') CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,`status` enum('pending','accepted','blocked') CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT 'pending',`created_at` datetime NULL DEFAULT NULL,PRIMARY KEY (`id`) USING BTREE,INDEX `user_id`(`user_id` ASC) USING BTREE,CONSTRAINT `friends_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;-- ----------------------------
-- Table structure for invites
-- ----------------------------
DROP TABLE IF EXISTS `invites`;
CREATE TABLE `invites`  (`id` int(11) NOT NULL AUTO_INCREMENT,`inviter_id` int(11) NULL DEFAULT NULL,`invitee_id` int(11) NULL DEFAULT NULL,`group_id` int(11) NULL DEFAULT NULL,`group_avatar` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,`inviter_avatar` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,`invitee_avatar` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,`status` enum('pending','accepted','declined') CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT 'pending',`created_at` datetime NULL DEFAULT NULL,PRIMARY KEY (`id`) USING BTREE,INDEX `inviter_id`(`inviter_id` ASC) USING BTREE,INDEX `invitee_id`(`invitee_id` ASC) USING BTREE,INDEX `group_id`(`group_id` ASC) USING BTREE,CONSTRAINT `invites_ibfk_1` FOREIGN KEY (`inviter_id`) REFERENCES `users` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT,CONSTRAINT `invites_ibfk_2` FOREIGN KEY (`invitee_id`) REFERENCES `users` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT,CONSTRAINT `invites_ibfk_3` FOREIGN KEY (`group_id`) REFERENCES `chatgroups` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;-- ----------------------------
-- Table structure for messages
-- ----------------------------
DROP TABLE IF EXISTS `messages`;
CREATE TABLE `messages`  (`id` int(11) NOT NULL AUTO_INCREMENT,`fid` int(11) NULL DEFAULT NULL,`tid` int(11) NULL DEFAULT NULL,`receiver_type` enum('user','group') CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,`type` enum('text','audio','video','image','join','left','broadcast','kick') CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,`content` text CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,`avatar` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,`is_retracted` tinyint(1) NULL DEFAULT 0,`retracted_at` datetime NULL DEFAULT NULL,`created_at` datetime NULL DEFAULT NULL,`sn` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '唯一码',`group_name` varchar(10) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,`user_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '用户名',PRIMARY KEY (`id`) USING BTREE,INDEX `sender_id`(`fid` ASC) USING BTREE,CONSTRAINT `messages_ibfk_1` FOREIGN KEY (`fid`) REFERENCES `users` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE = InnoDB AUTO_INCREMENT = 16 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;-- ----------------------------
-- Table structure for users
-- ----------------------------
DROP TABLE IF EXISTS `users`;
CREATE TABLE `users`  (`id` int(11) NOT NULL AUTO_INCREMENT,`username` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,`password` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,`email` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,`avatar_url` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,`brief` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL,`created_at` datetime NULL DEFAULT NULL,PRIMARY KEY (`id`) USING BTREE,UNIQUE INDEX `username`(`username` ASC) USING BTREE,UNIQUE INDEX `email`(`email` ASC) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 6 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;SET FOREIGN_KEY_CHECKS = 1;

用express 开发相关的model:

module.exports = (sequelize, DataTypes) => {const User = require('./User')(sequelize, DataTypes); // 确保 User 模型正确导入const Blacklist = sequelize.define('Blacklist', {user_id: {type: DataTypes.INTEGER,references: {model: User,key: 'id',},},blocked_user_id: {type: DataTypes.INTEGER,references: {model: User,key: 'id',},},created_at: {type: DataTypes.DATE,defaultValue: DataTypes.NOW,},}, {timestamps: false,primaryKey: false,});// 移除默认的主键 'id'Blacklist.removeAttribute('id');return Blacklist;
};
module.exports = (sequelize, DataTypes) => {const User = require('./User')(sequelize, DataTypes); // 确保 User 模型正确导入const ChatGroup = sequelize.define('ChatGroup', {id: {type: DataTypes.INTEGER,autoIncrement: true,primaryKey: true,},name: {type: DataTypes.STRING(100),allowNull: false,},description: {type: DataTypes.TEXT,},avatar_url: {type: DataTypes.STRING(255),},owner_id: {type: DataTypes.INTEGER,references: {model: User,key: 'id',},},created_at: {type: DataTypes.DATE,defaultValue: DataTypes.NOW,},}, {timestamps: false,});return ChatGroup;
};
module.exports = (sequelize, DataTypes) => {const User = require('./User')(sequelize, DataTypes); // 确保 User 模型正确导入const Friend = sequelize.define('Friend', {id: {type: DataTypes.INTEGER,autoIncrement: true,primaryKey: true,},user_id: {type: DataTypes.INTEGER,references: {model: User,key: 'id',},},group_friend_id: {type: DataTypes.INTEGER,},type: {type: DataTypes.ENUM('user', 'group'),allowNull: false,},status: {type: DataTypes.ENUM('pending', 'accepted', 'blocked'),defaultValue: 'pending',},created_at: {type: DataTypes.DATE,defaultValue: DataTypes.NOW,},}, {timestamps: false,primaryKey: false,});//Friend.removeAttribute('id');return Friend;
};
const Sequelize = require('sequelize');
const sequelize = new Sequelize('chat', 'root', 'asd123', {host: 'localhost',dialect: 'mysql', // 或 'postgres', 'sqlite', 'mssql'
});const User = require('./user')(sequelize, Sequelize.DataTypes);
const Friend = require('./friend')(sequelize, Sequelize.DataTypes);
const ChatGroup = require('./chatGroup')(sequelize, Sequelize.DataTypes);
const Blacklist = require('./blacklist')(sequelize, Sequelize.DataTypes);
const Invite = require('./invite')(sequelize, Sequelize.DataTypes);
const Message = require('./message')(sequelize, Sequelize.DataTypes);const db = {sequelize,Sequelize,User,Friend,ChatGroup,Blacklist,Invite,Message
};module.exports = db;
module.exports = (sequelize, DataTypes) => {const User = require('./User')(sequelize, DataTypes); // 确保 User 模型正确导入const ChatGroup = require('./ChatGroup')(sequelize, DataTypes); // 确保 ChatGroup 模型正确导入const Invite = sequelize.define('Invite', {id: {type: DataTypes.INTEGER,autoIncrement: true,primaryKey: true,},inviter_id: {type: DataTypes.INTEGER,references: {model: User,key: 'id',},},invitee_id: {type: DataTypes.INTEGER,references: {model: User,key: 'id',},},group_id: {type: DataTypes.INTEGER,references: {model: ChatGroup,key: 'id',},},group_avatar: {type: DataTypes.STRING(255),},inviter_avatar: {type: DataTypes.STRING(255),},invitee_avatar: {type: DataTypes.STRING(255),},status: {type: DataTypes.ENUM('pending', 'accepted', 'declined'),defaultValue: 'pending',},created_at: {type: DataTypes.DATE,defaultValue: DataTypes.NOW,},}, {timestamps: false,});return Invite;
};
module.exports = (sequelize, DataTypes) => {const User = require('./User')(sequelize, DataTypes); // 确保 User 模型正确导入const ChatGroup = require('./ChatGroup')(sequelize, DataTypes); // 确保 ChatGroup 模型正确导入const Message = sequelize.define('Message', {id: {type: DataTypes.INTEGER,autoIncrement: true,primaryKey: true,},fid: {type: DataTypes.INTEGER,references: {model: User,key: 'id',},allowNull: true,},tid: {type: DataTypes.INTEGER,allowNull: true,},type: {type: DataTypes.ENUM('text', 'audio', 'video', 'image','broadcast','left','kick','withdraw','join'),allowNull: false,},content: {type: DataTypes.TEXT,allowNull: false,},avatar: {type: DataTypes.STRING(255),allowNull: true,},is_retracted: {type: DataTypes.BOOLEAN,defaultValue: false,},retracted_at: {type: DataTypes.DATE,allowNull: true,},created_at: {type: DataTypes.DATE,defaultValue: DataTypes.NOW,},group_name:{type:DataTypes.STRING(10),allowNull: true,},user_name:{type: DataTypes.STRING(255),allowNull: true,},sn: {type: DataTypes.STRING(255),allowNull: true,},}, {timestamps: false,underscored: true, // 使用下划线风格以符合数据库字段命名});return Message;
};
module.exports = (sequelize, DataTypes) => {const User = sequelize.define('User', {id: {type: DataTypes.INTEGER,autoIncrement: true,primaryKey: true,},username: {type: DataTypes.STRING(50),allowNull: false,unique: true,},password: {type: DataTypes.STRING(100),allowNull: false,},email: {type: DataTypes.STRING(100),unique: true,},avatar_url: {type: DataTypes.STRING(255),},brief: {type: DataTypes.TEXT,},created_at: {type: DataTypes.DATE,defaultValue: DataTypes.NOW,},}, {timestamps: false,});return User;
};

聊天代码进行了调整:

const socketIo = require('socket.io');function setupChat(server) {const io = socketIo(server, {cors: {origin: "*",methods: ["GET", "POST"]}});const groups = {};  // 存储用户与群组的映射const kickedUsers = {};  // 存储被踢出用户的信息const groupUsers = {};  // 存储每个群组中的用户列表io.on('connection', (socket) => {// console.log('New user connected');// 用户加入群组socket.on('joinGroup', ({ groupName, userName }) => {if (!kickedUsers[groupName] || !kickedUsers[groupName].includes(userName)) {socket.join(groupName);// 更新用户列表if (!groupUsers[groupName]) {groupUsers[groupName] = [];}if (!groupUsers[groupName].includes(userName)) {groupUsers[groupName].push(userName);}groups[socket.id] = { groupName, userName };console.log( `${userName} has joined the group`)socket.to(groupName).emit('message',{'type':'join',content:`${userName} 加入`});// 发送当前用户列表到群组io.to(groupName).emit('userList', groupUsers[groupName]);console.log(`${userName} joined group ${groupName}`);} else {socket.emit('message', `您已被踢出群组 ${groupName}, 无法重新加入。`);}});// 发送消息socket.on('sendMessage', ({sn, group_name,avatar, content, user_name,type,fid,tid ,created_at}) => {if (!kickedUsers[group_name] || !kickedUsers[group_name].includes(user_name)) {io.to(group_name).emit('message', {sn, group_name,avatar, content, user_name,type,fid,tid  ,created_at});io.emit('message', {sn, group_name,avatar, content, user_name,'type':'broadcast',fid,tid  ,created_at});console.log({sn, group_name,avatar, content, user_name,type,fid,tid ,created_at});} else {socket.emit('message', `您已被踢出群组 ${group_name}, 无法发送消息。`);}});// 踢人socket.on('kickUser', ({ groupName, userName }) => {for (let id in groups) {if (groups[id].userName === userName && groups[id].groupName === groupName) {io.sockets.sockets.get(id).leave(groupName);io.to(groupName).emit('message', `${userName} 已被踢出群组`);// 从用户列表中删除if (groupUsers[groupName]) {groupUsers[groupName] = groupUsers[groupName].filter(user => user !== userName);io.to(groupName).emit('userList', groupUsers[groupName]);}console.log(`${userName} 被踢出群组 ${groupName}`);if (!kickedUsers[groupName]) {kickedUsers[groupName] = [];}kickedUsers[groupName].push(userName);break;}}});// 用户断开连接socket.on('disconnect', () => {if (groups[socket.id]) {const { groupName, userName } = groups[socket.id];// 从用户列表中删除if (groupUsers[groupName]) {groupUsers[groupName] = groupUsers[groupName].filter(user => user !== userName);io.to(groupName).emit('userList', groupUsers[groupName]);}socket.to(groupName).emit('message', {'type':'left',content:`${userName} 离开`});delete groups[socket.id];console.log(`${userName} 已离开群组 ${groupName}`);}});});return io;
}module.exports = setupChat;

启动页为:

const express = require('express');
const http = require('http');
const cors = require('cors');
const bodyParser = require('body-parser');
const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');
const db = require('./src/models');
const { User, Friend, ChatGroup, Blacklist, Invite, Message, sequelize } = require('./src/models');
const multer = require('multer');
const path = require('path');
const fs = require('fs');
const { Op } = require('sequelize');
const setupChat = require('./src/chat');const app = express();
const server = http.createServer(app);// 设置聊天
const io = setupChat(server);
// 使用中间件
app.use(cors());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));const port = 3000;
const SECRET_KEY = 'mykeyssssssd%#@##$#@$#$@$#@$$'; // 更改为实际的密钥const authenticateToken = (req, res, next) => {const authHeader = req.headers['authorization'];const token = authHeader && authHeader.split(' ')[1];if (token == null) return res.json({code:-1,message:'expire'});jwt.verify(token, SECRET_KEY, (err, user) => {if (err) return res.json({code:-1,message:'expire'});req.user = user;next();});
};// 设置文件存储配置
const storage = multer.diskStorage({destination: (req, file, cb) => {cb(null, 'uploads/');},filename: (req, file, cb) => {cb(null, `${Date.now()}-${file.originalname}`);}
});const upload = multer({ storage: storage });// 创建 uploads 目录const uploadsDir = path.join(__dirname, 'uploads');
if (!fs.existsSync(uploadsDir)) {fs.mkdirSync(uploadsDir);
}// 文件上传接口
app.post('/upload', upload.single('avatar'), (req, res) => {if (!req.file) {return res.status(400).json({ error: 'No file uploaded' });}const fileUrl = `http://localhost:3000/uploads/${req.file.filename}`;res.json({code:0,message:'图片上传成功', data: fileUrl });
});// 提供静态文件服务
app.use('/uploads', express.static(path.join(__dirname, 'uploads')));app.post('/register', async (req, res) => {try {const { username, password } = req.body;console.log('Received registration request for:', username);if (username.length < 6 || username.length > 10 || password.length < 6 || password.length > 10) {console.log('Invalid username or password length');return res.status(400).json({ error: 'Username and password must be 6-10 characters long' });}const hashedPassword = await bcrypt.hash(password, 10);console.log('Password hashed successfully');console.log('Attempting to create user in database');const user = await User.create({ username, password: hashedPassword });console.log('User created:', user.toJSON());res.status(201).json({ message: 'User registered successfully' });} catch (error) {console.error('Error in registration:', error);if (error.name === 'SequelizeUniqueConstraintError') {return res.status(400).json({ error: 'Username already exists' });}res.status(500).json({ error: error.message || 'An error occurred during registration' });}
});// 用户登录
app.post('/login', async (req, res) => {try {const { username, password } = req.body;console.log({ username, password });if (username.length < 6 || username.length > 10 || password.length < 6 || password.length > 10) {return res.status(400).json({ code: 0, msg: '用户名和密码必须是6-10个字符长', data: null });}const user = await User.findOne({ where: { username } });console.log(user);if (!user || !await bcrypt.compare(password, user.password)) {return res.status(401).json({ code: 0, msg: '无效凭证', data: null });}const token = jwt.sign({ id: user.id }, SECRET_KEY, { expiresIn: '1h' });res.json({ code: 1, msg: '登录成功', data: { token } });} catch (error) {console.log(error);res.status(500).json({ code: 0, msg: '登录时出错', data: null });}
});// 添加好友
app.post('/addFriend', authenticateToken, async (req, res) => {const { friendId } = req.body;const userId = req.user.id;try {const friend = await User.findByPk(friendId);if (!friend){return res.status(404).json({ error:'未找到朋友' });}await Friend.create({ user_id: userId, friend_id: friendId });res.json({ message:'成功添加好友' });}catch (error){res.status(500).json({ error:'添加好友时出错' });}
});// 获取好友列表
app.get('/friends', authenticateToken, async (req, res) => {try {const userId = req.user.id;const { page = 1, perPage = 20 } = req.query;// 计算分页参数const offset = (page - 1) * perPage;const limit = parseInt(perPage);const friends = await Friend.findAndCountAll({where: {[Op.or]: [{type: 'user',[Op.or]: [{ user_id: userId },{ group_friend_id: userId }]},{type: 'group',user_id: userId}]},offset,limit});// 判断是否还有更多数据const hasMoreFriends = friends.count > offset + limit;const friendDataPromises = friends.rows.map(async (item) => {if (item.type == 'user') {const user = await User.findOne({where: { id: item.group_friend_id },attributes: ['id', 'username', 'email', 'avatar_url', 'brief']});return { ...item.get(), user };}if (item.type == 'group') {const group = await ChatGroup.findOne({where: { id: item.group_friend_id },attributes: ['id', 'name', 'description', 'avatar_url']});return { ...item.get(), group };}});const friendsData = await Promise.all(friendDataPromises);return res.json({code: 0,message: '返回成功',data: friendsData,hasMoreFriends});} catch (error) {return res.json({ code: -1, message: error });}
});app.get('/checkFriend', authenticateToken, async (req, res) => {try {const userId = req.user.id;let { Id } = req.query;if( /^g_\d+$/.test(Id)){//是groupId = Id.replace("g_", "");const isFriend =  await Friend.findOne({where: { user_id: userId, group_friend_id:Id},attributes: ['id', 'user_id', 'group_friend_id','type']});if(isFriend){return res.json({ code: 0, message: 'User is a friend', data: isFriend });}else{return res.json({ code: 1, message: 'User is not a friend' });}}const isFriend =  await Friend.findOne({where: { id: Id,type:'user' },attributes: ['id', 'user_id', 'group_friend_id','type']});if (isFriend){if(isFriend.user_id==userId ||isFriend.group_friend_id==userId){return res.json({ code: 0, message: 'User is a friend', data: isFriend });}return res.json({ code: 1, message: 'User is not a friend' });}else{return res.json({ code: 1, message: 'User is not a friend' });}} catch (error) {return res.json({ code: -1, message: error.message });}
});app.post('/addmessage', authenticateToken, async (req, res) => {const { sn, group_name, avatar, content, type, user_name, fid, tid } = req.body;try {// 插入新消息const newMessage = await Message.create({sn,group_name,avatar,content,type,user_name,fid,tid,is_retracted:0,});res.json({ code: 0, message: '消息添加成功', data: newMessage });} catch (error) {console.error('添加消息失败:', error);res.json({ code: -1, message: '消息添加失败' });}
});// 获取用户信息接口
app.get('/user', authenticateToken, async (req, res) => {try {// 确保 `req.user` 和 `req.user.id` 存在if (!req.user || !req.user.id) {return res.status(400).json({ error: '用户 ID 未找到' });}const user = await User.findByPk(req.user.id, {attributes: ['id', 'username', 'email', 'avatar_url', 'brief', 'created_at']});if (!user) {//console.warn("User not found with ID:", req.user.id);return res.status(404).json({ error: '用户未找到' });}res.json(user);} catch (error) {res.status(500).json({ error: '获取用户信息时出错' });}
});app.post('/user/updateAvatar', authenticateToken, async (req, res) => {const { avatar_url } = req.body;try {await User.update({ avatar_url }, { where: { id: req.user.id } });res.json({code:0, message:'头像更新成功',data:avatar_url });} catch (error) {res.json({code:-1, message:'头象更新失败A'});}
});
app.post('/user/updateBrief', authenticateToken, async (req, res) => {const { brief } = req.body;const userId = req.user.id; // Assuming the user ID is stored in the tokenif (!brief) {return res.status(400).json({ code: 1, message: 'Brief is required' });}try {// Update the user's brief in the databaseconst [affectedRows] = await User.update({ brief }, // Fields to update{ where: { id: userId } } // Condition to find the user);if (affectedRows === 0) {return res.status(404).json({ code: 1, message: 'User not found' });}res.status(200).json({ code: 0, message: 'Brief updated successfully' });} catch (error) {//console.error('Error updating brief:', error);res.status(500).json({ code: 1, message: 'Internal server error' });}
});// 创建群组接口
app.post('/groups', authenticateToken, upload.single('avatar'), async (req, res) => {try {//console.log('req.body:', req.body); // 调试输出请求体const { name, description ,avatar_url} = req.body;const owner_id = req.user.id;if (name.length < 3 || name.length > 10) {return res.status(400).json({ error: '群名必须在3到10个汉字之间' });}if (description.length < 5 || description.length > 50) {return res.status(400).json({ error: '群说明必须在5到50个汉字之间' });}const existingGroup = await ChatGroup.findOne({ where: { name } });if (existingGroup) {return  res.json({code:-1, message: '群名已存在' });}const group = await ChatGroup.create({ name, description, avatar_url, owner_id });await Friend.create({ user_id: owner_id, group_friend_id: group.id, type: 'group', status: 'accepted' });return res.json({ code: 0, message: '群组创建成功', group });} catch (error) {return  res.json({code:-1, message: '创建群组时出错' });}
});// 获取群组信息接口
app.get('/groups/:id', authenticateToken, async (req, res) => {try {const group = await ChatGroup.findByPk(req.params.id);if (!group){return res.status(404).json({ error:'群组未找到' });}res.json(group);}catch (error){res.status(500).json({ error:'获取群组信息时出错' });}
});app.get('/groups', authenticateToken, async (req, res) => {try {const userId = req.user.id;//console.log('userId',userId)const groups = await ChatGroup.findAll({ where: { owner_id: userId } });//console.log('groups',groups)return res.json({ code: 0, data: groups });} catch (error) {//console.error('Error fetching groups:', error);return res.json({ code: -1, message: 'Failed to fetch groups' });}
});app.post('/group/update', authenticateToken, async (req, res) => {try {const { id, name, description, avatar_url } = req.body;// Check if the group name already exists and is not the current group being updatedconst existingGroup = await ChatGroup.findOne({where: {name,id: { [Op.ne]: id } // Use Op from Sequelize}});//// console.log('Op:', Op); // Should not be undefined// console.log('Query:', {//   name,//   id: { [Op.ne]: id }// });if (existingGroup) {return res.json({ code: -2, message: '群名重复' });}await ChatGroup.update({ name, description, avatar_url }, { where: { id } });return res.json({ code: 0, message: '群名创建成功' });} catch (error) {// console.error('Error updating group:', error);return res.json({ code: -1, message: '创建失败' });}
});app.post('/user/updateEmail', authenticateToken, async (req, res) => {try {const userId = req.user.id;const { email } = req.body;await User.update({ email }, { where: { id: userId } });return res.json({ code: 0, message: 'Email updated successfully' });} catch (error) {// console.error('Error updating email:', error);return res.json({ code: -1, message: 'Failed to update email' });}
});
app.get('/user', authenticateToken, async (req, res) => {try {const user = await User.findByPk(req.user.id, {attributes: ['id', 'username', 'email', 'avatar']});if (!user) {return res.status(404).json({ error: '用户未找到' });}res.json(user);} catch (error) {res.status(500).json({ error: '获取用户信息时出错' });}
});
app.post('/logout', authenticateToken, (req, res) => {// 这里可以添加一些服务器端的登出逻辑// 比如清除服务器端的 session 或标记 token 为无效res.json({ message: '成功登出' });
});
const PORT = process.env.PORT || port;server.listen(PORT, () => {console.log(`Server is running on port ${PORT}`);
});

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com