From 3a961fdf392c12871e77cc90f7f1141f62461850 Mon Sep 17 00:00:00 2001
From: LCJ-MinYa <1049468118@qq.com>
Date: Fri, 10 Oct 2025 17:25:14 +0800
Subject: [PATCH] =?UTF-8?q?feat:=20=E6=95=B0=E6=8D=AE=E5=AE=89=E5=85=A8-?=
=?UTF-8?q?=E5=8A=A0=E5=AF=86=E8=A7=A3=E5=AF=86=E4=B8=8E=E6=8E=A9=E7=A0=81?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/router/modules/demo.ts | 4 +
.../demo/dataSafe/components/editMaskVal.vue | 83 +++++++++++
src/views/demo/dataSafe/index.vue | 135 ++++++++++++++++++
src/views/demo/dataSafe/utils/mockData.js | 19 +++
src/views/demo/dataSafe/utils/paEncrypt.js | 50 +++++++
src/views/demo/dataSafe/utils/textMask.js | 101 +++++++++++++
6 files changed, 392 insertions(+)
create mode 100644 src/views/demo/dataSafe/components/editMaskVal.vue
create mode 100644 src/views/demo/dataSafe/index.vue
create mode 100644 src/views/demo/dataSafe/utils/mockData.js
create mode 100644 src/views/demo/dataSafe/utils/paEncrypt.js
create mode 100644 src/views/demo/dataSafe/utils/textMask.js
diff --git a/src/router/modules/demo.ts b/src/router/modules/demo.ts
index 89ee2be..6ba8c95 100644
--- a/src/router/modules/demo.ts
+++ b/src/router/modules/demo.ts
@@ -122,6 +122,10 @@ const titleArr = [
key: 'chat',
title: '聊天(智能客服)(移动端查看)',
},
+ {
+ key: 'dataSafe',
+ title: '数据安全-加密解密与掩码',
+ },
];
// @/views/demo/**/*.vue
diff --git a/src/views/demo/dataSafe/components/editMaskVal.vue b/src/views/demo/dataSafe/components/editMaskVal.vue
new file mode 100644
index 0000000..4c1ca79
--- /dev/null
+++ b/src/views/demo/dataSafe/components/editMaskVal.vue
@@ -0,0 +1,83 @@
+
+
+
+
diff --git a/src/views/demo/dataSafe/index.vue b/src/views/demo/dataSafe/index.vue
new file mode 100644
index 0000000..47bfc05
--- /dev/null
+++ b/src/views/demo/dataSafe/index.vue
@@ -0,0 +1,135 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 提交
+
+
+
+
+
+
+
+
+
diff --git a/src/views/demo/dataSafe/utils/mockData.js b/src/views/demo/dataSafe/utils/mockData.js
new file mode 100644
index 0000000..6e48023
--- /dev/null
+++ b/src/views/demo/dataSafe/utils/mockData.js
@@ -0,0 +1,19 @@
+/**
+ * 这里模拟后端返回的数据
+ * 需要加密返回
+ */
+import { str2binb } from './paEncrypt';
+
+const result = {
+ name: str2binb('洛子息'),
+ tel: str2binb('18888888888'),
+ cardNo: str2binb('6228480000000000000'),
+ carNo: str2binb('浙A88888'),
+ carVin: str2binb('5YJSA19A7DF109075'),
+ idNo: str2binb('110101199901011234'),
+ // 普通数据
+ age: 18,
+ sex: '男',
+};
+
+export default result;
diff --git a/src/views/demo/dataSafe/utils/paEncrypt.js b/src/views/demo/dataSafe/utils/paEncrypt.js
new file mode 100644
index 0000000..38d0963
--- /dev/null
+++ b/src/views/demo/dataSafe/utils/paEncrypt.js
@@ -0,0 +1,50 @@
+/**
+ * 加解密随便使用的一种(XOR还原),可以自行更换
+ */
+
+//解密
+export function binb2str(para) {
+ if (para == null || para == '') return '';
+ var data = para.split('_');
+ var str = '';
+ var chrsz = 16;
+ var mask = (1 << chrsz) - 1;
+ for (var i = 0; i < data.length * 32; i += chrsz) {
+ var asciiCode = (data[i >> 5] >>> (32 - chrsz - (i % 32))) & mask;
+ if (asciiCode > 0) {
+ str += String.fromCharCode(asciiCode);
+ }
+ }
+ return str;
+}
+
+//加密
+export function str2binb(str) {
+ if (str == null || str == '') return '';
+ var chrsz = 16;
+ var splitStr = '_';
+ var bin = Array();
+ var mask = (1 << chrsz) - 1;
+ for (var i = 0; i < str.length * chrsz; i += chrsz) {
+ bin[i >> 5] |= (str.charCodeAt(i / chrsz) & mask) << (32 - chrsz - (i % 32));
+ }
+ var s = '';
+ for (var i = 0; i < bin.length; i++) {
+ s += splitStr + bin[i];
+ }
+ return s.substring(1);
+}
+
+//业务数据解密
+export function decrypt(data, propNameArray) {
+ propNameArray.forEach((element) => {
+ data[element] = binb2str(data[element]);
+ });
+}
+
+//业务数据加密
+export function encrypt(data, propNameArray) {
+ propNameArray.forEach((element) => {
+ data[element] = str2binb(data[element]);
+ });
+}
diff --git a/src/views/demo/dataSafe/utils/textMask.js b/src/views/demo/dataSafe/utils/textMask.js
new file mode 100644
index 0000000..fd311e8
--- /dev/null
+++ b/src/views/demo/dataSafe/utils/textMask.js
@@ -0,0 +1,101 @@
+/**
+ * 手机号脱敏
+ * @name phoneFilter
+ * @param {*} phone
+ */
+
+export const phoneFilter = (phone) => {
+ if (phone != null) {
+ return phone.replace(/^(.{3}).+(.{4})$/, '$1****$2');
+ }
+};
+
+/**
+ * 身份证号脱敏
+ * @name IdNumberFilter
+ * @param {*} IdNum
+ */
+
+export const IdNumberFilter = (IdNum, sensitiveSwitch = 'OFF') => {
+ if (IdNum != null) {
+ if (IdNum.length <= 8) {
+ return IdNum.replace(/^(.{2}).+(.{2})$/, '$1****$2');
+ } else {
+ if (sensitiveSwitch === 'ON') {
+ return IdNum.replace(/^(.{2}).+(.{2})$/, '$1****$2');
+ } else {
+ return IdNum.replace(/^(.{4}).+(.{4})$/, '$1****$2');
+ }
+ }
+ }
+};
+/**
+ * 车架号脱敏
+ * @name carVinFilter
+ * @param {*} carVin
+ */
+
+export const carVinFilter = (carVin) => {
+ if (carVin != null) {
+ return carVin.replace(/^(.{4}).+(.{4})$/, '$1****$2');
+ }
+};
+/**
+ * 车牌号脱敏
+ * @name carBoardNumFilter
+ * @param {*} carBoardNum
+ */
+
+export const carBoardNumFilter = (carBoardNum, sensitiveSwitch = 'OFF') => {
+ if (carBoardNum != null) {
+ if (sensitiveSwitch === 'ON') {
+ return carBoardNum.replace(/^(.{3}).+(.{1})$/, '$1****$2');
+ } else {
+ return carBoardNum.replace(/^(.{2}).+(.{2})$/, '$1****$2');
+ }
+ }
+};
+/**
+ * 邮箱脱敏
+ * @name emailFilter
+ * @param {*} email
+ */
+
+export const emailFilter = (email) => {
+ if (email != null) {
+ return email.replace(/^(.{3}).+(.{4})$/, '$1****@$2');
+ }
+};
+
+/**
+ * 姓名脱敏
+ * @name nameMask
+ * @param {*} email
+ */
+export const nameMask = (name) => {
+ if (name) {
+ return name.slice(0, 1) + '*'.repeat(name.length - 1);
+ }
+};
+
+export const cardNoMask = (no) => {
+ if (!no) {
+ return '';
+ }
+ if (no.length > 7) {
+ return no.slice(0, 3) + '*'.repeat(no.length - 7) + no.slice(-4);
+ }
+ return '*******';
+};
+
+/**
+ * 银行卡号脱敏
+ * @name cardNoFilter
+ * @param {*} cardNo
+ */
+
+export const cardNoFilter = (cardNo) => {
+ if (cardNo != null) {
+ return cardNo.replace(/^(.{4}).+(.{4})$/, '$1****$2');
+ }
+};