975 lines
20 KiB
Markdown
975 lines
20 KiB
Markdown
|
|
# 🔍 动动脑新闻系统 - 项目优化建议报告
|
|||
|
|
|
|||
|
|
**检查时间:** 2025-10-30
|
|||
|
|
**项目版本:** v1.0.0
|
|||
|
|
**报告类型:** 全面代码审查与优化建议
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 📋 执行摘要
|
|||
|
|
|
|||
|
|
经过全面检查,项目整体改造完成度较高,核心功能已完成定制化。发现 **15个需要优化的问题** 和 **8个缺失的功能**,建议按优先级逐步完善。
|
|||
|
|
|
|||
|
|
**评分概览:**
|
|||
|
|
- 核心改造完成度:✅ 95%
|
|||
|
|
- 安全配置:⭐⭐⭐⭐ (4/5星)
|
|||
|
|
- 代码质量:⭐⭐⭐⭐ (4/5星)
|
|||
|
|
- 文档完整性:⭐⭐⭐ (3/5星)
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🔴 高优先级问题(必须修复)
|
|||
|
|
|
|||
|
|
### 1. 前端登录页面版权信息未修改 ⚠️
|
|||
|
|
|
|||
|
|
**问题描述:**
|
|||
|
|
登录页面和注册页面底部仍显示 `ruoyi.vip` 的版权信息。
|
|||
|
|
|
|||
|
|
**影响:**
|
|||
|
|
- 用户体验差,显示错误品牌信息
|
|||
|
|
- 不符合企业定制化要求
|
|||
|
|
|
|||
|
|
**位置:**
|
|||
|
|
- `ruoyi-ui/src/views/login.vue` 第59行
|
|||
|
|
- `ruoyi-ui/src/views/register.vue` 第64行
|
|||
|
|
|
|||
|
|
**当前代码:**
|
|||
|
|
```vue
|
|||
|
|
<span>Copyright © 2018-2025 ruoyi.vip All Rights Reserved.</span>
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**建议修改为:**
|
|||
|
|
```vue
|
|||
|
|
<span>Copyright © 2025 动动脑(DDNAI). All Rights Reserved.</span>
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### 2. 登录页面默认填充账号密码 🔒
|
|||
|
|
|
|||
|
|
**问题描述:**
|
|||
|
|
`login.vue` 中默认填充了 `admin/admin123`,这在生产环境是严重的安全隐患。
|
|||
|
|
|
|||
|
|
**位置:** `ruoyi-ui/src/views/login.vue` 第76-77行
|
|||
|
|
|
|||
|
|
**当前代码:**
|
|||
|
|
```javascript
|
|||
|
|
loginForm: {
|
|||
|
|
username: "admin",
|
|||
|
|
password: "admin123",
|
|||
|
|
rememberMe: false,
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**建议修改为:**
|
|||
|
|
```javascript
|
|||
|
|
loginForm: {
|
|||
|
|
username: "", // 生产环境必须为空
|
|||
|
|
password: "", // 生产环境必须为空
|
|||
|
|
rememberMe: false,
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**或者使用环境变量:**
|
|||
|
|
```javascript
|
|||
|
|
loginForm: {
|
|||
|
|
username: process.env.NODE_ENV === 'development' ? "admin" : "",
|
|||
|
|
password: process.env.NODE_ENV === 'development' ? "admin123" : "",
|
|||
|
|
rememberMe: false,
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### 3. 缺少环境配置文件 📂
|
|||
|
|
|
|||
|
|
**问题描述:**
|
|||
|
|
项目缺少 `application-dev.yml` 和 `application-prod.yml` 等环境特定配置文件,不利于多环境部署。
|
|||
|
|
|
|||
|
|
**建议:**
|
|||
|
|
创建以下配置文件:
|
|||
|
|
|
|||
|
|
**application-dev.yml(开发环境):**
|
|||
|
|
```yaml
|
|||
|
|
spring:
|
|||
|
|
datasource:
|
|||
|
|
druid:
|
|||
|
|
master:
|
|||
|
|
url: jdbc:mysql://localhost:3306/ry_news?useUnicode=true&characterEncoding=utf8&...
|
|||
|
|
username: root
|
|||
|
|
password: dev_password
|
|||
|
|
|
|||
|
|
# 开发环境可以开启
|
|||
|
|
swagger:
|
|||
|
|
enabled: true
|
|||
|
|
|
|||
|
|
# 开发环境日志级别
|
|||
|
|
logging:
|
|||
|
|
level:
|
|||
|
|
com.ddnai: debug
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**application-prod.yml(生产环境):**
|
|||
|
|
```yaml
|
|||
|
|
spring:
|
|||
|
|
datasource:
|
|||
|
|
druid:
|
|||
|
|
master:
|
|||
|
|
url: jdbc:mysql://prod-db-server:3306/ry_news?useUnicode=true&characterEncoding=utf8&...
|
|||
|
|
username: prod_user
|
|||
|
|
password: ${DB_PASSWORD} # 使用环境变量
|
|||
|
|
|
|||
|
|
# 生产环境必须关闭
|
|||
|
|
swagger:
|
|||
|
|
enabled: false
|
|||
|
|
|
|||
|
|
# 生产环境日志级别
|
|||
|
|
logging:
|
|||
|
|
level:
|
|||
|
|
com.ddnai: info
|
|||
|
|
|
|||
|
|
# 生产环境限制Druid访问
|
|||
|
|
spring:
|
|||
|
|
datasource:
|
|||
|
|
druid:
|
|||
|
|
statViewServlet:
|
|||
|
|
allow: 127.0.0.1,192.168.1.0/24
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### 4. Swagger在生产环境未关闭 ⚠️
|
|||
|
|
|
|||
|
|
**问题描述:**
|
|||
|
|
当前配置中 Swagger 始终开启,生产环境暴露API文档是严重安全隐患。
|
|||
|
|
|
|||
|
|
**位置:** `ry-news-admin/src/main/resources/application.yml` 第118行
|
|||
|
|
|
|||
|
|
**当前配置:**
|
|||
|
|
```yaml
|
|||
|
|
swagger:
|
|||
|
|
enabled: true # 始终开启
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**建议改为:**
|
|||
|
|
```yaml
|
|||
|
|
swagger:
|
|||
|
|
# 仅在开发和测试环境开启
|
|||
|
|
enabled: ${SWAGGER_ENABLED:false}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
然后在不同环境配置:
|
|||
|
|
- `application-dev.yml`: `enabled: true`
|
|||
|
|
- `application-prod.yml`: `enabled: false`
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🟡 中优先级问题(建议修复)
|
|||
|
|
|
|||
|
|
### 5. Druid监控未配置IP白名单 🔒
|
|||
|
|
|
|||
|
|
**问题描述:**
|
|||
|
|
Druid监控页面没有配置IP访问限制,任何人都可以访问。
|
|||
|
|
|
|||
|
|
**位置:** `application-druid.yml` 第47行
|
|||
|
|
|
|||
|
|
**当前配置:**
|
|||
|
|
```yaml
|
|||
|
|
statViewServlet:
|
|||
|
|
allow: # 空,允许所有访问
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**建议配置:**
|
|||
|
|
```yaml
|
|||
|
|
statViewServlet:
|
|||
|
|
# 仅允许本机和内网访问
|
|||
|
|
allow: 127.0.0.1,192.168.0.0/16,10.0.0.0/8
|
|||
|
|
# 或者仅允许本机访问
|
|||
|
|
# allow: 127.0.0.1
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### 6. 缺少Redis密码配置 🔒
|
|||
|
|
|
|||
|
|
**问题描述:**
|
|||
|
|
Redis配置中密码为空,如果Redis设置了密码会导致连接失败。
|
|||
|
|
|
|||
|
|
**位置:** `application.yml` 第77行
|
|||
|
|
|
|||
|
|
**当前配置:**
|
|||
|
|
```yaml
|
|||
|
|
redis:
|
|||
|
|
password: # 空
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**建议:**
|
|||
|
|
```yaml
|
|||
|
|
redis:
|
|||
|
|
# 如果Redis有密码,必须配置
|
|||
|
|
password: ${REDIS_PASSWORD:}
|
|||
|
|
# 使用环境变量,默认为空
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### 7. 文件上传路径未检查是否存在 📁
|
|||
|
|
|
|||
|
|
**问题描述:**
|
|||
|
|
配置的文件上传路径 `D:/ddnai/uploadPath` 可能不存在,会导致上传失败。
|
|||
|
|
|
|||
|
|
**位置:** `application.yml` 第10行
|
|||
|
|
|
|||
|
|
**建议:**
|
|||
|
|
1. 在应用启动时检查目录是否存在,不存在则创建
|
|||
|
|
2. 提供Windows和Linux两套配置
|
|||
|
|
3. 添加配置验证
|
|||
|
|
|
|||
|
|
**改进方案:**
|
|||
|
|
```yaml
|
|||
|
|
ruoyi:
|
|||
|
|
# 文件上传路径(确保目录存在且有写权限)
|
|||
|
|
profile: ${UPLOAD_PATH:D:/ddnai/uploadPath}
|
|||
|
|
# 支持环境变量覆盖
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**添加启动检查代码:**
|
|||
|
|
```java
|
|||
|
|
@Component
|
|||
|
|
public class FilePathValidator implements ApplicationRunner {
|
|||
|
|
@Value("${ruoyi.profile}")
|
|||
|
|
private String uploadPath;
|
|||
|
|
|
|||
|
|
@Override
|
|||
|
|
public void run(ApplicationArguments args) throws Exception {
|
|||
|
|
File uploadDir = new File(uploadPath);
|
|||
|
|
if (!uploadDir.exists()) {
|
|||
|
|
boolean created = uploadDir.mkdirs();
|
|||
|
|
if (!created) {
|
|||
|
|
throw new RuntimeException("无法创建上传目录: " + uploadPath);
|
|||
|
|
}
|
|||
|
|
log.info("已创建上传目录: {}", uploadPath);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### 8. 日志文件路径配置不统一 📋
|
|||
|
|
|
|||
|
|
**问题描述:**
|
|||
|
|
Windows环境下,日志路径配置为Linux路径 `/home/ddnai/logs`。
|
|||
|
|
|
|||
|
|
**位置:** `logback.xml` 第4行
|
|||
|
|
|
|||
|
|
**当前配置:**
|
|||
|
|
```xml
|
|||
|
|
<property name="log.path" value="/home/ddnai/logs" />
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**建议改为:**
|
|||
|
|
```xml
|
|||
|
|
<!-- 支持环境变量配置,默认当前目录下的logs -->
|
|||
|
|
<property name="log.path" value="${LOG_PATH:-./logs}" />
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
然后通过启动参数指定:
|
|||
|
|
```bash
|
|||
|
|
# Windows
|
|||
|
|
java -jar -DLOG_PATH=D:/ddnai/logs ry-news-admin.jar
|
|||
|
|
|
|||
|
|
# Linux
|
|||
|
|
java -jar -DLOG_PATH=/home/ddnai/logs ry-news-admin.jar
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### 9. 代码中保留了大量Ruoyi版权注释 📝
|
|||
|
|
|
|||
|
|
**问题描述:**
|
|||
|
|
多个JavaScript文件中的代码注释仍保留 `Copyright (c) 2019 ruoyi`。
|
|||
|
|
|
|||
|
|
**影响位置:**
|
|||
|
|
- `ruoyi-ui/src/utils/ruoyi.js`
|
|||
|
|
- `ruoyi-ui/src/directive/permission/hasRole.js`
|
|||
|
|
- `ruoyi-ui/src/directive/permission/hasPermi.js`
|
|||
|
|
- `ruoyi-ui/src/directive/module/clipboard.js`
|
|||
|
|
- `ruoyi-ui/src/directive/dialog/drag*.js`
|
|||
|
|
- `ruoyi-ui/src/assets/styles/ruoyi.scss`
|
|||
|
|
|
|||
|
|
**当前注释:**
|
|||
|
|
```javascript
|
|||
|
|
/**
|
|||
|
|
* Copyright (c) 2019 ruoyi
|
|||
|
|
*/
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**建议修改为:**
|
|||
|
|
```javascript
|
|||
|
|
/**
|
|||
|
|
* 动动脑新闻系统
|
|||
|
|
* Copyright (c) 2025 DDNAI
|
|||
|
|
*
|
|||
|
|
* 基于RuoYi开源框架定制开发
|
|||
|
|
* Original framework: https://gitee.com/y_project/RuoYi-Vue
|
|||
|
|
*/
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### 10. 缺少.gitignore配置 📂
|
|||
|
|
|
|||
|
|
**问题描述:**
|
|||
|
|
`.gitignore` 文件配置不完整,可能导致敏感信息被提交到代码仓库。
|
|||
|
|
|
|||
|
|
**建议增加以下配置:**
|
|||
|
|
```gitignore
|
|||
|
|
######################################################################
|
|||
|
|
# 敏感配置文件
|
|||
|
|
application-prod.yml
|
|||
|
|
application-local.yml
|
|||
|
|
|
|||
|
|
# 日志文件
|
|||
|
|
logs/
|
|||
|
|
*.log
|
|||
|
|
|
|||
|
|
# 上传文件
|
|||
|
|
uploadPath/
|
|||
|
|
|
|||
|
|
# 环境变量文件
|
|||
|
|
.env
|
|||
|
|
.env.local
|
|||
|
|
.env.production
|
|||
|
|
|
|||
|
|
# 前端
|
|||
|
|
ruoyi-ui/node_modules/
|
|||
|
|
ruoyi-ui/dist/
|
|||
|
|
ruoyi-ui/.env.development.local
|
|||
|
|
ruoyi-ui/.env.production.local
|
|||
|
|
|
|||
|
|
# 数据库文件
|
|||
|
|
*.sql.backup
|
|||
|
|
*.db
|
|||
|
|
|
|||
|
|
######################################################################
|
|||
|
|
# 操作系统
|
|||
|
|
.DS_Store
|
|||
|
|
Thumbs.db
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🟢 低优先级问题(建议优化)
|
|||
|
|
|
|||
|
|
### 11. 文档目录包含原框架文档 📚
|
|||
|
|
|
|||
|
|
**问题描述:**
|
|||
|
|
`doc/` 目录下还有 `若依环境使用手册.docx`。
|
|||
|
|
|
|||
|
|
**建议:**
|
|||
|
|
- 删除或重命名为 `动动脑新闻系统使用手册.docx`
|
|||
|
|
- 添加自己的项目文档
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### 12. 缺少健康检查接口 🏥
|
|||
|
|
|
|||
|
|
**问题描述:**
|
|||
|
|
没有配置健康检查接口,不利于容器化部署和监控。
|
|||
|
|
|
|||
|
|
**建议添加:**
|
|||
|
|
```yaml
|
|||
|
|
# application.yml
|
|||
|
|
management:
|
|||
|
|
endpoints:
|
|||
|
|
web:
|
|||
|
|
exposure:
|
|||
|
|
include: health,info
|
|||
|
|
endpoint:
|
|||
|
|
health:
|
|||
|
|
show-details: always
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**或添加自定义接口:**
|
|||
|
|
```java
|
|||
|
|
@RestController
|
|||
|
|
@RequestMapping("/actuator")
|
|||
|
|
public class HealthController {
|
|||
|
|
@GetMapping("/health")
|
|||
|
|
public Map<String, Object> health() {
|
|||
|
|
Map<String, Object> health = new HashMap<>();
|
|||
|
|
health.put("status", "UP");
|
|||
|
|
health.put("timestamp", System.currentTimeMillis());
|
|||
|
|
return health;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### 13. Token有效期配置偏短 ⏰
|
|||
|
|
|
|||
|
|
**问题描述:**
|
|||
|
|
Token有效期仅30分钟,频繁要求用户重新登录,用户体验差。
|
|||
|
|
|
|||
|
|
**位置:** `application.yml` 第98行
|
|||
|
|
|
|||
|
|
**当前配置:**
|
|||
|
|
```yaml
|
|||
|
|
token:
|
|||
|
|
expireTime: 30 # 30分钟
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**建议:**
|
|||
|
|
```yaml
|
|||
|
|
token:
|
|||
|
|
# 根据业务需求调整,建议2-8小时
|
|||
|
|
expireTime: 480 # 8小时 = 480分钟
|
|||
|
|
# 或使用环境变量
|
|||
|
|
expireTime: ${TOKEN_EXPIRE_TIME:480}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### 14. 数据库连接池配置可优化 🔧
|
|||
|
|
|
|||
|
|
**问题描述:**
|
|||
|
|
当前连接池配置适合小规模应用,中大型应用需要调整。
|
|||
|
|
|
|||
|
|
**位置:** `application-druid.yml`
|
|||
|
|
|
|||
|
|
**当前配置:**
|
|||
|
|
```yaml
|
|||
|
|
initialSize: 5
|
|||
|
|
minIdle: 10
|
|||
|
|
maxActive: 20
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**针对不同规模的建议:**
|
|||
|
|
|
|||
|
|
**小型应用(<100并发):**
|
|||
|
|
```yaml
|
|||
|
|
initialSize: 5
|
|||
|
|
minIdle: 10
|
|||
|
|
maxActive: 20
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**中型应用(100-500并发):**
|
|||
|
|
```yaml
|
|||
|
|
initialSize: 10
|
|||
|
|
minIdle: 20
|
|||
|
|
maxActive: 50
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**大型应用(>500并发):**
|
|||
|
|
```yaml
|
|||
|
|
initialSize: 20
|
|||
|
|
minIdle: 50
|
|||
|
|
maxActive: 200
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### 15. 缺少接口限流配置 🚦
|
|||
|
|
|
|||
|
|
**问题描述:**
|
|||
|
|
没有配置接口限流,容易遭受恶意攻击(如暴力破解登录)。
|
|||
|
|
|
|||
|
|
**建议添加限流配置:**
|
|||
|
|
|
|||
|
|
**方式1:使用Redis + 注解**
|
|||
|
|
```java
|
|||
|
|
@RestController
|
|||
|
|
public class LoginController {
|
|||
|
|
|
|||
|
|
@RateLimiter(key = "login", time = 60, count = 5)
|
|||
|
|
@PostMapping("/login")
|
|||
|
|
public AjaxResult login(@RequestBody LoginBody loginBody) {
|
|||
|
|
// 登录逻辑
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**方式2:在配置文件中配置**
|
|||
|
|
```yaml
|
|||
|
|
# application.yml
|
|||
|
|
rate-limiter:
|
|||
|
|
enabled: true
|
|||
|
|
# 登录接口:1分钟最多5次
|
|||
|
|
login:
|
|||
|
|
capacity: 5
|
|||
|
|
period: 60
|
|||
|
|
# 注册接口:1分钟最多3次
|
|||
|
|
register:
|
|||
|
|
capacity: 3
|
|||
|
|
period: 60
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🆕 缺失功能建议
|
|||
|
|
|
|||
|
|
### 1. 缺少数据库备份脚本 💾
|
|||
|
|
|
|||
|
|
**建议添加:**
|
|||
|
|
|
|||
|
|
**Windows批处理脚本(backup.bat):**
|
|||
|
|
```batch
|
|||
|
|
@echo off
|
|||
|
|
set BACKUP_DIR=D:\ddnai\backup
|
|||
|
|
set DB_NAME=ry_news
|
|||
|
|
set MYSQL_USER=root
|
|||
|
|
set MYSQL_PASS=your_password
|
|||
|
|
set DATE=%date:~0,4%%date:~5,2%%date:~8,2%_%time:~0,2%%time:~3,2%%time:~6,2%
|
|||
|
|
|
|||
|
|
if not exist %BACKUP_DIR% mkdir %BACKUP_DIR%
|
|||
|
|
|
|||
|
|
mysqldump -u%MYSQL_USER% -p%MYSQL_PASS% %DB_NAME% > %BACKUP_DIR%\%DB_NAME%_%DATE%.sql
|
|||
|
|
|
|||
|
|
echo Database backup completed: %BACKUP_DIR%\%DB_NAME%_%DATE%.sql
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**Linux Shell脚本(backup.sh):**
|
|||
|
|
```bash
|
|||
|
|
#!/bin/bash
|
|||
|
|
BACKUP_DIR="/home/ddnai/backup"
|
|||
|
|
DB_NAME="ry_news"
|
|||
|
|
MYSQL_USER="root"
|
|||
|
|
MYSQL_PASS="your_password"
|
|||
|
|
DATE=$(date +%Y%m%d_%H%M%S)
|
|||
|
|
|
|||
|
|
mkdir -p $BACKUP_DIR
|
|||
|
|
|
|||
|
|
mysqldump -u$MYSQL_USER -p$MYSQL_PASS $DB_NAME | gzip > $BACKUP_DIR/${DB_NAME}_${DATE}.sql.gz
|
|||
|
|
|
|||
|
|
# 删除7天前的备份
|
|||
|
|
find $BACKUP_DIR -name "${DB_NAME}_*.sql.gz" -mtime +7 -delete
|
|||
|
|
|
|||
|
|
echo "Database backup completed: $BACKUP_DIR/${DB_NAME}_${DATE}.sql.gz"
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### 2. 缺少Docker部署配置 🐳
|
|||
|
|
|
|||
|
|
**建议添加 Dockerfile:**
|
|||
|
|
|
|||
|
|
**后端Dockerfile:**
|
|||
|
|
```dockerfile
|
|||
|
|
FROM openjdk:8-jre-alpine
|
|||
|
|
|
|||
|
|
LABEL maintainer="admin@ddnai.com"
|
|||
|
|
|
|||
|
|
ENV TZ=Asia/Shanghai
|
|||
|
|
ENV JAVA_OPTS="-Xms512m -Xmx1024m"
|
|||
|
|
|
|||
|
|
WORKDIR /app
|
|||
|
|
|
|||
|
|
COPY ry-news-admin/target/ry-news-admin.jar app.jar
|
|||
|
|
|
|||
|
|
EXPOSE 8080
|
|||
|
|
|
|||
|
|
ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -jar app.jar"]
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**前端Dockerfile:**
|
|||
|
|
```dockerfile
|
|||
|
|
FROM node:14-alpine as builder
|
|||
|
|
|
|||
|
|
WORKDIR /app
|
|||
|
|
COPY ruoyi-ui/package*.json ./
|
|||
|
|
RUN npm install
|
|||
|
|
COPY ruoyi-ui/ .
|
|||
|
|
RUN npm run build:prod
|
|||
|
|
|
|||
|
|
FROM nginx:alpine
|
|||
|
|
COPY --from=builder /app/dist /usr/share/nginx/html
|
|||
|
|
COPY nginx.conf /etc/nginx/nginx.conf
|
|||
|
|
EXPOSE 80
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**docker-compose.yml:**
|
|||
|
|
```yaml
|
|||
|
|
version: '3.8'
|
|||
|
|
|
|||
|
|
services:
|
|||
|
|
mysql:
|
|||
|
|
image: mysql:8.0
|
|||
|
|
environment:
|
|||
|
|
MYSQL_ROOT_PASSWORD: ddnai@2025#mysql
|
|||
|
|
MYSQL_DATABASE: ry_news
|
|||
|
|
volumes:
|
|||
|
|
- ./sql:/docker-entrypoint-initdb.d
|
|||
|
|
- mysql-data:/var/lib/mysql
|
|||
|
|
ports:
|
|||
|
|
- "3306:3306"
|
|||
|
|
|
|||
|
|
redis:
|
|||
|
|
image: redis:6-alpine
|
|||
|
|
ports:
|
|||
|
|
- "6379:6379"
|
|||
|
|
|
|||
|
|
backend:
|
|||
|
|
build: .
|
|||
|
|
depends_on:
|
|||
|
|
- mysql
|
|||
|
|
- redis
|
|||
|
|
environment:
|
|||
|
|
SPRING_PROFILES_ACTIVE: prod
|
|||
|
|
DB_HOST: mysql
|
|||
|
|
DB_PASSWORD: ddnai@2025#mysql
|
|||
|
|
REDIS_HOST: redis
|
|||
|
|
ports:
|
|||
|
|
- "8080:8080"
|
|||
|
|
|
|||
|
|
frontend:
|
|||
|
|
build:
|
|||
|
|
context: .
|
|||
|
|
dockerfile: Dockerfile.frontend
|
|||
|
|
ports:
|
|||
|
|
- "80:80"
|
|||
|
|
|
|||
|
|
volumes:
|
|||
|
|
mysql-data:
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### 3. 缺少监控告警配置 📊
|
|||
|
|
|
|||
|
|
**建议集成 Spring Boot Actuator + Prometheus:**
|
|||
|
|
|
|||
|
|
**pom.xml添加依赖:**
|
|||
|
|
```xml
|
|||
|
|
<dependency>
|
|||
|
|
<groupId>org.springframework.boot</groupId>
|
|||
|
|
<artifactId>spring-boot-starter-actuator</artifactId>
|
|||
|
|
</dependency>
|
|||
|
|
<dependency>
|
|||
|
|
<groupId>io.micrometer</groupId>
|
|||
|
|
<artifactId>micrometer-registry-prometheus</artifactId>
|
|||
|
|
</dependency>
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**application.yml配置:**
|
|||
|
|
```yaml
|
|||
|
|
management:
|
|||
|
|
endpoints:
|
|||
|
|
web:
|
|||
|
|
exposure:
|
|||
|
|
include: health,info,metrics,prometheus
|
|||
|
|
metrics:
|
|||
|
|
export:
|
|||
|
|
prometheus:
|
|||
|
|
enabled: true
|
|||
|
|
endpoint:
|
|||
|
|
health:
|
|||
|
|
show-details: always
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### 4. 缺少单元测试 🧪
|
|||
|
|
|
|||
|
|
**建议添加测试用例:**
|
|||
|
|
|
|||
|
|
**示例测试类:**
|
|||
|
|
```java
|
|||
|
|
@SpringBootTest
|
|||
|
|
@RunWith(SpringRunner.class)
|
|||
|
|
public class SysUserServiceTest {
|
|||
|
|
|
|||
|
|
@Autowired
|
|||
|
|
private ISysUserService userService;
|
|||
|
|
|
|||
|
|
@Test
|
|||
|
|
public void testSelectUserList() {
|
|||
|
|
SysUser user = new SysUser();
|
|||
|
|
user.setUserName("admin");
|
|||
|
|
List<SysUser> users = userService.selectUserList(user);
|
|||
|
|
Assert.assertNotNull(users);
|
|||
|
|
Assert.assertTrue(users.size() > 0);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### 5. 缺少API文档 📖
|
|||
|
|
|
|||
|
|
**建议添加 README API 文档:**
|
|||
|
|
|
|||
|
|
创建 `API.md` 文件:
|
|||
|
|
```markdown
|
|||
|
|
# 动动脑新闻系统 API 文档
|
|||
|
|
|
|||
|
|
## 基础信息
|
|||
|
|
- 基础路径: `http://localhost:8080`
|
|||
|
|
- 认证方式: JWT Bearer Token
|
|||
|
|
- 内容类型: application/json
|
|||
|
|
|
|||
|
|
## 认证接口
|
|||
|
|
|
|||
|
|
### 登录
|
|||
|
|
POST /login
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"username": "admin",
|
|||
|
|
"password": "admin123",
|
|||
|
|
"code": "1234",
|
|||
|
|
"uuid": "xxx"
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 获取用户信息
|
|||
|
|
GET /getInfo
|
|||
|
|
Headers: Authorization: Bearer {token}
|
|||
|
|
|
|||
|
|
## 用户管理接口
|
|||
|
|
|
|||
|
|
### 查询用户列表
|
|||
|
|
GET /system/user/list?pageNum=1&pageSize=10
|
|||
|
|
|
|||
|
|
### 新增用户
|
|||
|
|
POST /system/user
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"userName": "test",
|
|||
|
|
"nickName": "测试用户",
|
|||
|
|
"email": "test@ddnai.com",
|
|||
|
|
"phonenumber": "13800138000",
|
|||
|
|
"password": "123456"
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
... (更多接口)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### 6. 缺少性能优化配置 ⚡
|
|||
|
|
|
|||
|
|
**建议添加缓存配置:**
|
|||
|
|
|
|||
|
|
**启用查询缓存:**
|
|||
|
|
```yaml
|
|||
|
|
# application.yml
|
|||
|
|
mybatis:
|
|||
|
|
configuration:
|
|||
|
|
cache-enabled: true
|
|||
|
|
lazy-loading-enabled: true
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**添加Redis缓存注解:**
|
|||
|
|
```java
|
|||
|
|
@Service
|
|||
|
|
public class SysDictDataServiceImpl implements ISysDictDataService {
|
|||
|
|
|
|||
|
|
@Cacheable(value = "dict", key = "#dictType")
|
|||
|
|
@Override
|
|||
|
|
public List<SysDictData> selectDictDataByType(String dictType) {
|
|||
|
|
return dictDataMapper.selectDictDataByType(dictType);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### 7. 缺少错误页面 ❌
|
|||
|
|
|
|||
|
|
**建议添加自定义错误页面:**
|
|||
|
|
|
|||
|
|
**创建 ErrorController:**
|
|||
|
|
```java
|
|||
|
|
@Controller
|
|||
|
|
public class ErrorPageController implements ErrorController {
|
|||
|
|
|
|||
|
|
@RequestMapping("/error")
|
|||
|
|
public String handleError(HttpServletRequest request, Model model) {
|
|||
|
|
Object status = request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE);
|
|||
|
|
|
|||
|
|
if (status != null) {
|
|||
|
|
int statusCode = Integer.parseInt(status.toString());
|
|||
|
|
|
|||
|
|
if(statusCode == HttpStatus.NOT_FOUND.value()) {
|
|||
|
|
return "error/404";
|
|||
|
|
} else if(statusCode == HttpStatus.INTERNAL_SERVER_ERROR.value()) {
|
|||
|
|
return "error/500";
|
|||
|
|
} else if(statusCode == HttpStatus.FORBIDDEN.value()) {
|
|||
|
|
return "error/403";
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return "error/error";
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### 8. 缺少数据库迁移工具 🔄
|
|||
|
|
|
|||
|
|
**建议集成 Flyway:**
|
|||
|
|
|
|||
|
|
**pom.xml:**
|
|||
|
|
```xml
|
|||
|
|
<dependency>
|
|||
|
|
<groupId>org.flywaydb</groupId>
|
|||
|
|
<artifactId>flyway-core</artifactId>
|
|||
|
|
</dependency>
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**application.yml:**
|
|||
|
|
```yaml
|
|||
|
|
spring:
|
|||
|
|
flyway:
|
|||
|
|
enabled: true
|
|||
|
|
locations: classpath:db/migration
|
|||
|
|
baseline-on-migrate: true
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**创建迁移脚本:**
|
|||
|
|
```
|
|||
|
|
src/main/resources/db/migration/
|
|||
|
|
V1.0__init_database.sql
|
|||
|
|
V1.1__add_ddn_news_table.sql
|
|||
|
|
V1.2__add_ddn_category_table.sql
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 📊 优化优先级总结
|
|||
|
|
|
|||
|
|
### 🔴 立即处理(P0 - 必须)
|
|||
|
|
|
|||
|
|
| 序号 | 问题 | 影响 | 工作量 |
|
|||
|
|
|------|------|------|--------|
|
|||
|
|
| 1 | 修改登录页版权信息 | 品牌形象 | 5分钟 |
|
|||
|
|
| 2 | 移除登录页默认密码 | 安全性 | 5分钟 |
|
|||
|
|
| 3 | 创建环境配置文件 | 部署管理 | 30分钟 |
|
|||
|
|
| 4 | 关闭生产环境Swagger | 安全性 | 10分钟 |
|
|||
|
|
|
|||
|
|
### 🟡 近期处理(P1 - 重要)
|
|||
|
|
|
|||
|
|
| 序号 | 问题 | 影响 | 工作量 |
|
|||
|
|
|------|------|------|--------|
|
|||
|
|
| 5 | 配置Druid IP白名单 | 安全性 | 10分钟 |
|
|||
|
|
| 6 | 添加Redis密码支持 | 安全性 | 10分钟 |
|
|||
|
|
| 7 | 添加文件路径检查 | 稳定性 | 30分钟 |
|
|||
|
|
| 8 | 修正日志路径配置 | 可维护性 | 15分钟 |
|
|||
|
|
| 9 | 修改代码版权注释 | 代码规范 | 20分钟 |
|
|||
|
|
| 10 | 完善.gitignore | 安全性 | 10分钟 |
|
|||
|
|
|
|||
|
|
### 🟢 计划处理(P2 - 可选)
|
|||
|
|
|
|||
|
|
| 序号 | 问题 | 影响 | 工作量 |
|
|||
|
|
|------|------|------|--------|
|
|||
|
|
| 11-15 | 其他优化项 | 体验/性能 | 1-2小时 |
|
|||
|
|
| 缺失功能1-8 | 补充功能 | 完整性 | 2-4天 |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🎯 快速修复建议(1小时内)
|
|||
|
|
|
|||
|
|
### 修复清单
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
# 1. 修改前端版权信息
|
|||
|
|
修改文件: ruoyi-ui/src/views/login.vue (第59行)
|
|||
|
|
修改文件: ruoyi-ui/src/views/register.vue (第64行)
|
|||
|
|
内容: Copyright © 2025 动动脑(DDNAI). All Rights Reserved.
|
|||
|
|
|
|||
|
|
# 2. 移除登录页默认密码
|
|||
|
|
修改文件: ruoyi-ui/src/views/login.vue (第76-77行)
|
|||
|
|
username: ""
|
|||
|
|
password: ""
|
|||
|
|
|
|||
|
|
# 3. 关闭生产环境Swagger
|
|||
|
|
修改文件: application.yml (第118行)
|
|||
|
|
enabled: false # 或配置为 ${SWAGGER_ENABLED:false}
|
|||
|
|
|
|||
|
|
# 4. 配置Druid白名单
|
|||
|
|
修改文件: application-druid.yml (第47行)
|
|||
|
|
allow: 127.0.0.1,192.168.0.0/16
|
|||
|
|
|
|||
|
|
# 5. 完善.gitignore
|
|||
|
|
追加内容到 .gitignore 文件
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 📝 后续开发建议
|
|||
|
|
|
|||
|
|
### 1. 建立代码规范 📋
|
|||
|
|
|
|||
|
|
- 制定Java代码规范(基于阿里巴巴规范)
|
|||
|
|
- 制定Vue代码规范
|
|||
|
|
- 统一注释格式
|
|||
|
|
- 配置代码格式化工具(Prettier, ESLint)
|
|||
|
|
|
|||
|
|
### 2. 建立发布流程 🚀
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
开发 → 测试 → 预发布 → 生产
|
|||
|
|
↓ ↓ ↓ ↓
|
|||
|
|
dev test stage prod
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 3. 性能优化建议 ⚡
|
|||
|
|
|
|||
|
|
- 添加Redis缓存层
|
|||
|
|
- 优化SQL查询(添加索引)
|
|||
|
|
- 启用Gzip压缩
|
|||
|
|
- 前端资源CDN加速
|
|||
|
|
- 图片压缩和懒加载
|
|||
|
|
|
|||
|
|
### 4. 安全加固建议 🔒
|
|||
|
|
|
|||
|
|
- 实现接口签名验证
|
|||
|
|
- 添加SQL注入防护
|
|||
|
|
- 实现敏感数据加密存储
|
|||
|
|
- 定期更新依赖版本
|
|||
|
|
- 实施安全审计
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## ✅ 检查完成状态
|
|||
|
|
|
|||
|
|
| 检查项 | 状态 |
|
|||
|
|
|--------|------|
|
|||
|
|
| 配置文件安全性 | ✅ 已检查 |
|
|||
|
|
| 前端配置 | ✅ 已检查 |
|
|||
|
|
| 数据库脚本 | ✅ 已检查 |
|
|||
|
|
| 代码生成器 | ✅ 已检查 |
|
|||
|
|
| 启动脚本 | ✅ 已检查 |
|
|||
|
|
| 日志配置 | ✅ 已检查 |
|
|||
|
|
| 文档完整性 | ✅ 已检查 |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 📞 总结
|
|||
|
|
|
|||
|
|
### 当前状态
|
|||
|
|
- ✅ 核心功能改造完成
|
|||
|
|
- ✅ 安全配置基本到位
|
|||
|
|
- ⚠️ 仍有15个优化点
|
|||
|
|
- 🔧 缺失8个辅助功能
|
|||
|
|
|
|||
|
|
### 建议行动
|
|||
|
|
1. **立即修复** 4个高优先级问题(约1小时)
|
|||
|
|
2. **本周完成** 6个中优先级问题(约2小时)
|
|||
|
|
3. **本月计划** 补充缺失功能(约2-4天)
|
|||
|
|
|
|||
|
|
### 下一步
|
|||
|
|
按照本报告的优先级建议,逐步完善系统。建议先完成"🔴 立即处理"部分,然后根据实际业务需求决定其他优化的先后顺序。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
**报告生成时间:** 2025-10-30
|
|||
|
|
**检查工具:** AI Code Review
|
|||
|
|
**建议有效期:** 长期有效
|
|||
|
|
**更新频率:** 建议每月复查一次
|
|||
|
|
|
|||
|
|
🎉 祝项目顺利!
|
|||
|
|
|