@@ -1,11 +1,17 @@ | |||||
package com.ruoyi.web.controller.system; | package com.ruoyi.web.controller.system; | ||||
import org.springframework.beans.factory.annotation.Autowired; | import org.springframework.beans.factory.annotation.Autowired; | ||||
import org.springframework.web.bind.annotation.GetMapping; | |||||
import org.springframework.web.bind.annotation.RequestMapping; | import org.springframework.web.bind.annotation.RequestMapping; | ||||
import org.springframework.web.bind.annotation.RestController; | import org.springframework.web.bind.annotation.RestController; | ||||
import com.ruoyi.common.config.RuoYiConfig; | import com.ruoyi.common.config.RuoYiConfig; | ||||
import com.ruoyi.common.utils.StringUtils; | import com.ruoyi.common.utils.StringUtils; | ||||
import javax.servlet.ServletException; | |||||
import javax.servlet.http.HttpServletRequest; | |||||
import javax.servlet.http.HttpServletResponse; | |||||
import java.io.IOException; | |||||
/** | /** | ||||
* 首页 | * 首页 | ||||
* | * | ||||
@@ -22,8 +28,9 @@ public class SysIndexController | |||||
* 访问首页,提示语 | * 访问首页,提示语 | ||||
*/ | */ | ||||
@RequestMapping("/") | @RequestMapping("/") | ||||
public String index() | |||||
public void index(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException | |||||
{ | { | ||||
return StringUtils.format("欢迎使用{}后台管理框架,当前版本:v{},请通过前端地址访问。", ruoyiConfig.getName(), ruoyiConfig.getVersion()); | |||||
//return "redirect:/index.html"; | |||||
request.getRequestDispatcher("/index.html").forward(request, response); | |||||
} | } | ||||
} | } |
@@ -1,13 +1,20 @@ | |||||
package com.ruoyi.web.controller.system; | package com.ruoyi.web.controller.system; | ||||
import com.alibaba.fastjson2.JSON; | |||||
import com.ruoyi.common.constant.Constants; | import com.ruoyi.common.constant.Constants; | ||||
import com.ruoyi.common.core.domain.AjaxResult; | import com.ruoyi.common.core.domain.AjaxResult; | ||||
import com.ruoyi.common.core.domain.entity.SysMenu; | import com.ruoyi.common.core.domain.entity.SysMenu; | ||||
import com.ruoyi.common.core.domain.entity.SysUser; | import com.ruoyi.common.core.domain.entity.SysUser; | ||||
import com.ruoyi.common.core.domain.model.LoginBody; | import com.ruoyi.common.core.domain.model.LoginBody; | ||||
import com.ruoyi.common.core.domain.model.LoginUser; | |||||
import com.ruoyi.common.utils.SecurityUtils; | import com.ruoyi.common.utils.SecurityUtils; | ||||
import com.ruoyi.common.utils.ServletUtils; | |||||
import com.ruoyi.common.utils.StringUtils; | |||||
import com.ruoyi.framework.manager.AsyncManager; | |||||
import com.ruoyi.framework.manager.factory.AsyncFactory; | |||||
import com.ruoyi.framework.web.service.SysLoginService; | import com.ruoyi.framework.web.service.SysLoginService; | ||||
import com.ruoyi.framework.web.service.SysPermissionService; | import com.ruoyi.framework.web.service.SysPermissionService; | ||||
import com.ruoyi.framework.web.service.TokenService; | |||||
import com.ruoyi.system.service.ISysMenuService; | import com.ruoyi.system.service.ISysMenuService; | ||||
import io.swagger.annotations.Api; | import io.swagger.annotations.Api; | ||||
import io.swagger.annotations.ApiOperation; | import io.swagger.annotations.ApiOperation; | ||||
@@ -17,6 +24,8 @@ import org.springframework.web.bind.annotation.PostMapping; | |||||
import org.springframework.web.bind.annotation.RequestBody; | import org.springframework.web.bind.annotation.RequestBody; | ||||
import org.springframework.web.bind.annotation.RestController; | import org.springframework.web.bind.annotation.RestController; | ||||
import javax.servlet.http.HttpServletRequest; | |||||
import javax.servlet.http.HttpServletResponse; | |||||
import java.util.List; | import java.util.List; | ||||
import java.util.Set; | import java.util.Set; | ||||
@@ -37,6 +46,8 @@ public class SysLoginController | |||||
@Autowired | @Autowired | ||||
private SysPermissionService permissionService; | private SysPermissionService permissionService; | ||||
@Autowired | |||||
private TokenService tokenService; | |||||
/** | /** | ||||
* 登录方法 | * 登录方法 | ||||
@@ -91,4 +102,20 @@ public class SysLoginController | |||||
List<SysMenu> menus = menuService.selectMenuTreeByUserId(userId); | List<SysMenu> menus = menuService.selectMenuTreeByUserId(userId); | ||||
return AjaxResult.success(menuService.buildMenus(menus)); | return AjaxResult.success(menuService.buildMenus(menus)); | ||||
} | } | ||||
@ApiOperation("登出") | |||||
@PostMapping("/adminLogout") | |||||
public AjaxResult adminLogout(HttpServletRequest request, HttpServletResponse response) | |||||
{ | |||||
LoginUser loginUser = tokenService.getLoginUser(request); | |||||
if (StringUtils.isNotNull(loginUser)) | |||||
{ | |||||
String userName = loginUser.getUsername(); | |||||
// 删除用户缓存记录 | |||||
tokenService.delLoginUser(loginUser.getToken()); | |||||
// 记录用户退出日志 | |||||
AsyncManager.me().execute(AsyncFactory.recordLogininfor(userName, Constants.LOGOUT, "退出成功")); | |||||
} | |||||
return AjaxResult.success("退出成功"); | |||||
} | |||||
} | } |
@@ -88,6 +88,8 @@ spring: | |||||
max-active: 8 | max-active: 8 | ||||
# #连接池最大阻塞等待时间(使用负值表示没有限制) | # #连接池最大阻塞等待时间(使用负值表示没有限制) | ||||
max-wait: -1ms | max-wait: -1ms | ||||
# key前缀 | |||||
keyPrefix: file_transfer | |||||
# 开发环境配置 | # 开发环境配置 | ||||
server: | server: | ||||
@@ -88,6 +88,8 @@ spring: | |||||
max-active: 8 | max-active: 8 | ||||
# #连接池最大阻塞等待时间(使用负值表示没有限制) | # #连接池最大阻塞等待时间(使用负值表示没有限制) | ||||
max-wait: -1ms | max-wait: -1ms | ||||
# key前缀 | |||||
keyPrefix: file_transfer | |||||
# token配置 | # token配置 | ||||
@@ -88,6 +88,8 @@ spring: | |||||
max-active: 8 | max-active: 8 | ||||
# #连接池最大阻塞等待时间(使用负值表示没有限制) | # #连接池最大阻塞等待时间(使用负值表示没有限制) | ||||
max-wait: -1ms | max-wait: -1ms | ||||
# key前缀 | |||||
keyPrefix: file_transfer | |||||
# 生产环境配置 | # 生产环境配置 | ||||
server: | server: | ||||
@@ -88,6 +88,8 @@ spring: | |||||
max-active: 8 | max-active: 8 | ||||
# #连接池最大阻塞等待时间(使用负值表示没有限制) | # #连接池最大阻塞等待时间(使用负值表示没有限制) | ||||
max-wait: -1ms | max-wait: -1ms | ||||
# key前缀 | |||||
keyPrefix: file_transfer | |||||
# 预发环境配置 | # 预发环境配置 | ||||
server: | server: | ||||
@@ -88,6 +88,8 @@ spring: | |||||
max-active: 8 | max-active: 8 | ||||
# #连接池最大阻塞等待时间(使用负值表示没有限制) | # #连接池最大阻塞等待时间(使用负值表示没有限制) | ||||
max-wait: -1ms | max-wait: -1ms | ||||
# key前缀 | |||||
keyPrefix: file_transfer | |||||
# 测试环境配置 | # 测试环境配置 | ||||
server: | server: | ||||
@@ -0,0 +1,37 @@ | |||||
package com.ruoyi.file.config; | |||||
import com.ruoyi.common.core.domain.AjaxResult; | |||||
import com.ruoyi.file.object.UploadException; | |||||
import org.slf4j.Logger; | |||||
import org.slf4j.LoggerFactory; | |||||
import org.springframework.core.annotation.Order; | |||||
import org.springframework.web.bind.annotation.ExceptionHandler; | |||||
import org.springframework.web.bind.annotation.RestControllerAdvice; | |||||
import javax.servlet.http.HttpServletRequest; | |||||
import javax.servlet.http.HttpServletResponse; | |||||
/** | |||||
* 外部文件上传异常处理器 | |||||
* | |||||
* @author ruoyi | |||||
*/ | |||||
@RestControllerAdvice | |||||
@Order(Integer.MIN_VALUE) | |||||
public class UploadExceptionHandler | |||||
{ | |||||
private static final Logger log = LoggerFactory.getLogger(UploadExceptionHandler.class); | |||||
/** | |||||
* 拦截文件上传异常 | |||||
*/ | |||||
@ExceptionHandler(UploadException.class) | |||||
public AjaxResult handleUploadException(UploadException e, HttpServletRequest request, HttpServletResponse response) | |||||
{ | |||||
String requestURI = request.getRequestURI(); | |||||
log.error("外部文件上传异常: 请求地址'{}',发生异常 {} = '{}'.", requestURI, e.code, e.getMessage()); | |||||
response.setStatus(e.code); | |||||
return AjaxResult.error(e.getMessage()); | |||||
} | |||||
} |
@@ -58,7 +58,7 @@ public class FileService | |||||
UploadResult result = FileUploadFunc.Upload(task); | UploadResult result = FileUploadFunc.Upload(task); | ||||
if(!result.isSuccess()) | if(!result.isSuccess()) | ||||
throw new UploadException(HttpStatus.INTERNAL_SERVER_ERROR.value(), "禁止上传"); | |||||
throw new UploadException(HttpStatus.INTERNAL_SERVER_ERROR.value(), "上传失败"); | |||||
UploadSession session = new UploadSession(project, task, result); | UploadSession session = new UploadSession(project, task, result); | ||||
DumpUpload(session); | DumpUpload(session); | ||||
@@ -213,7 +213,7 @@ public class FileService | |||||
{ | { | ||||
e.printStackTrace(); | e.printStackTrace(); | ||||
UploadLog.Appendln("异常"); | UploadLog.Appendln("异常"); | ||||
throw new UploadException(HttpServletResponse.SC_MOVED_PERMANENTLY, "重定向错误", e); | |||||
throw new UploadException(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "重定向错误", e); | |||||
} | } | ||||
finally | finally | ||||
{ | { | ||||
@@ -1,5 +1,7 @@ | |||||
package com.ruoyi.framework.config; | package com.ruoyi.framework.config; | ||||
import org.springframework.beans.factory.annotation.Autowired; | |||||
import org.springframework.beans.factory.annotation.Value; | |||||
import org.springframework.cache.annotation.CachingConfigurerSupport; | import org.springframework.cache.annotation.CachingConfigurerSupport; | ||||
import org.springframework.cache.annotation.EnableCaching; | import org.springframework.cache.annotation.EnableCaching; | ||||
import org.springframework.context.annotation.Bean; | import org.springframework.context.annotation.Bean; | ||||
@@ -7,7 +9,15 @@ import org.springframework.context.annotation.Configuration; | |||||
import org.springframework.data.redis.connection.RedisConnectionFactory; | import org.springframework.data.redis.connection.RedisConnectionFactory; | ||||
import org.springframework.data.redis.core.RedisTemplate; | import org.springframework.data.redis.core.RedisTemplate; | ||||
import org.springframework.data.redis.core.script.DefaultRedisScript; | import org.springframework.data.redis.core.script.DefaultRedisScript; | ||||
import org.springframework.data.redis.serializer.RedisSerializer; | |||||
import org.springframework.data.redis.serializer.StringRedisSerializer; | import org.springframework.data.redis.serializer.StringRedisSerializer; | ||||
import org.springframework.lang.Nullable; | |||||
import org.springframework.stereotype.Component; | |||||
import org.springframework.util.Assert; | |||||
import java.nio.charset.Charset; | |||||
import java.nio.charset.StandardCharsets; | |||||
import java.util.function.Supplier; | |||||
/** | /** | ||||
* redis配置 | * redis配置 | ||||
@@ -18,6 +28,9 @@ import org.springframework.data.redis.serializer.StringRedisSerializer; | |||||
@EnableCaching | @EnableCaching | ||||
public class RedisConfig extends CachingConfigurerSupport | public class RedisConfig extends CachingConfigurerSupport | ||||
{ | { | ||||
@Value("${spring.redis.keyPrefix}") | |||||
private String keyPrefix; | |||||
@Bean | @Bean | ||||
@SuppressWarnings(value = { "unchecked", "rawtypes" }) | @SuppressWarnings(value = { "unchecked", "rawtypes" }) | ||||
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory connectionFactory) | public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory connectionFactory) | ||||
@@ -27,12 +40,16 @@ public class RedisConfig extends CachingConfigurerSupport | |||||
FastJson2JsonRedisSerializer serializer = new FastJson2JsonRedisSerializer(Object.class); | FastJson2JsonRedisSerializer serializer = new FastJson2JsonRedisSerializer(Object.class); | ||||
Supplier<RedisSerializer<?>> keySerializer = () -> { | |||||
return new PrefixStringRedisSerializer(keyPrefix); | |||||
//return new StringRedisSerializer(); | |||||
}; | |||||
// 使用StringRedisSerializer来序列化和反序列化redis的key值 | // 使用StringRedisSerializer来序列化和反序列化redis的key值 | ||||
template.setKeySerializer(new StringRedisSerializer()); | |||||
template.setKeySerializer(keySerializer.get()); | |||||
template.setValueSerializer(serializer); | template.setValueSerializer(serializer); | ||||
// Hash的key也采用StringRedisSerializer的序列化方式 | // Hash的key也采用StringRedisSerializer的序列化方式 | ||||
template.setHashKeySerializer(new StringRedisSerializer()); | |||||
template.setHashKeySerializer(keySerializer.get()); | |||||
template.setHashValueSerializer(serializer); | template.setHashValueSerializer(serializer); | ||||
template.afterPropertiesSet(); | template.afterPropertiesSet(); | ||||
@@ -66,4 +83,57 @@ public class RedisConfig extends CachingConfigurerSupport | |||||
"end\n" + | "end\n" + | ||||
"return tonumber(current);"; | "return tonumber(current);"; | ||||
} | } | ||||
@Component | |||||
public static class PrefixStringRedisSerializer extends StringRedisSerializer | |||||
{ | |||||
private final String keyPrefix; | |||||
private final Charset charset; | |||||
public PrefixStringRedisSerializer() { | |||||
this(StandardCharsets.UTF_8); | |||||
} | |||||
public PrefixStringRedisSerializer(Charset charset) { | |||||
Assert.notNull(charset, "Charset must not be null!"); | |||||
this.charset = charset; | |||||
keyPrefix = null; | |||||
} | |||||
public PrefixStringRedisSerializer(String keyPrefix) { | |||||
this(keyPrefix, StandardCharsets.UTF_8); | |||||
} | |||||
public PrefixStringRedisSerializer(String keyPrefix, Charset charset) { | |||||
Assert.notNull(charset, "Charset must not be null!"); | |||||
this.charset = charset; | |||||
this.keyPrefix = keyPrefix; | |||||
} | |||||
private boolean keyPrefixEnabled() | |||||
{ | |||||
return null != keyPrefix && !keyPrefix.isEmpty(); | |||||
} | |||||
public String deserialize(@Nullable byte[] bytes) { | |||||
if(null == bytes) | |||||
return null; | |||||
String key = new String(bytes, this.charset); | |||||
if(keyPrefixEnabled()) | |||||
{ | |||||
Assert.isTrue(key.startsWith(keyPrefix), "Redis key must start with '" + keyPrefix + "'!"); | |||||
return key.substring(keyPrefix.length()); | |||||
} | |||||
else | |||||
return key; | |||||
} | |||||
public byte[] serialize(@Nullable String string) { | |||||
if(null == string) | |||||
return null; | |||||
if(keyPrefixEnabled()) | |||||
string = keyPrefix + ':' + string; | |||||
return string.getBytes(this.charset); | |||||
} | |||||
} | |||||
} | } |
@@ -1,10 +1,10 @@ | |||||
# 代码生成 | # 代码生成 | ||||
gen: | gen: | ||||
# 作者 | # 作者 | ||||
author: rongxin | |||||
author: zhao | |||||
# 默认生成包路径 system 需改成自己的模块名称 如 system monitor tool | # 默认生成包路径 system 需改成自己的模块名称 如 system monitor tool | ||||
packageName: com.ruoyi.score | |||||
packageName: com.ruoyi.xxx | |||||
# 自动去除表前缀,默认是false | # 自动去除表前缀,默认是false | ||||
autoRemovePre: true | autoRemovePre: true | ||||
# 表前缀(生成类名不会包含表前缀,多个用逗号分隔) | # 表前缀(生成类名不会包含表前缀,多个用逗号分隔) | ||||
tablePrefix: td_ | |||||
tablePrefix: t_ |
@@ -41,7 +41,7 @@ export function getInfo() { | |||||
// 退出方法 | // 退出方法 | ||||
export function logout() { | export function logout() { | ||||
return request({ | return request({ | ||||
url: '/logout', | |||||
url: '/adminLogout', // '/logout', | |||||
method: 'post' | method: 'post' | ||||
}) | }) | ||||
} | } | ||||
@@ -56,4 +56,4 @@ export function getCodeImg() { | |||||
method: 'get', | method: 'get', | ||||
timeout: 20000 | timeout: 20000 | ||||
}) | }) | ||||
} | |||||
} |
@@ -35,7 +35,7 @@ | |||||
<el-table-column v-for="(item, index) in columns" width="auto" resizable :label="item.name" header-align="center" align="left" :prop="item.name" /> | <el-table-column v-for="(item, index) in columns" width="auto" resizable :label="item.name" header-align="center" align="left" :prop="item.name" /> | ||||
<el-table-column fixed="right" label="操作" align="center"> | <el-table-column fixed="right" label="操作" align="center"> | ||||
<template slot-scope="scope"> | <template slot-scope="scope"> | ||||
<el-button size="mini" type="text" icon="el-icon-view" @click="handleLook(scope.row)" v-hasPermi="['score:farmerEvalMonth:query']">查看</el-button> | |||||
<el-button size="mini" type="text" icon="el-icon-view" @click="handleLook(scope.row)" v-hasPermi="['admin:xxx:xxx']">查看</el-button> | |||||
</template> | </template> | ||||
</el-table-column> | </el-table-column> | ||||
</el-table> | </el-table> | ||||