@@ -1,11 +1,17 @@ | |||
package com.ruoyi.web.controller.system; | |||
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.RestController; | |||
import com.ruoyi.common.config.RuoYiConfig; | |||
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("/") | |||
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; | |||
import com.alibaba.fastjson2.JSON; | |||
import com.ruoyi.common.constant.Constants; | |||
import com.ruoyi.common.core.domain.AjaxResult; | |||
import com.ruoyi.common.core.domain.entity.SysMenu; | |||
import com.ruoyi.common.core.domain.entity.SysUser; | |||
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.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.SysPermissionService; | |||
import com.ruoyi.framework.web.service.TokenService; | |||
import com.ruoyi.system.service.ISysMenuService; | |||
import io.swagger.annotations.Api; | |||
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.RestController; | |||
import javax.servlet.http.HttpServletRequest; | |||
import javax.servlet.http.HttpServletResponse; | |||
import java.util.List; | |||
import java.util.Set; | |||
@@ -37,6 +46,8 @@ public class SysLoginController | |||
@Autowired | |||
private SysPermissionService permissionService; | |||
@Autowired | |||
private TokenService tokenService; | |||
/** | |||
* 登录方法 | |||
@@ -91,4 +102,20 @@ public class SysLoginController | |||
List<SysMenu> menus = menuService.selectMenuTreeByUserId(userId); | |||
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-wait: -1ms | |||
# key前缀 | |||
keyPrefix: file_transfer | |||
# 开发环境配置 | |||
server: | |||
@@ -88,6 +88,8 @@ spring: | |||
max-active: 8 | |||
# #连接池最大阻塞等待时间(使用负值表示没有限制) | |||
max-wait: -1ms | |||
# key前缀 | |||
keyPrefix: file_transfer | |||
# token配置 | |||
@@ -88,6 +88,8 @@ spring: | |||
max-active: 8 | |||
# #连接池最大阻塞等待时间(使用负值表示没有限制) | |||
max-wait: -1ms | |||
# key前缀 | |||
keyPrefix: file_transfer | |||
# 生产环境配置 | |||
server: | |||
@@ -88,6 +88,8 @@ spring: | |||
max-active: 8 | |||
# #连接池最大阻塞等待时间(使用负值表示没有限制) | |||
max-wait: -1ms | |||
# key前缀 | |||
keyPrefix: file_transfer | |||
# 预发环境配置 | |||
server: | |||
@@ -88,6 +88,8 @@ spring: | |||
max-active: 8 | |||
# #连接池最大阻塞等待时间(使用负值表示没有限制) | |||
max-wait: -1ms | |||
# key前缀 | |||
keyPrefix: file_transfer | |||
# 测试环境配置 | |||
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); | |||
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); | |||
DumpUpload(session); | |||
@@ -213,7 +213,7 @@ public class FileService | |||
{ | |||
e.printStackTrace(); | |||
UploadLog.Appendln("异常"); | |||
throw new UploadException(HttpServletResponse.SC_MOVED_PERMANENTLY, "重定向错误", e); | |||
throw new UploadException(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "重定向错误", e); | |||
} | |||
finally | |||
{ | |||
@@ -1,5 +1,7 @@ | |||
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.EnableCaching; | |||
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.core.RedisTemplate; | |||
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.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配置 | |||
@@ -18,6 +28,9 @@ import org.springframework.data.redis.serializer.StringRedisSerializer; | |||
@EnableCaching | |||
public class RedisConfig extends CachingConfigurerSupport | |||
{ | |||
@Value("${spring.redis.keyPrefix}") | |||
private String keyPrefix; | |||
@Bean | |||
@SuppressWarnings(value = { "unchecked", "rawtypes" }) | |||
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory connectionFactory) | |||
@@ -27,12 +40,16 @@ public class RedisConfig extends CachingConfigurerSupport | |||
FastJson2JsonRedisSerializer serializer = new FastJson2JsonRedisSerializer(Object.class); | |||
Supplier<RedisSerializer<?>> keySerializer = () -> { | |||
return new PrefixStringRedisSerializer(keyPrefix); | |||
//return new StringRedisSerializer(); | |||
}; | |||
// 使用StringRedisSerializer来序列化和反序列化redis的key值 | |||
template.setKeySerializer(new StringRedisSerializer()); | |||
template.setKeySerializer(keySerializer.get()); | |||
template.setValueSerializer(serializer); | |||
// Hash的key也采用StringRedisSerializer的序列化方式 | |||
template.setHashKeySerializer(new StringRedisSerializer()); | |||
template.setHashKeySerializer(keySerializer.get()); | |||
template.setHashValueSerializer(serializer); | |||
template.afterPropertiesSet(); | |||
@@ -66,4 +83,57 @@ public class RedisConfig extends CachingConfigurerSupport | |||
"end\n" + | |||
"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: | |||
# 作者 | |||
author: rongxin | |||
author: zhao | |||
# 默认生成包路径 system 需改成自己的模块名称 如 system monitor tool | |||
packageName: com.ruoyi.score | |||
packageName: com.ruoyi.xxx | |||
# 自动去除表前缀,默认是false | |||
autoRemovePre: true | |||
# 表前缀(生成类名不会包含表前缀,多个用逗号分隔) | |||
tablePrefix: td_ | |||
tablePrefix: t_ |
@@ -41,7 +41,7 @@ export function getInfo() { | |||
// 退出方法 | |||
export function logout() { | |||
return request({ | |||
url: '/logout', | |||
url: '/adminLogout', // '/logout', | |||
method: 'post' | |||
}) | |||
} | |||
@@ -56,4 +56,4 @@ export function getCodeImg() { | |||
method: 'get', | |||
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 fixed="right" label="操作" align="center"> | |||
<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> | |||
</el-table-column> | |||
</el-table> | |||