From a11bf121f5c936ca227ea774029aefa933acd552 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=A9=AC=E4=B8=89=E7=82=AE?= <15856818120@163.com> Date: Mon, 29 Dec 2025 11:20:31 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8A=A0=E5=AF=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/crypto.js | 76 +++++++++++++++++++++++++ src/views/personManage/Person/config.js | 2 + src/views/system/user/index.vue | 10 +++- 3 files changed, 87 insertions(+), 1 deletion(-) create mode 100644 src/api/crypto.js diff --git a/src/api/crypto.js b/src/api/crypto.js new file mode 100644 index 0000000..de7791e --- /dev/null +++ b/src/api/crypto.js @@ -0,0 +1,76 @@ +import CryptoJS from 'crypto-js' + +/** + * AES 加解密工具类 + */ +class CryptoUtil { + // 默认密钥(生产环境应从配置或接口获取) + static KEY = '0123456789abcdef0123456789abcdef' // 32位密钥 + static IV = '0123456789abcdef' // 16位初始向量 + + /** + * 加密 + * @param {string} data 要加密的数据 + * @param {string} key 密钥(可选) + * @param {string} iv 初始向量(可选) + * @returns {string} 加密后的Base64字符串 + */ + static encrypt(data, key = this.KEY, iv = this.IV) { + try { + const keyHex = CryptoJS.enc.Utf8.parse(key) + const ivHex = CryptoJS.enc.Utf8.parse(iv) + + const encrypted = CryptoJS.AES.encrypt(data, keyHex, { + iv: ivHex, + mode: CryptoJS.mode.CBC, + padding: CryptoJS.pad.Pkcs7 + }) + + return encrypted.toString() + } catch (error) { + console.error('加密失败:', error) + throw new Error('加密失败') + } + } + + /** + * 解密 + * @param {string} encryptedData 加密后的Base64字符串 + * @param {string} key 密钥(可选) + * @param {string} iv 初始向量(可选) + * @returns {string} 解密后的原文 + */ + static decrypt(encryptedData, key = this.KEY, iv = this.IV) { + try { + const keyHex = CryptoJS.enc.Utf8.parse(key) + const ivHex = CryptoJS.enc.Utf8.parse(iv) + + const decrypted = CryptoJS.AES.decrypt(encryptedData, keyHex, { + iv: ivHex, + mode: CryptoJS.mode.CBC, + padding: CryptoJS.pad.Pkcs7 + }) + + return decrypted.toString(CryptoJS.enc.Utf8) + } catch (error) { + console.error('解密失败:', error) + throw new Error('解密失败') + } + } + + /** + * 生成随机密钥 + * @param {number} length 密钥长度(16/24/32对应128/192/256位) + * @returns {string} 随机密钥 + */ + static generateKey(length = 32) { + const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789' + let result = '' + for (let i = 0; i < length; i++) { + result += chars.charAt(Math.floor(Math.random() * chars.length)) + } + return result + } +} + +export default CryptoUtil diff --git a/src/views/personManage/Person/config.js b/src/views/personManage/Person/config.js index 8d557f4..419c127 100644 --- a/src/views/personManage/Person/config.js +++ b/src/views/personManage/Person/config.js @@ -1,4 +1,5 @@ import { reactive } from 'vue' +import CryptoUtil from "../../../api/crypto.js"; // 根据下拉数据构建搜索表单配置 // 注意:这里不直接发请求,只依赖调用方传入的 options,避免在模块顶层使用组合式 API @@ -73,6 +74,7 @@ export const tableColumns = [ { prop: 'phone', label: '电话', + formatter: (row) => (CryptoUtil.decrypt(row.phone)), }, { prop: 'positionName', diff --git a/src/views/system/user/index.vue b/src/views/system/user/index.vue index 1118839..e904150 100644 --- a/src/views/system/user/index.vue +++ b/src/views/system/user/index.vue @@ -62,7 +62,11 @@ - + + +