This commit is contained in:
xiaoxiao 2025-07-31 11:44:46 +08:00
parent 69a4ca17e8
commit 7d5a604665

View File

@ -3,12 +3,15 @@ import { authStore } from './auth';
import { promptAction, router } from '@kit.ArkUI';
import { BusinessError } from '@ohos.base';
import { logger } from './logger';
import { HashMap } from '@kit.ArkTS';
import { buffer, HashMap, util } from '@kit.ArkTS';
import { CryptoJS } from '@ohos/crypto-js'
import { Base64Util } from './Base64Util';
import { ChangeUtil } from './ChangeUtil'
import { bundleManager} from '@kit.AbilityKit';
import { deviceInfo } from '@kit.BasicServicesKit';
import { cryptoFramework } from '@kit.CryptoArchitectureKit';
import { rcp } from '@kit.RemoteCommunicationKit';
interface HdRequestOptions {
baseURL?: string
}
@ -29,11 +32,13 @@ export interface TimestampBean {
class HdHttp {
baseURL: string
osFullName: string = deviceInfo.marketName + '/' + deviceInfo.osFullName;
constructor(options: HdRequestOptions) {
this.baseURL = options.baseURL || ''
}
private request<T>(path: string, method: http.RequestMethod = http.RequestMethod.POST, extraDatas :HashMap<string, string>) {
private request<T>(path: string, method: http.RequestMethod = http.RequestMethod.POST,
extraDatas: HashMap<string, string>) {
const httpInstance = http.createHttp()
const options: http.HttpRequestOptions = {
@ -67,27 +72,42 @@ class HdHttp {
httpInstance.destroy()
})
}
private requestObject<T>(path: string, method: http.RequestMethod = http.RequestMethod.POST, extraDatas :HashMap<string, Object>) {
private requestObject<T>(path: string, method: http.RequestMethod = http.RequestMethod.POST,
extraDatas: HashMap<string, Object>) {
const httpInstance = http.createHttp()
// 1. 拼接参数
let signStr = this.concatParams(extraDatas);
console.info('拼接signStr=',signStr)
// 2. 字符清理
signStr = cleanString(signStr)
console.info('异常字符转化后signStr',signStr)
const timestamp = extraDatas.get('timestamp')
const timeStampMd5 = CryptoJS.MD5(timestamp.toString()).toString()
console.info('时间戳timeStampStr=',timeStampMd5)
signStr += timeStampMd5
console.info('时间戳+signStr=',signStr)
signStr = String(CryptoJS.MD5(signStr).toString())
console.info('时间戳+signStr的MD5后=',signStr)
signStr = this.safeUrlBase64Encode(signStr)
.replace(/\+/g, '-')
.replace(/\//g, '_')
.replace(/=+$/, '')
console.info('时间戳+signStr的MD5后的base64=',signStr)
const options: http.HttpRequestOptions = {
method: http.RequestMethod.POST,
// 可选默认为60s
connectTimeout: 60000,
// 可选默认为60s
readTimeout: 60000,
// 开发者根据自身业务需要添加header字段
header: {
'Content-Type': 'application/json',
'sign':this.getSignO(extraDatas),
'sign': signStr,
'User-Agent': this.osFullName
},
extraData: ChangeUtil.map2JsonO(extraDatas)
}
let fullUrl = this.baseURL + path
return httpInstance.request(fullUrl, options).then((res) => {
logger.info('Response param' + JSON.stringify(extraDatas))
logger.info('Response fullUrl:' + fullUrl + res.result);
@ -141,9 +161,6 @@ class HdHttp {
})
}
get<T>(url: string, data?: Object): Promise<HdResponse<T>> {
return this.requestafter<T>(url, http.RequestMethod.GET, data)
}
@ -159,12 +176,15 @@ class HdHttp {
delete<T>(url: string, data?: Object): Promise<HdResponse<T>> {
return this.requestafter<T>(url, http.RequestMethod.DELETE, data)
}
posts<T>(url: string, data: HashMap<string, string>): Promise<HdResponse<T>> {
return this.request<T>(url, http.RequestMethod.POST, data)
}
postO<T>(url: string, data: HashMap<string, Object>): Promise<HdResponse<T>> {
return this.requestObject<T>(url, http.RequestMethod.POST, data)
}
httpReq<T>(url: string, datas: HashMap<string, string>): Promise<HdResponse<T>> {
// 创建httpRequest对象。
let httpRequest = http.createHttp();
@ -248,6 +268,7 @@ class HdHttp {
httpRequest.destroy()
})
}
httpReqSimply<T>(url: string) {
// 创建httpRequest对象。
let httpRequest = http.createHttp();
@ -333,6 +354,91 @@ class HdHttp {
return res.versionName
}
// 安全Base64编码URL安全
safeUrlBase64Encode(input: string): string {
const base64 = new util.Base64Helper();
const encoded = base64.encodeToStringSync(new util.TextEncoder().encode(input));
return encoded.replace(/\+/g, '-')
.replace(/\//g, '_')
.replace(/=/g, '');
}
async md5To32bit(input: string): Promise<string> {
// 空值安全处理
if (!input || input.length === 0) {
return '';
}
try {
// 1. 创建MD5实例
const md = cryptoFramework.createMd('MD5');
// 2. 数据转换严格使用UTF8编码
const dataBlob:DataBlob = {
data: new Uint8Array(buffer.from(input, 'utf-8').buffer)
}
// 3. 更新数据
await md.update(dataBlob);
// 4. 获取摘要
const mdResult = await md.digest();
// 5. 转换为16进制小写字符串
return Array.from(mdResult.data)
.map(byte => byte.toString(16).padStart(2, '0'))
.join('');
} catch (err) {
console.error('MD5加密失败:', err.message);
return '';
}
}
concatParams(params: HashMap<string, Object>): string {
const keys = this.iosStyleSort(Array.from(params.keys())); // 使用新排序
let result = '';
for (const key of keys) {
const value = params.get(key);
if (value === null || value === undefined) {
result += key;
continue;
}
// 严格匹配iOS的JSON处理保留空格仅删除换行
if (typeof value === 'object') {
const jsonStr = JSON.stringify(value)
.replace(/\n/g, '') // 仅删除换行符
.replace(/\\"/g, '"'); // 处理转义引号
result += key + jsonStr;
} else {
result += key + String(value);
}
}
return result;
}
iosStyleSort(keys: string[]): string[] {
return keys.sort((a, b) => {
// 1. 主要排序:忽略大小写和数字值排序
let result = a.localeCompare(b, undefined, {
sensitivity: 'base',
numeric: true
});
// 2. 次要排序:宽度不敏感(全角/半角等效)
if (result === 0) {
const normalize = (str: string) =>
str.normalize('NFKC').replace(/[\uFF00-\uFFEF]/g, '');
result = normalize(a).localeCompare(normalize(b));
}
// 3. 强制确定顺序
return result === 0 ? (a < b ? -1 : 1) : result;
});
}
}
interface DataBlob {
data: Uint8Array;
}
function cleanString(str: string) {
const pattern: RegExp = /[\s\\;":]/g
return str.replace(pattern, (match) => match === ':' ? '=' : '')
}
export const hdHttp = new HdHttp({ baseURL: '' })