import HashMap from '@ohos.util.HashMap'; import { Base64Util } from './Base64Util'; import { CryptoJS } from '@ohos/crypto-js'; import { logger } from './logger'; import image from '@ohos.multimedia.image'; import fs from '@ohos.file.fs'; import { fileIo } from '@kit.CoreFileKit'; import util from '@ohos.util'; import { i18n } from '@kit.LocalizationKit'; import { connection } from '@kit.NetworkKit'; import http from '@ohos.net.http' import {BasicConstant} from '../constants/BasicConstant' import { componentUtils, router } from '@kit.ArkUI'; import { authStore } from './auth'; import { preferenceStore } from './PreferenceStore'; export class ChangeUtil { /** * 将HashMap转成JsonString * @param map * @returns */ static map2Json(map:HashMap): string { let jsonObject: Record = {}; map.forEach((value, key) => { if(key != undefined && value != undefined){ jsonObject[key] = value; } }) return JSON.stringify(jsonObject); } static getSign(extraDatas1: HashMap, secret: string): string { if(secret!=null) { let keyValueStr: string = ""; let entriesArray: Array = Array.from(extraDatas1.keys()); entriesArray.sort(); let sortedMap:HashMap = new HashMap(); entriesArray.forEach((value: string, index: number) => { sortedMap.set(value,extraDatas1.get(value)); keyValueStr +=value+extraDatas1.get(value) }); keyValueStr = keyValueStr.replace(" ", ""); keyValueStr = keyValueStr + CryptoJS.MD5(secret).toString(); let Md5keyValueStr: string = CryptoJS.MD5(keyValueStr).toString(); let base64Str:string=Base64Util.encodeToStrSync(Md5keyValueStr); return base64Str; } else { return ''; } } static isMobileNum(mobiles:string): boolean { const reg2: RegExp = new RegExp('^(1[3-9])[0-9]{9}$') return reg2.test(mobiles); } static isPassword(password:string): boolean { const reg2: RegExp = new RegExp('^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{6,16}$') return reg2.test(password); } static isEmail(email:string): boolean { const reg2: RegExp = new RegExp('^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$') return reg2.test(email); } static async convertUriToBase64(uri: string): Promise { // 打开文件并读取数据 const file = fileIo.openSync(uri, fileIo.OpenMode.READ_ONLY); const stat = await fileIo.stat(file.fd); const buffer = new ArrayBuffer(stat.size); fileIo.readSync(file.fd, buffer); fileIo.closeSync(file); const buffernew=await ChangeUtil.compression(buffer,"image/jpeg",0.5) // 编码为 Base64 const base64Helper = new util.Base64Helper(); return base64Helper.encodeToStringSync(new Uint8Array(buffernew)); } /** * 压缩图片 * @param buffer 二进制 * @param contentType image/jpeg 保存后的文件格式 * @param compressionRatio 1 就是 100%, 0.5 就是50% * @returns */ static async compression(buffer: ArrayBuffer, contentType: string, compressionRatio: number = 0.5) { // 这里判断 1,是因为压缩的时候传了 100%,也会丢失一点精度,所以直接返回了。 if (compressionRatio == 1) { return buffer } const imageSource: image.ImageSource = image.createImageSource(buffer); const imagePackerApi = image.createImagePacker(); const bf = await imagePackerApi.packing(imageSource, { format: contentType, quality: compressionRatio * 100 }) return bf } static isLetter(char: string): boolean { if (char.length !== 1) return false; const code = char.charCodeAt(0); return (code >= 65 && code <= 90) || (code >= 97 && code <= 122); } static isFirstDigit(str: string): boolean { if (str.length === 0) return false; return i18n.Unicode.isDigit(str.charAt(0)); } //判断是否有网络 static isOnline(): boolean { return connection.hasDefaultNetSync(); } //length转化为数字 static parseLengthToNumber(length: Length): number { if (typeof length === "string") { // 移除单位并转换 const numericPart = parseFloat(length.replace(/[^0-9.]/g, '')); return isNaN(numericPart) ? 0 : numericPart; } return length as number; // 已经是数值类型 } // 将HEX颜色转换为RGBA格式 static hexToRgba (hex: string, alpha: number) : string | ResourceStr { const r = parseInt(hex.slice(1, 3), 16); const g = parseInt(hex.slice(3, 5), 16); const b = parseInt(hex.slice(5, 7), 16); return `rgba(${r}, ${g}, ${b}, ${alpha})`; } static stringIsUndefinedAndNull (string:string | undefined):boolean { if (string == null||string == undefined || string == "null" || string == "" || string == "(null)" || string == 'undefined' || string.length <= 0) { return true } else { return false } } static map2JsonO(map:HashMap) { let jsonObject: Record = {}; map.forEach((value, key) => { if(key != undefined && value != undefined){ jsonObject[key] = value; } }) return jsonObject; } static async getImageBase64(url: string): Promise { // 创建 http 实例 let httpRequest = http.createHttp(); // 发起 GET 请求 let response = await httpRequest.request(url, { method: http.RequestMethod.GET, // 重要:设置 responseType 为 arraybuffer,获取二进制数据 expectDataType: http.HttpDataType.ARRAY_BUFFER }); // 检查响应 if (response.responseCode === 200 && response.result) { // 1. 转成 Uint8Array const buffernew=await ChangeUtil.compression(response.result as ArrayBuffer,"image/jpeg",0.5) // let uint8Arr = new Uint8Array(response.result as ArrayBuffer) const base64Helper = new util.Base64Helper(); return base64Helper.encodeToStringSync(new Uint8Array(buffernew)); // response.result 是 ArrayBuffer // let base64Str = base64.encode(response.result as ArrayBuffer); // // 可选:拼接 data url 前缀 // return "data:image/png;base64," + base64Str; } return ""; } //将第一位移动到最后一位 static moveFirstToEnd(arr: string[]): string[] { if (arr.length <= 1) return arr; const first = arr[0]; // 前移后续元素(从索引1开始) for (let i = 1; i < arr.length; i++) { arr[i - 1] = arr[i]; } arr[arr.length - 1] = first; // 首位移至末尾 return arr; } /** * 将URI或URL数组转换为Base64字符串数组 * @param items - 包含文件URI或网络URL的数组 * @returns Promise - Base64字符串数组 */ static async convertUrisOrUrlsToBase64(items: string[]): Promise { const results: string[] = []; for (const item of items) { try { let arrayBuffer: ArrayBuffer; let mimeType = 'image/jpeg'; // 默认MIME类型 // 处理本地文件URI if (item.startsWith('file://')) {// || !item.includes('://') arrayBuffer = await ChangeUtil.readLocalFile(item); } // 处理网络URL else if (item.startsWith('http://') || item.startsWith('https://') || ChangeUtil.isImageFileByRegex(item)) { arrayBuffer = await ChangeUtil.downloadNetworkResource(item); } // 处理其他类型资源 else { throw new Error(`Unsupported URI scheme: ${item}`); } // 关键优化:添加图片压缩步骤[6,8](@ref) const compressedBuffer = await ChangeUtil.compression( arrayBuffer, mimeType, 0.5 // 压缩质量为50% ); // 转换为Base64 results.push(ChangeUtil.convertToBase64(compressedBuffer)); } catch (err) { console.error(`转换失败: ${JSON.stringify(err)}`); results.push(''); // 失败时返回空字符串 } } return results; } /** * 读取本地文件到ArrayBuffer * @param uri - 文件URI * @returns Promise */ static async readLocalFile(uri: string): Promise { try { // 打开文件 const file = fs.openSync(uri, fs.OpenMode.READ_ONLY); // 获取文件大小 const stat = fs.statSync(file.fd); const size = stat.size; // 创建缓冲区并读取数据 const buffer = new ArrayBuffer(size); fs.readSync(file.fd, buffer); // 关闭文件 fs.closeSync(file); return buffer; } catch (err) { throw new Error(`文件读取失败: ${JSON.stringify(err)}`); } } /** * 下载网络资源到ArrayBuffer * @param url - 资源URL * @returns Promise */ static async downloadNetworkResource(url: string): Promise { return new Promise((resolve, reject) => { const httpRequest = http.createHttp(); httpRequest.request( url, { method: http.RequestMethod.GET }, (err, data) => { httpRequest.destroy(); if (err) { reject(new Error(`网络请求失败: ${JSON.stringify(err)}`)); return; } if (data.responseCode === 200) { resolve(data.result as ArrayBuffer); } else { reject(new Error(`HTTP错误: ${data.responseCode}`)); } } ) }) } static convertToBase64(buffer: ArrayBuffer): string { const helper = new util.Base64Helper(); const uint8Array = new Uint8Array(buffer); return helper.encodeToStringSync(uint8Array); } static isImageFileByRegex(path: string): boolean { const pattern = /\.(jpg|jpeg|png|gif|bmp|webp)$/i; return pattern.test(path); } static getColumnX(id:string):number { const componentInfo = componentUtils.getRectangleById(id) const screenX = componentInfo.screenOffset.x//3.38 return screenX } static getColumnY(id:string):number { const componentInfo = componentUtils.getRectangleById(id) const screenY = componentInfo.screenOffset.y//3.38 return screenY } static getColunmWidth(id:string):number { const componentInfo = componentUtils.getRectangleById(id) const width = componentInfo.size.width//3.38 return width } static getColunmHeight(id:string):number { const componentInfo = componentUtils.getRectangleById(id) const height = componentInfo.size.height//3.38 return height } static formatPrice(priceStr: string): string { let priceInFen = parseFloat(priceStr); let priceInYuan = priceInFen / 100; return `${priceInYuan.toFixed(2)}`; } static formatPrice2(priceStr: string,discount: string): string { let priceInFen = parseFloat(priceStr); let priceInYuan = priceInFen / 100 * parseFloat(discount); return `${priceInYuan.toFixed(2)}`; } static Logout(phone:string) { authStore.delUser(); preferenceStore.clear() preferenceStore.setItemBoolean('isLogin',false) preferenceStore.setItemBoolean('isFirstRun',false) // router.back() router.replaceUrl({ url: 'pages/LoginPage/LoginPage', // 目标url params: { phone:phone } },router.RouterMode.Single) router.clear() } }