Compare commits
No commits in common. 'f80d90a9de3f75b140123a3962cb0430752079cd' and '0992ceb334a02471acabea8afc073d624c920ffb' have entirely different histories.
f80d90a9de
...
0992ceb334
@ -1,93 +0,0 @@
|
|||||||
name: Backend CI
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: [ main, develop, feature/** ]
|
|
||||||
paths:
|
|
||||||
- 'pom.xml'
|
|
||||||
- 'ruoyi-*/**'
|
|
||||||
- 'book-system/**'
|
|
||||||
pull_request:
|
|
||||||
branches: [ main, develop ]
|
|
||||||
paths:
|
|
||||||
- 'pom.xml'
|
|
||||||
- 'ruoyi-*/**'
|
|
||||||
- 'book-system/**'
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
services:
|
|
||||||
mysql:
|
|
||||||
image: mysql:8.0
|
|
||||||
env:
|
|
||||||
MYSQL_ROOT_PASSWORD: root
|
|
||||||
MYSQL_DATABASE: ry-vue
|
|
||||||
ports:
|
|
||||||
- 3306:3306
|
|
||||||
options: >-
|
|
||||||
--health-cmd="mysqladmin ping"
|
|
||||||
--health-interval=10s
|
|
||||||
--health-timeout=5s
|
|
||||||
--health-retries=3
|
|
||||||
|
|
||||||
redis:
|
|
||||||
image: redis:7
|
|
||||||
ports:
|
|
||||||
- 6379:6379
|
|
||||||
options: >-
|
|
||||||
--health-cmd "redis-cli ping"
|
|
||||||
--health-interval 10s
|
|
||||||
--health-timeout 5s
|
|
||||||
--health-retries 5
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Set up JDK 11
|
|
||||||
uses: actions/setup-java@v4
|
|
||||||
with:
|
|
||||||
java-version: '11'
|
|
||||||
distribution: 'temurin'
|
|
||||||
cache: maven
|
|
||||||
|
|
||||||
- name: Cache Maven dependencies
|
|
||||||
uses: actions/cache@v3
|
|
||||||
with:
|
|
||||||
path: ~/.m2/repository
|
|
||||||
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
|
|
||||||
restore-keys: |
|
|
||||||
${{ runner.os }}-maven-
|
|
||||||
|
|
||||||
- name: Build with Maven
|
|
||||||
run: mvn clean compile -DskipTests
|
|
||||||
|
|
||||||
- name: Run Checkstyle
|
|
||||||
run: mvn checkstyle:checkstyle
|
|
||||||
continue-on-error: true
|
|
||||||
|
|
||||||
- name: Run tests
|
|
||||||
run: mvn test
|
|
||||||
|
|
||||||
- name: Upload test results
|
|
||||||
if: always()
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: test-results
|
|
||||||
path: '**/surefire-reports/*.xml'
|
|
||||||
|
|
||||||
- name: Upload coverage reports
|
|
||||||
uses: codecov/codecov-action@v3
|
|
||||||
with:
|
|
||||||
files: '**/jacoco.xml'
|
|
||||||
fail_ci_if_error: false
|
|
||||||
|
|
||||||
- name: Package application
|
|
||||||
run: mvn package -DskipTests
|
|
||||||
|
|
||||||
- name: Upload JAR
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: ruoyi-admin
|
|
||||||
path: ruoyi-admin/target/*.jar
|
|
||||||
@ -1,125 +0,0 @@
|
|||||||
name: Full CI/CD
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: [ main ]
|
|
||||||
pull_request:
|
|
||||||
branches: [ main ]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
# 后端构建
|
|
||||||
backend:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
services:
|
|
||||||
mysql:
|
|
||||||
image: mysql:8.0
|
|
||||||
env:
|
|
||||||
MYSQL_ROOT_PASSWORD: root
|
|
||||||
MYSQL_DATABASE: ry-vue
|
|
||||||
ports:
|
|
||||||
- 3306:3306
|
|
||||||
|
|
||||||
redis:
|
|
||||||
image: redis:7
|
|
||||||
ports:
|
|
||||||
- 6379:6379
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Set up JDK 11
|
|
||||||
uses: actions/setup-java@v4
|
|
||||||
with:
|
|
||||||
java-version: '11'
|
|
||||||
distribution: 'temurin'
|
|
||||||
cache: maven
|
|
||||||
|
|
||||||
- name: Build and test
|
|
||||||
run: mvn clean verify
|
|
||||||
|
|
||||||
- name: Package
|
|
||||||
run: mvn package -DskipTests
|
|
||||||
|
|
||||||
- name: Upload JAR
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: backend-jar
|
|
||||||
path: ruoyi-admin/target/*.jar
|
|
||||||
|
|
||||||
# 前端构建
|
|
||||||
frontend:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
defaults:
|
|
||||||
run:
|
|
||||||
working-directory: ruoyi-ui-next
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Setup Node.js
|
|
||||||
uses: actions/setup-node@v4
|
|
||||||
with:
|
|
||||||
node-version: '18'
|
|
||||||
cache: 'npm'
|
|
||||||
cache-dependency-path: ruoyi-ui-next/package-lock.json
|
|
||||||
|
|
||||||
- name: Install dependencies
|
|
||||||
run: npm ci
|
|
||||||
|
|
||||||
- name: Lint
|
|
||||||
run: npm run lint
|
|
||||||
|
|
||||||
- name: Build
|
|
||||||
run: npm run build
|
|
||||||
|
|
||||||
- name: Upload dist
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: frontend-dist
|
|
||||||
path: ruoyi-ui-next/dist/
|
|
||||||
|
|
||||||
# 集成测试
|
|
||||||
integration-test:
|
|
||||||
needs: [backend, frontend]
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Download backend JAR
|
|
||||||
uses: actions/download-artifact@v4
|
|
||||||
with:
|
|
||||||
name: backend-jar
|
|
||||||
|
|
||||||
- name: Download frontend dist
|
|
||||||
uses: actions/download-artifact@v4
|
|
||||||
with:
|
|
||||||
name: frontend-dist
|
|
||||||
|
|
||||||
- name: Run integration tests
|
|
||||||
run: |
|
|
||||||
echo "Integration tests would run here"
|
|
||||||
echo "Backend JAR and Frontend dist are available"
|
|
||||||
|
|
||||||
# 部署(仅 main 分支)
|
|
||||||
deploy:
|
|
||||||
needs: [backend, frontend, integration-test]
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
if: github.ref == 'refs/heads/main'
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Download artifacts
|
|
||||||
uses: actions/download-artifact@v4
|
|
||||||
|
|
||||||
- name: Deploy to server
|
|
||||||
run: |
|
|
||||||
echo "Deploy scripts would run here"
|
|
||||||
echo "In production, use SSH or deployment tools"
|
|
||||||
env:
|
|
||||||
DEPLOY_HOST: ${{ secrets.DEPLOY_HOST }}
|
|
||||||
DEPLOY_USER: ${{ secrets.DEPLOY_USER }}
|
|
||||||
DEPLOY_KEY: ${{ secrets.DEPLOY_KEY }}
|
|
||||||
@ -1,56 +0,0 @@
|
|||||||
name: Frontend CI
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: [ main, develop, feature/** ]
|
|
||||||
paths:
|
|
||||||
- 'ruoyi-ui-next/**'
|
|
||||||
pull_request:
|
|
||||||
branches: [ main, develop ]
|
|
||||||
paths:
|
|
||||||
- 'ruoyi-ui-next/**'
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
defaults:
|
|
||||||
run:
|
|
||||||
working-directory: ruoyi-ui-next
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Setup Node.js
|
|
||||||
uses: actions/setup-node@v4
|
|
||||||
with:
|
|
||||||
node-version: '18'
|
|
||||||
cache: 'npm'
|
|
||||||
cache-dependency-path: ruoyi-ui-next/package-lock.json
|
|
||||||
|
|
||||||
- name: Install dependencies
|
|
||||||
run: npm ci
|
|
||||||
|
|
||||||
- name: Run ESLint
|
|
||||||
run: npm run lint
|
|
||||||
continue-on-error: true
|
|
||||||
|
|
||||||
- name: Type check
|
|
||||||
run: npx vue-tsc --noEmit
|
|
||||||
continue-on-error: true
|
|
||||||
|
|
||||||
- name: Build
|
|
||||||
run: npm run build
|
|
||||||
|
|
||||||
- name: Upload build artifacts
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: frontend-dist
|
|
||||||
path: ruoyi-ui-next/dist/
|
|
||||||
|
|
||||||
- name: Upload coverage reports
|
|
||||||
if: always()
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: coverage-report
|
|
||||||
path: ruoyi-ui-next/coverage/
|
|
||||||
@ -1,13 +0,0 @@
|
|||||||
FROM eclipse-temurin:11-jre
|
|
||||||
|
|
||||||
LABEL maintainer="ruoyi"
|
|
||||||
|
|
||||||
WORKDIR /app
|
|
||||||
|
|
||||||
COPY ruoyi-admin/target/*.jar app.jar
|
|
||||||
|
|
||||||
EXPOSE 8080
|
|
||||||
|
|
||||||
ENV JAVA_OPTS="-Xms512m -Xmx1024m -Dspring.profiles.active=prod"
|
|
||||||
|
|
||||||
ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -jar app.jar"]
|
|
||||||
@ -1,48 +0,0 @@
|
|||||||
version: '3.8'
|
|
||||||
|
|
||||||
services:
|
|
||||||
mysql:
|
|
||||||
image: mysql:8.0
|
|
||||||
environment:
|
|
||||||
MYSQL_ROOT_PASSWORD: root
|
|
||||||
MYSQL_DATABASE: ry-vue
|
|
||||||
ports:
|
|
||||||
- "3306:3306"
|
|
||||||
volumes:
|
|
||||||
- mysql-data:/var/lib/mysql
|
|
||||||
- ./sql:/docker-entrypoint-initdb.d
|
|
||||||
command: --default-authentication-plugin=mysql_native_password
|
|
||||||
|
|
||||||
redis:
|
|
||||||
image: redis:7
|
|
||||||
ports:
|
|
||||||
- "6379:6379"
|
|
||||||
volumes:
|
|
||||||
- redis-data:/data
|
|
||||||
|
|
||||||
backend:
|
|
||||||
build: .
|
|
||||||
ports:
|
|
||||||
- "8080:8080"
|
|
||||||
environment:
|
|
||||||
SPRING_DATASOURCE_URL: jdbc:mysql://mysql:3306/ry-vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
|
|
||||||
SPRING_DATASOURCE_USERNAME: root
|
|
||||||
SPRING_DATASOURCE_PASSWORD: root
|
|
||||||
SPRING_REDIS_HOST: redis
|
|
||||||
depends_on:
|
|
||||||
- mysql
|
|
||||||
- redis
|
|
||||||
|
|
||||||
frontend:
|
|
||||||
image: nginx:alpine
|
|
||||||
ports:
|
|
||||||
- "80:80"
|
|
||||||
volumes:
|
|
||||||
- ./ruoyi-ui-next/dist:/usr/share/nginx/html
|
|
||||||
- ./scripts/deploy/nginx.conf:/etc/nginx/conf.d/default.conf
|
|
||||||
depends_on:
|
|
||||||
- backend
|
|
||||||
|
|
||||||
volumes:
|
|
||||||
mysql-data:
|
|
||||||
redis-data:
|
|
||||||
@ -1,30 +0,0 @@
|
|||||||
# Tasks: API 版本管理
|
|
||||||
|
|
||||||
## Task 1: 版本配置
|
|
||||||
|
|
||||||
- [ ] 1.1 创建版本注解
|
|
||||||
- [ ] 1.2 配置版本路由
|
|
||||||
- [ ] 1.3 创建版本常量
|
|
||||||
|
|
||||||
## Task 2: 版本 Controller
|
|
||||||
|
|
||||||
- [ ] 2.1 创建 v1 版本 Controller 示例
|
|
||||||
- [ ] 2.2 创建 v2 版本 Controller 示例
|
|
||||||
- [ ] 2.3 版本路由映射
|
|
||||||
|
|
||||||
## Task 3: 版本弃用机制
|
|
||||||
|
|
||||||
- [ ] 3.1 创建版本弃用注解
|
|
||||||
- [ ] 3.2 实现弃用警告
|
|
||||||
- [ ] 3.3 版本迁移提示
|
|
||||||
|
|
||||||
## Task 4: 版本文档
|
|
||||||
|
|
||||||
- [ ] 4.1 Swagger 版本分组
|
|
||||||
- [ ] 4.2 版本迁移指南
|
|
||||||
|
|
||||||
## 验收标准
|
|
||||||
|
|
||||||
- [ ] 支持 v1、v2 版本
|
|
||||||
- [ ] 版本路由正确映射
|
|
||||||
- [ ] 向后兼容
|
|
||||||
@ -1,4 +1,4 @@
|
|||||||
change_name: add-api-versioning
|
change_name: add-unit-tests
|
||||||
phase: build
|
phase: build
|
||||||
auto_transition: true
|
auto_transition: true
|
||||||
build_pause: null
|
build_pause: null
|
||||||
@ -1,7 +0,0 @@
|
|||||||
change_name: add-performance-monitor
|
|
||||||
phase: archive
|
|
||||||
auto_transition: true
|
|
||||||
build_pause: null
|
|
||||||
verify_result: pass
|
|
||||||
archived: false
|
|
||||||
workflow: full
|
|
||||||
@ -1,25 +0,0 @@
|
|||||||
# P1 优化:性能监控
|
|
||||||
|
|
||||||
## 目标
|
|
||||||
|
|
||||||
为 RuoYi-Vue 后端添加接口性能监控和慢查询日志,识别性能瓶颈。
|
|
||||||
|
|
||||||
## 范围
|
|
||||||
|
|
||||||
- 接口响应时间监控
|
|
||||||
- 慢 SQL 查询日志
|
|
||||||
- 性能统计报表
|
|
||||||
- 告警机制
|
|
||||||
|
|
||||||
## 技术栈
|
|
||||||
|
|
||||||
- AOP 切面
|
|
||||||
- Micrometer
|
|
||||||
- Spring Boot Actuator
|
|
||||||
- 自定义注解
|
|
||||||
|
|
||||||
## 验收标准
|
|
||||||
|
|
||||||
- 所有接口响应时间记录
|
|
||||||
- 慢查询日志(> 1 秒)
|
|
||||||
- 性能统计接口可访问
|
|
||||||
@ -1,30 +0,0 @@
|
|||||||
# Tasks: 性能监控
|
|
||||||
|
|
||||||
## Task 1: 监控配置
|
|
||||||
|
|
||||||
- [ ] 1.1 添加 Micrometer 和 Actuator 依赖
|
|
||||||
- [ ] 1.2 配置监控端点
|
|
||||||
- [ ] 1.3 创建性能监控注解
|
|
||||||
|
|
||||||
## Task 2: AOP 性能监控
|
|
||||||
|
|
||||||
- [ ] 2.1 创建性能监控切面
|
|
||||||
- [ ] 2.2 记录接口响应时间
|
|
||||||
- [ ] 2.3 慢查询日志(> 1 秒)
|
|
||||||
|
|
||||||
## Task 3: 性能统计
|
|
||||||
|
|
||||||
- [ ] 3.1 创建性能统计服务
|
|
||||||
- [ ] 3.2 性能监控接口
|
|
||||||
- [ ] 3.3 慢查询日志查询
|
|
||||||
|
|
||||||
## Task 4: 告警机制
|
|
||||||
|
|
||||||
- [ ] 4.1 慢接口告警
|
|
||||||
- [ ] 4.2 异常告警
|
|
||||||
|
|
||||||
## 验收标准
|
|
||||||
|
|
||||||
- [ ] 所有接口响应时间记录
|
|
||||||
- [ ] 慢查询日志(> 1 秒)
|
|
||||||
- [ ] 性能统计接口可访问
|
|
||||||
@ -1,7 +0,0 @@
|
|||||||
change_name: add-unit-tests
|
|
||||||
phase: archive
|
|
||||||
auto_transition: true
|
|
||||||
build_pause: null
|
|
||||||
verify_result: pass
|
|
||||||
archived: false
|
|
||||||
workflow: full
|
|
||||||
@ -1,7 +0,0 @@
|
|||||||
change_name: optimize-cache-strategy
|
|
||||||
phase: archive
|
|
||||||
auto_transition: true
|
|
||||||
build_pause: null
|
|
||||||
verify_result: pass
|
|
||||||
archived: false
|
|
||||||
workflow: full
|
|
||||||
@ -1,34 +0,0 @@
|
|||||||
# Tasks: 优化缓存策略
|
|
||||||
|
|
||||||
## Task 1: 缓存配置
|
|
||||||
|
|
||||||
- [ ] 1.1 添加 Spring Cache 和 Redis 依赖
|
|
||||||
- [ ] 1.2 配置 Redis 连接
|
|
||||||
- [ ] 1.3 配置缓存管理器
|
|
||||||
|
|
||||||
## Task 2: 字典缓存
|
|
||||||
|
|
||||||
- [ ] 2.1 字典类型缓存
|
|
||||||
- [ ] 2.2 字典数据缓存
|
|
||||||
- [ ] 2.3 缓存更新机制
|
|
||||||
|
|
||||||
## Task 3: 配置参数缓存
|
|
||||||
|
|
||||||
- [ ] 3.1 系统配置缓存
|
|
||||||
- [ ] 3.2 缓存刷新机制
|
|
||||||
|
|
||||||
## Task 4: 用户和菜单缓存
|
|
||||||
|
|
||||||
- [ ] 4.1 用户信息缓存
|
|
||||||
- [ ] 4.2 菜单数据缓存
|
|
||||||
|
|
||||||
## Task 5: 缓存监控
|
|
||||||
|
|
||||||
- [ ] 5.1 缓存命中率统计
|
|
||||||
- [ ] 5.2 缓存清理接口
|
|
||||||
|
|
||||||
## 验收标准
|
|
||||||
|
|
||||||
- [ ] 字典查询缓存命中率 > 90%
|
|
||||||
- [ ] 常用接口响应时间 < 100ms
|
|
||||||
- [ ] 缓存更新机制完整
|
|
||||||
@ -1,75 +0,0 @@
|
|||||||
package com.ruoyi.web.controller.api.v1;
|
|
||||||
|
|
||||||
import com.ruoyi.common.annotation.ApiVersion;
|
|
||||||
import com.ruoyi.common.core.controller.BaseController;
|
|
||||||
import com.ruoyi.common.core.domain.AjaxResult;
|
|
||||||
import com.ruoyi.common.core.domain.entity.SysUser;
|
|
||||||
import com.ruoyi.common.core.page.TableDataInfo;
|
|
||||||
import com.ruoyi.system.service.ISysUserService;
|
|
||||||
import io.swagger.annotations.Api;
|
|
||||||
import io.swagger.annotations.ApiOperation;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.web.bind.annotation.*;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用户管理 v1 版本
|
|
||||||
*/
|
|
||||||
@Api(tags = "用户管理 v1")
|
|
||||||
@RestController
|
|
||||||
@RequestMapping("/api/v1/users")
|
|
||||||
@ApiVersion("v1")
|
|
||||||
public class UserV1Controller extends BaseController {
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private ISysUserService userService;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询用户列表 v1
|
|
||||||
*/
|
|
||||||
@ApiOperation("查询用户列表 v1")
|
|
||||||
@GetMapping("/list")
|
|
||||||
public TableDataInfo list(SysUser user) {
|
|
||||||
startPage();
|
|
||||||
List<SysUser> list = userService.selectUserList(user);
|
|
||||||
return getDataTable(list);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取用户详细信息 v1
|
|
||||||
*/
|
|
||||||
@ApiOperation("获取用户详细信息 v1")
|
|
||||||
@GetMapping("/{userId}")
|
|
||||||
public AjaxResult getInfo(@PathVariable Long userId) {
|
|
||||||
return AjaxResult.success(userService.selectUserById(userId));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 新增用户 v1
|
|
||||||
*/
|
|
||||||
@ApiOperation("新增用户 v1")
|
|
||||||
@PostMapping
|
|
||||||
public AjaxResult add(@RequestBody SysUser user) {
|
|
||||||
return toAjax(userService.insertUser(user));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 修改用户 v1
|
|
||||||
*/
|
|
||||||
@ApiOperation("修改用户 v1")
|
|
||||||
@PutMapping("/{userId}")
|
|
||||||
public AjaxResult edit(@PathVariable Long userId, @RequestBody SysUser user) {
|
|
||||||
user.setUserId(userId);
|
|
||||||
return toAjax(userService.updateUser(user));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 删除用户 v1
|
|
||||||
*/
|
|
||||||
@ApiOperation("删除用户 v1")
|
|
||||||
@DeleteMapping("/{userIds}")
|
|
||||||
public AjaxResult remove(@PathVariable Long[] userIds) {
|
|
||||||
return toAjax(userService.deleteUserByIds(userIds));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,31 +0,0 @@
|
|||||||
package com.ruoyi.common.annotation;
|
|
||||||
|
|
||||||
import java.lang.annotation.*;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* API 版本注解
|
|
||||||
*/
|
|
||||||
@Target({ElementType.METHOD, ElementType.TYPE})
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
|
||||||
@Documented
|
|
||||||
public @interface ApiVersion {
|
|
||||||
/**
|
|
||||||
* 版本号
|
|
||||||
*/
|
|
||||||
String value() default "v1";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 是否已弃用
|
|
||||||
*/
|
|
||||||
boolean deprecated() default false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 弃用说明
|
|
||||||
*/
|
|
||||||
String deprecatedReason() default "";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 替代版本
|
|
||||||
*/
|
|
||||||
String replaceWith() default "";
|
|
||||||
}
|
|
||||||
@ -1,32 +0,0 @@
|
|||||||
package com.ruoyi.common.constant;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* API 版本常量
|
|
||||||
*/
|
|
||||||
public class ApiVersionConstants {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 当前版本
|
|
||||||
*/
|
|
||||||
public static final String CURRENT_VERSION = "v1";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 最新版本
|
|
||||||
*/
|
|
||||||
public static final String LATEST_VERSION = "v2";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 版本路径前缀
|
|
||||||
*/
|
|
||||||
public static final String VERSION_PREFIX = "/api/";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 支持的版本列表
|
|
||||||
*/
|
|
||||||
public static final String[] SUPPORTED_VERSIONS = {"v1", "v2"};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 已弃用的版本列表
|
|
||||||
*/
|
|
||||||
public static final String[] DEPRECATED_VERSIONS = {};
|
|
||||||
}
|
|
||||||
@ -1,18 +0,0 @@
|
|||||||
package com.ruoyi.framework.config;
|
|
||||||
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
|
||||||
import org.springframework.web.servlet.config.annotation.PathMatchConfigurer;
|
|
||||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* API 版本配置
|
|
||||||
*/
|
|
||||||
@Configuration
|
|
||||||
public class ApiVersionConfig implements WebMvcConfigurer {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void configurePathMatch(PathMatchConfigurer configurer) {
|
|
||||||
// 启用路径匹配,支持版本前缀
|
|
||||||
configurer.setUseSuffixPatternMatch(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,52 +0,0 @@
|
|||||||
package com.ruoyi.framework.interceptor;
|
|
||||||
|
|
||||||
import com.ruoyi.common.annotation.ApiVersion;
|
|
||||||
import com.ruoyi.common.constant.ApiVersionConstants;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
import org.springframework.web.method.HandlerMethod;
|
|
||||||
import org.springframework.web.servlet.HandlerInterceptor;
|
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* API 版本拦截器
|
|
||||||
*/
|
|
||||||
@Component
|
|
||||||
public class ApiVersionInterceptor implements HandlerInterceptor {
|
|
||||||
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(ApiVersionInterceptor.class);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
|
|
||||||
if (handler instanceof HandlerMethod) {
|
|
||||||
HandlerMethod handlerMethod = (HandlerMethod) handler;
|
|
||||||
ApiVersion apiVersion = handlerMethod.getMethodAnnotation(ApiVersion.class);
|
|
||||||
|
|
||||||
if (apiVersion != null) {
|
|
||||||
String version = apiVersion.value();
|
|
||||||
|
|
||||||
// 检查版本是否已弃用
|
|
||||||
if (apiVersion.deprecated()) {
|
|
||||||
String warning = String.format(
|
|
||||||
"API 版本 %s 已弃用。%s 请升级到 %s",
|
|
||||||
version,
|
|
||||||
apiVersion.deprecatedReason(),
|
|
||||||
apiVersion.replaceWith()
|
|
||||||
);
|
|
||||||
|
|
||||||
log.warn("⚠️ {}", warning);
|
|
||||||
response.setHeader("X-API-Deprecated", "true");
|
|
||||||
response.setHeader("X-API-Warning", warning);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 添加版本响应头
|
|
||||||
response.setHeader("X-API-Version", version);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,101 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
# ============================================
|
|
||||||
# RuoYi-Vue 后端部署脚本
|
|
||||||
# 使用方式: ./scripts/deploy/backend-deploy.sh
|
|
||||||
# ============================================
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
# 配置
|
|
||||||
APP_NAME="ruoyi-admin"
|
|
||||||
DEPLOY_DIR="/opt/ruoyi"
|
|
||||||
JAR_FILE="${DEPLOY_DIR}/${APP_NAME}.jar"
|
|
||||||
BACKUP_DIR="${DEPLOY_DIR}/backup"
|
|
||||||
LOG_DIR="${DEPLOY_DIR}/logs"
|
|
||||||
PID_FILE="${DEPLOY_DIR}/${APP_NAME}.pid"
|
|
||||||
|
|
||||||
# 颜色输出
|
|
||||||
RED='\033[0;31m'
|
|
||||||
GREEN='\033[0;32m'
|
|
||||||
YELLOW='\033[1;33m'
|
|
||||||
NC='\033[0m'
|
|
||||||
|
|
||||||
echo_info() {
|
|
||||||
echo -e "${GREEN}[INFO]${NC} $1"
|
|
||||||
}
|
|
||||||
|
|
||||||
echo_warn() {
|
|
||||||
echo -e "${YELLOW}[WARN]${NC} $1"
|
|
||||||
}
|
|
||||||
|
|
||||||
echo_error() {
|
|
||||||
echo -e "${RED}[ERROR]${NC} $1"
|
|
||||||
}
|
|
||||||
|
|
||||||
# 检查 JAR 文件
|
|
||||||
if [ ! -f "$1" ]; then
|
|
||||||
echo_error "JAR 文件不存在: $1"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo_info "========================================"
|
|
||||||
echo_info "RuoYi-Vue 后端部署"
|
|
||||||
echo_info "========================================"
|
|
||||||
|
|
||||||
# 创建目录
|
|
||||||
mkdir -p $DEPLOY_DIR $BACKUP_DIR $LOG_DIR
|
|
||||||
|
|
||||||
# 备份现有版本
|
|
||||||
if [ -f "$JAR_FILE" ]; then
|
|
||||||
echo_info "备份现有版本..."
|
|
||||||
cp $JAR_FILE ${BACKUP_DIR}/${APP_NAME}-$(date +%Y%m%d_%H%M%S).jar
|
|
||||||
fi
|
|
||||||
|
|
||||||
# 停止现有服务
|
|
||||||
if [ -f "$PID_FILE" ]; then
|
|
||||||
PID=$(cat $PID_FILE)
|
|
||||||
if ps -p $PID > /dev/null 2>&1; then
|
|
||||||
echo_info "停止现有服务 (PID: $PID)..."
|
|
||||||
kill $PID
|
|
||||||
sleep 5
|
|
||||||
|
|
||||||
# 强制停止
|
|
||||||
if ps -p $PID > /dev/null 2>&1; then
|
|
||||||
echo_warn "服务未正常停止,强制终止..."
|
|
||||||
kill -9 $PID
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# 部署新版本
|
|
||||||
echo_info "部署新版本..."
|
|
||||||
cp $1 $JAR_FILE
|
|
||||||
|
|
||||||
# 启动服务
|
|
||||||
echo_info "启动服务..."
|
|
||||||
nohup java -jar \
|
|
||||||
-Dspring.profiles.active=prod \
|
|
||||||
-Xms512m -Xmx1024m \
|
|
||||||
$JAR_FILE \
|
|
||||||
> ${LOG_DIR}/app.log 2>&1 &
|
|
||||||
|
|
||||||
echo $! > $PID_FILE
|
|
||||||
echo_info "服务已启动 (PID: $(cat $PID_FILE))"
|
|
||||||
|
|
||||||
# 等待启动
|
|
||||||
echo_info "等待服务启动..."
|
|
||||||
sleep 10
|
|
||||||
|
|
||||||
# 健康检查
|
|
||||||
if curl -f http://localhost:8080/actuator/health > /dev/null 2>&1; then
|
|
||||||
echo_info "✅ 部署成功!服务运行正常"
|
|
||||||
else
|
|
||||||
echo_error "❌ 部署失败!服务未正常启动"
|
|
||||||
echo_error "请查看日志: tail -f ${LOG_DIR}/app.log"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo_info "========================================"
|
|
||||||
echo_info "部署完成"
|
|
||||||
echo_info "日志: ${LOG_DIR}/app.log"
|
|
||||||
echo_info "========================================"
|
|
||||||
@ -1,54 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
# ============================================
|
|
||||||
# RuoYi-Vue 前端部署脚本
|
|
||||||
# 使用方式: ./scripts/deploy/frontend-deploy.sh <dist-dir>
|
|
||||||
# ============================================
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
# 配置
|
|
||||||
DEPLOY_DIR="/usr/share/nginx/html/ruoyi-ui"
|
|
||||||
BACKUP_DIR="/usr/share/nginx/html/backup"
|
|
||||||
NGINX_CONF="/etc/nginx/conf.d/ruoyi-ui.conf"
|
|
||||||
|
|
||||||
echo_info() {
|
|
||||||
echo -e "\033[0;32m[INFO]\033[0m $1"
|
|
||||||
}
|
|
||||||
|
|
||||||
echo_error() {
|
|
||||||
echo -e "\033[0;31m[ERROR]\033[0m $1"
|
|
||||||
}
|
|
||||||
|
|
||||||
if [ ! -d "$1" ]; then
|
|
||||||
echo_error "构建目录不存在: $1"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo_info "========================================"
|
|
||||||
echo_info "RuoYi-Vue 前端部署"
|
|
||||||
echo_info "========================================"
|
|
||||||
|
|
||||||
# 创建目录
|
|
||||||
mkdir -p $DEPLOY_DIR $BACKUP_DIR
|
|
||||||
|
|
||||||
# 备份现有版本
|
|
||||||
if [ -d "$DEPLOY_DIR" ] && [ "$(ls -A $DEPLOY_DIR)" ]; then
|
|
||||||
echo_info "备份现有版本..."
|
|
||||||
tar -czf ${BACKUP_DIR}/frontend-$(date +%Y%m%d_%H%M%S).tar.gz -C $(dirname $DEPLOY_DIR) $(basename $DEPLOY_DIR)
|
|
||||||
fi
|
|
||||||
|
|
||||||
# 部署新版本
|
|
||||||
echo_info "部署新版本..."
|
|
||||||
rm -rf ${DEPLOY_DIR}/*
|
|
||||||
cp -r $1/* $DEPLOY_DIR/
|
|
||||||
|
|
||||||
# 设置权限
|
|
||||||
chown -R nginx:nginx $DEPLOY_DIR
|
|
||||||
chmod -R 755 $DEPLOY_DIR
|
|
||||||
|
|
||||||
# 重新加载 Nginx
|
|
||||||
echo_info "重新加载 Nginx..."
|
|
||||||
nginx -t && systemctl reload nginx
|
|
||||||
|
|
||||||
echo_info "✅ 部署成功!"
|
|
||||||
echo_info "========================================"
|
|
||||||
@ -1,47 +0,0 @@
|
|||||||
server {
|
|
||||||
listen 80;
|
|
||||||
server_name your-domain.com;
|
|
||||||
|
|
||||||
# 前端静态文件
|
|
||||||
location / {
|
|
||||||
root /usr/share/nginx/html/ruoyi-ui;
|
|
||||||
index index.html;
|
|
||||||
try_files $uri $uri/ /index.html;
|
|
||||||
|
|
||||||
# 缓存策略
|
|
||||||
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
|
|
||||||
expires 30d;
|
|
||||||
add_header Cache-Control "public, immutable";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# 后端 API 代理
|
|
||||||
location /dev-api/ {
|
|
||||||
proxy_pass http://localhost:8080/;
|
|
||||||
proxy_set_header Host $host;
|
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
|
||||||
|
|
||||||
# 超时设置
|
|
||||||
proxy_connect_timeout 60s;
|
|
||||||
proxy_send_timeout 60s;
|
|
||||||
proxy_read_timeout 60s;
|
|
||||||
}
|
|
||||||
|
|
||||||
# 后端 API 代理(生产环境)
|
|
||||||
location /prod-api/ {
|
|
||||||
proxy_pass http://localhost:8080/;
|
|
||||||
proxy_set_header Host $host;
|
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Gzip 压缩
|
|
||||||
gzip on;
|
|
||||||
gzip_vary on;
|
|
||||||
gzip_proxied any;
|
|
||||||
gzip_comp_level 6;
|
|
||||||
gzip_types text/plain text/css text/xml text/javascript application/json application/javascript application/xml+rss application/rss+xml font/truetype font/opentype application/vnd.ms-fontobject image/svg+xml;
|
|
||||||
}
|
|
||||||
Loading…
Reference in new issue