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

avatar
作者
猴君
阅读量:0

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

/*  Navicat Premium Data Transfer   Source Server         : localhost  Source Server Type    : MySQL  Source Server Version : 80012 (8.0.12)  Source Host           : localhost:3306  Source Schema         : chat   Target Server Type    : MySQL  Target Server Version : 80012 (8.0.12)  File Encoding         : 65001   Date: 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)){       //是group       Id = 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 token    if (!brief) {     return res.status(400).json({ code: 1, message: 'Brief is required' });   }    try {     // Update the user's brief in the database     const [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 updated     const 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}`); }); 

广告一刻

为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!