345 lines
11 KiB
Plaintext
345 lines
11 KiB
Plaintext
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()
|
||
}
|
||
} |