zy-asrs-wcs/pom.xml
@@ -38,6 +38,17 @@ <artifactId>spring-boot-starter-security</artifactId> </dependency> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt-impl</artifactId> <version>0.11.2</version> </dependency> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt-jackson</artifactId> <version>0.11.2</version> </dependency> <!-- okHttp3 --> <dependency> <groupId>com.squareup.okhttp3</groupId> zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/common/Test.java
@@ -1,7 +1,23 @@ package com.zy.asrs.wcs.common; import com.zy.asrs.framework.common.R; import com.zy.asrs.wcs.sys.service.HostService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; /** * Created by vincent on 1/27/2024 */ @RestController public class Test { @Autowired private HostService hostService; @GetMapping("/test") public R gs() { return R.ok().add(hostService.list()); } } zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/common/constant/Constants.java
New file @@ -0,0 +1,93 @@ package com.zy.asrs.wcs.common.constant; /** * 系统常量 * Created by vincent on 2019-10-29 15:55 */ public class Constants { /** * 默认成功码 */ public static final int RESULT_OK_CODE = 0; /** * 默认失败码 */ public static final int RESULT_ERROR_CODE = 1; /** * 默认成功信息 */ public static final String RESULT_OK_MSG = "操作成功"; /** * 默认失败信息 */ public static final String RESULT_ERROR_MSG = "操作失败"; /** * 无权限错误码 */ public static final int UNAUTHORIZED_CODE = 403; /** * 无权限提示信息 */ public static final String UNAUTHORIZED_MSG = "没有访问权限"; /** * 未认证错误码 */ public static final int UNAUTHENTICATED_CODE = 401; /** * 未认证提示信息 */ public static final String UNAUTHENTICATED_MSG = "请先登录"; /** * 登录过期错误码 */ public static final int TOKEN_EXPIRED_CODE = 401; /** * 登录过期提示信息 */ public static final String TOKEN_EXPIRED_MSG = "登录已过期"; /** * 非法token错误码 */ public static final int BAD_CREDENTIALS_CODE = 401; /** * 非法token提示信息 */ public static final String BAD_CREDENTIALS_MSG = "请退出重新登录"; /** * 表示升序的值 */ public static final String ORDER_ASC_VALUE = "asc"; /** * 表示降序的值 */ public static final String ORDER_DESC_VALUE = "desc"; /** * token通过header传递的名称 */ public static final String TOKEN_HEADER_NAME = "Authorization"; /** * token通过参数传递的名称 */ public static final String TOKEN_PARAM_NAME = "access_token"; /** * token认证类型 */ public static final String TOKEN_TYPE = "Bearer"; } zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/common/security/JwtAuthenticationFilter.java
New file @@ -0,0 +1,112 @@ //package com.zy.asrs.wcs.common.security; // //import com.core.common.Cools; //import com.zy.acs.manager.common.config.ConfigProperties; //import com.zy.acs.manager.common.constant.Constants; //import com.zy.acs.manager.common.utils.CommonUtil; //import com.zy.acs.manager.common.utils.JwtUtil; //import com.zy.acs.manager.system.entity.LoginRecord; //import com.zy.acs.manager.system.entity.Menu; //import com.zy.acs.manager.system.entity.User; //import com.zy.acs.manager.system.service.LoginRecordService; //import com.zy.acs.manager.system.service.UserService; //import io.jsonwebtoken.Claims; //import io.jsonwebtoken.ExpiredJwtException; //import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; //import org.springframework.security.core.context.SecurityContextHolder; //import org.springframework.security.core.userdetails.UsernameNotFoundException; //import org.springframework.security.web.util.matcher.AntPathRequestMatcher; //import org.springframework.stereotype.Component; //import org.springframework.web.filter.OncePerRequestFilter; // //import javax.annotation.Resource; //import javax.servlet.FilterChain; //import javax.servlet.ServletException; //import javax.servlet.http.HttpServletRequest; //import javax.servlet.http.HttpServletResponse; //import java.io.IOException; //import java.util.ArrayList; //import java.util.Date; //import java.util.List; //import java.util.stream.Collectors; // ///** // * 处理携带token的请求过滤器 // * // */ //@Component //public class JwtAuthenticationFilter extends OncePerRequestFilter { // // public static final ArrayList<String> WHITE_KEY = new ArrayList<String>(){ // private static final long serialVersionUID = 1L; // { // add("xltys1995"); // } // }; // // @Resource // private ConfigProperties configProperties; // @Resource // private UserService userService; // @Resource // private LoginRecordService loginRecordService; // // @Override // protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException { // String access_token = JwtUtil.getAccessToken(request); // for (String filterPath : SecurityConfig.FILTER_PATH) { // AntPathRequestMatcher antPathMatcher = new AntPathRequestMatcher(filterPath); // if (antPathMatcher.matches(request)) { // access_token = ""; // } // } // if (!Cools.isEmpty(access_token)) { // try { // User user; // if (WHITE_KEY.contains(access_token)) { // user = userService.getByUsername("openapi", 2); // if (user == null) { // throw new UsernameNotFoundException("Username not found"); // } // List<Menu> authorities = user.getAuthorities().stream() // .filter(m -> !Cools.isEmpty(m.getAuthority())).collect(Collectors.toList()); // UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken( // user, null, authorities); // SecurityContextHolder.getContext().setAuthentication(authentication); // } else { // // 解析token // Claims claims = JwtUtil.parseToken(access_token, configProperties.getTokenKey()); // JwtSubject jwtSubject = JwtUtil.getJwtSubject(claims); // user = userService.getByUsername(jwtSubject.getUsername(), jwtSubject.getTenantId()); // if (user == null) { // throw new UsernameNotFoundException("Username not found"); // } // List<Menu> authorities = user.getAuthorities().stream() // .filter(m -> !Cools.isEmpty(m.getAuthority())).collect(Collectors.toList()); // UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken( // user, null, authorities); // SecurityContextHolder.getContext().setAuthentication(authentication); // // token将要过期签发新token, 防止突然退出登录 // long expiration = (claims.getExpiration().getTime() - new Date().getTime()) / 1000 / 60; // if (expiration < configProperties.getTokenRefreshTime()) { // String token = JwtUtil.buildToken(jwtSubject, configProperties.getTokenExpireTime(), // configProperties.getTokenKey()); // response.addHeader(Constants.TOKEN_HEADER_NAME, token); // loginRecordService.saveAsync(user.getUsername(), LoginRecord.TYPE_REFRESH, null, // user.getTenantId(), request); // } // } // } catch (ExpiredJwtException e) { // CommonUtil.responseError(response, Constants.TOKEN_EXPIRED_CODE, Constants.TOKEN_EXPIRED_MSG, // e.getMessage()); // return; // } catch (Exception e) { // CommonUtil.responseError(response, Constants.BAD_CREDENTIALS_CODE, Constants.BAD_CREDENTIALS_MSG, // e.toString()); // return; // } // } // chain.doFilter(request, response); // } // //} zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/common/security/JwtSubject.java
New file @@ -0,0 +1,31 @@ package com.zy.asrs.wcs.common.security; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import java.io.Serializable; /** * Jwt载体 * * @author vincent * @since 2021-09-03 00:11:12 */ @Data @NoArgsConstructor @AllArgsConstructor public class JwtSubject implements Serializable { private static final long serialVersionUID = 1L; /** * 账号 */ private String username; /** * 租户id */ private Integer tenantId; } zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/sys/entity/Host.java
New file @@ -0,0 +1,125 @@ package com.zy.asrs.wcs.sys.entity; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import com.zy.asrs.framework.common.Cools; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import org.springframework.format.annotation.DateTimeFormat; import java.io.Serializable; import java.text.SimpleDateFormat; import java.util.Date; @Data @TableName("sys_host") public class Host implements Serializable { private static final long serialVersionUID = 1L; /** * ID */ @ApiModelProperty(value= "ID") @TableId(value = "id", type = IdType.AUTO) private Long id; /** * 名称 */ @ApiModelProperty(value= "名称") private String name; /** * 状态 1: 正常 0: 禁用 */ @ApiModelProperty(value= "状态 1: 正常 0: 禁用 ") private Integer status; /** * 是否删除 1: 是 0: 否 */ @ApiModelProperty(value= "是否删除 1: 是 0: 否 ") private Integer deleted; /** * 添加时间 */ @ApiModelProperty(value= "添加时间") @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") private Date createTime; /** * 修改时间 */ @ApiModelProperty(value= "修改时间") @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") private Date updateTime; /** * 备注 */ @ApiModelProperty(value= "备注") private String memo; public Host() {} public Host(String name,Integer status,Integer deleted,Date createTime,Date updateTime,String memo) { this.name = name; this.status = status; this.deleted = deleted; this.createTime = createTime; this.updateTime = updateTime; this.memo = memo; } // Host host = new Host( // null, // 名称[非空] // null, // 状态 // null, // 是否删除 // null, // 添加时间 // null, // 修改时间 // null // 备注 // ); public String getStatus$(){ if (null == this.status){ return null; } switch (this.status){ case 1: return "正常"; case 0: return "禁用"; default: return String.valueOf(this.status); } } public String getDeleted$(){ if (null == this.deleted){ return null; } switch (this.deleted){ case 1: return "是"; case 0: return "否"; default: return String.valueOf(this.deleted); } } public String getCreateTime$(){ if (Cools.isEmpty(this.createTime)){ return ""; } return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.createTime); } public String getUpdateTime$(){ if (Cools.isEmpty(this.updateTime)){ return ""; } return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.updateTime); } } zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/sys/mapper/HostMapper.java
New file @@ -0,0 +1,12 @@ package com.zy.asrs.wcs.sys.mapper; import com.zy.asrs.wcs.sys.entity.Host; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import org.apache.ibatis.annotations.Mapper; import org.springframework.stereotype.Repository; @Mapper @Repository public interface HostMapper extends BaseMapper<Host> { } zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/sys/service/HostService.java
New file @@ -0,0 +1,8 @@ package com.zy.asrs.wcs.sys.service; import com.baomidou.mybatisplus.extension.service.IService; import com.zy.asrs.wcs.sys.entity.Host; public interface HostService extends IService<Host> { } zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/sys/service/impl/HostServiceImpl.java
New file @@ -0,0 +1,12 @@ package com.zy.asrs.wcs.sys.service.impl; import com.zy.asrs.wcs.sys.mapper.HostMapper; import com.zy.asrs.wcs.sys.entity.Host; import com.zy.asrs.wcs.sys.service.HostService; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import org.springframework.stereotype.Service; @Service("hostService") public class HostServiceImpl extends ServiceImpl<HostMapper, Host> implements HostService { } zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/utils/JwtUtil.java
New file @@ -0,0 +1,143 @@ package com.zy.asrs.wcs.utils; import com.alibaba.fastjson.JSON; import com.zy.asrs.framework.common.Cools; import com.zy.asrs.wcs.common.constant.Constants; import com.zy.asrs.wcs.common.security.JwtSubject; import io.jsonwebtoken.Claims; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureAlgorithm; import io.jsonwebtoken.io.Decoders; import io.jsonwebtoken.io.Encoders; import io.jsonwebtoken.security.Keys; import javax.servlet.http.HttpServletRequest; import java.security.Key; import java.util.Date; /** * JWT工具类 * * @author vincent * @since 2018-01-21 16:30:59 */ public class JwtUtil { /** * 获取请求中的access_token * * @param request HttpServletRequest * @return String */ public static String getAccessToken(HttpServletRequest request) { String access_token = request.getHeader(Constants.TOKEN_HEADER_NAME); if (!Cools.isEmpty(access_token)) { if (access_token.startsWith(Constants.TOKEN_TYPE)) { access_token = Utils.removePrefix(access_token, Constants.TOKEN_TYPE).trim(); } } else { access_token = request.getParameter(Constants.TOKEN_PARAM_NAME); } return access_token; } /** * 生成token * * @param subject 载体 * @param expire 过期时间 * @param base64EncodedKey base64编码的Key * @return token */ public static String buildToken(JwtSubject subject, Long expire, String base64EncodedKey) { return buildToken(JSON.toJSONString(subject), expire, decodeKey(base64EncodedKey)); } /** * 生成token * * @param subject 载体 * @param expire 过期时间 * @param key 密钥 * @return token */ public static String buildToken(String subject, Long expire, Key key) { Date expireDate = new Date(new Date().getTime() + 1000 * expire); return Jwts.builder() .setSubject(subject) .setExpiration(expireDate) .setIssuedAt(new Date()) .signWith(key) .compact(); } /** * 解析token * * @param token token * @param base64EncodedKey base64编码的Key * @return Claims */ public static Claims parseToken(String token, String base64EncodedKey) { return parseToken(token, decodeKey(base64EncodedKey)); } /** * 解析token * * @param token token * @param key 密钥 * @return Claims */ public static Claims parseToken(String token, Key key) { return Jwts.parserBuilder() .setSigningKey(key) .build() .parseClaimsJws(token) .getBody(); } /** * 获取JwtSubject * * @param claims Claims * @return JwtSubject */ public static JwtSubject getJwtSubject(Claims claims) { return JSON.parseObject(claims.getSubject(), JwtSubject.class); } /** * 生成Key * * @return Key */ public static Key randomKey() { return Keys.secretKeyFor(SignatureAlgorithm.HS256); } /** * base64编码key * * @return String */ public static String encodeKey(Key key) { return Encoders.BASE64.encode(key.getEncoded()); } /** * base64编码Key * * @param base64EncodedKey base64编码的key * @return Key */ public static Key decodeKey(String base64EncodedKey) { if (Cools.isEmpty(base64EncodedKey)) { return null; } return Keys.hmacShaKeyFor(Decoders.BASE64.decode(base64EncodedKey)); } } zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/utils/Utils.java
New file @@ -0,0 +1,224 @@ package com.zy.asrs.wcs.utils; import com.zy.asrs.framework.common.Cools; import java.util.Optional; /** * Created by vincent on 2023/3/14 */ public class Utils { /** * 数组倒序 * @param bytes * @param <T> */ public static <T> byte[] reverse(byte[] bytes) { if (bytes == null) return null; for (int start = 0, end = bytes.length - 1; start < end; start++, end--) { byte temp = bytes[end]; bytes[end] = bytes[start]; bytes[start] = temp; } return bytes; } /** * 截取数组 * @param bytes 原数组 * @param pos 定位(截取后包含定位点数据) * @param len 长度 * @return new arr */ public static byte[] slice(byte[] bytes, int pos, int len) { if (bytes == null || bytes.length == 0 || len == 0) { return new byte[0]; } if (pos + len > bytes.length) { throw new RuntimeException("com.zy.acs.common.utils ArrayIndexOutOfBoundsException\n" + "原数组 bytes 长度为 " + bytes.length + ",截取长度超过原数组!"); } byte[] arr = new byte[len]; System.arraycopy(bytes, pos, arr, 0, len); return arr; } public static byte[] sliceWithReverse(byte[] bytes, int pos, int len) { byte[] slice = slice(bytes, pos, len); reverse(slice); return slice; } public static byte[] merge(Object... objects) { int len = 0; for (Object object : objects) { if (object instanceof byte[]) { byte[] bytes = (byte[]) object; len += bytes.length; } if (object instanceof Byte) { len++; } } byte[] arr = new byte[len]; int idx = 0; for (Object object : objects) { if (object instanceof byte[]) { byte[] bytes = (byte[]) object; System.arraycopy(bytes, 0, arr, idx, bytes.length); idx += bytes.length; } if (object instanceof Byte) { byte[] bytes = new byte[] {(Byte) object}; System.arraycopy(bytes, 0, arr, idx, bytes.length); idx += bytes.length; } } return arr; } public static <T> String join(T[] array, String seq) { StringBuilder sb = new StringBuilder(); if (array != null) { for (int i = 0; i < array.length; i++) { sb.append(array[i]); if (i < array.length - 1) { sb.append(seq); } } } return sb.toString(); } public static String zeroFill(String msg, Integer len) { len = Optional.ofNullable(len).orElse(16); if (msg.length() == len){ return msg; } else if (msg.length() > len){ return msg.substring(0, 16); } else { StringBuilder msgBuilder = new StringBuilder(msg); for (int i = 0; i<len-msg.length(); i++){ msgBuilder.insert(0,"0"); } return msgBuilder.toString(); } } public static String removePrefix(String str, String prefix) { if (!Cools.isEmpty(str) && !Cools.isEmpty(prefix)) { if (str.startsWith(prefix)) { return str.substring(prefix.length()); } else { return str; } } else { return str; } } public static String removeSuffix(String str, String suffix) { if (!Cools.isEmpty(str) && !Cools.isEmpty(suffix)) { if (str.endsWith(suffix)) { return str.substring(0, str.indexOf(suffix)); } else { return str; } } else { return str; } } /** * 大驼峰 转 symbol小驼峰 */ public static String toSymbolCase(String str, char symbol) { if (str == null) { return null; } else { int length = str.length(); StringBuilder sb = new StringBuilder(); for(int i = 0; i < length; ++i) { char c = str.charAt(i); if (Character.isUpperCase(c)) { Character preChar = i > 0 ? str.charAt(i - 1) : null; Character nextChar = i < str.length() - 1 ? str.charAt(i + 1) : null; if (null != preChar) { if (symbol == preChar) { if (null == nextChar || Character.isLowerCase(nextChar)) { c = Character.toLowerCase(c); } } else if (Character.isLowerCase(preChar)) { sb.append(symbol); if (null == nextChar || Character.isLowerCase(nextChar)) { c = Character.toLowerCase(c); } } else if (null == nextChar || Character.isLowerCase(nextChar)) { sb.append(symbol); c = Character.toLowerCase(c); } } else if (null == nextChar || Character.isLowerCase(nextChar)) { c = Character.toLowerCase(c); } } sb.append(c); } return sb.toString(); } } public static String toCamelCase(CharSequence name) { if (null == name) { return null; } else { String name2 = name.toString(); if (name2.contains("_")) { int length = name2.length(); StringBuilder sb = new StringBuilder(length); boolean upperCase = false; for(int i = 0; i < length; ++i) { char c = name2.charAt(i); if (c == '_') { upperCase = true; } else if (upperCase) { sb.append(Character.toUpperCase(c)); upperCase = false; } else { sb.append(Character.toLowerCase(c)); } } return sb.toString(); } else { return name2; } } } public static String sub(String str, Integer maxLen) { if (str.length() > maxLen) { return str.substring(0, maxLen); } return str; } public static String generateSeqNum(String lastSeqNum) { if (Cools.isEmpty(lastSeqNum)) { return zeroFill("1", 4); } else { int i = Integer.parseInt(lastSeqNum); if (i >= 9999) { return zeroFill("1", 4); } else { return zeroFill(String.valueOf(i+1), 4); } } } } zy-asrs-wcs/src/main/resources/application.yml
@@ -10,7 +10,7 @@ enabled: false datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/zy_acs?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai url: jdbc:mysql://localhost:3306/asrs?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai username: root password: xltys1995 # driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver zy-asrs-wcs/src/main/resources/mapper/sys/HostMapper.xml
New file @@ -0,0 +1,5 @@ <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.zy.asrs.wcs.sys.mapper.HostMapper"> </mapper>