| @@ -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> | |||