全栈项目:校友论坛系统

基于 Vue 3 + Node.js + MongoDB的全栈校园论坛系统

1. 项目概述

随着互联网技术的快速发展和社交网络的普及,校友之间的交流与联系变得越来越重要。传统的校友联系方式存在信息分散、交流不便等问题,难以满足现代校友群体的需求。为了解决这些问题,本文设计并实现了一个基于 Web 技术的校友论坛系统。

本系统采用前后端分离的架构模式,前端使用 Vue 3 框架结合 TypeScript 和 Element Plus 组件库构建用户界面,后端使用 Node.js 的 Koa 框架提供 RESTful API 服务,数据存储采用 MongoDB 非关系型数据库。系统实现了用户注册登录、帖子发布与浏览、评论互动、私信交流、公告管理等核心功能,并提供了完善的管理后台用于内容管理和数据统计。

2. 项目截图

用户端:

后台管理:

3.功能需求

3.1 用户角色分析

系统设计了两种用户角色:

1. 普通用户

普通用户是系统的主要使用者,包括在校学生和已毕业校友。其主要需求包括:

  • 注册账号并完善个人信息
  • 浏览和搜索帖子内容
  • 发布帖子分享经验和求助
  • 评论和点赞帖子
  • 与其他用户私信交流
  • 查看系统公告

2. 管理员

管理员负责系统的日常管理和维护,其主要需求包括:

  • 管理用户账号(查看、禁用、启用)
  • 管理帖子内容(删除违规内容、置顶重要帖子)
  • 管理评论(删除不当评论)
  • 发布和管理系统公告
  • 查看系统数据统计

3.2 功能模块划分

根据用户需求,系统划分为以下功能模块:

1. 用户管理模块

该模块负责用户相关的所有功能:

  • 用户注册:新用户通过邮箱注册账号,填写基本信息
  • 用户登录:已注册用户通过邮箱和密码登录系统
  • 个人资料管理:用户可以查看和编辑个人信息,包括用户名、学校、专业、毕业年份、职业、个人简介等
  • 密码管理:用户可以修改登录密码
  • 用户主页:展示用户的基本信息和发帖历史

2. 帖子管理模块

该模块是系统的核心功能:

  • 帖子发布:用户可以发布新帖子,包括标题、内容、分类和标签
  • 帖子浏览:用户可以浏览帖子列表,支持按分类筛选和排序
  • 帖子详情:查看帖子的完整内容、作者信息、评论列表
  • 帖子搜索:通过关键词搜索相关帖子
  • 帖子编辑:作者可以编辑自己发布的帖子
  • 帖子删除:作者和管理员可以删除帖子
  • 帖子点赞:用户可以对帖子进行点赞或取消点赞

帖子分类包括:

  • 求助:寻求帮助和建议
  • 分享:分享经验和知识
  • 求职:求职信息和职业发展
  • 学习:学习资源和心得
  • 创业:创业经验和项目
  • 生活:生活话题和闲聊

3. 评论管理模块

该模块支持用户对帖子进行评论互动:

  • 发表评论:用户可以对帖子发表评论
  • 评论点赞:用户可以对评论进行点赞
  • 删除评论:评论作者、帖子作者和管理员可以删除评论
  • 评论列表:按时间顺序展示帖子的所有评论

4. 私信模块

该模块支持用户之间的私密交流:

  • 发送私信:用户可以向其他用户发送私信
  • 会话列表:展示所有私信会话,显示未读消息数量
  • 消息详情:查看与某个用户的完整对话历史
  • 消息已读:自动标记已读消息

5. 公告模块

该模块用于发布系统公告和重要通知:

  • 公告展示:在首页顶部展示活跃的公告
  • 公告管理:管理员可以创建、编辑、删除公告
  • 公告分类:系统、活动、维护、重要等类型
  • 公告优先级:支持设置公告的优先级
  • 公告过期:支持设置公告的过期时间

6. 管理后台模块

该模块为管理员提供系统管理功能:

  • 用户管理:查看用户列表,搜索用户,禁用/启用用户账号
  • 内容管理:查看所有帖子,删除违规内容,置顶重要帖子
  • 评论管理:查看所有评论,删除不当评论
  • 公告管理:创建、编辑、删除公告
  • 数据统计:展示用户数、帖子数、评论数等统计数据

4. 系统架构设计

4.1 总体架构

本系统采用前后端分离的架构模式,将系统分为三层:表现层、业务逻辑层和数据访问层。系统总体架构如图 3-1 所示。

bash 复制代码
┌─────────────────────────────────────────┐
│           表现层(前端)                  │
│  ┌─────────────────────────────────┐   │
│  │  Vue 3 + TypeScript + Vite      │   │
│  │  ├─ 路由管理(Vue Router)       │   │
│  │  ├─ 状态管理(Pinia)            │   │
│  │  ├─ UI 组件(Element Plus)      │   │
│  │  └─ HTTP 客户端(Axios)         │   │
│  └─────────────────────────────────┘   │
└─────────────────────────────────────────┘
                    ↕ HTTP/HTTPS
┌─────────────────────────────────────────┐
│        业务逻辑层(后端)                 │
│  ┌─────────────────────────────────┐   │
│  │  Node.js + Koa                  │   │
│  │  ├─ 路由层(Koa Router)         │   │
│  │  ├─ 中间件层(认证、日志等)      │   │
│  │  ├─ 业务逻辑层(Controllers)    │   │
│  │  └─ 数据访问层(Mongoose)       │   │
│  └─────────────────────────────────┘   │
└─────────────────────────────────────────┘
                    ↕
┌─────────────────────────────────────────┐
│         数据访问层(数据库)              │
│  ┌─────────────────────────────────┐   │
│  │  MongoDB                        │   │
│  │  ├─ users(用户集合)            │   │
│  │  ├─ posts(帖子集合)            │   │
│  │  ├─ comments(评论集合)         │   │
│  │  ├─ messages(消息集合)         │   │
│  │  └─ announcements(公告集合)    │   │
│  └─────────────────────────────────┘   │
└─────────────────────────────────────────┘

架构特点

  1. 前后端分离:前端和后端独立开发、部署和维护
  2. RESTful API:前后端通过标准的 RESTful API 进行通信
  3. 模块化设计:各层职责明确,模块之间低耦合高内聚
  4. 可扩展性强:便于功能扩展和技术升级

4.2 前端架构

前端采用 Vue 3 框架,结合 TypeScript 和 Element Plus 构建单页应用(SPA)。前端架构如图 3-2 所示。

bash 复制代码
src/
├── api/              # API 接口封装
│   ├── index.ts      # Axios 实例配置
│   ├── auth.ts       # 认证相关接口
│   ├── posts.ts      # 帖子相关接口
│   └── ...
├── assets/           # 静态资源
├── components/       # 通用组件
│   ├── Header.vue    # 头部组件
│   ├── Footer.vue    # 底部组件
│   └── ...
├── router/           # 路由配置
│   └── index.ts      # 路由定义和守卫
├── stores/           # 状态管理
│   ├── auth.ts       # 用户认证状态
│   └── ...
├── types/            # TypeScript 类型定义
│   └── index.ts      # 全局类型
├── utils/            # 工具函数
│   └── index.ts      # 通用工具
├── views/            # 页面组件
│   ├── Home.vue      # 首页
│   ├── Login.vue     # 登录页
│   ├── Posts.vue     # 帖子列表
│   └── ...
├── App.vue           # 根组件
└── main.ts           # 应用入口

关键技术

  1. Vue Router:实现单页应用的路由管理
  2. Pinia:轻量级的状态管理库
  3. Axios:HTTP 客户端,封装 API 请求
  4. TypeScript:提供类型安全和更好的开发体验

4.3 后端架构

后端采用 Node.js 的 Koa 框架,使用 Mongoose 进行数据库操作。后端架构如图 3-3 所示。

bash 复制代码
server/
├── src/
│   ├── config/           # 配置文件
│   │   └── database.js   # 数据库配置
│   ├── middleware/       # 中间件
│   │   └── auth.js       # 认证中间件
│   ├── models/           # 数据模型
│   │   ├── User.js       # 用户模型
│   │   ├── Post.js       # 帖子模型
│   │   └── ...
│   ├── routes/           # 路由处理
│   │   ├── auth.js       # 认证路由
│   │   ├── posts.js      # 帖子路由
│   │   └── ...
│   └── app.js            # 应用入口
├── scripts/              # 脚本文件
│   └── import-data.js    # 数据导入脚本
└── .env                  # 环境变量

关键技术

  1. Koa:轻量级的 Web 框架
  2. Koa Router:路由管理
  3. Mongoose:MongoDB ODM
  4. JWT:身份认证
  5. bcryptjs:密码加密

4.4 数据库设计

数据库选型

本系统选择 MongoDB 作为数据库,主要基于以下考虑:

  1. 灵活的数据模型:MongoDB 使用文档模型,适合存储非结构化数据
  2. 易于扩展:支持水平扩展,便于应对数据增长
  3. 开发效率高:与 JavaScript 对象模型匹配,开发便捷
  4. 性能优秀:读写性能好,适合高并发场景

数据模型设计

1. 用户(User)集合

javascript 复制代码
{
  _id: ObjectId,              // 用户ID
  username: String,           // 用户名(唯一)
  email: String,              // 邮箱(唯一)
  password: String,           // 密码(加密)
  avatar: String,             // 头像URL
  role: String,               // 角色(user/admin)
  school: String,             // 学校
  major: String,              // 专业
  graduationYear: Number,     // 毕业年份
  profession: String,         // 职业
  bio: String,                // 个人简介
  points: Number,             // 积分
  isVerified: Boolean,        // 是否认证
  lastLoginAt: Date,          // 最后登录时间
  isActive: Boolean,          // 是否激活
  createdAt: Date,            // 创建时间
  updatedAt: Date             // 更新时间
}

2. 帖子(Post)集合

javascript 复制代码
{
  _id: ObjectId,              // 帖子ID
  title: String,              // 标题
  content: String,            // 内容
  category: String,           // 分类
  tags: [String],             // 标签数组
  author: ObjectId,           // 作者ID(引用User)
  likes: [{                   // 点赞列表
    user: ObjectId,           // 用户ID
    createdAt: Date           // 点赞时间
  }],
  views: Number,              // 浏览量
  comments: [ObjectId],       // 评论ID数组
  isPinned: Boolean,          // 是否置顶
  isActive: Boolean,          // 是否激活
  isDeleted: Boolean,         // 是否删除
  deletedAt: Date,            // 删除时间
  deletedBy: ObjectId,        // 删除者ID
  createdAt: Date,            // 创建时间
  updatedAt: Date             // 更新时间
}

3. 评论(Comment)集合

javascript 复制代码
{
  _id: ObjectId,              // 评论ID
  content: String,            // 内容
  author: ObjectId,           // 作者ID(引用User)
  post: ObjectId,             // 帖子ID(引用Post)
  likes: [{                   // 点赞列表
    user: ObjectId,           // 用户ID
    createdAt: Date           // 点赞时间
  }],
  parentComment: ObjectId,    // 父评论ID(用于回复)
  replies: [ObjectId],        // 回复ID数组
  isActive: Boolean,          // 是否激活
  isDeleted: Boolean,         // 是否删除
  deletedAt: Date,            // 删除时间
  deletedBy: ObjectId,        // 删除者ID
  createdAt: Date,            // 创建时间
  updatedAt: Date             // 更新时间
}

4. 消息(Message)集合

javascript 复制代码
{
  _id: ObjectId,              // 消息ID
  sender: ObjectId,           // 发送者ID(引用User)
  receiver: ObjectId,         // 接收者ID(引用User)
  content: String,            // 内容
  isRead: Boolean,            // 是否已读
  createdAt: Date,            // 创建时间
  updatedAt: Date             // 更新时间
}

5. 公告(Announcement)集合

javascript 复制代码
{
  _id: ObjectId,              // 公告ID
  title: String,              // 标题
  content: String,            // 内容
  type: String,               // 类型(system/activity/maintenance/important)
  author: ObjectId,           // 作者ID(引用User)
  priority: Number,           // 优先级
  expiresAt: Date,            // 过期时间
  viewCount: Number,          // 浏览量
  isActive: Boolean,          // 是否激活
  createdAt: Date,            // 创建时间
  updatedAt: Date             // 更新时间
}

5. 技术知识点文档

5.1 前端技术栈

5.1.1 Vue 3

Composition API

  • setup 函数: 组件的入口点,替代 Options API
  • 响应式 API :
    • ref(): 创建响应式引用,适用于基本类型
    • reactive(): 创建响应式对象,适用于对象类型
    • computed(): 创建计算属性
    • watch(): 监听响应式数据变化
  • 生命周期钩子 :
    • onMounted(): 组件挂载后执行
    • onUnmounted(): 组件卸载前执行
    • onBeforeMount(): 组件挂载前执行

Vue Router 4

  • 路由配置: 定义应用的路由规则
  • 路由守卫 :
    • 全局前置守卫 beforeEach: 用于权限验证
    • 路由独享守卫: 特定路由的守卫
  • 编程式导航 :
    • router.push(): 跳转到新路由
    • router.replace(): 替换当前路由
    • router.back(): 返回上一页
  • 动态路由 : 使用参数匹配路由,如 /posts/:id

Pinia 状态管理

  • Store 定义 : 使用 defineStore 创建状态仓库
  • State: 存储应用状态
  • Getters: 计算派生状态
  • Actions: 定义修改状态的方法
  • 持久化: 使用 localStorage 持久化用户信息和 Token
5.1.2 TypeScript

类型系统

  • 基础类型: string, number, boolean, array, object
  • 接口定义: 定义对象的结构
  • 类型别名 : 使用 type 定义复杂类型
  • 泛型: 创建可重用的组件
  • 类型断言: 手动指定值的类型

在 Vue 中使用 TypeScript

  • Props 类型定义 : 使用 defineProps<T>()
  • Emit 类型定义 : 使用 defineEmits<T>()
  • Ref 类型 : Ref<T>, ComputedRef<T>
  • 组件实例类型 : ComponentPublicInstance
5.1.3 Element Plus

组件库

  • 表单组件: el-form, el-input, el-select, el-button
  • 数据展示: el-table, el-card, el-tag, el-avatar
  • 反馈组件: el-message, el-dialog, el-loading
  • 导航组件: el-menu, el-tabs, el-pagination
  • 布局组件: el-container, el-row, el-col
5.1.4 Axios

HTTP 客户端

  • 实例创建: 创建自定义 axios 实例
  • 请求拦截器: 在请求发送前添加 Token
  • 响应拦截器: 统一处理响应和错误
  • 错误处理: 根据状态码显示不同错误信息

API 封装

  • 模块化: 按功能模块划分 API
  • 类型安全: 使用 TypeScript 定义请求和响应类型
  • 统一格式: 保持 API 调用的一致性

5.2 后端技术栈

5.2.1 Koa 框架
  • 中间件: 洋葱模型的中间件机制
  • Context 对象: 封装 request 和 response
  • 错误处理: 统一的错误处理机制
  • 异步流程: 基于 async/await
5.2.2 常用中间件
  • koa-router: 路由管理
  • koa-bodyparser: 解析请求体
  • koa-cors: 处理跨域请求
  • 自定义中间件: 认证、日志等

5.3 数据库:MongoDB

5.3.1 NoSQL 数据库
  • 文档存储: 使用 JSON 格式存储数据
  • 集合: 类似关系型数据库的表
  • 灵活的模式: 无需预定义结构
  • 索引: 提高查询性能
5.3.2 Mongoose ODM
  • Schema 定义: 定义数据模型结构
  • 模型方法: 实例方法和静态方法
  • 中间件: pre/post 钩子
  • 验证: 数据验证规则
  • 关联: 使用 ref 建立文档关联
  • 查询构建器: 链式查询 API
5.3.3 常用操作
  • CRUD: Create, Read, Update, Delete
  • 查询: find, findOne, findById
  • 更新: updateOne, updateMany, findByIdAndUpdate
  • 删除: deleteOne, deleteMany, findByIdAndDelete
  • 聚合: aggregate 管道操作

6. 系统详细设计与实现

6.1 前端实现

前端项目结构

本系统前端采用 Vue3 + TypeScript + Vite 技术栈,项目结构如下:

less 复制代码
src/
  ├── api/           // 封装所有后端接口请求
  ├── assets/        // 静态资源
  ├── components/    // 公共组件
  ├── layouts/       // 页面布局
  ├── router/        // 路由配置
  ├── stores/        // 状态管理
  ├── styles/        // 全局样式
  ├── types/         // 类型定义
  ├── views/         // 业务页面
  └── main.ts        // 入口文件

路由与页面设计

前端采用 Vue Router 实现页面路由管理,主要路由包括:首页、登录、注册、帖子列表、帖子详情、个人中心、消息中心、后台管理等。部分路由配置示例:

js 复制代码
// src/router/index.ts
import { createRouter, createWebHistory } from 'vue-router'
import Home from '../views/Home.vue'
import Login from '../views/Login.vue'
import Register from '../views/Register.vue'
// ... 其他页面

const routes = [
  { path: '/', component: Home },
  { path: '/login', component: Login },
  { path: '/register', component: Register },
  // ... 其他路由
]

const router = createRouter({
  history: createWebHistory(),
  routes,
})

export default router

状态管理 本系统采用 Pinia 进行全局状态管理,主要管理用户信息、帖子列表、消息通知等。以用户认证为例:

js 复制代码
// src/stores/auth.ts
import { defineStore } from 'pinia'

export const useAuthStore = defineStore('auth', {
  state: () => ({
    token: '',
    user: null,
  }),
  actions: {
    setToken(token: string) {
      this.token = token
    },
    setUser(user: any) {
      this.user = user
    },
    logout() {
      this.token = ''
      this.user = null
    }
  }
})

API 封装

所有后端接口请求统一封装在 src/api/ 目录下,便于维护和复用。例如用户登录接口:

js 复制代码
// src/api/auth.ts
import axios from 'axios'

export function login(data: { username: string, password: string }) {
  return axios.post('/api/auth/login', data)
}

主要页面与组件实现

  • 首页(Home.vue):展示最新帖子、热门标签、公告等
  • 帖子列表(Posts.vue):分页展示所有帖子,支持分类、标签筛选
  • 帖子详情(PostDetail.vue):展示帖子内容、评论列表、评论输入框
  • 登录/注册(Login.vue/Register.vue):表单校验、接口对接
  • 个人中心(Profile.vue):展示和编辑个人信息
  • 消息中心(Messages.vue):展示系统消息、私信
  • 后台管理(admin/):管理员专属页面,管理用户、帖子、举报等

6.2 后端实现

后端项目结构

后端采用 Node.js + Express + MongoDB 技术栈,项目结构如下:

arduino 复制代码
server/
  ├── src/
      ├── app.js            // 应用入口
      ├── config/           // 配置文件
      ├── middleware/       // 中间件
      ├── models/           // 数据模型
      ├── routes/           // 路由
      └── ...               // 其他

路由与中间件

后端采用 Express 路由机制,将不同功能模块的接口分离管理。例如用户认证路由:

js 复制代码
// server/src/routes/auth.js
const express = require('express')
const router = express.Router()
const { login, register } = require('../controllers/authController')

router.post('/login', login)
router.post('/register', register)

module.exports = router

中间件用于处理请求认证、错误处理、日志记录等。例如 JWT 认证中间件:

js 复制代码
// server/src/middleware/auth.js
const jwt = require('jsonwebtoken')

module.exports = function (req, res, next) {
  const token = req.headers['authorization']
  if (!token) return res.status(401).json({ message: '未登录' })
  try {
    const decoded = jwt.verify(token, 'your_jwt_secret')
    req.user = decoded
    next()
  } catch (err) {
    res.status(401).json({ message: 'Token无效' })
  }
}

数据模型设计

后端采用 Mongoose 定义数据模型。例如用户模型:

评论与互动

  1. 用户可对帖子进行评论,评论可被回复
  2. 评论数据与帖子关联,支持评论点赞、删除
  3. 评论成功后,系统自动生成通知消息

消息通知

  1. 用户收到评论、回复、私信等事件时,后端生成消息记录
  2. 前端定时拉取或通过 WebSocket 获取新消息
  3. 用户可在消息中心查看、标记已读

举报与后台管理

  1. 用户可对违规内容进行举报,填写举报原因
  2. 后端存储举报信息,管理员后台可查看、处理举报
  3. 管理员可对用户、帖子、评论等进行管理操作

6.3 代码实现示例

6.1 用户注册接口(后端)
js 复制代码
// server/src/controllers/authController.js
const User = require('../models/User')
const bcrypt = require('bcryptjs')
const jwt = require('jsonwebtoken')

exports.register = async (req, res) => {
  const { username, password, email } = req.body
  const user = await User.findOne({ username })
  if (user) return res.status(400).json({ message: '用户名已存在' })
  const hash = await bcrypt.hash(password, 10)
  const newUser = new User({ username, password: hash, email })
  await newUser.save()
  res.json({ message: '注册成功' })
}
6.2 用户登录接口(后端)
php 复制代码
exports.login = async (req, res) => {
  const { username, password } = req.body
  const user = await User.findOne({ username })
  if (!user) return res.status(400).json({ message: '用户不存在' })
  const isMatch = await bcrypt.compare(password, user.password)
  if (!isMatch) return res.status(400).json({ message: '密码错误' })
  const token = jwt.sign({ id: user._id, username: user.username }, 'your_jwt_secret', { expiresIn: '7d' })
  res.json({ token, user })
}
6.3 帖子发布接口(后端)
js 复制代码
// server/src/controllers/postController.js
const Post = require('../models/Post')

exports.createPost = async (req, res) => {
  const { title, content, category, tags } = req.body
  const post = new Post({
    author: req.user.id,
    title,
    content,
    category,
    tags,
    createdAt: new Date()
  })
  await post.save()
  res.json({ message: '帖子发布成功', post })
}
相关推荐
木易 士心1 小时前
Element UI 多级菜单缩进的动态控制:从原理到工程化实践
前端·vue.js·ui
正在走向自律2 小时前
企业微信消息推送全链路实战:Java后端与Vue前端集成指南
前端·vue.js·企业微信·企业微信消息推送·官方企业微信
lcc1872 小时前
Vue3 CompositionAPI的优势
前端·vue.js
Lazy_zheng2 小时前
前端页面更新检测实战:一次关于「用户不刷新」的需求拉扯战
前端·vue.js·性能优化
undsky2 小时前
【RuoYi-Eggjs】:告别手写,自动生成代码
后端·node.js
August_._3 小时前
【软件安装教程】Node.js 开发环境搭建详解:从安装包下载到全局配置,一篇搞定所有流程
java·vue.js·windows·后端·node.js·配置
一颗烂土豆3 小时前
🚀从 autofit 到 vfit:Vue 开发者该选哪个大屏适配工具?
前端·vue.js
一颗宁檬不酸3 小时前
Vue.js 初学者基础知识点总结 第一弹
前端·javascript·vue.js
T0uken3 小时前
Go + Node.js 全栈单文件部署方案
golang·node.js·状态模式