作为一款基于SpringBoot+Vue的全栈快速开发框架,RuoYi-Vue-Plus在4.8.2版本中引入了多项功能增强和性能优化。本文将深入解析后端环境的完整搭建过程,特别针对Windows平台下的关键组件配置进行详细说明。
在开始部署前,需要确保以下基础服务已就绪:
提示:生产环境建议使用Docker容器化部署,本文以开发环境配置为主。
推荐使用tporadowski维护的Windows版本Redis:
E:\Program Files\redis)bash复制redis-server.exe redis.windows.conf
为方便使用,可将Redis注册为Windows服务:
bash复制# 安装服务(需管理员权限)
redis-server --service-install redis.windows.conf --service-name Redis
# 启动服务
redis-server --service-start --service-name Redis
# 停止服务
redis-server --service-stop --service-name Redis
# 卸载服务
redis-server --service-uninstall --service-name Redis
启动后默认监听6379端口,可通过redis-cli测试连接:
bash复制redis-cli.exe
127.0.0.1:6379> ping
PONG
创建存储目录结构:
code复制E:\Program Files\minio
├── bin # 存放可执行文件
├── data # 存储桶数据
└── log # 日志文件
从官网下载minio.exe(Windows版)放入bin目录
设置MinIO访问凭证(长度要求:用户名≥3,密码≥8):
batch复制setx MINIO_ROOT_USER admin
setx MINIO_ROOT_PASSWORD yourpassword
在bin目录下执行:
batch复制.\minio.exe server E:\Program Files\minio\data --console-address "127.0.0.1:9000" --address "127.0.0.1:9090"
端口说明:
为方便使用,创建start-minio.bat:
batch复制@echo off
cd /d "%~dp0"
set MINIO_ROOT_USER=admin
set MINIO_ROOT_PASSWORD=yourpassword
set MINIO_CONSOLE_ADDRESS=127.0.0.1:9000
set MINIO_ADDRESS=127.0.0.1:9090
set "MINIO_DATA_PATH=E:\Program Files\minio\data"
set "MINIO_LOG_PATH=E:\Program Files\minio\log\minio.log"
start "" http://%MINIO_CONSOLE_ADDRESS%
minio.exe server "%MINIO_DATA_PATH%" --console-address "%MINIO_CONSOLE_ADDRESS%" --address "%MINIO_ADDRESS%" > "%MINIO_LOG_PATH%" 2>&1
bash复制mc alias set minio http://127.0.0.1:9090 admin yourpassword
mc anonymous set public minio/ruoyi
在pom.xml中添加:
xml复制<properties>
<satoken.version>1.37.0</satoken.version>
</properties>
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-spring-boot-starter</artifactId>
<version>${satoken.version}</version>
</dependency>
application.yml配置:
yaml复制sa-token:
token-name: Authorization
timeout: 86400 # token有效期(秒)
active-timeout: 1800 # token活跃有效期
is-concurrent: true # 允许并发登录
is-share: false # 不共享token
is-read-header: true # 从header读取token
jwt-secret-key: abcdefghijklmnopqrstuvwxyz # JWT密钥
创建SaTokenConfig配置类:
java复制@Configuration
public class SaTokenConfig implements WebMvcConfigurer {
@Bean
public StpLogic getStpLogicJwt() {
return new StpLogicJwtForSimple(); // JWT简单模式
}
@Bean
public StpInterface stpInterface() {
return new SaPermissionImpl(); // 权限实现
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new SaInterceptor(handler -> {
// 拦截所有URL(排除配置的路径)
SaRouter.match("/**").check(StpUtil::checkLogin);
}));
}
}
SaPermissionImpl核心逻辑:
java复制public class SaPermissionImpl implements StpInterface {
@Override
public List<String> getPermissionList(Object loginId, String loginType) {
LoginUser loginUser = LoginHelper.getLoginUser();
return new ArrayList<>(loginUser.getMenuPermission());
}
@Override
public List<String> getRoleList(Object loginId, String loginType) {
LoginUser loginUser = LoginHelper.getLoginUser();
return new ArrayList<>(loginUser.getRolePermission());
}
}
SysLoginController处理登录请求:
java复制@PostMapping("/login")
public R<Map<String, Object>> login(@RequestBody LoginBody loginBody) {
String token = loginService.login(loginBody);
Map<String, Object> ajax = new HashMap<>();
ajax.put("token", token);
return R.ok(ajax);
}
SysLoginService核心逻辑:
java复制public String login(String username, String password, String code, String uuid) {
// 验证码校验
if (captchaEnabled) {
validateCaptcha(username, code, uuid);
}
// 用户认证
SysUser user = loadUserByUsername(username);
checkLogin(LoginType.PASSWORD, username,
() -> !BCrypt.checkpw(password, user.getPassword()));
// 构建登录用户信息
LoginUser loginUser = buildLoginUser(user);
// 执行登录
LoginHelper.loginByDevice(loginUser, DeviceType.PC);
// 记录日志
recordLogininfor(username, Constants.LOGIN_SUCCESS, "登录成功");
return StpUtil.getTokenValue();
}
LoginHelper关键方法:
java复制public static void loginByDevice(LoginUser loginUser, DeviceType deviceType) {
SaStorage storage = SaHolder.getStorage();
storage.set(LOGIN_USER_KEY, loginUser);
storage.set(USER_KEY, loginUser.getUserId());
SaLoginModel model = new SaLoginModel();
if (deviceType != null) {
model.setDevice(deviceType.getDevice());
}
// 执行Sa-Token登录
StpUtil.login(loginUser.getLoginId(), model.setExtra(USER_KEY, loginUser.getUserId()));
StpUtil.getTokenSession().set(LOGIN_USER_KEY, loginUser);
}
pom.xml依赖:
xml复制<dependency>
<groupId>org.dromara</groupId>
<artifactId>sms4j-spring-boot-starter</artifactId>
<version>2.2.0</version>
</dependency>
application-dev.yml配置:
yaml复制sms:
alibaba:
accessKeyId: your-access-key
accessKeySecret: your-secret-key
signature: 测试签名
tencent:
accessKeyId: your-access-key
accessKeySecret: your-secret-key
signature: 测试签名
sdkAppId: your-app-id
java复制@Autowired
private SmsBlend smsBlend;
public void sendSms(String phone, String templateId, String params) {
smsBlend.sendMessage(phone, templateId, params);
}
提供通用控制器方法:
java复制public class BaseController {
// 操作结果响应
protected R<Void> toAjax(int rows) {
return rows > 0 ? R.ok() : R.fail();
}
// 页面跳转
protected String redirect(String url) {
return StringUtils.format("redirect:{}", url);
}
// 获取当前用户信息
protected LoginUser getLoginUser() {
return LoginHelper.getLoginUser();
}
}
使用MyBatis批量插入:
java复制@PostMapping("/addBatch")
public R<Void> addBatch() {
List<TestDemo> list = new ArrayList<>(1000);
for (int i = 0; i < 1000; i++) {
TestDemo demo = new TestDemo();
demo.setTestKey("批量新增");
demo.setValue("测试值");
list.add(demo);
}
return toAjax(testDemoMapper.insertBatch(list));
}
性能提示:MySQL需配置rewriteBatchedStatements=true以启用真正的批量插入
症状:使用自定义账号密码无法登录控制台
解决方案:
可能原因:
排查步骤:
bash复制netstat -ano | findstr 6379 # 检查端口占用
taskkill /F /PID <pid> # 结束占用进程
redis-server --test-memory 256 # 测试内存是否足够
检查要点:
日志调试:
java复制@Bean
public SaTokenConfig saTokenConfig() {
SaManager.setLog(new SaLog() {
@Override
public void trace(String str, Object... args) {
log.debug(str, args);
}
});
return new SaTokenConfig();
}
yaml复制spring:
redis:
lettuce:
pool:
max-active: 50
max-idle: 20
min-idle: 5
java复制@Configuration
@MapperScan("com.ruoyi.**.mapper")
public class MyBatisConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor());
return interceptor;
}
}
code复制-Xms512m -Xmx1024m -XX:+UseG1GC -XX:MaxGCPauseMillis=200
JWT密钥增强:
接口防刷:
java复制@SaCheckLimit(value = 5, time = 60, message = "操作过于频繁")
@PostMapping("/sms")
public R<Void> sendSms(@RequestBody SmsRequest request) {
// 短信发送逻辑
}
在实际项目部署中,建议结合企业级安全规范进行深度配置。对于生产环境,还需要考虑HTTPS加密、IP白名单、操作审计等安全措施。