保存进度

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

View File

@ -1,18 +1,13 @@
/* /**
* @Author: Kane * @Author: Kane
* * @Date: 2025-03-15 21:01:56
* @Date: 2025-03-15 16:41:05 * @LastEditors: Kane
* * @FilePath: /cpicxim-huixiabao/src/main/java/com/cpic/xim/huixiabao/web/controllers/MediCover/MediCoverRequestBody.java
* @LastEditors: Kane * @Description:
* * @
* @FilePath: * @Copyright (c) ${2023} by Kane, All Rights Reserved.
* /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.
*/ */
package com.cpic.xim.huixiabao.web.controllers.MediCover; package com.cpic.xim.huixiabao.web.controllers.MediCover;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
@ -100,7 +95,8 @@ public class MediCoverRequestBody
this.timestamp = timestamp; this.timestamp = timestamp;
} }
@Override public String toString() @Override
public String toString()
{ {
return "MediCoverRequestBody [transId=" + transId + ", format=" + format + ", bizContent=" + bizContent + ", key=" + key + ", timestamp=" + timestamp + "]"; 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 * @Date: 2025-03-15 17:21:50
* @LastEditors: Kane * @LastEditors: Kane
* @FilePath: /cpicxim-huixiabao/src/main/java/com/cpic/xim/huixiabao/web/controllers/MediCover/MediCoverResponse.java * @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; package com.cpic.xim.huixiabao.web.controllers.MediCover;
@ -15,11 +15,11 @@ public class MediCoverResponse
{ {
MediCoverResponse() MediCoverResponse()
{ {
code = "500"; code = "500";
message = "未知失败原因"; message = "未知失败原因";
subMessage = ""; subMessage = "";
result = new MediCoverResultInResponse("", ""); result = new MediCoverResultInResponse( "", "" );
success = false; success = false;
} }
public MediCoverResponse( public MediCoverResponse(
@ -28,27 +28,28 @@ public class MediCoverResponse
String subMessage, String subMessage,
String key, String key,
String content, String content,
Boolean success ) Boolean success
)
{ {
this.code = code; this.code = code;
this.message = message; this.message = message;
this.subMessage = subMessage; this.subMessage = subMessage;
this.result = new MediCoverResultInResponse(key, content); this.result = new MediCoverResultInResponse( key, content );
this.success = success; this.success = success;
} }
@JsonProperty("code") @JsonProperty( "code" )
private String code; private String code;
@JsonProperty("message") @JsonProperty( "message" )
private String message; private String message;
@JsonProperty("subMessage") @JsonProperty( "subMessage" )
private String subMessage; private String subMessage;
@JsonProperty("result") @JsonProperty( "result" )
private MediCoverResultInResponse result; private MediCoverResultInResponse result;
@JsonProperty("success") @JsonProperty( "success" )
private Boolean success; private Boolean success;
} }

View File

@ -1,19 +1,23 @@
/* /**
* @Author: Kane * @Author: Kane
* * @Date: 2025-03-15 21:01:56
* @Date: 2025-03-15 17:29:27
*
* @LastEditors: Kane * @LastEditors: Kane
* * @FilePath: /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
* /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
*
* @Description: * @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; package com.cpic.xim.huixiabao.web.controllers.MediCover;
import com.fasterxml.jackson.annotation.JsonProperty; 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 * @Author: Kane
* * @Date: 2025-03-15 21:01:56
* @Date: 2025-03-15 18:28:17
*
* @LastEditors: Kane * @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 * Copyright (c) ${2023} by Kane, All Rights Reserved.
*
* @Description: 惠厦保 小药箱数据同步对象
* 对应惠厦保理赔规范接口 3.7
* 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; import com.fasterxml.jackson.annotation.JsonProperty;
public class HmbXyxInfo public class HmbXyxInfoItem
{ {
public String getPsnName() public String getPsnName()
{ {
return psnName; return psnName;

View File

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

View File

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