293 lines
8.0 KiB
Plaintext
293 lines
8.0 KiB
Plaintext
import dayTs from './Date';
|
||
import fs from '@ohos.file.fs';
|
||
import { BusinessError } from '@ohos.base';
|
||
import { CommonFileTag } from '../config';
|
||
import abilityAccessCtrl, { Permissions } from '@ohos.abilityAccessCtrl';
|
||
import Prompt from '@system.prompt';
|
||
import common from '@ohos.app.ability.common';
|
||
|
||
enum timeType {
|
||
fulltime = 1
|
||
}
|
||
|
||
/**
|
||
* 获取当前时间
|
||
* @param type
|
||
* @returns
|
||
*/
|
||
export function GetCurrentTime(type?: timeType): string {
|
||
if (type === 1) {
|
||
return dayTs().format("YYYYMMDDHHmmss")
|
||
} else {
|
||
return dayTs().format("YYYY-MM-DD HH:mm:ss")
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 是否是指定天数之前
|
||
* @param date
|
||
* @param days
|
||
* @returns
|
||
*/
|
||
export function IsDaysAgo(date: string | number | Date, days: number = 2): boolean {
|
||
const today = dayTs(); // 当前日期
|
||
const target = dayTs(date).format("YYYY-MM-DD HH:mm:ss.SSS"); // 需要判断的日期
|
||
// 计算两个日期之间的差异天数
|
||
const diffDays = today.diff(target, 'day');
|
||
// 如果差异天数大于等于指定天数,则返回 true
|
||
return diffDays >= days;
|
||
}
|
||
|
||
/**
|
||
* 字符串转字节数组
|
||
* @param str
|
||
* @returns
|
||
*/
|
||
export function StringToBytes(str: string): Uint8Array {
|
||
const bytes = new Uint8Array(str.length);
|
||
for (let i = 0; i < str.length; i++) {
|
||
bytes[i] = str.charCodeAt(i);
|
||
}
|
||
return bytes;
|
||
}
|
||
|
||
/**
|
||
* 字符串转ASCII码
|
||
* @param str 需要转换的字符串
|
||
* @returns 返回ASCII码数组
|
||
*/
|
||
export function StringToASCII(str: string): number[] {
|
||
const arr: number[] = [];
|
||
for (let i = 0; i < str.length; i++) {
|
||
arr.push(str.charCodeAt(i));
|
||
}
|
||
return arr;
|
||
}
|
||
|
||
/**
|
||
* 数组转字节
|
||
* @param array 需要转换的数组
|
||
* @returns 返回字节数组
|
||
*/
|
||
export function ArrayToByteArray(array: number[]): Uint8Array {
|
||
const buf = new ArrayBuffer(array.length);
|
||
const view = new Uint8Array(buf);
|
||
for (let i = 0; i < array.length; i++) {
|
||
view[i] = array[i] & 0xFF;
|
||
}
|
||
return view;
|
||
}
|
||
|
||
/**
|
||
* 数字转字节数组
|
||
* @param number 要转换的数字
|
||
* @param len 字节数
|
||
* @returns 返回字节数组
|
||
*/
|
||
export function NumberToByteArray(number: number | string, len: number): number[] {
|
||
let str = Math.floor(Number(number)).toString(2);
|
||
if (str.length > len) {
|
||
console.log('数据长度不对~~');
|
||
return [];
|
||
}
|
||
const byteString = FillZero(str, len);
|
||
|
||
const arrBytes: number[] = [];
|
||
for (let i = byteString.length; i > 0; ) {
|
||
let j = i - 8;
|
||
if (j < 0) {
|
||
j = 0;
|
||
}
|
||
const s = byteString.slice(j, i);
|
||
const v = parseInt(s, 2);
|
||
arrBytes.push(v);
|
||
i -= 8;
|
||
}
|
||
return arrBytes;
|
||
}
|
||
|
||
/*
|
||
* 将字符串填充为指定长度的字符串,前面补0
|
||
* @param str 要填充的字符串或数字
|
||
* @param len 目标长度
|
||
* @return 返回填充后的字符串
|
||
*/
|
||
export function FillZero(str: string | number, len: number): string {
|
||
str = str.toString();
|
||
if (str.length >= len || len <= 0) {
|
||
return str;
|
||
}
|
||
const zeroStr = '0'.repeat(len - str.length);
|
||
return zeroStr + str;
|
||
}
|
||
|
||
/**
|
||
* 将数组按指定大小分块
|
||
* @param arr 原始数组
|
||
* @param size 每块大小(必须 >= 1)
|
||
* @returns 分块后的二维数组
|
||
*/
|
||
export function CutArray<T>(arr: readonly T[], size: number): T[][] {
|
||
if (!Array.isArray(arr) || size < 1) {
|
||
return [];
|
||
}
|
||
|
||
const result: T[][] = [];
|
||
for (let i = 0; i < arr.length; i += size) {
|
||
result.push(arr.slice(i, i + size));
|
||
}
|
||
return result;
|
||
}
|
||
|
||
/**
|
||
* 将GPS坐标从度分格式(DDMM.MMMM)转换为十进制度格式
|
||
* @param ddmm - 度分格式坐标(例如 11630.1234 表示116度30.1234分)
|
||
* @returns 十进制度格式坐标(例如 116.502056666...)
|
||
*/
|
||
export function ConvertDdmmToDecimalDegrees(ddmm: number): number {
|
||
// 提取度数部分:除以100后取整
|
||
const degrees = Math.floor(ddmm / 100);
|
||
// 提取分数部分(包含小数):对100取模
|
||
const minutes = ddmm % 100;
|
||
// 将分数转换为度并相加:1度=60分
|
||
return degrees + minutes / 60;
|
||
}
|
||
|
||
/**
|
||
* 深度克隆对象
|
||
* @param target
|
||
* @returns
|
||
*/
|
||
export function DeepClone<T extends Object>(target: T): T {
|
||
// 如果是对象,且不是原始值null
|
||
if (typeof target === 'object' && target !== null) {
|
||
// 创建容器
|
||
const result: ESObject = Array.isArray(target) ? [] : {};
|
||
const keys = Object.keys(target) as Array<keyof T>; //注解二
|
||
keys.forEach(key => {
|
||
Reflect.set(result, key, DeepClone(Reflect.get(target, key)));
|
||
});
|
||
return result;
|
||
}
|
||
// 如果是原始值,则直接返回
|
||
return target;
|
||
}
|
||
|
||
/*
|
||
* 检查文件或目录是否存在
|
||
* @param path 文件或目录的路径
|
||
* @return 返回一个 Promise,解析为 true 如果存在,否则为 false
|
||
*/
|
||
export function IsExit(path: string): Promise<boolean> {
|
||
return new Promise((resolve, reject) => {
|
||
try {
|
||
let res = fs.accessSync(path);
|
||
if (res) {
|
||
console.info(CommonFileTag, "file exists");
|
||
resolve(true);
|
||
} else {
|
||
console.info(CommonFileTag, "file not exists");
|
||
resolve(false);
|
||
}
|
||
} catch (error) {
|
||
let err: BusinessError = error as BusinessError;
|
||
console.error(CommonFileTag,
|
||
"accessSync failed with error message: " + err.message + ", error code: " + err.code);
|
||
reject(false);
|
||
}
|
||
});
|
||
}
|
||
|
||
/**
|
||
* 创建文件夹
|
||
* @param path 文件夹路径
|
||
* @return 返回一个 Promise,解析为 true 如果创建成功,否则为 false
|
||
*/
|
||
export function CreateDir(path: string): Promise<boolean> {
|
||
return new Promise((resolve, reject) => {
|
||
try {
|
||
fs.mkdirSync(path);
|
||
console.info(CommonFileTag, "Directory created successfully");
|
||
resolve(true);
|
||
} catch (error) {
|
||
let err: BusinessError = error as BusinessError;
|
||
console.error(CommonFileTag, "mkdirSync failed with error message: " + err.message + ", error code: " + err.code);
|
||
reject(false);
|
||
}
|
||
});
|
||
}
|
||
|
||
/*
|
||
* 将秒数转换为灵活的时间格式(HH:MM:SS)
|
||
* @param seconds 要转换的秒数
|
||
* @return 返回格式化后的时间字符串
|
||
*/
|
||
export function FormatTimeFlexible(seconds: number): string {
|
||
if (seconds < 0) {
|
||
throw new Error("秒数不能为负数");
|
||
}
|
||
|
||
const hours = Math.floor(seconds / 3600);
|
||
const minutes = Math.floor((seconds % 3600) / 60);
|
||
const secs = seconds % 60;
|
||
|
||
// 强制使用两位数格式化,确保始终是 HH:MM:SS
|
||
const formattedHours = hours.toString().padStart(2, '0');
|
||
const formattedMinutes = minutes.toString().padStart(2, '0');
|
||
const formattedSeconds = secs.toString().padStart(2, '0');
|
||
|
||
return `${formattedHours}:${formattedMinutes}:${formattedSeconds}`;
|
||
}
|
||
|
||
/**
|
||
* 申请授权
|
||
* @param context 上下文
|
||
* @param permissionList 需要申请的权限列表
|
||
*/
|
||
export function ApplyForAuthorization(context: Context, permissionList: Array<Permissions>) {
|
||
const atManager = abilityAccessCtrl.createAtManager()
|
||
atManager.requestPermissionsFromUser(context, permissionList, (code, result) => {
|
||
if (result.authResults[0] === -1) {
|
||
Prompt.showToast({
|
||
message: '请先授权',
|
||
duration: 3000,
|
||
})
|
||
}
|
||
})
|
||
}
|
||
|
||
/*
|
||
* 使用权限
|
||
* @param context 上下文
|
||
* @return 返回一个 Promise,解析为 true 如果授权成功,否则为 false
|
||
*/
|
||
export async function UseAuth(context: common.UIAbilityContext): Promise<boolean> {
|
||
const permissions: Array<Permissions> = [
|
||
"ohos.permission.SET_TIME",
|
||
"ohos.permission.READ_IMAGEVIDEO",
|
||
"ohos.permission.DISTRIBUTED_DATASYNC",
|
||
"ohos.permission.CONNECTIVITY_INTERNAL",
|
||
"ohos.permission.CAMERA",
|
||
"ohos.permission.READ_MEDIA",
|
||
"ohos.permission.WRITE_MEDIA",
|
||
"ohos.permission.FILE_ACCESS_MANAGER"
|
||
];
|
||
|
||
try {
|
||
const res = await abilityAccessCtrl.createAtManager().requestPermissionsFromUser(context, permissions);
|
||
const grantStatus = res.authResults;
|
||
if (grantStatus.every(status => status === 0)) {
|
||
return true;
|
||
} else {
|
||
Prompt.showToast({
|
||
message: "部分权限未授权,请全部授权,否则无法正常使用",
|
||
})
|
||
return false;
|
||
}
|
||
} catch (err) {
|
||
Prompt.showToast({
|
||
message: "授权出错,请联系开发者或检查权限设置",
|
||
})
|
||
return false;
|
||
}
|
||
} |