122 lines
3.1 KiB
JavaScript
122 lines
3.1 KiB
JavaScript
const Sm4Util = require('../../utils/sm4-util');
|
||
|
||
/**
|
||
* 需要加密的字段列表
|
||
*/
|
||
const ENCRYPTED_FIELDS = ['name', 'mobile', 'idCard'];
|
||
|
||
/**
|
||
* 判断数据是否已加密
|
||
* @param {string} value - 待判断的值
|
||
* @param {string} field - 字段名称
|
||
* @returns {boolean} true表示已加密,false表示未加密
|
||
*/
|
||
function isEncrypted(value, field) {
|
||
if (!value || typeof value !== 'string') {
|
||
return false;
|
||
}
|
||
|
||
// 手机号:如果是11位纯数字,则未加密
|
||
if (field === 'mobile') {
|
||
return !/^1\d{10}$/.test(value);
|
||
}
|
||
|
||
// 身份证:如果是15或18位数字(最后一位可能是X),则未加密
|
||
if (field === 'idCard') {
|
||
return !/^(\d{15}|\d{17}[\dXx])$/.test(value);
|
||
}
|
||
|
||
// 姓名:如果是常见的中文/英文姓名格式(2-20个字符),则未加密
|
||
if (field === 'name') {
|
||
// 纯中文姓名(2-10个字符)或纯英文字母姓名(含空格,2-50个字符)
|
||
if (/^[\u4e00-\u9fa5]{2,10}$/.test(value) || /^[a-zA-Z\s]{2,50}$/.test(value)) {
|
||
return false;
|
||
}
|
||
}
|
||
|
||
// 其他情况:如果符合base64格式且长度较长,则认为已加密
|
||
// URL-safe base64 格式:包含字母、数字、-、_
|
||
if (/^[A-Za-z0-9_-]+={0,2}$/.test(value) && value.length >= 20) {
|
||
return true;
|
||
}
|
||
|
||
// 默认认为未加密
|
||
return false;
|
||
}
|
||
|
||
/**
|
||
* 加密订单敏感字段
|
||
* @param {Object} data - 订单数据
|
||
* @returns {Object} 加密后的数据
|
||
*/
|
||
function encryptOrderFields(data) {
|
||
if (!data || typeof data !== 'object') {
|
||
return data;
|
||
}
|
||
|
||
const encryptedData = { ...data };
|
||
|
||
ENCRYPTED_FIELDS.forEach(field => {
|
||
if (encryptedData[field] && typeof encryptedData[field] === 'string' && encryptedData[field].trim() !== '') {
|
||
try {
|
||
encryptedData[field] = Sm4Util.encryptDataForSm3(encryptedData[field]);
|
||
} catch (error) {
|
||
console.error(`加密字段 ${field} 失败:`, error.message);
|
||
}
|
||
}
|
||
});
|
||
|
||
return encryptedData;
|
||
}
|
||
|
||
/**
|
||
* 解密订单敏感字段
|
||
* @param {Object} data - 订单数据
|
||
* @returns {Object} 解密后的数据
|
||
*/
|
||
function decryptOrderFields(data) {
|
||
if (!data || typeof data !== 'object') {
|
||
return data;
|
||
}
|
||
const decryptedData = { ...data };
|
||
|
||
ENCRYPTED_FIELDS.forEach(field => {
|
||
if (decryptedData[field] && typeof decryptedData[field] === 'string' && decryptedData[field].trim() !== '') {
|
||
// 先判断是否已加密,如果未加密则跳过解密
|
||
if (!isEncrypted(decryptedData[field], field)) {
|
||
return; // 跳过此字段
|
||
}
|
||
|
||
try {
|
||
decryptedData[field] = Sm4Util.decryptDataForSm3(decryptedData[field]);
|
||
} catch (error) {
|
||
console.error(`解密字段 ${field} 失败:`, error.message);
|
||
// 解密失败时保留原值
|
||
}
|
||
}
|
||
});
|
||
return decryptedData;
|
||
}
|
||
|
||
/**
|
||
* 批量解密订单列表的敏感字段
|
||
* @param {Array} list - 订单列表
|
||
* @returns {Array} 解密后的订单列表
|
||
*/
|
||
function decryptOrderList(list) {
|
||
if (!Array.isArray(list)) {
|
||
return list;
|
||
}
|
||
|
||
return list.map(item => decryptOrderFields(item));
|
||
}
|
||
|
||
module.exports = {
|
||
encryptOrderFields,
|
||
decryptOrderFields,
|
||
decryptOrderList,
|
||
isEncrypted,
|
||
ENCRYPTED_FIELDS
|
||
};
|
||
|