harmony/commons/basic/src/main/ets/utils/ChangeUtil.ets
2025-09-09 13:27:34 +08:00

345 lines
11 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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, string>): string {
let jsonObject: Record<string, Object> = {};
map.forEach((value, key) => {
if(key != undefined && value != undefined){
jsonObject[key] = value;
}
})
return JSON.stringify(jsonObject);
}
static getSign(extraDatas1: HashMap<string, string>, secret: string): string {
if(secret!=null) {
let keyValueStr: string = "";
let entriesArray: Array<string> = Array.from(extraDatas1.keys());
entriesArray.sort();
let sortedMap:HashMap<string, string> = 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<string> {
// 打开文件并读取数据
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 == "<null>" || string == "(null)" || string == 'undefined' || string.length <= 0) {
return true
} else {
return false
}
}
static map2JsonO(map:HashMap<string, Object>) {
let jsonObject: Record<string, Object> = {};
map.forEach((value, key) => {
if(key != undefined && value != undefined){
jsonObject[key] = value;
}
})
return jsonObject;
}
static async getImageBase64(url: string): Promise<string> {
// 创建 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<string[]> - Base64字符串数组
*/
static async convertUrisOrUrlsToBase64(items: string[]): Promise<string[]> {
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<ArrayBuffer>
*/
static async readLocalFile(uri: string): Promise<ArrayBuffer> {
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<ArrayBuffer>
*/
static async downloadNetworkResource(url: string): Promise<ArrayBuffer> {
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()
}
}