Echo/README.md

281 lines
8.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Echo — 开源社区系统
---
## 📚 从本项目你能学到什么
- 学会主流的 Java Web 开发技术和框架
- 积累一个真实的 Web 项目开发经验
- 掌握本项目中涉及的常见面试题的答题策略
## 💻 核心技术栈
后端:
- Spring
- Spring Boot 2.1.5 RELEASE
- Spring MVC
- ORMMyBatis
- 数据库MySQL 5.7
- 日志SLF4J日志接口 + Logback日志实现
- 缓存Redis
- 消息队列Kafka 2.13-2.7.0
- 搜索引擎Elasticsearch 6.4.3
- 安全Spring Security
- 邮件Spring Mail
- 分布式定时任务Spring Quartz
- 监控Spring Actuator
前端:
- Thymeleaf
- Bootstrap 4.x
- Jquery
- Ajax
## 🔨 开发环境
- 操作系统Windows 10
- 构建工具Apache Maven
- 集成开发工具Intellij IDEA
- 数据库MySQL 5.7
- 应用服务器Apache Tomcat
- 接口测试工具Postman
- 版本控制工具Git
## 🎨 功能列表
- [x] **注册**MySQL
- 用户注册成功,将用户信息存入 MySQL但此时该用户状态为未激活
- 向用户发送激活邮件用户点击链接则激活账号Spring Mail
- [x] **登录 | 登出**MySQL、Redis
- 进入登录界面,动态生成验证码,并将验证码短暂存入 Redis60 秒)
- 用户登录成功(验证用户名、密码、验证码),生成登录凭证且设置状态为有效,并将登录凭证存入 Redis
注意:登录凭证存在有效期,在所有的请求执行之前,都会检查凭证是否有效和是否过期,只要该用户的凭证有效并在有效期时间内,本次请求就会一直持有该用户信息(使用 ThreadLocal 持有用户信息)
- 勾选记住我,则延长登录凭证有效时间
- 用户登录成功,将用户信息短暂存入 Redis1 小时)
- 用户登出,将凭证状态设为无效,并更新 Redis 中该用户的登录凭证信息
- [x] **账号设置**MySQL
- 修改头像
- 修改密码
- [x] **帖子模块**MySQL
- 发布帖子(过滤敏感词),将其存入 MySQL
- 分页显示所有的帖子
- 支持按照 “发帖时间” 显示
- 支持按照 “热度排行” 显示Spring Quartz
- 查看帖子详情
- 权限管理Spring Security + Thymeleaf Security
- 未登录用户无法发帖
- “版主” 可以看到帖子的置顶和加精按钮并执行相应操作
- “管理员” 可以看到帖子的删除按钮并执行相应操作
- “普通用户” 无法看到帖子的置顶、加精、删除按钮,也无法执行相应操作
- [x] **评论模块**MySQL
- 发布对帖子的评论(过滤敏感词),将其存入 MySQL
- 分页显示评论
- 发布对评论的回复(过滤敏感词)
- 权限管理Spring Security
- 未登录用户无法使用评论功能
- [x] **私信模块**MySQL
- 发送私信(过滤敏感词)
- 私信列表
- 查询当前用户的会话列表
- 每个会话只显示一条最新的私信
- 支持分页显示
- 私信详情
- 查询某个会话所包含的所有私信
- 访问私信详情时,将显示的私信设为已读状态
- 支持分页显示
- 权限管理Spring Security
- 未登录用户无法使用私信功能
- [x] **统一处理异常**404、500
- 普通请求异常
- 异步请求异常
- [x] **统一记录日志**
- [x] **点赞模块**Redis
- 点赞
- 获赞
- 权限管理Spring Security
- 未登录用户无法使用点赞相关功能
- [x] **关注模块**Redis
- 关注功能
- 取消关注功能
- 统计用户的关注数和粉丝数
- 关注列表(查询某个用户关注的人),支持分页
- 粉丝列表(查询某个用户的粉丝),支持分页
- 权限管理Spring Security
- 未登录用户无法使用关注相关功能
- [x] **系统通知模块**Kafka
- 通知列表
- 显示评论、点赞、关注三种类型的通知
- 通知详情
- 分页显示某一类主题所包含的通知
- 进入某种类型的系统通知详情,则将该页的所有未读的系统通知状态设置为已读
- 未读数量
- 分别显示每种类型的系统通知的未读数量
- 显示所有系统通知的未读数量
- 导航栏显示所有消息的未读数量(未读私信 + 未读系统通知)
- 权限管理Spring Security
- 未登录用户无法使用系统通知功能
- [x] **搜索模块**Elasticsearch + Kafka
- 发布事件
- 发布帖子时,通过消息队列将帖子异步地提交到 Elasticsearch 服务器
- 为帖子增加评论时,通过消息队列将帖子异步地提交到 Elasticsearch 服务器
- 搜索服务
- 从 Elasticsearch 服务器搜索帖子
- 从 Elasticsearch 服务器删除帖子(当帖子从数据库中被删除时)
- 显示搜索结果
- [x] **网站数据统计**(管理员专属)
- 独立访客 UV
- 存入 Redis 的 HyperLogLog
- 支持单日查询和区间日期查询
- 日活跃用户 DAU
- 存入 Redis 的 Bitmap
- 支持单日查询和区间日期查询
- 权限管理Spring Security
- 只有管理员可以查看网站数据统计
- [ ] 文件上传
- [ ] 优化网站性能
## 🔐 待实现及优化
- [ ] 修改用户名
- [ ] 查询我的帖子
- [ ] 查询我的评论
- [ ] 查询我的点赞
- [ ] 管理员对帖子的二次点击取消置顶功能
- [ ] 管理员对已删除帖子的恢复功能
## 🎀 界面展示
## 📜 数据库设计
用户 `user`
```sql
DROP TABLE IF EXISTS `user`;
SET character_set_client = utf8mb4 ;
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(50) DEFAULT NULL,
`password` varchar(50) DEFAULT NULL,
`salt` varchar(50) DEFAULT NULL,
`email` varchar(100) DEFAULT NULL,
`type` int(11) DEFAULT NULL COMMENT '0-普通用户; 1-超级管理员; 2-版主;',
`status` int(11) DEFAULT NULL COMMENT '0-未激活; 1-已激活;',
`activation_code` varchar(100) DEFAULT NULL,
`header_url` varchar(200) DEFAULT NULL,
`create_time` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `index_username` (`username`(20)),
KEY `index_email` (`email`(20))
) ENGINE=InnoDB AUTO_INCREMENT=101 DEFAULT CHARSET=utf8;
```
讨论帖 `discuss_post`
```sql
DROP TABLE IF EXISTS `discuss_post`;
SET character_set_client = utf8mb4 ;
CREATE TABLE `discuss_post` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) DEFAULT NULL,
`title` varchar(100) DEFAULT NULL,
`content` text,
`type` int(11) DEFAULT NULL COMMENT '0-普通; 1-置顶;',
`status` int(11) DEFAULT NULL COMMENT '0-正常; 1-精华; 2-拉黑;',
`create_time` timestamp NULL DEFAULT NULL,
`comment_count` int(11) DEFAULT NULL,
`score` double DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `index_user_id` (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
```
评论(回复)`comment`
```sql
CREATE TABLE `comment` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) DEFAULT NULL,
`entity_type` int(11) DEFAULT NULL COMMENT '评论目标的类别1 帖子2 评论 ',
`entity_id` int(11) DEFAULT NULL COMMENT '评论目标的 id',
`target_id` int(11) DEFAULT NULL COMMENT '指明对谁进行评论',
`content` text,
`status` int(11) DEFAULT NULL COMMENT '状态0 正常1 禁用',
`create_time` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `index_user_id` (`user_id`),
KEY `index_entity_id` (`entity_id`)
) ENGINE=InnoDB AUTO_INCREMENT=247 DEFAULT CHARSET=utf8;
```
登录凭证 `login_ticket`(废弃,使用 Redis 存储):
```sql
DROP TABLE IF EXISTS `login_ticket`;
SET character_set_client = utf8mb4 ;
CREATE TABLE `login_ticket` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`ticket` varchar(45) NOT NULL COMMENT '凭证',
`status` int(11) DEFAULT '0' COMMENT '凭证状态0-有效; 1-无效;',
`expired` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '凭证到期时间',
PRIMARY KEY (`id`),
KEY `index_ticket` (`ticket`(20))
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
```
私信 `message`
```sql
DROP TABLE IF EXISTS `message`;
SET character_set_client = utf8mb4 ;
CREATE TABLE `message` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`from_id` int(11) DEFAULT NULL,
`to_id` int(11) DEFAULT NULL,
`conversation_id` varchar(45) NOT NULL,
`content` text,
`status` int(11) DEFAULT NULL COMMENT '0-未读;1-已读;2-删除;',
`create_time` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `index_from_id` (`from_id`),
KEY `index_to_id` (`to_id`),
KEY `index_conversation_id` (`conversation_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
```
## 📖 常见面试题