/** * 复制文本到剪贴板 * @param {string} text 需要复制的文本 * @returns {Promise} 是否复制成功 */ export function copyToClipboard(text) { // 现代浏览器方案 (推荐) if (navigator.clipboard && window.isSecureContext) { return navigator.clipboard.writeText(text) .then(() => true) .catch(() => false); } // 传统浏览器兼容方案 return new Promise((resolve) => { try { // 创建临时文本域 const textarea = document.createElement('textarea'); textarea.value = text; textarea.style.position = 'fixed'; // 防止滚动 textarea.style.opacity = '0'; // 透明化 document.body.appendChild(textarea); // 选中内容 (兼容iOS) if (navigator.userAgent.match(/ipad|ipod|iphone/i)) { const range = document.createRange(); range.selectNodeContents(textarea); const selection = window.getSelection(); selection.removeAllRanges(); selection.addRange(range); textarea.setSelectionRange(0, 999999); } else { textarea.select(); } // 执行复制命令 const success = document.execCommand('copy'); document.body.removeChild(textarea); resolve(success); } catch (err) { resolve(false); } }); } export async function copy(value) { const success = await copyToClipboard(value); if (success) { uni.showToast({ //提示 title: '复制成功' }) } else { uni.showToast({ //提示 title: '复制失败', }) } } /** * 通用数据脱敏函数 * @param {string} str 原始字符串 * @param {number} start 脱敏起始位置(从0开始) * @param {number} end 脱敏结束位置(不包含) * @param {string} mask 替换字符(默认*) * @returns {string} 脱敏后的字符串 */ export function dataMasking(str, start = 0, end = 0, mask = '*') { if (!str || typeof str !== 'string') return str if (start >= end) return str const head = str.slice(0, start) const tail = str.slice(end) const masked = mask.repeat(end - start) return head + masked + tail } // 常用预定义规则 export const MaskRules = { // 手机号脱敏(显示前3后4) mobile: (str) => dataMasking(str, 3, 7), // 身份证号脱敏(显示前6后4) idCard: (str) => { if (str.length === 18) return dataMasking(str, 6, 14) if (str.length === 15) return dataMasking(str, 6, 12) return str }, // 银行卡号脱敏(显示前6后4) bankCard: (str) => dataMasking(str, 6, str.length - 4), // 姓名脱敏(张三 → 张*,欧阳修 → 欧**) name: (str) => { if (str.length <= 1) return str return dataMasking(str, 1, str.length - 1) } } // 使用示例 const sensitiveData = { mobile: '13812345678', idCard: '110101199003077654', bankCard: '6225880136745321', name: '张三丰' } // 脱敏处理 const maskedData = { mobile: MaskRules.mobile(sensitiveData.mobile), // 138****5678 idCard: MaskRules.idCard(sensitiveData.idCard), // 110101********7654 bankCard: MaskRules.bankCard(sensitiveData.bankCard), // 622588******5321 name: MaskRules.name(sensitiveData.name) // 张*丰 } /** * 对象转查询字符串 * @param {object} params - 输入对象 * @param {boolean} [encode=true] - 是否进行URL编码 * @returns {string} 转换后的字符串 */ export function toQueryString(params, encode = true) { const processValue = (value) => { if (value === null || value === undefined) return '' if (Array.isArray(value)) return value.join(',') if (typeof value === 'object') return JSON.stringify(value) return String(value) } return Object.entries(params) .filter(([_, value]) => value !== null && value !== undefined) .map(([key, value]) => { const processed = processValue(value) return encode ? `${encodeURIComponent(key)}=${encodeURIComponent(processed)}` : `${key}=${processed}` }) .join('&') } /** * 构造树型结构数据 * @param {*} data 数据源 * @param {*} id id字段 默认 'id' * @param {*} parentId 父节点字段 默认 'parentId' * @param {*} children 孩子节点字段 默认 'children' * @param {*} rootId 根Id 默认 0 */ export function handleTree(data, id = 'id', parentId = 'parentId', children = 'children', rootId = 0) { rootId = rootId || Math.min.apply(Math, data.map(item => { return item[parentId] })) || 0 //对源数据深度克隆 const cloneData = JSON.parse(JSON.stringify(data)) //循环所有项 const treeData = cloneData.filter(father => { let branchArr = cloneData.filter(child => { //返回每一项的子级数组 return father[id] === child[parentId] }); branchArr.length > 0 ? father.children = branchArr : ''; //返回第一层 return father[parentId] === rootId; }); return treeData !== '' ? treeData : data; } export function reNameKeys(data=[]) { return data.map(item => { const newItem = { name: item.label, id: item.value, type: item.children ? 0 : 1 }; if (item.children && Array.isArray(item.children)) { newItem.children = reNameKeys(item.children); } return newItem; }); } export function reTextKeys(data = []) { return data.map(item => { const newItem = { text: item.label, value: item.value, type: item.children ? 0 : 1, selected: item.selected || false, }; if (item.children && Array.isArray(item.children)) { newItem.children = reTextKeys(item.children); } return newItem; }); }