Commit de12fbc897c5f6d55277f450869ff1b4bcc90280

Authored by huhai
2 parents e4f42286 cc677126

Merge branch 'develop' into WMSV2-HH

.gitignore
... ... @@ -10,8 +10,7 @@ target/
10 10 *.iws
11 11 *.iml
12 12 *.ipr
13   -#.idea/workspace.xml
14   -.idea/compiler.xml
  13 +
15 14  
16 15  
17 16 ### NetBeans ###
... ...
huaheng.iml
... ... @@ -195,9 +195,27 @@
195 195 <orderEntry type="library" name="Maven: org.unbescape:unbescape:1.1.6.RELEASE" level="project" />
196 196 <orderEntry type="library" name="Maven: org.thymeleaf.extras:thymeleaf-extras-java8time:3.0.3.RELEASE" level="project" />
197 197 <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-devtools:2.1.3.RELEASE" level="project" />
  198 + <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-data-redis:2.1.3.RELEASE" level="project" />
  199 + <orderEntry type="library" name="Maven: org.springframework.data:spring-data-redis:2.1.5.RELEASE" level="project" />
  200 + <orderEntry type="library" name="Maven: org.springframework.data:spring-data-keyvalue:2.1.5.RELEASE" level="project" />
  201 + <orderEntry type="library" name="Maven: org.springframework.data:spring-data-commons:2.1.5.RELEASE" level="project" />
  202 + <orderEntry type="library" name="Maven: org.springframework:spring-tx:5.1.5.RELEASE" level="project" />
  203 + <orderEntry type="library" name="Maven: org.springframework:spring-oxm:5.1.5.RELEASE" level="project" />
  204 + <orderEntry type="library" name="Maven: io.lettuce:lettuce-core:5.1.4.RELEASE" level="project" />
  205 + <orderEntry type="library" name="Maven: io.netty:netty-common:4.1.33.Final" level="project" />
  206 + <orderEntry type="library" name="Maven: io.netty:netty-handler:4.1.33.Final" level="project" />
  207 + <orderEntry type="library" name="Maven: io.netty:netty-buffer:4.1.33.Final" level="project" />
  208 + <orderEntry type="library" name="Maven: io.netty:netty-codec:4.1.33.Final" level="project" />
  209 + <orderEntry type="library" name="Maven: io.netty:netty-transport:4.1.33.Final" level="project" />
  210 + <orderEntry type="library" name="Maven: io.netty:netty-resolver:4.1.33.Final" level="project" />
  211 + <orderEntry type="library" name="Maven: io.projectreactor:reactor-core:3.2.6.RELEASE" level="project" />
  212 + <orderEntry type="library" name="Maven: org.reactivestreams:reactive-streams:1.0.2" level="project" />
  213 + <orderEntry type="library" name="Maven: org.apache.commons:commons-pool2:2.6.1" level="project" />
198 214 <orderEntry type="library" name="Maven: net.sourceforge.nekohtml:nekohtml:1.9.22" level="project" />
199 215 <orderEntry type="library" name="Maven: xerces:xercesImpl:2.11.0" level="project" />
200 216 <orderEntry type="library" name="Maven: xml-apis:xml-apis:1.4.01" level="project" />
  217 + <orderEntry type="library" name="Maven: io.jsonwebtoken:jjwt:0.9.1" level="project" />
  218 + <orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-databind:2.9.8" level="project" />
201 219 <orderEntry type="library" name="Maven: mysql:mysql-connector-java:8.0.16" level="project" />
202 220 <orderEntry type="library" name="Maven: com.github.pagehelper:pagehelper-spring-boot-starter:1.2.12" level="project" />
203 221 <orderEntry type="library" name="Maven: org.mybatis.spring.boot:mybatis-spring-boot-starter:2.0.1" level="project" />
... ... @@ -272,7 +290,6 @@
272 290 <orderEntry type="library" name="Maven: org.codehaus.castor:castor-core:1.4.1" level="project" />
273 291 <orderEntry type="library" name="Maven: javax.inject:javax.inject:1" level="project" />
274 292 <orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-core:2.9.8" level="project" />
275   - <orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-databind:2.9.8" level="project" />
276 293 <orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.9.0" level="project" />
277 294 <orderEntry type="library" name="Maven: net.sf.jasperreports:jasperreports-fonts:6.10.0" level="project" />
278 295 <orderEntry type="library" name="Maven: com.itextpdf:itextpdf:5.5.7" level="project" />
... ... @@ -295,7 +312,6 @@
295 312 <orderEntry type="library" name="Maven: org.springframework.amqp:spring-amqp:2.1.4.RELEASE" level="project" />
296 313 <orderEntry type="library" name="Maven: org.springframework.retry:spring-retry:1.2.4.RELEASE" level="project" />
297 314 <orderEntry type="library" name="Maven: com.rabbitmq:amqp-client:5.4.3" level="project" />
298   - <orderEntry type="library" name="Maven: org.springframework:spring-tx:5.1.5.RELEASE" level="project" />
299 315 <orderEntry type="library" name="Maven: com.baomidou:mybatis-plus-boot-starter:3.1.2" level="project" />
300 316 <orderEntry type="library" name="Maven: com.baomidou:mybatis-plus:3.1.2" level="project" />
301 317 <orderEntry type="library" name="Maven: com.baomidou:mybatis-plus-extension:3.1.2" level="project" />
... ...
... ... @@ -91,12 +91,30 @@
91 91 <optional>true</optional> <!-- 表示依赖不会传递 -->
92 92 </dependency>
93 93  
  94 + <!-- redis 缓存操作 -->
  95 + <dependency>
  96 + <groupId>org.springframework.boot</groupId>
  97 + <artifactId>spring-boot-starter-data-redis</artifactId>
  98 + </dependency>
  99 +
  100 + <!-- pool 对象池 -->
  101 + <dependency>
  102 + <groupId>org.apache.commons</groupId>
  103 + <artifactId>commons-pool2</artifactId>
  104 + </dependency>
  105 +
94 106 <!-- thymeleaf网页解析 -->
95 107 <dependency>
96 108 <groupId>net.sourceforge.nekohtml</groupId>
97 109 <artifactId>nekohtml</artifactId>
98 110 </dependency>
99 111  
  112 + <dependency>
  113 + <groupId>io.jsonwebtoken</groupId>
  114 + <artifactId>jjwt</artifactId>
  115 + <version>0.9.1</version>
  116 + </dependency>
  117 +
100 118 <!-- Mysql8驱动包 -->
101 119 <dependency>
102 120 <groupId>mysql</groupId>
... ...
src/main/java/com/huaheng/framework/config/ShiroConfig.java
... ... @@ -3,6 +3,7 @@ package com.huaheng.framework.config;
3 3 import java.util.LinkedHashMap;
4 4 import java.util.Map;
5 5 import javax.servlet.Filter;
  6 +
6 7 import org.apache.shiro.cache.ehcache.EhCacheManager;
7 8 import org.apache.shiro.codec.Base64;
8 9 import org.apache.shiro.mgt.SecurityManager;
... ... @@ -28,12 +29,11 @@ import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
28 29  
29 30 /**
30 31 * 权限配置加载
31   - *
  32 + *
32 33 * @author huaheng
33 34 */
34 35 @Configuration
35   -public class ShiroConfig
36   -{
  36 +public class ShiroConfig {
37 37 public static final String PREMISSION_STRING = "perms[\"{0}\"]";
38 38  
39 39 // Session超时时间,单位为毫秒(默认30分钟)
... ... @@ -84,17 +84,13 @@ public class ShiroConfig
84 84 * 缓存管理器 使用Ehcache实现
85 85 */
86 86 @Bean
87   - public EhCacheManager getEhCacheManager()
88   - {
  87 + public EhCacheManager getEhCacheManager() {
89 88 net.sf.ehcache.CacheManager cacheManager = net.sf.ehcache.CacheManager.getCacheManager("huaheng");
90 89 EhCacheManager em = new EhCacheManager();
91   - if (StringUtils.isNull(cacheManager))
92   - {
  90 + if (StringUtils.isNull(cacheManager)) {
93 91 em.setCacheManagerConfigFile("classpath:ehcache/ehcache-shiro.xml");
94 92 return em;
95   - }
96   - else
97   - {
  93 + } else {
98 94 em.setCacheManager(cacheManager);
99 95 return em;
100 96 }
... ... @@ -104,8 +100,7 @@ public class ShiroConfig
104 100 * 自定义Realm
105 101 */
106 102 @Bean
107   - public UserRealm userRealm(EhCacheManager cacheManager)
108   - {
  103 + public UserRealm userRealm(EhCacheManager cacheManager) {
109 104 UserRealm userRealm = new UserRealm();
110 105 userRealm.setCacheManager(cacheManager);
111 106 return userRealm;
... ... @@ -115,8 +110,7 @@ public class ShiroConfig
115 110 * 自定义sessionDAO会话
116 111 */
117 112 @Bean
118   - public OnlineSessionDAO sessionDAO()
119   - {
  113 + public OnlineSessionDAO sessionDAO() {
120 114 OnlineSessionDAO sessionDAO = new OnlineSessionDAO();
121 115 return sessionDAO;
122 116 }
... ... @@ -125,8 +119,7 @@ public class ShiroConfig
125 119 * 自定义sessionFactory会话
126 120 */
127 121 @Bean
128   - public OnlineSessionFactory sessionFactory()
129   - {
  122 + public OnlineSessionFactory sessionFactory() {
130 123 OnlineSessionFactory sessionFactory = new OnlineSessionFactory();
131 124 return sessionFactory;
132 125 }
... ... @@ -135,8 +128,7 @@ public class ShiroConfig
135 128 * 自定义sessionFactory调度器
136 129 */
137 130 @Bean
138   - public SpringSessionValidationScheduler sessionValidationScheduler()
139   - {
  131 + public SpringSessionValidationScheduler sessionValidationScheduler() {
140 132 SpringSessionValidationScheduler sessionValidationScheduler = new SpringSessionValidationScheduler();
141 133 // 相隔多久检查一次session的有效性,单位毫秒,默认就是10分钟
142 134 sessionValidationScheduler.setSessionValidationInterval(validationInterval * 60 * 1000);
... ... @@ -149,8 +141,7 @@ public class ShiroConfig
149 141 * 会话管理器
150 142 */
151 143 @Bean
152   - public OnlineWebSessionManager sessionValidationManager()
153   - {
  144 + public OnlineWebSessionManager sessionValidationManager() {
154 145 OnlineWebSessionManager manager = new OnlineWebSessionManager();
155 146 // 加入缓存管理器
156 147 manager.setCacheManager(getEhCacheManager());
... ... @@ -173,8 +164,7 @@ public class ShiroConfig
173 164 * 会话管理器
174 165 */
175 166 @Bean
176   - public OnlineWebSessionManager sessionManager()
177   - {
  167 + public OnlineWebSessionManager sessionManager() {
178 168 OnlineWebSessionManager manager = new OnlineWebSessionManager();
179 169 // 加入缓存管理器
180 170 manager.setCacheManager(getEhCacheManager());
... ... @@ -199,8 +189,7 @@ public class ShiroConfig
199 189 * 安全管理器
200 190 */
201 191 @Bean
202   - public SecurityManager securityManager(UserRealm userRealm)
203   - {
  192 + public SecurityManager securityManager(UserRealm userRealm) {
204 193 DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
205 194 // 设置realm.
206 195 securityManager.setRealm(userRealm);
... ... @@ -216,15 +205,13 @@ public class ShiroConfig
216 205 /**
217 206 * 退出过滤器
218 207 */
219   - public LogoutFilter logoutFilter()
220   - {
  208 + public LogoutFilter logoutFilter() {
221 209 LogoutFilter logoutFilter = new LogoutFilter();
222 210 logoutFilter.setLoginUrl(loginUrl);
223 211 return logoutFilter;
224 212 }
225 213  
226   - public LogoutFilter logoutFilters()
227   - {
  214 + public LogoutFilter logoutFilters() {
228 215 LogoutFilter logoutFilter = new LogoutFilter();
229 216 logoutFilter.setLoginUrl(loginUrls);
230 217 return logoutFilter;
... ... @@ -234,8 +221,7 @@ public class ShiroConfig
234 221 * Shiro过滤器配置
235 222 */
236 223 @Bean
237   - public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager)
238   - {
  224 + public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
239 225 ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
240 226 // Shiro的核心安全接口,这个属性是必须的
241 227 shiroFilterFactoryBean.setSecurityManager(securityManager);
... ... @@ -270,6 +256,7 @@ public class ShiroConfig
270 256 filterChainDefinitionMap.put("/mobile/login", "anon");
271 257 filterChainDefinitionMap.put("/getWarehouseByUserCode", "anon");
272 258 filterChainDefinitionMap.put("/API/WMS/v2/login", "anon");
  259 + filterChainDefinitionMap.put("/api/**", "anon");
273 260 // 系统权限列表
274 261 // filterChainDefinitionMap.putAll(SpringUtils.getBean(IMenuService.class).selectPermsAll());
275 262  
... ... @@ -292,8 +279,7 @@ public class ShiroConfig
292 279 * 自定义在线用户处理过滤器
293 280 */
294 281 @Bean
295   - public OnlineSessionFilter onlineSessionFilter()
296   - {
  282 + public OnlineSessionFilter onlineSessionFilter() {
297 283 OnlineSessionFilter onlineSessionFilter = new OnlineSessionFilter();
298 284 onlineSessionFilter.setLoginUrl(loginUrl);
299 285 return onlineSessionFilter;
... ... @@ -303,8 +289,7 @@ public class ShiroConfig
303 289 * 自定义在线用户同步过滤器
304 290 */
305 291 @Bean
306   - public SyncOnlineSessionFilter syncOnlineSessionFilter()
307   - {
  292 + public SyncOnlineSessionFilter syncOnlineSessionFilter() {
308 293 SyncOnlineSessionFilter syncOnlineSessionFilter = new SyncOnlineSessionFilter();
309 294 return syncOnlineSessionFilter;
310 295 }
... ... @@ -312,8 +297,7 @@ public class ShiroConfig
312 297 /**
313 298 * cookie 属性设置
314 299 */
315   - public SimpleCookie rememberMeCookie()
316   - {
  300 + public SimpleCookie rememberMeCookie() {
317 301 SimpleCookie cookie = new SimpleCookie("rememberMe");
318 302 cookie.setDomain(domain);
319 303 cookie.setPath(path);
... ... @@ -325,8 +309,7 @@ public class ShiroConfig
325 309 /**
326 310 * 记住我
327 311 */
328   - public CookieRememberMeManager rememberMeManager()
329   - {
  312 + public CookieRememberMeManager rememberMeManager() {
330 313 CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager();
331 314 cookieRememberMeManager.setCookie(rememberMeCookie());
332 315 cookieRememberMeManager.setCipherKey(Base64.decode("fCq+/xW488hMTCD+cmJ3aQ=="));
... ... @@ -337,8 +320,7 @@ public class ShiroConfig
337 320 * thymeleaf模板引擎和shiro框架的整合
338 321 */
339 322 @Bean
340   - public ShiroDialect shiroDialect()
341   - {
  323 + public ShiroDialect shiroDialect() {
342 324 return new ShiroDialect();
343 325 }
344 326  
... ... @@ -347,8 +329,7 @@ public class ShiroConfig
347 329 */
348 330 @Bean
349 331 public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(
350   - @Qualifier("securityManager") SecurityManager securityManager)
351   - {
  332 + @Qualifier("securityManager") SecurityManager securityManager) {
352 333 AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
353 334 authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
354 335 return authorizationAttributeSourceAdvisor;
... ...
src/main/java/com/huaheng/framework/redis/RedisCache.java 0 → 100644
  1 +package com.huaheng.framework.redis;
  2 +
  3 +import org.springframework.beans.factory.annotation.Autowired;
  4 +import org.springframework.data.redis.core.*;
  5 +import org.springframework.stereotype.Component;
  6 +
  7 +import java.util.*;
  8 +import java.util.concurrent.TimeUnit;
  9 +
  10 +/**
  11 + * spring redis 工具类
  12 + *
  13 + * @author ruoyi
  14 + **/
  15 +@SuppressWarnings(value = {"unchecked", "rawtypes"})
  16 +@Component
  17 +public class RedisCache {
  18 +
  19 + @Autowired
  20 + public RedisTemplate redisTemplate;
  21 +
  22 + /**
  23 + * 缓存基本的对象,Integer、String、实体类等
  24 + *
  25 + * @param key 缓存的键值
  26 + * @param value 缓存的值
  27 + * @return 缓存的对象
  28 + */
  29 + public <T> ValueOperations<String, T> setCacheObject(String key, T value) {
  30 + ValueOperations<String, T> operation = redisTemplate.opsForValue();
  31 + operation.set(key, value);
  32 + return operation;
  33 + }
  34 +
  35 + /**
  36 + * 缓存基本的对象,Integer、String、实体类等
  37 + *
  38 + * @param key 缓存的键值
  39 + * @param value 缓存的值
  40 + * @param timeout 时间
  41 + * @param timeUnit 时间颗粒度
  42 + * @return 缓存的对象
  43 + */
  44 + public <T> ValueOperations<String, T> setCacheObject(String key, T value, Integer timeout, TimeUnit timeUnit) {
  45 + ValueOperations<String, T> operation = redisTemplate.opsForValue();
  46 + operation.set(key, value, timeout, timeUnit);
  47 + return operation;
  48 + }
  49 +
  50 + /**
  51 + * 获得缓存的基本对象。
  52 + *
  53 + * @param key 缓存键值
  54 + * @return 缓存键值对应的数据
  55 + */
  56 + public <T> T getCacheObject(String key) {
  57 + ValueOperations<String, T> operation = redisTemplate.opsForValue();
  58 + return operation.get(key);
  59 + }
  60 +
  61 + /**
  62 + * 删除单个对象
  63 + *
  64 + * @param key
  65 + */
  66 + public void deleteObject(String key) {
  67 + redisTemplate.delete(key);
  68 + }
  69 +
  70 + /**
  71 + * 删除集合对象
  72 + *
  73 + * @param collection
  74 + */
  75 + public void deleteObject(Collection collection) {
  76 + redisTemplate.delete(collection);
  77 + }
  78 +
  79 + /**
  80 + * 缓存List数据
  81 + *
  82 + * @param key 缓存的键值
  83 + * @param dataList 待缓存的List数据
  84 + * @return 缓存的对象
  85 + */
  86 + public <T> ListOperations<String, T> setCacheList(String key, List<T> dataList) {
  87 + ListOperations listOperation = redisTemplate.opsForList();
  88 + if (null != dataList) {
  89 + int size = dataList.size();
  90 + for (int i = 0; i < size; i++) {
  91 + listOperation.leftPush(key, dataList.get(i));
  92 + }
  93 + }
  94 + return listOperation;
  95 + }
  96 +
  97 + /**
  98 + * 获得缓存的list对象
  99 + *
  100 + * @param key 缓存的键值
  101 + * @return 缓存键值对应的数据
  102 + */
  103 + public <T> List<T> getCacheList(String key) {
  104 + List<T> dataList = new ArrayList<T>();
  105 + ListOperations<String, T> listOperation = redisTemplate.opsForList();
  106 + Long size = listOperation.size(key);
  107 +
  108 + for (int i = 0; i < size; i++) {
  109 + dataList.add(listOperation.index(key, i));
  110 + }
  111 + return dataList;
  112 + }
  113 +
  114 + /**
  115 + * 缓存Set
  116 + *
  117 + * @param key 缓存键值
  118 + * @param dataSet 缓存的数据
  119 + * @return 缓存数据的对象
  120 + */
  121 + public <T> BoundSetOperations<String, T> setCacheSet(String key, Set<T> dataSet) {
  122 + BoundSetOperations<String, T> setOperation = redisTemplate.boundSetOps(key);
  123 + Iterator<T> it = dataSet.iterator();
  124 + while (it.hasNext()) {
  125 + setOperation.add(it.next());
  126 + }
  127 + return setOperation;
  128 + }
  129 +
  130 + /**
  131 + * 获得缓存的set
  132 + *
  133 + * @param key
  134 + * @return
  135 + */
  136 + public <T> Set<T> getCacheSet(String key) {
  137 + Set<T> dataSet = new HashSet<T>();
  138 + BoundSetOperations<String, T> operation = redisTemplate.boundSetOps(key);
  139 + dataSet = operation.members();
  140 + return dataSet;
  141 + }
  142 +
  143 + /**
  144 + * 缓存Map
  145 + *
  146 + * @param key
  147 + * @param dataMap
  148 + * @return
  149 + */
  150 + public <T> HashOperations<String, String, T> setCacheMap(String key, Map<String, T> dataMap) {
  151 + HashOperations hashOperations = redisTemplate.opsForHash();
  152 + if (null != dataMap) {
  153 + for (Map.Entry<String, T> entry : dataMap.entrySet()) {
  154 + hashOperations.put(key, entry.getKey(), entry.getValue());
  155 + }
  156 + }
  157 + return hashOperations;
  158 + }
  159 +
  160 + /**
  161 + * 获得缓存的Map
  162 + *
  163 + * @param key
  164 + * @return
  165 + */
  166 + public <T> Map<String, T> getCacheMap(String key) {
  167 + Map<String, T> map = redisTemplate.opsForHash().entries(key);
  168 + return map;
  169 + }
  170 +
  171 + /**
  172 + * 获得缓存的基本对象列表
  173 + *
  174 + * @param pattern 字符串前缀
  175 + * @return 对象列表
  176 + */
  177 + public Collection<String> keys(String pattern) {
  178 + return redisTemplate.keys(pattern);
  179 + }
  180 +}
... ...
src/main/java/com/huaheng/framework/token/ApiInterceptor.java 0 → 100644
  1 +package com.huaheng.framework.token;
  2 +
  3 +import com.alibaba.fastjson.JSONObject;
  4 +import com.huaheng.common.utils.ServletUtils;
  5 +import com.huaheng.common.utils.StringUtils;
  6 +import com.huaheng.framework.redis.RedisCache;
  7 +import org.springframework.web.servlet.HandlerInterceptor;
  8 +
  9 +import javax.annotation.Resource;
  10 +import javax.servlet.http.HttpServletRequest;
  11 +import javax.servlet.http.HttpServletResponse;
  12 +import java.security.SignatureException;
  13 +
  14 +/**
  15 + * Created by Enzo Cotter on 2020/6/11.
  16 + */
  17 +public class ApiInterceptor implements HandlerInterceptor {
  18 +
  19 + @Resource
  20 + private RedisCache redisCache;
  21 + /**
  22 + * 可以在这里设置各种规则,取到token后解析,来验证token有效性,有效期等等。这里仅仅验证了是不是token为空。
  23 + */
  24 + @Override
  25 + public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
  26 + //这个就是从http头中取约定好的token的key。
  27 + String token = httpServletRequest.getHeader("Authorization");
  28 + try {
  29 + if (token == null || token.trim().equals("")) {
  30 + throw new SignatureException("token is null");
  31 + } else {
  32 + token = token.substring(7);
  33 + String user = redisCache.getCacheObject(token);
  34 + if (StringUtils.isEmpty(user)) {
  35 + JSONObject jsonObject = new JSONObject();
  36 + jsonObject.put("msg", "token不正确或过期");
  37 + jsonObject.put("code", 401);
  38 + ServletUtils.renderString(httpServletResponse, jsonObject.toString());
  39 + return false;
  40 + }
  41 + }
  42 + } catch (SignatureException e) {
  43 + JSONObject jsonObject = new JSONObject();
  44 + jsonObject.put("msg", "请求参数中找不到Token");
  45 + jsonObject.put("code", 401);
  46 + ServletUtils.renderString(httpServletResponse, jsonObject.toString());
  47 + return false;
  48 + }
  49 +
  50 + return true;
  51 + }
  52 +}
... ...
src/main/java/com/huaheng/framework/token/TokenController.java 0 → 100644
  1 +package com.huaheng.framework.token;
  2 +
  3 +import com.huaheng.common.utils.StringUtils;
  4 +import com.huaheng.framework.shiro.service.PasswordService;
  5 +import com.huaheng.framework.web.controller.BaseController;
  6 +import com.huaheng.framework.web.domain.Result;
  7 +import com.huaheng.pc.system.user.domain.User;
  8 +import com.huaheng.pc.system.user.service.IUserService;
  9 +import org.springframework.web.bind.annotation.PostMapping;
  10 +import org.springframework.web.bind.annotation.RequestMapping;
  11 +import org.springframework.web.bind.annotation.ResponseBody;
  12 +import org.springframework.web.bind.annotation.RestController;
  13 +
  14 +import javax.annotation.Resource;
  15 +import java.util.Calendar;
  16 +
  17 +/**
  18 + * Created by Enzo Cotter on 2020/6/11.
  19 + */
  20 +@RestController
  21 +@RequestMapping("/api")
  22 +public class TokenController extends BaseController {
  23 +
  24 + @Resource
  25 + private TokenService tokenService;
  26 + @Resource
  27 + private IUserService userService;
  28 + @Resource
  29 + private PasswordService passwordService;
  30 +
  31 + @PostMapping("/getToken")
  32 + @ResponseBody
  33 + public Result getToken(String username, String password, String warehouseCode) {
  34 + if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password)) {
  35 + return Result.error("用户名和密码不能为空");
  36 + }
  37 + if (StringUtils.isEmpty(warehouseCode)) {
  38 + return Result.error("请选择仓库");
  39 + }
  40 + User user = userService.selectUserByLoginName(username);
  41 +
  42 + if (!userService.checkWarehouseCodeAndUserName(warehouseCode, username)) {
  43 + return Result.error("用户没有该仓库操作权限");
  44 + }
  45 + if (user.getPassword().equals(passwordService.encryptPassword(user.getLoginName(), password, user.getSalt()))) {
  46 + String token = tokenService.createToken(user);
  47 + Result ajaxResult = Result.success("成功");
  48 + ajaxResult.put("token", token);
  49 + ajaxResult.put("expireTime", Calendar.getInstance().getTime());
  50 + return ajaxResult;
  51 + } else {
  52 + return Result.error("密码错误");
  53 + }
  54 +
  55 + }
  56 +}
... ...
src/main/java/com/huaheng/framework/token/TokenService.java 0 → 100644
  1 +package com.huaheng.framework.token;
  2 +
  3 +import com.alibaba.fastjson.JSONArray;
  4 +import com.alibaba.fastjson.JSONObject;
  5 +import com.fasterxml.jackson.annotation.JsonFormat;
  6 +import com.google.gson.JsonObject;
  7 +import com.huaheng.common.exception.service.ServiceException;
  8 +import com.huaheng.framework.redis.RedisCache;
  9 +import com.huaheng.pc.system.user.domain.User;
  10 +import io.jsonwebtoken.Claims;
  11 +import io.jsonwebtoken.Jws;
  12 +import io.jsonwebtoken.Jwts;
  13 +import io.jsonwebtoken.SignatureAlgorithm;
  14 +import jdk.nashorn.internal.parser.JSONParser;
  15 +import org.springframework.boot.autoconfigure.cache.CacheProperties;
  16 +import org.springframework.stereotype.Service;
  17 +
  18 +import javax.annotation.Resource;
  19 +import java.util.Calendar;
  20 +import java.util.Date;
  21 +import java.util.Map;
  22 +import java.util.concurrent.TimeUnit;
  23 +
  24 +/**
  25 + * token生成与解析
  26 + * @author Enzo Cotter
  27 + * @date 2020/6/11
  28 + */
  29 +@Service
  30 +public class TokenService {
  31 +
  32 + @Resource
  33 + private RedisCache redisCache;
  34 +
  35 + /**
  36 + * 有效期7天
  37 + */
  38 + private static final int EXPIRE_TIME = 7;
  39 +
  40 + /**
  41 + * 盐
  42 + */
  43 + private static final String signingKey = "secret";
  44 +
  45 + /**
  46 + * 创建token
  47 + * @param user 用户
  48 + * @return
  49 + */
  50 + public String createToken(User user){
  51 + //签发时间
  52 + Date iatTime = new Date();
  53 + //expire time
  54 + Calendar nowTime = Calendar.getInstance();
  55 + nowTime.add(Calendar.DATE, EXPIRE_TIME);
  56 + Date expireTime = nowTime.getTime();
  57 +
  58 + Claims claims = Jwts.claims();
  59 + claims.put("user", user);
  60 + claims.setIssuedAt(iatTime);
  61 + String token = Jwts.builder().setClaims(claims)
  62 + .signWith(SignatureAlgorithm.HS512,signingKey).compact();
  63 + if (redisCache.setCacheObject(token, user.toString(), EXPIRE_TIME, TimeUnit.DAYS) == null) {
  64 + throw new ServiceException("redis异常");
  65 + }
  66 + return token;
  67 + }
  68 +
  69 + /**
  70 + * 解析token
  71 + * @param token
  72 + */
  73 + public void parseToken(String token){
  74 + Jws<Claims> jws = Jwts.parser().setSigningKey(signingKey).parseClaimsJws(token);
  75 + Claims claims = jws.getBody();
  76 + Map<String,String> header = jws.getHeader();
  77 + System.out.println("parse");
  78 + }
  79 +}
... ...
src/main/java/com/huaheng/framework/token/WebAppConfigurer.java 0 → 100644
  1 +package com.huaheng.framework.token;
  2 +
  3 +import org.springframework.context.annotation.Bean;
  4 +import org.springframework.context.annotation.Configuration;
  5 +import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
  6 +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
  7 +
  8 +/**
  9 + * Created by Enzo Cotter on 2020/6/11.
  10 + */
  11 +@Configuration
  12 +public class WebAppConfigurer implements WebMvcConfigurer {
  13 +
  14 + @Bean
  15 + ApiInterceptor apiInterceptor(){return new ApiInterceptor();}
  16 +
  17 + @Override
  18 + public void addInterceptors(InterceptorRegistry interceptorRegistry) {
  19 + interceptorRegistry.addInterceptor(apiInterceptor())
  20 + .addPathPatterns("/api/**")
  21 + .excludePathPatterns("/api/getToken");
  22 + }
  23 +}
... ...
src/main/java/com/huaheng/framework/web/domain/Result.java 0 → 100644
  1 +package com.huaheng.framework.web.domain;
  2 +
  3 +import com.huaheng.common.utils.StringUtils;
  4 +
  5 +import java.util.HashMap;
  6 +
  7 +/**
  8 + * 操作消息提醒
  9 + * @author Enzo Cotter
  10 + * @date 2020/6/11
  11 + */
  12 +public class Result extends HashMap<String, Object> {
  13 + private static final long serialVersionUID = 1L;
  14 +
  15 + /**
  16 + * 状态码
  17 + */
  18 + public static final String CODE_TAG = "code";
  19 +
  20 + /**
  21 + * 返回内容
  22 + */
  23 + public static final String MSG_TAG = "msg";
  24 +
  25 + /**
  26 + * 数据对象
  27 + */
  28 + public static final String DATA_TAG = "data";
  29 +
  30 + /**
  31 + * 初始化一个新创建的 AjaxResult 对象,使其表示一个空消息。
  32 + */
  33 + public Result() {
  34 + }
  35 +
  36 + /**
  37 + * 初始化一个新创建的 AjaxResult 对象
  38 + *
  39 + * @param code 状态码
  40 + * @param msg 返回内容
  41 + */
  42 + public Result(int code, String msg) {
  43 + super.put(CODE_TAG, code);
  44 + super.put(MSG_TAG, msg);
  45 + }
  46 +
  47 + /**
  48 + * 初始化一个新创建的 AjaxResult 对象
  49 + *
  50 + * @param code 状态码
  51 + * @param msg 返回内容
  52 + * @param data 数据对象
  53 + */
  54 + public Result(int code, String msg, Object data) {
  55 + super.put(CODE_TAG, code);
  56 + super.put(MSG_TAG, msg);
  57 + if (StringUtils.isNotNull(data)) {
  58 + super.put(DATA_TAG, data);
  59 + }
  60 + }
  61 +
  62 + /**
  63 + * 返回成功消息
  64 + *
  65 + * @return 成功消息
  66 + */
  67 + public static Result success() {
  68 + return Result.success("操作成功");
  69 + }
  70 +
  71 + /**
  72 + * 返回成功数据
  73 + *
  74 + * @return 成功消息
  75 + */
  76 + public static Result success(Object data) {
  77 + return Result.success("操作成功", data);
  78 + }
  79 +
  80 + /**
  81 + * 返回成功消息
  82 + *
  83 + * @param msg 返回内容
  84 + * @return 成功消息
  85 + */
  86 + public static Result success(String msg) {
  87 + return Result.success(msg, null);
  88 + }
  89 +
  90 + /**
  91 + * 返回成功消息
  92 + *
  93 + * @param msg 返回内容
  94 + * @param data 数据对象
  95 + * @return 成功消息
  96 + */
  97 + public static Result success(String msg, Object data) {
  98 + return new Result(200, msg, data);
  99 + }
  100 +
  101 + /**
  102 + * 返回错误消息
  103 + *
  104 + * @return
  105 + */
  106 + public static Result error() {
  107 + return Result.error("操作失败");
  108 + }
  109 +
  110 + /**
  111 + * 返回错误消息
  112 + *
  113 + * @param msg 返回内容
  114 + * @return 警告消息
  115 + */
  116 + public static Result error(String msg) {
  117 + return Result.error(msg, null);
  118 + }
  119 +
  120 + /**
  121 + * 返回错误消息
  122 + *
  123 + * @param msg 返回内容
  124 + * @param data 数据对象
  125 + * @return 警告消息
  126 + */
  127 + public static Result error(String msg, Object data) {
  128 + return new Result(400, msg, data);
  129 + }
  130 +
  131 + /**
  132 + * 返回错误消息
  133 + *
  134 + * @param code 状态码
  135 + * @param msg 返回内容
  136 + * @return 警告消息
  137 + */
  138 + public static Result error(int code, String msg) {
  139 + return new Result(code, msg, null);
  140 + }
  141 +
  142 +}
... ...
src/main/java/com/huaheng/pc/receipt/receiving/controller/ReceivingController.java
... ... @@ -98,7 +98,7 @@ public class ReceivingController extends BaseController {
98 98 // if (count > 0) {
99 99 // return AjaxResult.error("仓库有“出库查看”任务没有完成,请先完成任务");
100 100 // }
101   - AjaxResult result = receiptContainerHeaderService.saveCountain(receiptCode, containerCode, receiptDetailId,
  101 + AjaxResult result = receiptContainerHeaderService.saveContainer(receiptCode, containerCode, receiptDetailId,
102 102 locationCode, qty, locatingRule);
103 103 return result;
104 104 }
... ...
src/main/java/com/huaheng/pc/system/user/mapper/UserMapper.java
... ... @@ -119,6 +119,14 @@ public interface UserMapper
119 119 public User checkEmailUnique(String email);
120 120  
121 121 /**
  122 + * 检查用户是否拥有该仓库权限
  123 + * @param warehouseCode 仓库code
  124 + * @param username 登录名
  125 + * @return
  126 + */
  127 + List<Map<String, Object>> checkWarehouseCodeAndUserName(@Param("warehouseCode") String warehouseCode, @Param("loginName") String username);
  128 +
  129 + /**
122 130 * 根据用户id查询该用户所有仓库
123 131 * @param userId
124 132 * @return
... ...
src/main/java/com/huaheng/pc/system/user/service/IUserService.java
... ... @@ -200,6 +200,8 @@ public interface IUserService
200 200 public User selectmen(String loginName);
201 201  
202 202 public int batchUserWarehouse(@Param("userWarehouseList") List<SysUserWarehouse> userWarehouseList);
  203 +
  204 + boolean checkWarehouseCodeAndUserName(String warehouseCode, String username);
203 205 }
204 206  
205 207  
... ...
src/main/java/com/huaheng/pc/system/user/service/UserServiceImpl.java
... ... @@ -594,4 +594,9 @@ public class UserServiceImpl implements IUserService
594 594 return sysUserWarehouseMapper.batchUserWarehouse(userWarehouseList);
595 595 }
596 596  
  597 + @Override
  598 + public boolean checkWarehouseCodeAndUserName(String warehouseCode, String username) {
  599 + return !userMapper.checkWarehouseCodeAndUserName(warehouseCode, username).isEmpty();
  600 + }
  601 +
597 602 }
... ...
src/main/resources/application.yml
... ... @@ -84,6 +84,26 @@ spring:
84 84 password: owobzjvlgsxrbdfe
85 85 # 编码类型
86 86 default-encoding: utf-8
  87 + # redis 配置
  88 + redis:
  89 + # 地址
  90 + host: localhost
  91 + # 端口,默认为6379
  92 + port: 6379
  93 + # 密码
  94 + password:
  95 + # 连接超时时间
  96 + timeout: 10s
  97 + lettuce:
  98 + pool:
  99 + # 连接池中的最小空闲连接
  100 + min-idle: 0
  101 + # 连接池中的最大空闲连接
  102 + max-idle: 8
  103 + # 连接池的最大数据库连接数
  104 + max-active: 8
  105 + # #连接池最大阻塞等待时间(使用负值表示没有限制)
  106 + max-wait: -1ms
87 107  
88 108 mybatis-plus:
89 109 mapper-locations: classpath:mybatis/**/*.xml
... ...
src/main/resources/mybatis/system/UserMapper.xml
... ... @@ -203,5 +203,12 @@
203 203 <update id="insertupdateTime" >
204 204 update sys_user set updateTime = #{date} where loginName = #{cPersonCode}
205 205 </update>
  206 + <select id="checkWarehouseCodeAndUserName" resultType="java.util.Map">
  207 + SELECT r.`name`, r.code
  208 + FROM sys_user u
  209 + LEFT JOIN sys_user_warehouse ur ON u.id = ur.userId
  210 + LEFT JOIN warehouse r ON ur.warehouseCode = r.code
  211 + WHERE u.loginName=#{loginName,jdbcType=VARCHAR} AND r.`code` =#{warehouseCode,jdbcType=VARCHAR}
  212 + </select>
206 213  
207 214 </mapper>
208 215 \ No newline at end of file
... ...
src/main/resources/templates/config/container/print.html
... ... @@ -4,7 +4,7 @@
4 4 <head>
5 5 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
6 6 <head th:include="include :: header"></head>
7   - <title>库存交易明细</title>
  7 + <title>容器打印</title>
8 8 <!--<link href="css/bootstrap.min.css" rel="stylesheet" />-->
9 9 <!--<link href="css/font-awesome.min.css" rel="stylesheet" />-->
10 10 <!--&lt;!&ndash;[if IE]>-->
... ...