diff --git a/.gitignore b/.gitignore index 7834e46..a38c95c 100644 --- a/.gitignore +++ b/.gitignore @@ -10,8 +10,7 @@ target/ *.iws *.iml *.ipr -#.idea/workspace.xml -.idea/compiler.xml + ### NetBeans ### diff --git a/huaheng.iml b/huaheng.iml index 5f40adb..675dfb1 100644 --- a/huaheng.iml +++ b/huaheng.iml @@ -195,9 +195,27 @@ <orderEntry type="library" name="Maven: org.unbescape:unbescape:1.1.6.RELEASE" level="project" /> <orderEntry type="library" name="Maven: org.thymeleaf.extras:thymeleaf-extras-java8time:3.0.3.RELEASE" level="project" /> <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-devtools:2.1.3.RELEASE" level="project" /> + <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-data-redis:2.1.3.RELEASE" level="project" /> + <orderEntry type="library" name="Maven: org.springframework.data:spring-data-redis:2.1.5.RELEASE" level="project" /> + <orderEntry type="library" name="Maven: org.springframework.data:spring-data-keyvalue:2.1.5.RELEASE" level="project" /> + <orderEntry type="library" name="Maven: org.springframework.data:spring-data-commons:2.1.5.RELEASE" level="project" /> + <orderEntry type="library" name="Maven: org.springframework:spring-tx:5.1.5.RELEASE" level="project" /> + <orderEntry type="library" name="Maven: org.springframework:spring-oxm:5.1.5.RELEASE" level="project" /> + <orderEntry type="library" name="Maven: io.lettuce:lettuce-core:5.1.4.RELEASE" level="project" /> + <orderEntry type="library" name="Maven: io.netty:netty-common:4.1.33.Final" level="project" /> + <orderEntry type="library" name="Maven: io.netty:netty-handler:4.1.33.Final" level="project" /> + <orderEntry type="library" name="Maven: io.netty:netty-buffer:4.1.33.Final" level="project" /> + <orderEntry type="library" name="Maven: io.netty:netty-codec:4.1.33.Final" level="project" /> + <orderEntry type="library" name="Maven: io.netty:netty-transport:4.1.33.Final" level="project" /> + <orderEntry type="library" name="Maven: io.netty:netty-resolver:4.1.33.Final" level="project" /> + <orderEntry type="library" name="Maven: io.projectreactor:reactor-core:3.2.6.RELEASE" level="project" /> + <orderEntry type="library" name="Maven: org.reactivestreams:reactive-streams:1.0.2" level="project" /> + <orderEntry type="library" name="Maven: org.apache.commons:commons-pool2:2.6.1" level="project" /> <orderEntry type="library" name="Maven: net.sourceforge.nekohtml:nekohtml:1.9.22" level="project" /> <orderEntry type="library" name="Maven: xerces:xercesImpl:2.11.0" level="project" /> <orderEntry type="library" name="Maven: xml-apis:xml-apis:1.4.01" level="project" /> + <orderEntry type="library" name="Maven: io.jsonwebtoken:jjwt:0.9.1" level="project" /> + <orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-databind:2.9.8" level="project" /> <orderEntry type="library" name="Maven: mysql:mysql-connector-java:8.0.16" level="project" /> <orderEntry type="library" name="Maven: com.github.pagehelper:pagehelper-spring-boot-starter:1.2.12" level="project" /> <orderEntry type="library" name="Maven: org.mybatis.spring.boot:mybatis-spring-boot-starter:2.0.1" level="project" /> @@ -272,7 +290,6 @@ <orderEntry type="library" name="Maven: org.codehaus.castor:castor-core:1.4.1" level="project" /> <orderEntry type="library" name="Maven: javax.inject:javax.inject:1" level="project" /> <orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-core:2.9.8" level="project" /> - <orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-databind:2.9.8" level="project" /> <orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.9.0" level="project" /> <orderEntry type="library" name="Maven: net.sf.jasperreports:jasperreports-fonts:6.10.0" level="project" /> <orderEntry type="library" name="Maven: com.itextpdf:itextpdf:5.5.7" level="project" /> @@ -295,7 +312,6 @@ <orderEntry type="library" name="Maven: org.springframework.amqp:spring-amqp:2.1.4.RELEASE" level="project" /> <orderEntry type="library" name="Maven: org.springframework.retry:spring-retry:1.2.4.RELEASE" level="project" /> <orderEntry type="library" name="Maven: com.rabbitmq:amqp-client:5.4.3" level="project" /> - <orderEntry type="library" name="Maven: org.springframework:spring-tx:5.1.5.RELEASE" level="project" /> <orderEntry type="library" name="Maven: com.baomidou:mybatis-plus-boot-starter:3.1.2" level="project" /> <orderEntry type="library" name="Maven: com.baomidou:mybatis-plus:3.1.2" level="project" /> <orderEntry type="library" name="Maven: com.baomidou:mybatis-plus-extension:3.1.2" level="project" /> diff --git a/pom.xml b/pom.xml index 13ac078..f558341 100644 --- a/pom.xml +++ b/pom.xml @@ -91,12 +91,30 @@ <optional>true</optional> <!-- 表示依赖不会传递 --> </dependency> + <!-- redis 缓存操作 --> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-data-redis</artifactId> + </dependency> + + <!-- pool 对象池 --> + <dependency> + <groupId>org.apache.commons</groupId> + <artifactId>commons-pool2</artifactId> + </dependency> + <!-- thymeleaf网页解析 --> <dependency> <groupId>net.sourceforge.nekohtml</groupId> <artifactId>nekohtml</artifactId> </dependency> + <dependency> + <groupId>io.jsonwebtoken</groupId> + <artifactId>jjwt</artifactId> + <version>0.9.1</version> + </dependency> + <!-- Mysql8驱动包 --> <dependency> <groupId>mysql</groupId> diff --git a/src/main/java/com/huaheng/framework/config/ShiroConfig.java b/src/main/java/com/huaheng/framework/config/ShiroConfig.java index 54d6455..6878aa9 100644 --- a/src/main/java/com/huaheng/framework/config/ShiroConfig.java +++ b/src/main/java/com/huaheng/framework/config/ShiroConfig.java @@ -3,6 +3,7 @@ package com.huaheng.framework.config; import java.util.LinkedHashMap; import java.util.Map; import javax.servlet.Filter; + import org.apache.shiro.cache.ehcache.EhCacheManager; import org.apache.shiro.codec.Base64; import org.apache.shiro.mgt.SecurityManager; @@ -28,12 +29,11 @@ import at.pollux.thymeleaf.shiro.dialect.ShiroDialect; /** * 权限配置加载 - * + * * @author huaheng */ @Configuration -public class ShiroConfig -{ +public class ShiroConfig { public static final String PREMISSION_STRING = "perms[\"{0}\"]"; // Session超时时间,单位为毫秒(默认30分钟) @@ -84,17 +84,13 @@ public class ShiroConfig * 缓存管理器 使用Ehcache实现 */ @Bean - public EhCacheManager getEhCacheManager() - { + public EhCacheManager getEhCacheManager() { net.sf.ehcache.CacheManager cacheManager = net.sf.ehcache.CacheManager.getCacheManager("huaheng"); EhCacheManager em = new EhCacheManager(); - if (StringUtils.isNull(cacheManager)) - { + if (StringUtils.isNull(cacheManager)) { em.setCacheManagerConfigFile("classpath:ehcache/ehcache-shiro.xml"); return em; - } - else - { + } else { em.setCacheManager(cacheManager); return em; } @@ -104,8 +100,7 @@ public class ShiroConfig * 自定义Realm */ @Bean - public UserRealm userRealm(EhCacheManager cacheManager) - { + public UserRealm userRealm(EhCacheManager cacheManager) { UserRealm userRealm = new UserRealm(); userRealm.setCacheManager(cacheManager); return userRealm; @@ -115,8 +110,7 @@ public class ShiroConfig * 自定义sessionDAO会话 */ @Bean - public OnlineSessionDAO sessionDAO() - { + public OnlineSessionDAO sessionDAO() { OnlineSessionDAO sessionDAO = new OnlineSessionDAO(); return sessionDAO; } @@ -125,8 +119,7 @@ public class ShiroConfig * 自定义sessionFactory会话 */ @Bean - public OnlineSessionFactory sessionFactory() - { + public OnlineSessionFactory sessionFactory() { OnlineSessionFactory sessionFactory = new OnlineSessionFactory(); return sessionFactory; } @@ -135,8 +128,7 @@ public class ShiroConfig * 自定义sessionFactory调度器 */ @Bean - public SpringSessionValidationScheduler sessionValidationScheduler() - { + public SpringSessionValidationScheduler sessionValidationScheduler() { SpringSessionValidationScheduler sessionValidationScheduler = new SpringSessionValidationScheduler(); // 相隔多久检查一次session的有效性,单位毫秒,默认就是10分钟 sessionValidationScheduler.setSessionValidationInterval(validationInterval * 60 * 1000); @@ -149,8 +141,7 @@ public class ShiroConfig * 会话管理器 */ @Bean - public OnlineWebSessionManager sessionValidationManager() - { + public OnlineWebSessionManager sessionValidationManager() { OnlineWebSessionManager manager = new OnlineWebSessionManager(); // 加入缓存管理器 manager.setCacheManager(getEhCacheManager()); @@ -173,8 +164,7 @@ public class ShiroConfig * 会话管理器 */ @Bean - public OnlineWebSessionManager sessionManager() - { + public OnlineWebSessionManager sessionManager() { OnlineWebSessionManager manager = new OnlineWebSessionManager(); // 加入缓存管理器 manager.setCacheManager(getEhCacheManager()); @@ -199,8 +189,7 @@ public class ShiroConfig * 安全管理器 */ @Bean - public SecurityManager securityManager(UserRealm userRealm) - { + public SecurityManager securityManager(UserRealm userRealm) { DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); // 设置realm. securityManager.setRealm(userRealm); @@ -216,15 +205,13 @@ public class ShiroConfig /** * 退出过滤器 */ - public LogoutFilter logoutFilter() - { + public LogoutFilter logoutFilter() { LogoutFilter logoutFilter = new LogoutFilter(); logoutFilter.setLoginUrl(loginUrl); return logoutFilter; } - public LogoutFilter logoutFilters() - { + public LogoutFilter logoutFilters() { LogoutFilter logoutFilter = new LogoutFilter(); logoutFilter.setLoginUrl(loginUrls); return logoutFilter; @@ -234,8 +221,7 @@ public class ShiroConfig * Shiro过滤器配置 */ @Bean - public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) - { + public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) { ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); // Shiro的核心安全接口,这个属性是必须的 shiroFilterFactoryBean.setSecurityManager(securityManager); @@ -270,6 +256,7 @@ public class ShiroConfig filterChainDefinitionMap.put("/mobile/login", "anon"); filterChainDefinitionMap.put("/getWarehouseByUserCode", "anon"); filterChainDefinitionMap.put("/API/WMS/v2/login", "anon"); + filterChainDefinitionMap.put("/api/**", "anon"); // 系统权限列表 // filterChainDefinitionMap.putAll(SpringUtils.getBean(IMenuService.class).selectPermsAll()); @@ -292,8 +279,7 @@ public class ShiroConfig * 自定义在线用户处理过滤器 */ @Bean - public OnlineSessionFilter onlineSessionFilter() - { + public OnlineSessionFilter onlineSessionFilter() { OnlineSessionFilter onlineSessionFilter = new OnlineSessionFilter(); onlineSessionFilter.setLoginUrl(loginUrl); return onlineSessionFilter; @@ -303,8 +289,7 @@ public class ShiroConfig * 自定义在线用户同步过滤器 */ @Bean - public SyncOnlineSessionFilter syncOnlineSessionFilter() - { + public SyncOnlineSessionFilter syncOnlineSessionFilter() { SyncOnlineSessionFilter syncOnlineSessionFilter = new SyncOnlineSessionFilter(); return syncOnlineSessionFilter; } @@ -312,8 +297,7 @@ public class ShiroConfig /** * cookie 属性设置 */ - public SimpleCookie rememberMeCookie() - { + public SimpleCookie rememberMeCookie() { SimpleCookie cookie = new SimpleCookie("rememberMe"); cookie.setDomain(domain); cookie.setPath(path); @@ -325,8 +309,7 @@ public class ShiroConfig /** * 记住我 */ - public CookieRememberMeManager rememberMeManager() - { + public CookieRememberMeManager rememberMeManager() { CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager(); cookieRememberMeManager.setCookie(rememberMeCookie()); cookieRememberMeManager.setCipherKey(Base64.decode("fCq+/xW488hMTCD+cmJ3aQ==")); @@ -337,8 +320,7 @@ public class ShiroConfig * thymeleaf模板引擎和shiro框架的整合 */ @Bean - public ShiroDialect shiroDialect() - { + public ShiroDialect shiroDialect() { return new ShiroDialect(); } @@ -347,8 +329,7 @@ public class ShiroConfig */ @Bean public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor( - @Qualifier("securityManager") SecurityManager securityManager) - { + @Qualifier("securityManager") SecurityManager securityManager) { AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor(); authorizationAttributeSourceAdvisor.setSecurityManager(securityManager); return authorizationAttributeSourceAdvisor; diff --git a/src/main/java/com/huaheng/framework/redis/RedisCache.java b/src/main/java/com/huaheng/framework/redis/RedisCache.java new file mode 100644 index 0000000..3699ee1 --- /dev/null +++ b/src/main/java/com/huaheng/framework/redis/RedisCache.java @@ -0,0 +1,180 @@ +package com.huaheng.framework.redis; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.core.*; +import org.springframework.stereotype.Component; + +import java.util.*; +import java.util.concurrent.TimeUnit; + +/** + * spring redis 工具类 + * + * @author ruoyi + **/ +@SuppressWarnings(value = {"unchecked", "rawtypes"}) +@Component +public class RedisCache { + + @Autowired + public RedisTemplate redisTemplate; + + /** + * 缓存基本的对象,Integer、String、实体类等 + * + * @param key 缓存的键值 + * @param value 缓存的值 + * @return 缓存的对象 + */ + public <T> ValueOperations<String, T> setCacheObject(String key, T value) { + ValueOperations<String, T> operation = redisTemplate.opsForValue(); + operation.set(key, value); + return operation; + } + + /** + * 缓存基本的对象,Integer、String、实体类等 + * + * @param key 缓存的键值 + * @param value 缓存的值 + * @param timeout 时间 + * @param timeUnit 时间颗粒度 + * @return 缓存的对象 + */ + public <T> ValueOperations<String, T> setCacheObject(String key, T value, Integer timeout, TimeUnit timeUnit) { + ValueOperations<String, T> operation = redisTemplate.opsForValue(); + operation.set(key, value, timeout, timeUnit); + return operation; + } + + /** + * 获得缓存的基本对象。 + * + * @param key 缓存键值 + * @return 缓存键值对应的数据 + */ + public <T> T getCacheObject(String key) { + ValueOperations<String, T> operation = redisTemplate.opsForValue(); + return operation.get(key); + } + + /** + * 删除单个对象 + * + * @param key + */ + public void deleteObject(String key) { + redisTemplate.delete(key); + } + + /** + * 删除集合对象 + * + * @param collection + */ + public void deleteObject(Collection collection) { + redisTemplate.delete(collection); + } + + /** + * 缓存List数据 + * + * @param key 缓存的键值 + * @param dataList 待缓存的List数据 + * @return 缓存的对象 + */ + public <T> ListOperations<String, T> setCacheList(String key, List<T> dataList) { + ListOperations listOperation = redisTemplate.opsForList(); + if (null != dataList) { + int size = dataList.size(); + for (int i = 0; i < size; i++) { + listOperation.leftPush(key, dataList.get(i)); + } + } + return listOperation; + } + + /** + * 获得缓存的list对象 + * + * @param key 缓存的键值 + * @return 缓存键值对应的数据 + */ + public <T> List<T> getCacheList(String key) { + List<T> dataList = new ArrayList<T>(); + ListOperations<String, T> listOperation = redisTemplate.opsForList(); + Long size = listOperation.size(key); + + for (int i = 0; i < size; i++) { + dataList.add(listOperation.index(key, i)); + } + return dataList; + } + + /** + * 缓存Set + * + * @param key 缓存键值 + * @param dataSet 缓存的数据 + * @return 缓存数据的对象 + */ + public <T> BoundSetOperations<String, T> setCacheSet(String key, Set<T> dataSet) { + BoundSetOperations<String, T> setOperation = redisTemplate.boundSetOps(key); + Iterator<T> it = dataSet.iterator(); + while (it.hasNext()) { + setOperation.add(it.next()); + } + return setOperation; + } + + /** + * 获得缓存的set + * + * @param key + * @return + */ + public <T> Set<T> getCacheSet(String key) { + Set<T> dataSet = new HashSet<T>(); + BoundSetOperations<String, T> operation = redisTemplate.boundSetOps(key); + dataSet = operation.members(); + return dataSet; + } + + /** + * 缓存Map + * + * @param key + * @param dataMap + * @return + */ + public <T> HashOperations<String, String, T> setCacheMap(String key, Map<String, T> dataMap) { + HashOperations hashOperations = redisTemplate.opsForHash(); + if (null != dataMap) { + for (Map.Entry<String, T> entry : dataMap.entrySet()) { + hashOperations.put(key, entry.getKey(), entry.getValue()); + } + } + return hashOperations; + } + + /** + * 获得缓存的Map + * + * @param key + * @return + */ + public <T> Map<String, T> getCacheMap(String key) { + Map<String, T> map = redisTemplate.opsForHash().entries(key); + return map; + } + + /** + * 获得缓存的基本对象列表 + * + * @param pattern 字符串前缀 + * @return 对象列表 + */ + public Collection<String> keys(String pattern) { + return redisTemplate.keys(pattern); + } +} diff --git a/src/main/java/com/huaheng/framework/token/ApiInterceptor.java b/src/main/java/com/huaheng/framework/token/ApiInterceptor.java new file mode 100644 index 0000000..13966d7 --- /dev/null +++ b/src/main/java/com/huaheng/framework/token/ApiInterceptor.java @@ -0,0 +1,52 @@ +package com.huaheng.framework.token; + +import com.alibaba.fastjson.JSONObject; +import com.huaheng.common.utils.ServletUtils; +import com.huaheng.common.utils.StringUtils; +import com.huaheng.framework.redis.RedisCache; +import org.springframework.web.servlet.HandlerInterceptor; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.security.SignatureException; + +/** + * Created by Enzo Cotter on 2020/6/11. + */ +public class ApiInterceptor implements HandlerInterceptor { + + @Resource + private RedisCache redisCache; + /** + * 可以在这里设置各种规则,取到token后解析,来验证token有效性,有效期等等。这里仅仅验证了是不是token为空。 + */ + @Override + public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception { + //这个就是从http头中取约定好的token的key。 + String token = httpServletRequest.getHeader("Authorization"); + try { + if (token == null || token.trim().equals("")) { + throw new SignatureException("token is null"); + } else { + token = token.substring(7); + String user = redisCache.getCacheObject(token); + if (StringUtils.isEmpty(user)) { + JSONObject jsonObject = new JSONObject(); + jsonObject.put("msg", "token不正确或过期"); + jsonObject.put("code", 401); + ServletUtils.renderString(httpServletResponse, jsonObject.toString()); + return false; + } + } + } catch (SignatureException e) { + JSONObject jsonObject = new JSONObject(); + jsonObject.put("msg", "请求参数中找不到Token"); + jsonObject.put("code", 401); + ServletUtils.renderString(httpServletResponse, jsonObject.toString()); + return false; + } + + return true; + } +} diff --git a/src/main/java/com/huaheng/framework/token/TokenController.java b/src/main/java/com/huaheng/framework/token/TokenController.java new file mode 100644 index 0000000..81994dd --- /dev/null +++ b/src/main/java/com/huaheng/framework/token/TokenController.java @@ -0,0 +1,56 @@ +package com.huaheng.framework.token; + +import com.huaheng.common.utils.StringUtils; +import com.huaheng.framework.shiro.service.PasswordService; +import com.huaheng.framework.web.controller.BaseController; +import com.huaheng.framework.web.domain.Result; +import com.huaheng.pc.system.user.domain.User; +import com.huaheng.pc.system.user.service.IUserService; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import java.util.Calendar; + +/** + * Created by Enzo Cotter on 2020/6/11. + */ +@RestController +@RequestMapping("/api") +public class TokenController extends BaseController { + + @Resource + private TokenService tokenService; + @Resource + private IUserService userService; + @Resource + private PasswordService passwordService; + + @PostMapping("/getToken") + @ResponseBody + public Result getToken(String username, String password, String warehouseCode) { + if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password)) { + return Result.error("用户名和密码不能为空"); + } + if (StringUtils.isEmpty(warehouseCode)) { + return Result.error("请选择仓库"); + } + User user = userService.selectUserByLoginName(username); + + if (!userService.checkWarehouseCodeAndUserName(warehouseCode, username)) { + return Result.error("用户没有该仓库操作权限"); + } + if (user.getPassword().equals(passwordService.encryptPassword(user.getLoginName(), password, user.getSalt()))) { + String token = tokenService.createToken(user); + Result ajaxResult = Result.success("成功"); + ajaxResult.put("token", token); + ajaxResult.put("expireTime", Calendar.getInstance().getTime()); + return ajaxResult; + } else { + return Result.error("密码错误"); + } + + } +} diff --git a/src/main/java/com/huaheng/framework/token/TokenService.java b/src/main/java/com/huaheng/framework/token/TokenService.java new file mode 100644 index 0000000..e28763f --- /dev/null +++ b/src/main/java/com/huaheng/framework/token/TokenService.java @@ -0,0 +1,79 @@ +package com.huaheng.framework.token; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.google.gson.JsonObject; +import com.huaheng.common.exception.service.ServiceException; +import com.huaheng.framework.redis.RedisCache; +import com.huaheng.pc.system.user.domain.User; +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.Jws; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.SignatureAlgorithm; +import jdk.nashorn.internal.parser.JSONParser; +import org.springframework.boot.autoconfigure.cache.CacheProperties; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.Calendar; +import java.util.Date; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +/** + * token生成与解析 + * @author Enzo Cotter + * @date 2020/6/11 + */ +@Service +public class TokenService { + + @Resource + private RedisCache redisCache; + + /** + * 有效期7天 + */ + private static final int EXPIRE_TIME = 7; + + /** + * 盐 + */ + private static final String signingKey = "secret"; + + /** + * 创建token + * @param user 用户 + * @return + */ + public String createToken(User user){ + //签发时间 + Date iatTime = new Date(); + //expire time + Calendar nowTime = Calendar.getInstance(); + nowTime.add(Calendar.DATE, EXPIRE_TIME); + Date expireTime = nowTime.getTime(); + + Claims claims = Jwts.claims(); + claims.put("user", user); + claims.setIssuedAt(iatTime); + String token = Jwts.builder().setClaims(claims) + .signWith(SignatureAlgorithm.HS512,signingKey).compact(); + if (redisCache.setCacheObject(token, user.toString(), EXPIRE_TIME, TimeUnit.DAYS) == null) { + throw new ServiceException("redis异常"); + } + return token; + } + + /** + * 解析token + * @param token + */ + public void parseToken(String token){ + Jws<Claims> jws = Jwts.parser().setSigningKey(signingKey).parseClaimsJws(token); + Claims claims = jws.getBody(); + Map<String,String> header = jws.getHeader(); + System.out.println("parse"); + } +} diff --git a/src/main/java/com/huaheng/framework/token/WebAppConfigurer.java b/src/main/java/com/huaheng/framework/token/WebAppConfigurer.java new file mode 100644 index 0000000..24306c8 --- /dev/null +++ b/src/main/java/com/huaheng/framework/token/WebAppConfigurer.java @@ -0,0 +1,23 @@ +package com.huaheng.framework.token; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +/** + * Created by Enzo Cotter on 2020/6/11. + */ +@Configuration +public class WebAppConfigurer implements WebMvcConfigurer { + + @Bean + ApiInterceptor apiInterceptor(){return new ApiInterceptor();} + + @Override + public void addInterceptors(InterceptorRegistry interceptorRegistry) { + interceptorRegistry.addInterceptor(apiInterceptor()) + .addPathPatterns("/api/**") + .excludePathPatterns("/api/getToken"); + } +} diff --git a/src/main/java/com/huaheng/framework/web/domain/Result.java b/src/main/java/com/huaheng/framework/web/domain/Result.java new file mode 100644 index 0000000..597ef1e --- /dev/null +++ b/src/main/java/com/huaheng/framework/web/domain/Result.java @@ -0,0 +1,142 @@ +package com.huaheng.framework.web.domain; + +import com.huaheng.common.utils.StringUtils; + +import java.util.HashMap; + +/** + * 操作消息提醒 + * @author Enzo Cotter + * @date 2020/6/11 + */ +public class Result extends HashMap<String, Object> { + private static final long serialVersionUID = 1L; + + /** + * 状态码 + */ + public static final String CODE_TAG = "code"; + + /** + * 返回内容 + */ + public static final String MSG_TAG = "msg"; + + /** + * 数据对象 + */ + public static final String DATA_TAG = "data"; + + /** + * 初始化一个新创建的 AjaxResult 对象,使其表示一个空消息。 + */ + public Result() { + } + + /** + * 初始化一个新创建的 AjaxResult 对象 + * + * @param code 状态码 + * @param msg 返回内容 + */ + public Result(int code, String msg) { + super.put(CODE_TAG, code); + super.put(MSG_TAG, msg); + } + + /** + * 初始化一个新创建的 AjaxResult 对象 + * + * @param code 状态码 + * @param msg 返回内容 + * @param data 数据对象 + */ + public Result(int code, String msg, Object data) { + super.put(CODE_TAG, code); + super.put(MSG_TAG, msg); + if (StringUtils.isNotNull(data)) { + super.put(DATA_TAG, data); + } + } + + /** + * 返回成功消息 + * + * @return 成功消息 + */ + public static Result success() { + return Result.success("操作成功"); + } + + /** + * 返回成功数据 + * + * @return 成功消息 + */ + public static Result success(Object data) { + return Result.success("操作成功", data); + } + + /** + * 返回成功消息 + * + * @param msg 返回内容 + * @return 成功消息 + */ + public static Result success(String msg) { + return Result.success(msg, null); + } + + /** + * 返回成功消息 + * + * @param msg 返回内容 + * @param data 数据对象 + * @return 成功消息 + */ + public static Result success(String msg, Object data) { + return new Result(200, msg, data); + } + + /** + * 返回错误消息 + * + * @return + */ + public static Result error() { + return Result.error("操作失败"); + } + + /** + * 返回错误消息 + * + * @param msg 返回内容 + * @return 警告消息 + */ + public static Result error(String msg) { + return Result.error(msg, null); + } + + /** + * 返回错误消息 + * + * @param msg 返回内容 + * @param data 数据对象 + * @return 警告消息 + */ + public static Result error(String msg, Object data) { + return new Result(400, msg, data); + } + + /** + * 返回错误消息 + * + * @param code 状态码 + * @param msg 返回内容 + * @return 警告消息 + */ + public static Result error(int code, String msg) { + return new Result(code, msg, null); + } + +} diff --git a/src/main/java/com/huaheng/pc/receipt/receiving/controller/ReceivingController.java b/src/main/java/com/huaheng/pc/receipt/receiving/controller/ReceivingController.java index e643c20..70d311d 100644 --- a/src/main/java/com/huaheng/pc/receipt/receiving/controller/ReceivingController.java +++ b/src/main/java/com/huaheng/pc/receipt/receiving/controller/ReceivingController.java @@ -98,7 +98,7 @@ public class ReceivingController extends BaseController { // if (count > 0) { // return AjaxResult.error("仓库有“出库查看”任务没有完成,请先完成任务"); // } - AjaxResult result = receiptContainerHeaderService.saveCountain(receiptCode, containerCode, receiptDetailId, + AjaxResult result = receiptContainerHeaderService.saveContainer(receiptCode, containerCode, receiptDetailId, locationCode, qty, locatingRule); return result; } diff --git a/src/main/java/com/huaheng/pc/system/user/mapper/UserMapper.java b/src/main/java/com/huaheng/pc/system/user/mapper/UserMapper.java index 3be853e..bfebcf1 100644 --- a/src/main/java/com/huaheng/pc/system/user/mapper/UserMapper.java +++ b/src/main/java/com/huaheng/pc/system/user/mapper/UserMapper.java @@ -119,6 +119,14 @@ public interface UserMapper public User checkEmailUnique(String email); /** + * 检查用户是否拥有该仓库权限 + * @param warehouseCode 仓库code + * @param username 登录名 + * @return + */ + List<Map<String, Object>> checkWarehouseCodeAndUserName(@Param("warehouseCode") String warehouseCode, @Param("loginName") String username); + + /** * 根据用户id查询该用户所有仓库 * @param userId * @return diff --git a/src/main/java/com/huaheng/pc/system/user/service/IUserService.java b/src/main/java/com/huaheng/pc/system/user/service/IUserService.java index d20d89c..7dc503d 100644 --- a/src/main/java/com/huaheng/pc/system/user/service/IUserService.java +++ b/src/main/java/com/huaheng/pc/system/user/service/IUserService.java @@ -200,6 +200,8 @@ public interface IUserService public User selectmen(String loginName); public int batchUserWarehouse(@Param("userWarehouseList") List<SysUserWarehouse> userWarehouseList); + + boolean checkWarehouseCodeAndUserName(String warehouseCode, String username); } diff --git a/src/main/java/com/huaheng/pc/system/user/service/UserServiceImpl.java b/src/main/java/com/huaheng/pc/system/user/service/UserServiceImpl.java index fa48246..a37842d 100644 --- a/src/main/java/com/huaheng/pc/system/user/service/UserServiceImpl.java +++ b/src/main/java/com/huaheng/pc/system/user/service/UserServiceImpl.java @@ -594,4 +594,9 @@ public class UserServiceImpl implements IUserService return sysUserWarehouseMapper.batchUserWarehouse(userWarehouseList); } + @Override + public boolean checkWarehouseCodeAndUserName(String warehouseCode, String username) { + return !userMapper.checkWarehouseCodeAndUserName(warehouseCode, username).isEmpty(); + } + } diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 913ade4..a35a52d 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -84,6 +84,26 @@ spring: password: owobzjvlgsxrbdfe # 编码类型 default-encoding: utf-8 + # redis 配置 + redis: + # 地址 + host: localhost + # 端口,默认为6379 + port: 6379 + # 密码 + password: + # 连接超时时间 + timeout: 10s + lettuce: + pool: + # 连接池中的最小空闲连接 + min-idle: 0 + # 连接池中的最大空闲连接 + max-idle: 8 + # 连接池的最大数据库连接数 + max-active: 8 + # #连接池最大阻塞等待时间(使用负值表示没有限制) + max-wait: -1ms mybatis-plus: mapper-locations: classpath:mybatis/**/*.xml diff --git a/src/main/resources/mybatis/system/UserMapper.xml b/src/main/resources/mybatis/system/UserMapper.xml index 88a4010..5646090 100644 --- a/src/main/resources/mybatis/system/UserMapper.xml +++ b/src/main/resources/mybatis/system/UserMapper.xml @@ -203,5 +203,12 @@ <update id="insertupdateTime" > update sys_user set updateTime = #{date} where loginName = #{cPersonCode} </update> + <select id="checkWarehouseCodeAndUserName" resultType="java.util.Map"> + SELECT r.`name`, r.code + FROM sys_user u + LEFT JOIN sys_user_warehouse ur ON u.id = ur.userId + LEFT JOIN warehouse r ON ur.warehouseCode = r.code + WHERE u.loginName=#{loginName,jdbcType=VARCHAR} AND r.`code` =#{warehouseCode,jdbcType=VARCHAR} + </select> </mapper> \ No newline at end of file diff --git a/src/main/resources/templates/config/container/print.html b/src/main/resources/templates/config/container/print.html index 553327a..3c033d6 100644 --- a/src/main/resources/templates/config/container/print.html +++ b/src/main/resources/templates/config/container/print.html @@ -4,7 +4,7 @@ <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <head th:include="include :: header"></head> - <title>库存交易明细</title> + <title>容器打印</title> <!--<link href="css/bootstrap.min.css" rel="stylesheet" />--> <!--<link href="css/font-awesome.min.css" rel="stylesheet" />--> <!--<!–[if IE]>-->