保存进度

This commit is contained in:
Kane Wang 2025-03-16 08:41:32 +08:00
parent 5bf6b6f679
commit d25f43db18
9 changed files with 264 additions and 139 deletions

View File

@ -0,0 +1,87 @@
/*
* @Author: Kane
* @Date: 2025-03-16 00:35:09
* @LastEditors: Kane
* @FilePath: /cpicxim-huixiabao/.vscode/fileheader.template.js
* @Description:
*
* Copyright (c) ${2023} by Kane, All Rights Reserved.
*/
/**
* This file is generated by VSCode extension: Fileheader Pro
*/
/**
* These comments can help you write your own template with type hint
* @typedef {Object} FileheaderVariable Fileheader variables
* @property {string} birthtime file birth time. will get it from VCS or fallback to filesystem when it is not available
* @property {string} mtime file modification time. will get it from VCS or fallback to filesystem when it is not available
* @property {string} authorName if the file is tracked by VCS, it will get the author name from VCS. else it will get it from current user name
* @property {string} authorEmail if the file is tracked by VCS, it will get the author email from VCS. else it will get it from current user email
* @property {string} userName else it will get it from current user name
* @property {string} userEmail user email is from VSCode config, and fallback to VCS config
* @property {string} companyName
* @property {string} projectName name of current project
* @property {string} filePath the file path, relative to project root with POSIX path separator
* @property {string} dirPath the directory path, relative to project root with POSIX path separator
* @property {string} fileName filename with extension
*/
/**
* @typedef {string | number | null | undefined | Template | boolean} TemplateInterpolation NOTE: boolean or falsy value will render empty string
*
* @typedef {{ strings: TemplateStringsArray; interpolations: TemplateInterpolation[]; }} Template
* @typedef {(strings: TemplateStringsArray, ...values: any[]) => string} ITemplateFunction
*
*/
/**
* Please confirm your provider extends from globalThis.FileheaderLanguageProvider
*/
class CustomLanguageProvider extends globalThis.FileheaderLanguageProvider {
/**
* @type {string[]}
*/
languages = [
"java",
"javascript",
"typescript",
"javascriptreact",
"typescriptreact",
];
/**
* @type {string=} the language block comment start string.
* this is for future feature: support detect old custom template when custom template changes
*/
blockCommentStart = "/**";
/**
* @type {string=}
*/
blockCommentEnd = "*/";
/**
* get your template when document language matched
* @param {ITemplateFunction} tpl template function, it is a tagged function, support nested interpolation
* @param {FileheaderVariable} variables template variables
* @returns {Template}
*/
getTemplate(tpl, variables) {
// prettier-ignore
return tpl
`/**
* @Author: ${variables.authorName} <${variables.authorEmail}>
* @Date: ${variables.birthtime}
* @LastEditors: ${variables.userName}
* @LastModified: ${variables.mtime}
* @FilePath: ${variables.filePath}
* @Description:
*
* Copyright (c) ${2025} by Kane All rights reserved
*/`;
}
}
// export your provider classes
module.exports = [CustomLanguageProvider];

View File

@ -1,16 +1,14 @@
/*
/**
* @Author: Kane
*
* @Date: 2025-03-15 17:09:50
*
* @Date: 2025-03-15 21:01:56
* @LastEditors: Kane
*
* @FilePath: /cpicxim-huixiabao/src/main/java/com/cpic/xim/huixiabao/web/controllers/MediCover/MediCoverController.java
*
* @Description:
*
* @
* Copyright (c) ${2023} by Kane, All Rights Reserved.
*/
package com.cpic.xim.huixiabao.web.controllers.MediCover;
import org.springframework.stereotype.Controller;
@ -35,7 +33,7 @@ public class MediCoverController
private static String publicyKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDAWpwF05xwoXelv72KunlZpq9UdqdubYIYrwxG/Kq4MRzAmN5amISQMN44EAB9x80jhcWdzM/1nEWltws1nwGdJpuXXFWNKhIMk/9QTrHYS8CmtwQblEUQhKeWT2qRK5t1IJfzgcYxFEYLXPSZ1QThAnPSr5NxV77jeLQ1pdfJcQIDAQAB";
/**
* 接收医保局财政支持小药箱数据
* 接收医保局财政支持小药箱数据
*
* @param request
* @return
@ -54,7 +52,7 @@ public class MediCoverController
logger.info( "【接收小药箱数据】请求参数<{}>", request.toString() );
logger.info( "【接收小药箱数据】解密参数<{}>", decryptData );
// jsonMapper.readValue(decryptData, null)
// jsonMapper.readValue( decryptData, null );
return response;
}
}

View File

@ -1,18 +1,13 @@
/*
* @Author: Kane
*
* @Date: 2025-03-15 16:41:05
*
* @LastEditors: Kane
*
* @FilePath:
* /cpicxim-huixiabao/src/main/java/com/cpic/xim/huixiabao/web/controllers/MediCover/MediCoverRequestBody.java
* /cpicxim-huixiabao/src/main/java/com/cpic/xim/huixiabao/web/controllers/MediCover/MediCoverRequestBody.java
*
* @Description:
*
* Copyright (c) ${2023} by Kane, All Rights Reserved.
/**
* @Author: Kane
* @Date: 2025-03-15 21:01:56
* @LastEditors: Kane
* @FilePath: /cpicxim-huixiabao/src/main/java/com/cpic/xim/huixiabao/web/controllers/MediCover/MediCoverRequestBody.java
* @Description:
* @
* @Copyright (c) ${2023} by Kane, All Rights Reserved.
*/
package com.cpic.xim.huixiabao.web.controllers.MediCover;
import com.fasterxml.jackson.annotation.JsonProperty;
@ -100,7 +95,8 @@ public class MediCoverRequestBody
this.timestamp = timestamp;
}
@Override public String toString()
@Override
public String toString()
{
return "MediCoverRequestBody [transId=" + transId + ", format=" + format + ", bizContent=" + bizContent + ", key=" + key + ", timestamp=" + timestamp + "]";
}

View File

@ -3,9 +3,9 @@
* @Date: 2025-03-15 17:21:50
* @LastEditors: Kane
* @FilePath: /cpicxim-huixiabao/src/main/java/com/cpic/xim/huixiabao/web/controllers/MediCover/MediCoverResponse.java
* @Description:
* @Description:
*
* Copyright (c) ${2023} by Kane, All Rights Reserved.
* Copyright (c) ${2023} by Kane, All Rights Reserved.
*/
package com.cpic.xim.huixiabao.web.controllers.MediCover;
@ -15,11 +15,11 @@ public class MediCoverResponse
{
MediCoverResponse()
{
code = "500";
message = "未知失败原因";
code = "500";
message = "未知失败原因";
subMessage = "";
result = new MediCoverResultInResponse("", "");
success = false;
result = new MediCoverResultInResponse( "", "" );
success = false;
}
public MediCoverResponse(
@ -28,27 +28,28 @@ public class MediCoverResponse
String subMessage,
String key,
String content,
Boolean success )
Boolean success
)
{
this.code = code;
this.message = message;
this.subMessage = subMessage;
this.result = new MediCoverResultInResponse(key, content);
this.result = new MediCoverResultInResponse( key, content );
this.success = success;
}
@JsonProperty("code")
@JsonProperty( "code" )
private String code;
@JsonProperty("message")
@JsonProperty( "message" )
private String message;
@JsonProperty("subMessage")
@JsonProperty( "subMessage" )
private String subMessage;
@JsonProperty("result")
@JsonProperty( "result" )
private MediCoverResultInResponse result;
@JsonProperty("success")
@JsonProperty( "success" )
private Boolean success;
}

View File

@ -1,19 +1,23 @@
/*
/**
* @Author: Kane
*
* @Date: 2025-03-15 17:29:27
*
* @Date: 2025-03-15 21:01:56
* @LastEditors: Kane
*
* @FilePath:
* /cpicxim-huixiabao/src/main/java/com/cpic/xim/huixiabao/web/controllers/MediCover/MediCoverResultInResponse.java
* /cpicxim-huixiabao/src/main/java/com/cpic/xim/huixiabao/web/controllers/MediCover/MediCoverResultInResponse.java
* /cpicxim-huixiabao/src/main/java/com/cpic/xim/huixiabao/web/controllers/MediCover/MediCoverResultInResponse.java
*
* @FilePath: /cpicxim-huixiabao/src/main/java/com/cpic/xim/huixiabao/web/controllers/MediCover/MediCoverResultInResponse.java
* @Description:
*
* Copyright (c) ${2023} by Kane, All Rights Reserved.
* Copyright (c) ${2023} by Kane, All Rights Reserved.
*/
/**
* @Author: Kane Wang <wangkane@qq.com>
* @Date: 2025-03-15 18:40:54
* @LastEditors: Kane Wang
* @LastModified: 2025-03-16 01:13:50
* @FilePath: src/main/java/com/cpic/xim/huixiabao/web/controllers/MediCover/MediCoverResultInResponse.java
* @Description:
*
* Copyright (c) 2025 by Kane All rights reserved
*/
package com.cpic.xim.huixiabao.web.controllers.MediCover;
import com.fasterxml.jackson.annotation.JsonProperty;

View File

@ -0,0 +1,10 @@
/**
* @Author: Kane
* @Date: 2025-03-16 00:12:27
* @LastEditors: Kane
* @FilePath: /cpicxim-huixiabao/src/main/java/com/cpic/xim/huixiabao/web/data/nhs/HmbXyxInfo.java
* @Description:
*
* Copyright (c) ${2023} by Kane, All Rights Reserved.
*/
package com.cpic.xim.huixiabao.web.data.nhs.xyx;

View File

@ -1,24 +1,21 @@
/*
/**
* @Author: Kane
*
* @Date: 2025-03-15 18:28:17
*
* @Date: 2025-03-15 21:01:56
* @LastEditors: Kane
* @FilePath: /cpicxim-huixiabao/src/main/java/com/cpic/xim/huixiabao/web/data/nhs/xyx/HmbXyxInfoItem.java
* @Description:
*
* @FilePath: /cpicxim-huixiabao/src/main/java/com/cpic/xim/huixiabao/web/data/nhs/HmbXyxInfo.java
*
* @Description: 惠厦保 小药箱数据同步对象
* 对应惠厦保理赔规范接口 3.7
* Copyright (c) ${2023} by Kane, All Rights Reserved.
* Copyright (c) ${2023} by Kane, All Rights Reserved.
*/
package com.cpic.xim.huixiabao.web.data.nhs;
package com.cpic.xim.huixiabao.web.data.nhs.xyx;
import com.fasterxml.jackson.annotation.JsonProperty;
public class HmbXyxInfo
public class HmbXyxInfoItem
{
public String getPsnName()
{
return psnName;

View File

@ -1,16 +1,23 @@
/*
* @Author: Kane
*
* @Date: 2025-03-15 12:04:19
*
* @LastEditors: Kane
*
* @FilePath: /cpicxim-huixiabao/src/main/java/com/cpic/xim/utils/secrecy/Base64Utils.java
*
/**
* @Author: Kane Wang <wangkane@qq.com>
* @Date: 2025-03-15 12:50:53
* @LastEditors: Kane Wang
* @LastModified: 2025-03-16 08:40:07
* @FilePath: src/main/java/com/cpic/xim/utils/secrecy/Base64Utils.java
* @Description:
*
* Copyright (c) ${2023} by Kane, All Rights Reserved.
* Copyright (c) 2025 by Kane All rights reserved
*/
/**
* @Author: Kane
* @Date: 2025-03-15 12:04:19
* @LastEditors: Kane
* @FilePath: /cpicxim-huixiabao/src/main/java/com/cpic/xim/utils/secrecy/Base64Utils.java
* @Description:
*
* Copyright (c) ${2023} by Kane, All Rights Reserved.
*/
package com.cpic.xim.utils.secrecy;
import org.apache.commons.codec.binary.Base64;
@ -38,12 +45,14 @@ public class Base64Utils
* @return
* @throws Exception
*/
public static byte[] decode( String base64 ) throws Exception
public static byte[] decode( String base64 )
throws Exception
{
return Base64.decodeBase64( base64.getBytes() );
}
public static String decode( byte[] b ) throws Exception
public static String decode( byte[] b )
throws Exception
{
return new String( Base64.decodeBase64( b ) );
}

View File

@ -15,7 +15,8 @@ import java.util.Map;
/**
* RSAUtils
*/
public class RSAUtils {
public class RSAUtils
{
/**
* RSA最大加密明文大小
@ -37,27 +38,31 @@ public class RSAUtils {
*
* @throws Exception
*/
public static Map<String, String> getKeys() throws Exception {
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
keyPairGen.initialize(1024);
KeyPair keyPair = keyPairGen.generateKeyPair();
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
public static Map<String, String> getKeys()
throws Exception
{
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance( "RSA" );
keyPairGen.initialize( 1024 );
KeyPair keyPair = keyPairGen.generateKeyPair();
RSAPublicKey publicKey = ( RSAPublicKey ) keyPair.getPublic();
RSAPrivateKey privateKey = ( RSAPrivateKey ) keyPair.getPrivate();
String publicKeyStr = getPublicKeyStr(publicKey);
String privateKeyStr = getPrivateKeyStr(privateKey);
String publicKeyStr = getPublicKeyStr( publicKey );
String privateKeyStr = getPrivateKeyStr( privateKey );
Map<String, String> result = new HashMap<>(2);
result.put("publicKeyStr", publicKeyStr);
result.put("privateKeyStr", privateKeyStr);
Map<String, String> result = new HashMap<>( 2 );
result.put( "publicKeyStr", publicKeyStr );
result.put( "privateKeyStr", privateKeyStr );
return result;
}
public static void main(String[] args) throws Exception {
public static void main( String[] args )
throws Exception
{
Map<String, String> keys = getKeys();
System.out.println("publicKeyStr=" + keys.get("publicKeyStr"));
System.out.println("privateKeyStr=" + keys.get("privateKeyStr"));
System.out.println( "publicKeyStr=" + keys.get( "publicKeyStr" ) );
System.out.println( "privateKeyStr=" + keys.get( "privateKeyStr" ) );
}
/**
@ -69,14 +74,18 @@ public class RSAUtils {
* @param exponent 指数
* @return
*/
public static RSAPrivateKey getPrivateKey(String modulus, String exponent) {
try {
BigInteger b1 = new BigInteger(modulus);
BigInteger b2 = new BigInteger(exponent);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(b1, b2);
return (RSAPrivateKey) keyFactory.generatePrivate(keySpec);
} catch (Exception e) {
public static RSAPrivateKey getPrivateKey( String modulus, String exponent )
{
try
{
BigInteger b1 = new BigInteger( modulus );
BigInteger b2 = new BigInteger( exponent );
KeyFactory keyFactory = KeyFactory.getInstance( "RSA" );
RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec( b1, b2 );
return ( RSAPrivateKey ) keyFactory.generatePrivate( keySpec );
}
catch ( Exception e )
{
e.printStackTrace();
return null;
}
@ -90,34 +99,40 @@ public class RSAUtils {
* @return
* @throws Exception
*/
public static String encryptByPublicKey(String data, String publicKey) throws Exception {
byte[] dataByte = data.getBytes();
byte[] keyBytes = Base64Utils.decode(publicKey);
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key publicK = keyFactory.generatePublic(x509KeySpec);
public static String encryptByPublicKey( String data, String publicKey )
throws Exception
{
byte[] dataByte = data.getBytes();
byte[] keyBytes = Base64Utils.decode( publicKey );
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec( keyBytes );
KeyFactory keyFactory = KeyFactory.getInstance( KEY_ALGORITHM );
Key publicK = keyFactory.generatePublic( x509KeySpec );
// 对数据加密
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.ENCRYPT_MODE, publicK);
int inputLen = dataByte.length;
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offSet = 0;
byte[] cache;
int i = 0;
Cipher cipher = Cipher.getInstance( "RSA/ECB/PKCS1Padding" );
cipher.init( Cipher.ENCRYPT_MODE, publicK );
int inputLen = dataByte.length;
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offSet = 0;
byte[] cache;
int i = 0;
// 对数据分段加密
while (inputLen - offSet > 0) {
if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
cache = cipher.doFinal(dataByte, offSet, MAX_ENCRYPT_BLOCK);
} else {
cache = cipher.doFinal(dataByte, offSet, inputLen - offSet);
while ( inputLen - offSet > 0 )
{
if ( inputLen - offSet > MAX_ENCRYPT_BLOCK )
{
cache = cipher.doFinal( dataByte, offSet, MAX_ENCRYPT_BLOCK );
}
out.write(cache, 0, cache.length);
else
{
cache = cipher.doFinal( dataByte, offSet, inputLen - offSet );
}
out.write( cache, 0, cache.length );
i++;
offSet = i * MAX_ENCRYPT_BLOCK;
}
byte[] encryptedData = out.toByteArray();
out.close();
return Base64Utils.encode(encryptedData);
return Base64Utils.encode( encryptedData );
}
/**
@ -128,42 +143,50 @@ public class RSAUtils {
* @return
* @throws Exception
*/
public static String decryptByPrivateKey(String privateKey, String data) throws Exception {
byte[] encryptedData = Base64Utils.decode(data);
byte[] keyBytes = Base64Utils.decode(privateKey);
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
public static String decryptByPrivateKey( String privateKey, String data )
throws Exception
{
byte[] encryptedData = Base64Utils.decode( data );
byte[] keyBytes = Base64Utils.decode( privateKey );
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec( keyBytes );
KeyFactory keyFactory = KeyFactory.getInstance( KEY_ALGORITHM );
Key privateK = keyFactory.generatePrivate( pkcs8KeySpec );
// Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
Cipher cipher = Cipher.getInstance( "RSA/ECB/PKCS1Padding" );
cipher.init(Cipher.DECRYPT_MODE, privateK);
int inputLen = encryptedData.length;
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offSet = 0;
byte[] cache;
int i = 0;
cipher.init( Cipher.DECRYPT_MODE, privateK );
int inputLen = encryptedData.length;
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offSet = 0;
byte[] cache;
int i = 0;
// 对数据分段解密
while (inputLen - offSet > 0) {
if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK);
} else {
cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);
while ( inputLen - offSet > 0 )
{
if ( inputLen - offSet > MAX_DECRYPT_BLOCK )
{
cache = cipher.doFinal( encryptedData, offSet, MAX_DECRYPT_BLOCK );
}
out.write(cache, 0, cache.length);
else
{
cache = cipher.doFinal( encryptedData, offSet, inputLen - offSet );
}
out.write( cache, 0, cache.length );
i++;
offSet = i * MAX_DECRYPT_BLOCK;
}
byte[] decryptedData = out.toByteArray();
out.close();
return new String(decryptedData);
return new String( decryptedData );
}
public static String getPrivateKeyStr(PrivateKey privateKey) {
return Base64Utils.encode(privateKey.getEncoded());
public static String getPrivateKeyStr( PrivateKey privateKey )
{
return Base64Utils.encode( privateKey.getEncoded() );
}
public static String getPublicKeyStr(PublicKey publicKey) {
return Base64Utils.encode(publicKey.getEncoded());
public static String getPublicKeyStr( PublicKey publicKey )
{
return Base64Utils.encode( publicKey.getEncoded() );
}
}