提交代码

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.redis.RedisCache;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.enums.HttpStatusEnum;
import com.ruoyi.common.enums.LimitType;
import com.ruoyi.common.enums.ShiFouEnum;
import com.ruoyi.common.enums.UserTypeEnum;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.AuthRsaUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
@ -81,14 +84,17 @@ public class LabourApiController extends BaseController {
public AjaxResult getToken(@Validated @RequestBody TokenReqVo req) {
SysApplyConfig sysApplyConfig = redisCache.getCacheObject(CacheConstants.YANZHU_SYSTEM_CONFIG+req.getAppId());
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();
String systemToken = "";
if (req.getLoginSign(sysApplyConfig.getPrivateKey())) {
systemToken = this.getAppIdLoginToken(req.getAppId(),sysApplyConfig);
} else {
throw new RuntimeException("签名值不合法");
throw new ServiceException(HttpStatusEnum.SINGET_ERROR.getInfo(),HttpStatusEnum.SINGET_ERROR.getCode());
}
ajax.put("systemToken", systemToken);
return ajax;
@ -136,6 +142,9 @@ public class LabourApiController extends BaseController {
SysApplyConfig sysApplyConfig = redisCache.getCacheObject(CacheConstants.YANZHU_SYSTEM_CONFIG+super.getUsername());
if(req.checkTimestamp()){
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());
SurProjectAttendanceGroup surProjectAttendanceGroup = JSONObject.parseObject(result, SurProjectAttendanceGroup.class);
if(StringUtils.isNotEmpty(surProjectAttendanceGroup.getServerid())){
@ -157,13 +166,13 @@ public class LabourApiController extends BaseController {
surProjectAttendanceGroupService.insertSurProjectAttendanceGroup(surProjectAttendanceGroup);
}
}else{
throw new RuntimeException("数据解析异常");
throw new ServiceException(HttpStatusEnum.DARA_EXCEPTION.getInfo(),HttpStatusEnum.DARA_EXCEPTION.getCode());
}
}catch (Exception e){
throw new RuntimeException("签名解密异常");
throw new ServiceException(HttpStatusEnum.SINGET_EXCEPTION.getInfo(),HttpStatusEnum.SINGET_EXCEPTION.getCode());
}
}else{
throw new RuntimeException("数据已过期");
throw new ServiceException(HttpStatusEnum.SINGET_TIMEOUT.getInfo(),HttpStatusEnum.SINGET_TIMEOUT.getCode());
}
return success();
}
@ -179,11 +188,14 @@ public class LabourApiController extends BaseController {
@RateLimiter(time = 30, count = 10, limitType = LimitType.IP)
@PostMapping("/v1/pushLabourGroupList")
public AjaxResult pushLabourGroupList(@Validated @RequestBody LabourSignetVo req) {
// 失败集合
List<Integer> failServiceIdList = new ArrayList<>();
SysApplyConfig sysApplyConfig = redisCache.getCacheObject(CacheConstants.YANZHU_SYSTEM_CONFIG+super.getUsername());
if(req.checkTimestamp()){
try {
// 失败集合
List<Integer> failServiceIdList = new ArrayList<>();
if(StringUtils.equals(ShiFouEnum.SHI.getCode()+"",sysApplyConfig.getIsDel())){
throw new ServiceException(HttpStatusEnum.DISABLE.getInfo(),HttpStatusEnum.DISABLE.getCode());
}
// 保存集合
List<SurProjectAttendanceGroup> saveList = new ArrayList<>();
String result = AuthRsaUtils.decryptByPrivateKey(sysApplyConfig.getPrivateKey(),req.getSign());
@ -207,15 +219,15 @@ public class LabourApiController extends BaseController {
}
surProjectAttendanceGroupService.batchSurProjectAttendanceGroup(saveList);
}else{
throw new RuntimeException("数据解析异常");
throw new ServiceException(HttpStatusEnum.DARA_EXCEPTION.getInfo(),HttpStatusEnum.DARA_EXCEPTION.getCode());
}
}catch (Exception e){
throw new RuntimeException("签名解密异常");
throw new ServiceException(HttpStatusEnum.SINGET_EXCEPTION.getInfo(),HttpStatusEnum.SINGET_EXCEPTION.getCode());
}
}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());
if(req.checkTimestamp()){
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());
SurProjectAttendanceUser surProjectAttendanceUser = JSONObject.parseObject(result, SurProjectAttendanceUser.class);
if(StringUtils.isNotEmpty(surProjectAttendanceUser.getWorkerId())){
@ -253,13 +268,13 @@ public class LabourApiController extends BaseController {
surProjectAttendanceUserService.insertSurProjectAttendanceUser(surProjectAttendanceUser);
}
}else{
throw new RuntimeException("数据解析异常");
throw new ServiceException(HttpStatusEnum.DARA_EXCEPTION.getInfo(),HttpStatusEnum.DARA_EXCEPTION.getCode());
}
}catch (Exception e){
throw new RuntimeException("签名解密异常");
throw new ServiceException(HttpStatusEnum.SINGET_EXCEPTION.getInfo(),HttpStatusEnum.SINGET_EXCEPTION.getCode());
}
}else{
throw new RuntimeException("数据已过期");
throw new ServiceException(HttpStatusEnum.SINGET_TIMEOUT.getInfo(),HttpStatusEnum.SINGET_TIMEOUT.getCode());
}
return success();
}
@ -275,11 +290,14 @@ public class LabourApiController extends BaseController {
@RateLimiter(time = 30, count = 10, limitType = LimitType.IP)
@PostMapping("/v1/pushLabourUserList")
public AjaxResult pushLabourUserList(@Validated @RequestBody LabourSignetVo req) {
// 失败集合
List<Integer> failServiceIdList = new ArrayList<>();
SysApplyConfig sysApplyConfig = redisCache.getCacheObject(CacheConstants.YANZHU_SYSTEM_CONFIG+super.getUsername());
if(req.checkTimestamp()){
try {
// 失败集合
List<Integer> failServiceIdList = new ArrayList<>();
if(StringUtils.equals(ShiFouEnum.SHI.getCode()+"",sysApplyConfig.getIsDel())){
throw new ServiceException(HttpStatusEnum.DISABLE.getInfo(),HttpStatusEnum.DISABLE.getCode());
}
// 保存集合
List<SurProjectAttendanceUser> saveList = new ArrayList<>();
String result = AuthRsaUtils.decryptByPrivateKey(sysApplyConfig.getPrivateKey(),req.getSign());
@ -303,15 +321,15 @@ public class LabourApiController extends BaseController {
}
surProjectAttendanceUserService.batchSurProjectAttendanceUser(saveList);
}else{
throw new RuntimeException("数据解析异常");
throw new ServiceException(HttpStatusEnum.DARA_EXCEPTION.getInfo(),HttpStatusEnum.DARA_EXCEPTION.getCode());
}
}catch (Exception e){
throw new RuntimeException("签名解密异常");
throw new ServiceException(HttpStatusEnum.SINGET_EXCEPTION.getInfo(),HttpStatusEnum.SINGET_EXCEPTION.getCode());
}
}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());
if(req.checkTimestamp()){
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());
SurProjectAttendanceData surProjectAttendanceData = JSONObject.parseObject(result, SurProjectAttendanceData.class);
if(StringUtils.isNotEmpty(surProjectAttendanceData.getWorkerId()) && StringUtils.isNotEmpty(surProjectAttendanceData.getServerid())){
@ -350,13 +371,13 @@ public class LabourApiController extends BaseController {
surProjectAttendanceDataService.insertSurProjectAttendanceData(surProjectAttendanceData);
}
}else{
throw new RuntimeException("数据解析异常");
throw new ServiceException(HttpStatusEnum.DARA_EXCEPTION.getInfo(),HttpStatusEnum.DARA_EXCEPTION.getCode());
}
}catch (Exception e){
throw new RuntimeException("签名解密异常");
throw new ServiceException(HttpStatusEnum.SINGET_EXCEPTION.getInfo(),HttpStatusEnum.SINGET_EXCEPTION.getCode());
}
}else{
throw new RuntimeException("数据已过期");
throw new ServiceException(HttpStatusEnum.SINGET_TIMEOUT.getInfo(),HttpStatusEnum.SINGET_TIMEOUT.getCode());
}
return success();
}
@ -372,11 +393,14 @@ public class LabourApiController extends BaseController {
@RateLimiter(time = 30, count = 10, limitType = LimitType.IP)
@PostMapping("/v1/pushLabourDataList")
public AjaxResult pushLabourDataList(@Validated @RequestBody LabourSignetVo req) {
// 失败集合
List<Integer> failServiceIdList = new ArrayList<>();
SysApplyConfig sysApplyConfig = redisCache.getCacheObject(CacheConstants.YANZHU_SYSTEM_CONFIG+super.getUsername());
if(req.checkTimestamp()){
try {
// 失败集合
List<Integer> failServiceIdList = new ArrayList<>();
if(StringUtils.equals(ShiFouEnum.SHI.getCode()+"",sysApplyConfig.getIsDel())){
throw new ServiceException(HttpStatusEnum.DISABLE.getInfo(),HttpStatusEnum.DISABLE.getCode());
}
// 保存集合
List<SurProjectAttendanceData> saveList = new ArrayList<>();
String result = AuthRsaUtils.decryptByPrivateKey(sysApplyConfig.getPrivateKey(),req.getSign());
@ -400,15 +424,15 @@ public class LabourApiController extends BaseController {
}
surProjectAttendanceDataService.batchSurProjectAttendanceData(saveList);
}else{
throw new RuntimeException("数据解析异常");
throw new ServiceException(HttpStatusEnum.DARA_EXCEPTION.getInfo(),HttpStatusEnum.DARA_EXCEPTION.getCode());
}
}catch (Exception e){
throw new RuntimeException("签名解密异常");
throw new ServiceException(HttpStatusEnum.SINGET_EXCEPTION.getInfo(),HttpStatusEnum.SINGET_EXCEPTION.getCode());
}
}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.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.NoUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.system.domain.SysApplyConfig;
import com.ruoyi.system.service.ISysApplyConfigService;
@ -95,4 +96,15 @@ public class SysApplyConfigController extends BaseController
{
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;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.*;
import org.springframework.util.AntPathMatcher;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.text.StrFormatter;
@ -611,4 +607,27 @@ public class StringUtils extends org.apache.commons.lang3.StringUtils
}
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 = "项目主键")
private Long projectId;
/** 项目名称 */
@Excel(name = "项目名称")
private Long projectName;
/** 部门主键 */
@Excel(name = "部门主键")
private Long deptId;
/** 部门名称 */
@Excel(name = "部门名称")
private Long deptName;
/** 是否删除 */
@Excel(name = "是否删除")
private String isDel;

View File

@ -1,10 +1,13 @@
package com.ruoyi.system.service.impl;
import java.security.KeyPair;
import java.util.List;
import com.ruoyi.common.constant.CacheConstants;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.sign.RSAUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@ -88,6 +91,18 @@ public class SysApplyConfigServiceImpl implements ISysApplyConfigService
{
sysApplyConfig.setCreateBy(SecurityUtils.getUsername());
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);
if(res>0){
this.loadingSysApplyConfigCache();

View File

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

View File

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

View File

@ -9,18 +9,18 @@
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="项目主键" prop="projectId">
<el-form-item label="项目名称" prop="projectName">
<el-input
v-model="queryParams.projectId"
v-model="queryParams.projectName"
placeholder="请输入项目主键"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="部门主键" prop="deptId">
<el-form-item label="单位名称" prop="deptName">
<el-input
v-model="queryParams.deptId"
placeholder="请输入部门主键"
v-model="queryParams.deptName"
placeholder="请输入单位名称"
clearable
@keyup.enter.native="handleQuery"
/>
@ -28,7 +28,7 @@
<el-form-item label="是否删除" prop="isDel">
<el-select v-model="queryParams.isDel" placeholder="请选择是否删除" clearable>
<el-option
v-for="dict in dict.type.sys_common_isdel"
v-for="dict in dict.type.sys_normal_disable"
:key="dict.value"
:label="dict.label"
:value="dict.value"
@ -95,7 +95,7 @@
<el-table-column label="部门主键" align="center" prop="deptId" />
<el-table-column label="是否删除" align="center" prop="isDel">
<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>
</el-table-column>
<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">
<div class="page-warning">
<p><strong style="color: #E6A23C;">应用公钥</strong> 在注册应用后由系统生成请在保存后查看</p>
</div>
<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 label="公钥" prop="publicKey">
<el-input v-model="form.publicKey" type="textarea" placeholder="请输入内容" />
<el-form-item label="应用公钥" prop="publicKey" v-if="form.publicKey">
<el-input type="textarea" :rows="3" v-model="form.publicKey" placeholder="请输入应用公钥" :disabled="true"/>
</el-form-item>
<el-form-item label="私钥" prop="privateKey">
<el-input v-model="form.privateKey" type="textarea" placeholder="请输入内容" />
</el-form-item>
<el-form-item label="项目主键" prop="projectId">
<el-input v-model="form.projectId" placeholder="请输入项目主键" />
</el-form-item>
<el-form-item label="部门主键" prop="deptId">
<el-input v-model="form.deptId" placeholder="请输入部门主键" />
</el-form-item>
<el-form-item label="是否删除" prop="isDel">
<el-select v-model="form.isDel" placeholder="请选择是否删除">
<el-form-item label="项目信息" prop="projectId">
<el-select
v-model="form.projectId"
filterable
clearable
placeholder="请选择所属项目"
style="width: 100%"
@change="projectChange"
>
<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"
:label="dict.label"
:value="dict.value"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" placeholder="请输入备注" />
<el-form-item label="册说明" prop="remark">
<el-input type="textarea" :rows="3" v-model="form.remark" placeholder="请输入册说明" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
@ -172,11 +203,11 @@
</template>
<script>
import { listApplyConfig, getApplyConfig, delApplyConfig, addApplyConfig, updateApplyConfig } from "@/api/system/applyConfig";
import { listApplyConfig, getApplyConfig, delApplyConfig, addApplyConfig, updateApplyConfig, getApplyId } from "@/api/system/applyConfig";
export default {
name: "ApplyConfig",
dicts: ['sys_common_isdel'],
dicts: ['sys_normal_disable'],
data() {
return {
//
@ -203,20 +234,45 @@ export default {
pageSize: 10,
appId: null,
projectId: null,
projectName: null,
deptId: null,
deptName: null,
isDel: null,
},
//
form: {},
//
rules: {
}
},
projectOptions: [],
deptOptions :[],
};
},
created() {
this.getList();
this.getProjectList();
},
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() {
this.loading = true;
@ -226,6 +282,16 @@ export default {
this.loading = false;
});
},
//
getProjectList() {
let param = {
data: {},
};
//
this.$api.publics.getProjectList(param).then((response) => {
this.projectOptions = response.rows;
});
},
//
cancel() {
this.open = false;
@ -268,8 +334,11 @@ export default {
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.open = true;
this.title = "添加系统应用注册";
getApplyId().then(response => {
this.form.appId = response.msg;
this.open = true;
this.title = "系统应用注册";
});
},
/** 修改按钮操作 */
handleUpdate(row) {
@ -278,7 +347,7 @@ export default {
getApplyConfig(id).then(response => {
this.form = response.data;
this.open = true;
this.title = "修改系统应用注册";
this.title = "系统应用修改";
});
},
/** 提交按钮 */
@ -304,7 +373,7 @@ export default {
/** 删除按钮操作 */
handleDelete(row) {
const ids = row.id || this.ids;
this.$modal.confirm('是否确认删除系统应用注册编号为"' + ids + '"的数据项?').then(function() {
this.$modal.confirm('是否确认删除系统应用编号为"' + ids + '"的数据项?').then(function() {
return delApplyConfig(ids);
}).then(() => {
this.getList();
@ -320,3 +389,14 @@ export default {
}
};
</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>