提交代码

dev_xds
姜玉琦 2024-01-13 22:30:18 +08:00
parent b529cf5946
commit 7065aa0648
12 changed files with 707 additions and 73 deletions

View File

@ -12,8 +12,11 @@ import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysUser; import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.redis.RedisCache; import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.core.text.Convert; import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.enums.HttpStatusEnum;
import com.ruoyi.common.enums.LimitType; import com.ruoyi.common.enums.LimitType;
import com.ruoyi.common.enums.ShiFouEnum;
import com.ruoyi.common.enums.UserTypeEnum; import com.ruoyi.common.enums.UserTypeEnum;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.AuthRsaUtils; import com.ruoyi.common.utils.AuthRsaUtils;
import com.ruoyi.common.utils.SecurityUtils; import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.StringUtils;
@ -81,14 +84,17 @@ public class LabourApiController extends BaseController {
public AjaxResult getToken(@Validated @RequestBody TokenReqVo req) { public AjaxResult getToken(@Validated @RequestBody TokenReqVo req) {
SysApplyConfig sysApplyConfig = redisCache.getCacheObject(CacheConstants.YANZHU_SYSTEM_CONFIG+req.getAppId()); SysApplyConfig sysApplyConfig = redisCache.getCacheObject(CacheConstants.YANZHU_SYSTEM_CONFIG+req.getAppId());
if(sysApplyConfig==null){ if(sysApplyConfig==null){
throw new RuntimeException("AppId不存在或已被停用"); throw new ServiceException(HttpStatusEnum.ERROR.getInfo(),HttpStatusEnum.ERROR.getCode());
}
if(StringUtils.equals(ShiFouEnum.SHI.getCode()+"",sysApplyConfig.getIsDel())){
throw new ServiceException(HttpStatusEnum.DISABLE.getInfo(),HttpStatusEnum.DISABLE.getCode());
} }
AjaxResult ajax = AjaxResult.success(); AjaxResult ajax = AjaxResult.success();
String systemToken = ""; String systemToken = "";
if (req.getLoginSign(sysApplyConfig.getPrivateKey())) { if (req.getLoginSign(sysApplyConfig.getPrivateKey())) {
systemToken = this.getAppIdLoginToken(req.getAppId(),sysApplyConfig); systemToken = this.getAppIdLoginToken(req.getAppId(),sysApplyConfig);
} else { } else {
throw new RuntimeException("签名值不合法"); throw new ServiceException(HttpStatusEnum.SINGET_ERROR.getInfo(),HttpStatusEnum.SINGET_ERROR.getCode());
} }
ajax.put("systemToken", systemToken); ajax.put("systemToken", systemToken);
return ajax; return ajax;
@ -136,6 +142,9 @@ public class LabourApiController extends BaseController {
SysApplyConfig sysApplyConfig = redisCache.getCacheObject(CacheConstants.YANZHU_SYSTEM_CONFIG+super.getUsername()); SysApplyConfig sysApplyConfig = redisCache.getCacheObject(CacheConstants.YANZHU_SYSTEM_CONFIG+super.getUsername());
if(req.checkTimestamp()){ if(req.checkTimestamp()){
try { try {
if(StringUtils.equals(ShiFouEnum.SHI.getCode()+"",sysApplyConfig.getIsDel())){
throw new ServiceException(HttpStatusEnum.DISABLE.getInfo(),HttpStatusEnum.DISABLE.getCode());
}
String result = AuthRsaUtils.decryptByPrivateKey(sysApplyConfig.getPrivateKey(),req.getSign()); String result = AuthRsaUtils.decryptByPrivateKey(sysApplyConfig.getPrivateKey(),req.getSign());
SurProjectAttendanceGroup surProjectAttendanceGroup = JSONObject.parseObject(result, SurProjectAttendanceGroup.class); SurProjectAttendanceGroup surProjectAttendanceGroup = JSONObject.parseObject(result, SurProjectAttendanceGroup.class);
if(StringUtils.isNotEmpty(surProjectAttendanceGroup.getServerid())){ if(StringUtils.isNotEmpty(surProjectAttendanceGroup.getServerid())){
@ -157,13 +166,13 @@ public class LabourApiController extends BaseController {
surProjectAttendanceGroupService.insertSurProjectAttendanceGroup(surProjectAttendanceGroup); surProjectAttendanceGroupService.insertSurProjectAttendanceGroup(surProjectAttendanceGroup);
} }
}else{ }else{
throw new RuntimeException("数据解析异常"); throw new ServiceException(HttpStatusEnum.DARA_EXCEPTION.getInfo(),HttpStatusEnum.DARA_EXCEPTION.getCode());
} }
}catch (Exception e){ }catch (Exception e){
throw new RuntimeException("签名解密异常"); throw new ServiceException(HttpStatusEnum.SINGET_EXCEPTION.getInfo(),HttpStatusEnum.SINGET_EXCEPTION.getCode());
} }
}else{ }else{
throw new RuntimeException("数据已过期"); throw new ServiceException(HttpStatusEnum.SINGET_TIMEOUT.getInfo(),HttpStatusEnum.SINGET_TIMEOUT.getCode());
} }
return success(); return success();
} }
@ -179,11 +188,14 @@ public class LabourApiController extends BaseController {
@RateLimiter(time = 30, count = 10, limitType = LimitType.IP) @RateLimiter(time = 30, count = 10, limitType = LimitType.IP)
@PostMapping("/v1/pushLabourGroupList") @PostMapping("/v1/pushLabourGroupList")
public AjaxResult pushLabourGroupList(@Validated @RequestBody LabourSignetVo req) { public AjaxResult pushLabourGroupList(@Validated @RequestBody LabourSignetVo req) {
// 失败集合
List<Integer> failServiceIdList = new ArrayList<>();
SysApplyConfig sysApplyConfig = redisCache.getCacheObject(CacheConstants.YANZHU_SYSTEM_CONFIG+super.getUsername()); SysApplyConfig sysApplyConfig = redisCache.getCacheObject(CacheConstants.YANZHU_SYSTEM_CONFIG+super.getUsername());
if(req.checkTimestamp()){ if(req.checkTimestamp()){
try { try {
// 失败集合 if(StringUtils.equals(ShiFouEnum.SHI.getCode()+"",sysApplyConfig.getIsDel())){
List<Integer> failServiceIdList = new ArrayList<>(); throw new ServiceException(HttpStatusEnum.DISABLE.getInfo(),HttpStatusEnum.DISABLE.getCode());
}
// 保存集合 // 保存集合
List<SurProjectAttendanceGroup> saveList = new ArrayList<>(); List<SurProjectAttendanceGroup> saveList = new ArrayList<>();
String result = AuthRsaUtils.decryptByPrivateKey(sysApplyConfig.getPrivateKey(),req.getSign()); String result = AuthRsaUtils.decryptByPrivateKey(sysApplyConfig.getPrivateKey(),req.getSign());
@ -207,15 +219,15 @@ public class LabourApiController extends BaseController {
} }
surProjectAttendanceGroupService.batchSurProjectAttendanceGroup(saveList); surProjectAttendanceGroupService.batchSurProjectAttendanceGroup(saveList);
}else{ }else{
throw new RuntimeException("数据解析异常"); throw new ServiceException(HttpStatusEnum.DARA_EXCEPTION.getInfo(),HttpStatusEnum.DARA_EXCEPTION.getCode());
} }
}catch (Exception e){ }catch (Exception e){
throw new RuntimeException("签名解密异常"); throw new ServiceException(HttpStatusEnum.SINGET_EXCEPTION.getInfo(),HttpStatusEnum.SINGET_EXCEPTION.getCode());
} }
}else{ }else{
throw new RuntimeException("数据已过期"); throw new ServiceException(HttpStatusEnum.SINGET_TIMEOUT.getInfo(),HttpStatusEnum.SINGET_TIMEOUT.getCode());
} }
return success(); return success(failServiceIdList);
} }
/** /**
@ -232,6 +244,9 @@ public class LabourApiController extends BaseController {
SysApplyConfig sysApplyConfig = redisCache.getCacheObject(CacheConstants.YANZHU_SYSTEM_CONFIG+super.getUsername()); SysApplyConfig sysApplyConfig = redisCache.getCacheObject(CacheConstants.YANZHU_SYSTEM_CONFIG+super.getUsername());
if(req.checkTimestamp()){ if(req.checkTimestamp()){
try { try {
if(StringUtils.equals(ShiFouEnum.SHI.getCode()+"",sysApplyConfig.getIsDel())){
throw new ServiceException(HttpStatusEnum.DISABLE.getInfo(),HttpStatusEnum.DISABLE.getCode());
}
String result = AuthRsaUtils.decryptByPrivateKey(sysApplyConfig.getPrivateKey(),req.getSign()); String result = AuthRsaUtils.decryptByPrivateKey(sysApplyConfig.getPrivateKey(),req.getSign());
SurProjectAttendanceUser surProjectAttendanceUser = JSONObject.parseObject(result, SurProjectAttendanceUser.class); SurProjectAttendanceUser surProjectAttendanceUser = JSONObject.parseObject(result, SurProjectAttendanceUser.class);
if(StringUtils.isNotEmpty(surProjectAttendanceUser.getWorkerId())){ if(StringUtils.isNotEmpty(surProjectAttendanceUser.getWorkerId())){
@ -253,13 +268,13 @@ public class LabourApiController extends BaseController {
surProjectAttendanceUserService.insertSurProjectAttendanceUser(surProjectAttendanceUser); surProjectAttendanceUserService.insertSurProjectAttendanceUser(surProjectAttendanceUser);
} }
}else{ }else{
throw new RuntimeException("数据解析异常"); throw new ServiceException(HttpStatusEnum.DARA_EXCEPTION.getInfo(),HttpStatusEnum.DARA_EXCEPTION.getCode());
} }
}catch (Exception e){ }catch (Exception e){
throw new RuntimeException("签名解密异常"); throw new ServiceException(HttpStatusEnum.SINGET_EXCEPTION.getInfo(),HttpStatusEnum.SINGET_EXCEPTION.getCode());
} }
}else{ }else{
throw new RuntimeException("数据已过期"); throw new ServiceException(HttpStatusEnum.SINGET_TIMEOUT.getInfo(),HttpStatusEnum.SINGET_TIMEOUT.getCode());
} }
return success(); return success();
} }
@ -275,11 +290,14 @@ public class LabourApiController extends BaseController {
@RateLimiter(time = 30, count = 10, limitType = LimitType.IP) @RateLimiter(time = 30, count = 10, limitType = LimitType.IP)
@PostMapping("/v1/pushLabourUserList") @PostMapping("/v1/pushLabourUserList")
public AjaxResult pushLabourUserList(@Validated @RequestBody LabourSignetVo req) { public AjaxResult pushLabourUserList(@Validated @RequestBody LabourSignetVo req) {
// 失败集合
List<Integer> failServiceIdList = new ArrayList<>();
SysApplyConfig sysApplyConfig = redisCache.getCacheObject(CacheConstants.YANZHU_SYSTEM_CONFIG+super.getUsername()); SysApplyConfig sysApplyConfig = redisCache.getCacheObject(CacheConstants.YANZHU_SYSTEM_CONFIG+super.getUsername());
if(req.checkTimestamp()){ if(req.checkTimestamp()){
try { try {
// 失败集合 if(StringUtils.equals(ShiFouEnum.SHI.getCode()+"",sysApplyConfig.getIsDel())){
List<Integer> failServiceIdList = new ArrayList<>(); throw new ServiceException(HttpStatusEnum.DISABLE.getInfo(),HttpStatusEnum.DISABLE.getCode());
}
// 保存集合 // 保存集合
List<SurProjectAttendanceUser> saveList = new ArrayList<>(); List<SurProjectAttendanceUser> saveList = new ArrayList<>();
String result = AuthRsaUtils.decryptByPrivateKey(sysApplyConfig.getPrivateKey(),req.getSign()); String result = AuthRsaUtils.decryptByPrivateKey(sysApplyConfig.getPrivateKey(),req.getSign());
@ -303,15 +321,15 @@ public class LabourApiController extends BaseController {
} }
surProjectAttendanceUserService.batchSurProjectAttendanceUser(saveList); surProjectAttendanceUserService.batchSurProjectAttendanceUser(saveList);
}else{ }else{
throw new RuntimeException("数据解析异常"); throw new ServiceException(HttpStatusEnum.DARA_EXCEPTION.getInfo(),HttpStatusEnum.DARA_EXCEPTION.getCode());
} }
}catch (Exception e){ }catch (Exception e){
throw new RuntimeException("签名解密异常"); throw new ServiceException(HttpStatusEnum.SINGET_EXCEPTION.getInfo(),HttpStatusEnum.SINGET_EXCEPTION.getCode());
} }
}else{ }else{
throw new RuntimeException("数据已过期"); throw new ServiceException(HttpStatusEnum.SINGET_TIMEOUT.getInfo(),HttpStatusEnum.SINGET_TIMEOUT.getCode());
} }
return success(); return success(failServiceIdList);
} }
/** /**
@ -328,6 +346,9 @@ public class LabourApiController extends BaseController {
SysApplyConfig sysApplyConfig = redisCache.getCacheObject(CacheConstants.YANZHU_SYSTEM_CONFIG+super.getUsername()); SysApplyConfig sysApplyConfig = redisCache.getCacheObject(CacheConstants.YANZHU_SYSTEM_CONFIG+super.getUsername());
if(req.checkTimestamp()){ if(req.checkTimestamp()){
try { try {
if(StringUtils.equals(ShiFouEnum.SHI.getCode()+"",sysApplyConfig.getIsDel())){
throw new ServiceException(HttpStatusEnum.DISABLE.getInfo(),HttpStatusEnum.DISABLE.getCode());
}
String result = AuthRsaUtils.decryptByPrivateKey(sysApplyConfig.getPrivateKey(),req.getSign()); String result = AuthRsaUtils.decryptByPrivateKey(sysApplyConfig.getPrivateKey(),req.getSign());
SurProjectAttendanceData surProjectAttendanceData = JSONObject.parseObject(result, SurProjectAttendanceData.class); SurProjectAttendanceData surProjectAttendanceData = JSONObject.parseObject(result, SurProjectAttendanceData.class);
if(StringUtils.isNotEmpty(surProjectAttendanceData.getWorkerId()) && StringUtils.isNotEmpty(surProjectAttendanceData.getServerid())){ if(StringUtils.isNotEmpty(surProjectAttendanceData.getWorkerId()) && StringUtils.isNotEmpty(surProjectAttendanceData.getServerid())){
@ -350,13 +371,13 @@ public class LabourApiController extends BaseController {
surProjectAttendanceDataService.insertSurProjectAttendanceData(surProjectAttendanceData); surProjectAttendanceDataService.insertSurProjectAttendanceData(surProjectAttendanceData);
} }
}else{ }else{
throw new RuntimeException("数据解析异常"); throw new ServiceException(HttpStatusEnum.DARA_EXCEPTION.getInfo(),HttpStatusEnum.DARA_EXCEPTION.getCode());
} }
}catch (Exception e){ }catch (Exception e){
throw new RuntimeException("签名解密异常"); throw new ServiceException(HttpStatusEnum.SINGET_EXCEPTION.getInfo(),HttpStatusEnum.SINGET_EXCEPTION.getCode());
} }
}else{ }else{
throw new RuntimeException("数据已过期"); throw new ServiceException(HttpStatusEnum.SINGET_TIMEOUT.getInfo(),HttpStatusEnum.SINGET_TIMEOUT.getCode());
} }
return success(); return success();
} }
@ -372,11 +393,14 @@ public class LabourApiController extends BaseController {
@RateLimiter(time = 30, count = 10, limitType = LimitType.IP) @RateLimiter(time = 30, count = 10, limitType = LimitType.IP)
@PostMapping("/v1/pushLabourDataList") @PostMapping("/v1/pushLabourDataList")
public AjaxResult pushLabourDataList(@Validated @RequestBody LabourSignetVo req) { public AjaxResult pushLabourDataList(@Validated @RequestBody LabourSignetVo req) {
// 失败集合
List<Integer> failServiceIdList = new ArrayList<>();
SysApplyConfig sysApplyConfig = redisCache.getCacheObject(CacheConstants.YANZHU_SYSTEM_CONFIG+super.getUsername()); SysApplyConfig sysApplyConfig = redisCache.getCacheObject(CacheConstants.YANZHU_SYSTEM_CONFIG+super.getUsername());
if(req.checkTimestamp()){ if(req.checkTimestamp()){
try { try {
// 失败集合 if(StringUtils.equals(ShiFouEnum.SHI.getCode()+"",sysApplyConfig.getIsDel())){
List<Integer> failServiceIdList = new ArrayList<>(); throw new ServiceException(HttpStatusEnum.DISABLE.getInfo(),HttpStatusEnum.DISABLE.getCode());
}
// 保存集合 // 保存集合
List<SurProjectAttendanceData> saveList = new ArrayList<>(); List<SurProjectAttendanceData> saveList = new ArrayList<>();
String result = AuthRsaUtils.decryptByPrivateKey(sysApplyConfig.getPrivateKey(),req.getSign()); String result = AuthRsaUtils.decryptByPrivateKey(sysApplyConfig.getPrivateKey(),req.getSign());
@ -400,15 +424,15 @@ public class LabourApiController extends BaseController {
} }
surProjectAttendanceDataService.batchSurProjectAttendanceData(saveList); surProjectAttendanceDataService.batchSurProjectAttendanceData(saveList);
}else{ }else{
throw new RuntimeException("数据解析异常"); throw new ServiceException(HttpStatusEnum.DARA_EXCEPTION.getInfo(),HttpStatusEnum.DARA_EXCEPTION.getCode());
} }
}catch (Exception e){ }catch (Exception e){
throw new RuntimeException("签名解密异常"); throw new ServiceException(HttpStatusEnum.SINGET_EXCEPTION.getInfo(),HttpStatusEnum.SINGET_EXCEPTION.getCode());
} }
}else{ }else{
throw new RuntimeException("数据已过期"); throw new ServiceException(HttpStatusEnum.SINGET_TIMEOUT.getInfo(),HttpStatusEnum.SINGET_TIMEOUT.getCode());
} }
return success(); return success(failServiceIdList);
} }
} }

View File

@ -5,6 +5,7 @@ import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo; import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType; import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.NoUtils;
import com.ruoyi.common.utils.poi.ExcelUtil; import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.system.domain.SysApplyConfig; import com.ruoyi.system.domain.SysApplyConfig;
import com.ruoyi.system.service.ISysApplyConfigService; import com.ruoyi.system.service.ISysApplyConfigService;
@ -95,4 +96,15 @@ public class SysApplyConfigController extends BaseController
{ {
return toAjax(sysApplyConfigService.deleteSysApplyConfigByIds(ids)); return toAjax(sysApplyConfigService.deleteSysApplyConfigByIds(ids));
} }
/**
* AppId
*/
@PreAuthorize("@ss.hasPermi('system:applyConfig:add')")
@GetMapping("/createAppId")
public AjaxResult createAppId()
{
return success(NoUtils.createAppId());
}
} }

View File

@ -0,0 +1,36 @@
package com.ruoyi.common.enums;
/**
* Http
*
* @author JiangYuQi
*/
public enum HttpStatusEnum {
ERROR(11110, "AppId不存在或已被停用"),
DISABLE(11112, "AppId已被停用"),
SINGET_ERROR(11113, "签名值不正确"),
SINGET_TIMEOUT(11114, "签名数据已过期"),
SINGET_EXCEPTION(11115, "签名数据解密异常"),
DARA_EXCEPTION(11116, "数据解析异常");
private final Integer code;
private final String info;
HttpStatusEnum(Integer code, String info)
{
this.code = code;
this.info = info;
}
public Integer getCode()
{
return code;
}
public String getInfo()
{
return info;
}
}

View File

@ -0,0 +1,38 @@
package com.ruoyi.common.enums;
import com.ruoyi.common.core.text.Convert;
/**
*
*
* @author JiangYuQi
*/
public enum ShiFouEnum {
FOU(0, "否"), SHI(1, "是");
private final Integer code;
private final String info;
ShiFouEnum(Integer code, String info)
{
this.code = code;
this.info = info;
}
public Integer getCode()
{
return code;
}
public String getInfo()
{
return info;
}
public Long getLongCode()
{
return Convert.toLong(code);
}
}

View File

@ -0,0 +1,33 @@
package com.ruoyi.common.utils;
/**
*
*
* @author JiangYuQi
* @date 2023-11-07
*/
public class NoUtils {
private static final String PREFIX = "jhcf";
private static int COUNTER = 0;
/**
* appId
*
* @author JiangYuQi
* @date 2023-11-07
*/
public static String createAppId() {
long timestamp = System.currentTimeMillis();
String sequencePart = String.format("%03d", getContractNextSequence());
return PREFIX + timestamp+ StringUtils.randomString(10) + sequencePart;
}
private static synchronized int getContractNextSequence() {
if (COUNTER >= 999) {
COUNTER = 0;
}
return ++COUNTER;
}
}

View File

@ -1,11 +1,7 @@
package com.ruoyi.common.utils; package com.ruoyi.common.utils;
import java.util.ArrayList; import java.util.*;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.springframework.util.AntPathMatcher; import org.springframework.util.AntPathMatcher;
import com.ruoyi.common.constant.Constants; import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.text.StrFormatter; import com.ruoyi.common.core.text.StrFormatter;
@ -611,4 +607,27 @@ public class StringUtils extends org.apache.commons.lang3.StringUtils
} }
return sb.toString(); return sb.toString();
} }
private static final String CHARACTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890";
/**
*
*
* @param length
* @return
*/
public static String randomString(int length) {
if (length < 1) {
length = 1;
}
StringBuilder sb = new StringBuilder();
Random random = new Random();
for (int i = 0; i < length; i++) {
int randomIndex = random.nextInt(CHARACTERS.length());
char randomChar = CHARACTERS.charAt(randomIndex);
sb.append(randomChar);
}
String randomString = sb.toString();
return randomString;
}
} }

View File

@ -0,0 +1,356 @@
package com.ruoyi.common.utils.sign;
import javax.crypto.Cipher;
import java.io.ByteArrayOutputStream;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
/**
* @description: Rsa
* @author: JiangYuQi
* @date: 2024/1/13 15:14
*/
public final class RSAUtil {
private RSAUtil() {}
private static final String RSA = "RSA";
private static final String SIGN_ALGORITHMS = "SHA1WithRSA";
private static final Base64.Decoder DECODER = Base64.getDecoder();
private static final Base64.Encoder ENCODER = Base64.getEncoder();
public static void main(String[] args) throws NoSuchAlgorithmException {
// 生成密钥对
KeyPair keyPair = getKeyPair();
// 公匙
String publicKey = getPublicKeyBase64(keyPair);
System.out.println("公匙 -> " + publicKey);
// 私匙
String privateKey = getPrivateKeyBase64(keyPair);
System.out.println("私匙 -> " + privateKey);
// 明文
String plaintext = "hello world!";
System.out.println("明文 -> " + plaintext);
// 密文base64公匙加密
String ciphertext = publicKeyEncrypt(plaintext, publicKey);
System.out.println("密文base64 -> " + ciphertext);
// 解密后明文(私匙解密)
String decryptString = privateKeyDecrypt(ciphertext, privateKey);
System.out.println("解密后明文 -> " + decryptString);
// 数字签名
// String sign = sign(ciphertext, privateKey);
// System.out.println("数字签名 -> " + decryptString);
// // 验证签名
// boolean pass = verify(ciphertext, sign, publicKey);
// System.out.println("验证签名 -> " + pass);
}
/**
*
*
* @return
* @throws Exception
*/
public static KeyPair getKeyPair() throws NoSuchAlgorithmException {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(RSA);
keyPairGenerator.initialize(2048);
return keyPairGenerator.generateKeyPair();
}
/**
* (Base64)
*
* @param keyPair
* @return
*/
public static String getPublicKeyBase64(KeyPair keyPair) {
PublicKey publicKey = keyPair.getPublic();
byte[] bytes = publicKey.getEncoded();
// 先用base64编码再转换为字符串
return new String(ENCODER.encode(bytes), StandardCharsets.UTF_8);
}
/**
* (Base64)
*
* @param keyPair
* @return
*/
public static String getPrivateKeyBase64(KeyPair keyPair) {
PrivateKey privateKey = keyPair.getPrivate();
byte[] bytes = privateKey.getEncoded();
// 先用base64编码再转换为字符串
return new String(ENCODER.encode(bytes), StandardCharsets.UTF_8);
}
/**
* Base64PublicKey
*
* @param publicKeyBase64 base64
* @return
*/
public static PublicKey getPublicKey(String publicKeyBase64) throws NoSuchAlgorithmException, InvalidKeySpecException {
byte[] keyBytes = DECODER.decode(publicKeyBase64);
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(RSA);
return keyFactory.generatePublic(keySpec);
}
/**
* Base64PrivateKey
*
* @param privateKeyBase64 base64
* @return
* @throws Exception
*/
public static PrivateKey getPrivateKey(String privateKeyBase64) throws NoSuchAlgorithmException, InvalidKeySpecException {
byte[] keyBytes = DECODER.decode((privateKeyBase64));
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(RSA);
return keyFactory.generatePrivate(keySpec);
}
/**
*
*
* @param plaintext
* @param publicKeyBase64 base64
* @return base64
*/
public static String publicKeyEncrypt(String plaintext, String publicKeyBase64) {
try {
// 获取明文字节数组
byte[] bytes = plaintext.getBytes(StandardCharsets.UTF_8);
Cipher cipher = Cipher.getInstance(RSA);
// 编码前设定编码方式及密钥
PublicKey publicKey = getPublicKey(publicKeyBase64);
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
int keyBit = getKeySize(publicKey);
int inputLen = bytes.length;
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offSet = 0;
int step = keyBit / 8 - 11;
for (int i = 0; inputLen - offSet > 0; offSet = i * step) {
byte[] cache;
if (inputLen - offSet > step) {
cache = cipher.doFinal(bytes, offSet, step);
} else {
cache = cipher.doFinal(bytes, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
++i;
}
// 密文字节数组
byte[] ciphertextBytes = out.toByteArray();
out.close();
// 返回密文字节数组base64编码后的字符串
return new String(ENCODER.encode(ciphertextBytes), StandardCharsets.UTF_8);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
*
*
* @param ciphertext
* @param publicKeyBase64 base64
* @return
*/
public static String publicKeyDecrypt(String ciphertext, String publicKeyBase64) {
try {
// 密文base64解码字节数组
byte[] bytes = DECODER.decode(ciphertext.getBytes(StandardCharsets.UTF_8));
Cipher cipher = Cipher.getInstance(RSA);
PublicKey publicKey = getPublicKey(publicKeyBase64);
cipher.init(Cipher.DECRYPT_MODE, publicKey);
int keyBit = getKeySize(publicKey);
int inputLen = bytes.length;
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offSet = 0;
int step = keyBit / 8;
for (int i = 0; inputLen - offSet > 0; offSet = i * step) {
byte[] cache;
if (inputLen - offSet > step) {
cache = cipher.doFinal(bytes, offSet, step);
} else {
cache = cipher.doFinal(bytes, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
++i;
}
// 明文字节数组
byte[] plaintextBytes = out.toByteArray();
out.close();
return new String(plaintextBytes, StandardCharsets.UTF_8);
} catch (Exception e) {
return null;
}
}
/**
*
*
* @param plaintext
* @param privateKeyBase64 base64
* @return
*/
public static String privateKeyEncrypt(String plaintext, String privateKeyBase64) {
try {
// 获取明文字节数组
byte[] bytes = plaintext.getBytes(StandardCharsets.UTF_8);
Cipher cipher = Cipher.getInstance(RSA);
// 编码前设定编码方式及密钥
PrivateKey privateKey = getPrivateKey(privateKeyBase64);
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
int keyBit = getKeySize(privateKey);
int inputLen = bytes.length;
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offSet = 0;
int step = keyBit / 8 - 11;
for (int i = 0; inputLen - offSet > 0; offSet = i * step) {
byte[] cache;
if (inputLen - offSet > step) {
cache = cipher.doFinal(bytes, offSet, step);
} else {
cache = cipher.doFinal(bytes, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
++i;
}
// 密文字节数组
byte[] ciphertextBytes = out.toByteArray();
out.close();
// 返回密文字节数组base64编码后的字符串
return new String(ENCODER.encode(ciphertextBytes), StandardCharsets.UTF_8);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
*
*
* @param ciphertext
* @param privateKeyBase64 base64
* @return
*/
public static String privateKeyDecrypt(String ciphertext, String privateKeyBase64) {
try {
// 密文base64解码字节数组
byte[] bytes = DECODER.decode(ciphertext.getBytes(StandardCharsets.UTF_8));
Cipher cipher = Cipher.getInstance(RSA);
PrivateKey privateKey = getPrivateKey(privateKeyBase64);
cipher.init(Cipher.DECRYPT_MODE, privateKey);
int keyBit = getKeySize(privateKey);
int inputLen = bytes.length;
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offSet = 0;
int step = keyBit / 8;
for (int i = 0; inputLen - offSet > 0; offSet = i * step) {
byte[] cache;
if (inputLen - offSet > step) {
cache = cipher.doFinal(bytes, offSet, step);
} else {
cache = cipher.doFinal(bytes, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
++i;
}
// 明文字节数组
byte[] plaintextBytes = out.toByteArray();
out.close();
return new String(plaintextBytes, StandardCharsets.UTF_8);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 使
*
* @param ciphertext
* @param privateKeyBase64 Base64
* @return base64
*/
public static String sign(String ciphertext, String privateKeyBase64) {
try {
// 密文字节数组
byte[] ciphertextBytes = DECODER.decode(ciphertext.getBytes(StandardCharsets.UTF_8));
PrivateKey privateKey = getPrivateKey(privateKeyBase64);
Signature signature = Signature.getInstance(SIGN_ALGORITHMS);
signature.initSign(privateKey);
signature.update(ciphertextBytes);
byte[] signed = signature.sign();
return new String(ENCODER.encode(signed), StandardCharsets.UTF_8);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 使
*
* @param ciphertext
* @param sign
* @param publicKeyBase64 base64
* @return
*/
public static boolean verify(String ciphertext, String sign, String publicKeyBase64) {
try {
// 密文base64解码字节数组
byte[] ciphertextBytes = DECODER.decode(ciphertext.getBytes(StandardCharsets.UTF_8));
// 签名base64解码字节数组
byte[] signBytes = DECODER.decode(sign.getBytes(StandardCharsets.UTF_8));
PublicKey publicKey = getPublicKey(publicKeyBase64);
Signature signature = Signature.getInstance(SIGN_ALGORITHMS);
signature.initVerify(publicKey);
signature.update(ciphertextBytes);
return signature.verify(signBytes);
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
/**
*
*
* @param publicKey
* @return
*/
public static int getKeySize(PublicKey publicKey) {
RSAPublicKey rsaPublicKey = (RSAPublicKey) publicKey;
return rsaPublicKey.getModulus().bitLength();
}
/**
*
*
* @param privateKey
* @return
*/
public static int getKeySize(PrivateKey privateKey) {
RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) privateKey;
return rsaPrivateKey.getModulus().bitLength();
}
}

View File

@ -32,10 +32,18 @@ public class SysApplyConfig extends BaseEntity
@Excel(name = "项目主键") @Excel(name = "项目主键")
private Long projectId; private Long projectId;
/** 项目名称 */
@Excel(name = "项目名称")
private Long projectName;
/** 部门主键 */ /** 部门主键 */
@Excel(name = "部门主键") @Excel(name = "部门主键")
private Long deptId; private Long deptId;
/** 部门名称 */
@Excel(name = "部门名称")
private Long deptName;
/** 是否删除 */ /** 是否删除 */
@Excel(name = "是否删除") @Excel(name = "是否删除")
private String isDel; private String isDel;

View File

@ -1,10 +1,13 @@
package com.ruoyi.system.service.impl; package com.ruoyi.system.service.impl;
import java.security.KeyPair;
import java.util.List; import java.util.List;
import com.ruoyi.common.constant.CacheConstants; import com.ruoyi.common.constant.CacheConstants;
import com.ruoyi.common.core.redis.RedisCache; import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils; import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.sign.RSAUtil;
import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@ -88,6 +91,18 @@ public class SysApplyConfigServiceImpl implements ISysApplyConfigService
{ {
sysApplyConfig.setCreateBy(SecurityUtils.getUsername()); sysApplyConfig.setCreateBy(SecurityUtils.getUsername());
sysApplyConfig.setCreateTime(DateUtils.getNowDate()); sysApplyConfig.setCreateTime(DateUtils.getNowDate());
try {
// 生成密钥对
KeyPair keyPair = RSAUtil.getKeyPair();
// 公匙
String publicKey = RSAUtil.getPublicKeyBase64(keyPair);
sysApplyConfig.setPublicKey(publicKey);
// 私匙
String privateKey = RSAUtil.getPrivateKeyBase64(keyPair);
sysApplyConfig.setPrivateKey(privateKey);
}catch (Exception e){
throw new ServiceException();
}
int res = sysApplyConfigMapper.insertSysApplyConfig(sysApplyConfig); int res = sysApplyConfigMapper.insertSysApplyConfig(sysApplyConfig);
if(res>0){ if(res>0){
this.loadingSysApplyConfigCache(); this.loadingSysApplyConfigCache();

View File

@ -10,7 +10,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="publicKey" column="public_key" /> <result property="publicKey" column="public_key" />
<result property="privateKey" column="private_key" /> <result property="privateKey" column="private_key" />
<result property="projectId" column="project_id" /> <result property="projectId" column="project_id" />
<result property="projectName" column="projectName" />
<result property="deptId" column="dept_id" /> <result property="deptId" column="dept_id" />
<result property="deptName" column="deptName" />
<result property="isDel" column="is_del" /> <result property="isDel" column="is_del" />
<result property="createBy" column="create_by" /> <result property="createBy" column="create_by" />
<result property="createTime" column="create_time" /> <result property="createTime" column="create_time" />
@ -20,22 +22,25 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</resultMap> </resultMap>
<sql id="selectSysApplyConfigVo"> <sql id="selectSysApplyConfigVo">
select id, app_id, public_key, private_key, project_id, dept_id, is_del, create_by, create_time, update_by, update_time, remark from sys_apply_config select sac.id, sac.app_id, sac.public_key, sac.private_key, sac.project_id, sp.projectName, sac.dept_id, sd.dept_name as deptName, sac.is_del, sac.create_by, sac.create_time, sac.update_by, sac.update_time, sac.remark from sys_apply_config sac
left join sur_project sp on sac.project_id = sp.id
left join sys_dept sd on sac.dept_id = sd.dept_id
</sql> </sql>
<select id="selectSysApplyConfigList" parameterType="SysApplyConfig" resultMap="SysApplyConfigResult"> <select id="selectSysApplyConfigList" parameterType="SysApplyConfig" resultMap="SysApplyConfigResult">
<include refid="selectSysApplyConfigVo"/> <include refid="selectSysApplyConfigVo"/>
<where> <where>
<if test="appId != null "> and app_id like concat('%', #{appId}, '%')</if> <if test="appId != null "> and sac.app_id like concat('%', #{appId}, '%')</if>
<if test="projectId != null "> and project_id like concat('%', #{projectId}, '%')</if> <if test="projectName != null "> and sp.projectName like concat('%', #{projectName}, '%')</if>
<if test="deptId != null "> and dept_id like concat('%', #{deptId}, '%')</if> <if test="deptName != null "> and sd.dept_name like concat('%', #{deptName}, '%')</if>
<if test="isDel != null and isDel != ''"> and is_del = #{isDel}</if> <if test="isDel != null and isDel != ''"> and sac.is_del = #{isDel}</if>
</where> </where>
order by sac.id desc
</select> </select>
<select id="selectSysApplyConfigById" parameterType="Long" resultMap="SysApplyConfigResult"> <select id="selectSysApplyConfigById" parameterType="Long" resultMap="SysApplyConfigResult">
<include refid="selectSysApplyConfigVo"/> <include refid="selectSysApplyConfigVo"/>
where id = #{id} where sac.id = #{id}
</select> </select>
<insert id="insertSysApplyConfig" parameterType="SysApplyConfig"> <insert id="insertSysApplyConfig" parameterType="SysApplyConfig">

View File

@ -42,3 +42,11 @@ export function delApplyConfig(id) {
method: 'delete' method: 'delete'
}) })
} }
// 生成有效的AppId
export function getApplyId() {
return request({
url: '/system/applyConfig/createAppId',
method: 'get'
})
}

View File

@ -9,18 +9,18 @@
@keyup.enter.native="handleQuery" @keyup.enter.native="handleQuery"
/> />
</el-form-item> </el-form-item>
<el-form-item label="项目主键" prop="projectId"> <el-form-item label="项目名称" prop="projectName">
<el-input <el-input
v-model="queryParams.projectId" v-model="queryParams.projectName"
placeholder="请输入项目主键" placeholder="请输入项目主键"
clearable clearable
@keyup.enter.native="handleQuery" @keyup.enter.native="handleQuery"
/> />
</el-form-item> </el-form-item>
<el-form-item label="部门主键" prop="deptId"> <el-form-item label="单位名称" prop="deptName">
<el-input <el-input
v-model="queryParams.deptId" v-model="queryParams.deptName"
placeholder="请输入部门主键" placeholder="请输入单位名称"
clearable clearable
@keyup.enter.native="handleQuery" @keyup.enter.native="handleQuery"
/> />
@ -28,7 +28,7 @@
<el-form-item label="是否删除" prop="isDel"> <el-form-item label="是否删除" prop="isDel">
<el-select v-model="queryParams.isDel" placeholder="请选择是否删除" clearable> <el-select v-model="queryParams.isDel" placeholder="请选择是否删除" clearable>
<el-option <el-option
v-for="dict in dict.type.sys_common_isdel" v-for="dict in dict.type.sys_normal_disable"
:key="dict.value" :key="dict.value"
:label="dict.label" :label="dict.label"
:value="dict.value" :value="dict.value"
@ -95,7 +95,7 @@
<el-table-column label="部门主键" align="center" prop="deptId" /> <el-table-column label="部门主键" align="center" prop="deptId" />
<el-table-column label="是否删除" align="center" prop="isDel"> <el-table-column label="是否删除" align="center" prop="isDel">
<template slot-scope="scope"> <template slot-scope="scope">
<dict-tag :options="dict.type.sys_common_isdel" :value="scope.row.isDel"/> <dict-tag :options="dict.type.sys_normal_disable" :value="scope.row.isDel"/>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="创建时间" align="center" prop="createTime" width="180"> <el-table-column label="创建时间" align="center" prop="createTime" width="180">
@ -132,35 +132,66 @@
/> />
<!-- 添加或修改系统应用注册对话框 --> <!-- 添加或修改系统应用注册对话框 -->
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body> <el-dialog :title="title" :visible.sync="open" width="680px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="80px"> <el-form ref="form" :model="form" :rules="rules" label-width="80px">
<div class="page-warning">
<p><strong style="color: #E6A23C;">应用公钥</strong> 在注册应用后由系统生成请在保存后查看</p>
</div>
<el-form-item label="应用主键" prop="appId"> <el-form-item label="应用主键" prop="appId">
<el-input v-model="form.appId" placeholder="请输入应用主键" /> <el-input v-model="form.appId" placeholder="请输入应用主键" :disabled="true"/>
</el-form-item> </el-form-item>
<el-form-item label="公钥" prop="publicKey"> <el-form-item label="应用公钥" prop="publicKey" v-if="form.publicKey">
<el-input v-model="form.publicKey" type="textarea" placeholder="请输入内容" /> <el-input type="textarea" :rows="3" v-model="form.publicKey" placeholder="请输入应用公钥" :disabled="true"/>
</el-form-item> </el-form-item>
<el-form-item label="私钥" prop="privateKey"> <el-form-item label="项目信息" prop="projectId">
<el-input v-model="form.privateKey" type="textarea" placeholder="请输入内容" /> <el-select
</el-form-item> v-model="form.projectId"
<el-form-item label="项目主键" prop="projectId"> filterable
<el-input v-model="form.projectId" placeholder="请输入项目主键" /> clearable
</el-form-item> placeholder="请选择所属项目"
<el-form-item label="部门主键" prop="deptId"> style="width: 100%"
<el-input v-model="form.deptId" placeholder="请输入部门主键" /> @change="projectChange"
</el-form-item> >
<el-form-item label="是否删除" prop="isDel">
<el-select v-model="form.isDel" placeholder="请选择是否删除">
<el-option <el-option
v-for="dict in dict.type.sys_common_isdel" v-for="item in projectOptions"
:key="item.id"
:label="item.projectName"
:value="item.id"
>
</el-option>
</el-select>
</el-form-item>
<div class="page-warning">
<p><strong style="color: #E6A23C;">单位信息</strong> 只能选择<strong style="color: #E6A23C;">总包单位</strong></p>
</div>
<el-form-item label="单位信息" prop="deptId">
<el-select
v-model="form.deptId"
clearable
placeholder="请选择所属单位"
style="width: 100%"
>
<el-option
v-for="item in deptOptions"
:key="item.deptId"
:label="item.deptName"
:value="item.deptId"
>
</el-option>
</el-select>
</el-form-item>
<el-form-item label="应用状态" prop="isDel">
<el-select v-model="form.isDel" placeholder="请选择应用状态" style="width: 100%">
<el-option
v-for="dict in dict.type.sys_normal_disable"
:key="dict.value" :key="dict.value"
:label="dict.label" :label="dict.label"
:value="dict.value" :value="dict.value"
></el-option> ></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="备注" prop="remark"> <el-form-item label="册说明" prop="remark">
<el-input v-model="form.remark" placeholder="请输入备注" /> <el-input type="textarea" :rows="3" v-model="form.remark" placeholder="请输入册说明" />
</el-form-item> </el-form-item>
</el-form> </el-form>
<div slot="footer" class="dialog-footer"> <div slot="footer" class="dialog-footer">
@ -172,11 +203,11 @@
</template> </template>
<script> <script>
import { listApplyConfig, getApplyConfig, delApplyConfig, addApplyConfig, updateApplyConfig } from "@/api/system/applyConfig"; import { listApplyConfig, getApplyConfig, delApplyConfig, addApplyConfig, updateApplyConfig, getApplyId } from "@/api/system/applyConfig";
export default { export default {
name: "ApplyConfig", name: "ApplyConfig",
dicts: ['sys_common_isdel'], dicts: ['sys_normal_disable'],
data() { data() {
return { return {
// //
@ -203,20 +234,45 @@ export default {
pageSize: 10, pageSize: 10,
appId: null, appId: null,
projectId: null, projectId: null,
projectName: null,
deptId: null, deptId: null,
deptName: null,
isDel: null, isDel: null,
}, },
// //
form: {}, form: {},
// //
rules: { rules: {
} },
projectOptions: [],
deptOptions :[],
}; };
}, },
created() { created() {
this.getList(); this.getList();
this.getProjectList();
}, },
methods: { methods: {
projectChange(val){
this.form.deptId=null;
//
this.initDept(val);
},
initDept(val){
this.$api.publics
.queryUnitList({
projectId: val,
unitType: 2
})
.then((d) => {
this.deptOptions = d.rows;
if (d.rows.length > 0) {
//
} else {
this.$message.error("当前项目未分配总包单位,不能注册应用!");
}
});
},
/** 查询系统应用注册列表 */ /** 查询系统应用注册列表 */
getList() { getList() {
this.loading = true; this.loading = true;
@ -226,6 +282,16 @@ export default {
this.loading = false; this.loading = false;
}); });
}, },
//
getProjectList() {
let param = {
data: {},
};
//
this.$api.publics.getProjectList(param).then((response) => {
this.projectOptions = response.rows;
});
},
// //
cancel() { cancel() {
this.open = false; this.open = false;
@ -268,8 +334,11 @@ export default {
/** 新增按钮操作 */ /** 新增按钮操作 */
handleAdd() { handleAdd() {
this.reset(); this.reset();
this.open = true; getApplyId().then(response => {
this.title = "添加系统应用注册"; this.form.appId = response.msg;
this.open = true;
this.title = "系统应用注册";
});
}, },
/** 修改按钮操作 */ /** 修改按钮操作 */
handleUpdate(row) { handleUpdate(row) {
@ -278,7 +347,7 @@ export default {
getApplyConfig(id).then(response => { getApplyConfig(id).then(response => {
this.form = response.data; this.form = response.data;
this.open = true; this.open = true;
this.title = "修改系统应用注册"; this.title = "系统应用修改";
}); });
}, },
/** 提交按钮 */ /** 提交按钮 */
@ -304,7 +373,7 @@ export default {
/** 删除按钮操作 */ /** 删除按钮操作 */
handleDelete(row) { handleDelete(row) {
const ids = row.id || this.ids; const ids = row.id || this.ids;
this.$modal.confirm('是否确认删除系统应用注册编号为"' + ids + '"的数据项?').then(function() { this.$modal.confirm('是否确认删除系统应用编号为"' + ids + '"的数据项?').then(function() {
return delApplyConfig(ids); return delApplyConfig(ids);
}).then(() => { }).then(() => {
this.getList(); this.getList();
@ -320,3 +389,14 @@ export default {
} }
}; };
</script> </script>
<style lang="scss">
.page-warning {
padding: 8px 16px;
background-color: #f0f9eb;
border-radius: 4px;
border-left: 5px solid #67C23A;
margin: 20px 0;
font-size: 13px;
margin-top: 10px;
}
</style>