You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
434 lines
15 KiB
434 lines
15 KiB
import { HmacMD5 } from 'crypto-js'; |
|
import Base64 from 'crypto-js/enc-base64'; |
|
import Latin1 from 'crypto-js/enc-latin1'; |
|
import md5 from 'md5'; |
|
import { AxiosResponse } from 'axios'; |
|
import * as des from './des'; |
|
import NetworkError from './error'; |
|
import { toNumber, toString, startsWith, isString, isNumber } from 'lodash-es'; |
|
import { NetworkTypeEnum } from '@/constants/network'; |
|
import appConfig from '../config'; |
|
|
|
// import NetworkError from './error' |
|
// import { storeToRefs, useTenantStore, useUserStore, useAppStore, start } from '../index'; |
|
// import { isMobile, getBetPlatform } from '@star/utils'; |
|
// import { langToNum } from '@star/languages'; |
|
|
|
// 请求到的数据返回 |
|
export type NetworkResponse<T> = { |
|
type: NetworkTypeEnum; |
|
data: T; |
|
}; |
|
|
|
export const getBetPlatform = (isReturnIndex = false) => { |
|
// 5=PC; 7=HOMESCREEN_IOS; 6=HOMESCREEN_ANDROID; 4=H5_IOS 3=IOS 2=H5_ANDROID; 1=ANDROID 8=马甲包 |
|
return 'H5_IOS'; |
|
// const platform = new URLSearchParams(window.location.search).get('platform'); |
|
// if (platform) { |
|
// return platform?.includes('IOS') ? 'IOS' : platform?.includes('ANDROID') ? 'ANDROID' : ''; |
|
// } |
|
// if (isAppMJB()) { |
|
// return 'APPS_ANDROID'; |
|
// } |
|
// if (isPWA()) { |
|
// if (isIOS()) { |
|
// return isReturnIndex ? 4 : 'HS_IOS'; |
|
// } else { |
|
// return isReturnIndex ? 2 : 'HS_ANDROID'; |
|
// } |
|
// } |
|
// if (isAndroid()) { |
|
// if (BASE_CONFIG.appVersion > 0) { |
|
// return isReturnIndex ? 1 : 'ANDROID'; |
|
// } else { |
|
// return isReturnIndex ? 2 : 'H5_ANDROID'; |
|
// } |
|
// } |
|
// if (isIOS()) { |
|
// if (BASE_CONFIG.appVersion > 0) { |
|
// return isReturnIndex ? 3 : 'IOS'; |
|
// } else { |
|
// return isReturnIndex ? 4 : 'H5_IOS'; |
|
// } |
|
// } |
|
// return isReturnIndex ? 5 : 'PC'; |
|
}; |
|
|
|
const uuid = (len: number, radix: number) => { |
|
const chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split(''); |
|
const uuid: any[] = []; |
|
radix = radix || chars.length; |
|
|
|
if (len) { |
|
// Compact form |
|
for (let i = 0; i < len; i++) uuid[i] = chars[0 | (Math.random() * radix)]; |
|
} else { |
|
// rfc4122, version 4 form |
|
/* eslint-disable */ |
|
let r; |
|
|
|
// rfc4122 requires these characters |
|
uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-'; |
|
uuid[14] = '4'; |
|
|
|
// Fill in random data. At i==19 set the high bits of clock sequence as |
|
// per rfc4122, sec. 4.1.5 |
|
for (let i = 0; i < 36; i++) { |
|
if (!uuid[i]) { |
|
r = 0 | (Math.random() * 16); |
|
uuid[i] = chars[i == 19 ? (r & 0x3) | 0x8 : r]; |
|
} |
|
} |
|
/* eslint-enable */ |
|
} |
|
return uuid.join(''); |
|
}; |
|
|
|
// 格式化要发送的数据 |
|
export const formatSendData = (data: any, type: number = 0) => { |
|
// url code |
|
if (type === 0) { |
|
const arr: any[] = []; |
|
for (const k in data) { |
|
const v = data[k]; |
|
if (v instanceof Array) { |
|
for (const subK in v) { |
|
arr.push(`${k}[]=${v[subK]}`); |
|
} |
|
} else { |
|
arr.push(`${k}=${data[k]}`); |
|
} |
|
} |
|
return arr.join('&'); |
|
} else if (type === 2) { |
|
return data.join('/'); |
|
} |
|
// json |
|
return JSON.stringify(data); |
|
}; |
|
|
|
export const getP = (p: any) => { |
|
return HmacMD5(p, '7NEkojNzfkk=').toString(); |
|
}; |
|
|
|
export const enD = (rk: string, str: string) => { |
|
const enc = des.des(rk, str, 1, 0, null, 1); |
|
return Base64.stringify(Latin1.parse(enc)); |
|
}; |
|
|
|
export const dnD = (rk: string, str: string) => { |
|
const s = Latin1.stringify(Base64.parse(str)); |
|
const d = des.des(rk, s, 0, 0, null, 1); |
|
return d; |
|
}; |
|
|
|
export const enP = (rk: string, vk: string, t: number) => { |
|
const enc = des.des(vk, rk + t, 1, 0, null, 1); |
|
return Base64.stringify(Latin1.parse(enc)); |
|
}; |
|
|
|
export const dnP = (vk: string, str: string) => { |
|
const s = Latin1.stringify(Base64.parse(str)); |
|
const p = des.des(vk, s, 0, 0, null, 1); |
|
return p; |
|
}; |
|
|
|
export const enC = (rk: string, vk: string, m: string) => { |
|
const enc = HmacMD5(m + rk, vk); |
|
return Base64.stringify(enc); |
|
}; |
|
|
|
export const getRequestKey = (cmdId: number, data: any) => { |
|
return `${cmdId}&${data ? md5(JSON.stringify(data)) : ''}`; |
|
}; |
|
|
|
// 加工请求数据 |
|
export const transformRequest = (config: any) => { |
|
const { headerType = 2, paramType = 0, cmdId, tid, ...reset } = config.headers; |
|
const headers: Record<string, any> = {}; |
|
// const { tenantInfo } = storeToRefs(useTenantStore()); |
|
// const { userInfo } = storeToRefs(useUserStore()); |
|
// const { language } = storeToRefs(useAppStore()); |
|
const t = new Date().getTime(); |
|
const rk = md5(toString(Math.random() + t)).substring(0, 8); |
|
const vk = appConfig.app.vk as string; |
|
const pwds = enP(rk, vk, t); |
|
|
|
const tenantInfo = { |
|
tid: 3, |
|
}; |
|
let userInfo = { |
|
cust_id: '', |
|
cust_name: '', |
|
access_token: '' |
|
}; |
|
|
|
// if (['17', '3310052', '310111', '310122', '310400', '4', '402', '401', '310635'].includes(cmdId)) { |
|
// const publicParams = { |
|
// tid: tid ?? tenantInfo.value?.tid ?? '', |
|
// cust_id: (config.data?.cust_id === 0 ? '0' : '') || userInfo?.value?.cust_id || '', |
|
// cust_name: (config.data?.cust_name === 0 ? '0' : config.data?.cust_name) || userInfo?.value?.cust_name || '', |
|
// oper_code: (config.data?.cust_id === 0 ? '0' : '') || userInfo?.value?.cust_id || '', |
|
// oper_name: (config.data?.cust_name === 0 ? '0' : config.data?.cust_name) || userInfo?.value?.cust_name || '', |
|
// }; |
|
// const localData = localStorage.getItem('publicData') || ''; |
|
// const publicData = localData ? JSON.parse(localData) : {}; |
|
// if (['17', '3310052', '310111', '310122'].includes(cmdId)) { |
|
// if (['4', '402', '401'].includes(cmdId)) { |
|
// publicParams.tid = publicParams?.tid.toString(); |
|
// publicData.client_type = publicData?.client_type.toString(); |
|
// publicData.oper_class_type = publicData?.oper_class_type.toString(); |
|
// publicData.oper_source_type = publicData?.oper_source_type.toString(); |
|
// publicData.mark = publicData?.mark.toString(); |
|
// // publicData.ori_value = ""; |
|
// // publicData.new_value = ""; |
|
// // publicData.trans_type = "101"; |
|
// // publicData.busi_type = "206"; |
|
// // publicData.oper_method = "11"; |
|
// } |
|
// |
|
// Object.assign(config.data, publicParams, publicData); |
|
// } else if (['310400'].includes(cmdId)) { |
|
// console.log('publicParams', publicParams, publicData); |
|
// config.data.memberOperInfoVo = { |
|
// ...publicParams, |
|
// ...publicData, |
|
// ori_value: '', |
|
// new_value: '', |
|
// oper_method: 1, |
|
// trans_type: 105, |
|
// busi_type: 222, |
|
// }; |
|
// } else if (['310635', '4', '402', '401'].includes(cmdId)) { |
|
// config.data.trans_type = '101'; |
|
// config.data.client_type = publicData.client_type; |
|
// config.data.browser_brand = publicData.browser_brand; |
|
// config.data.os_name = publicData.os_name; |
|
// config.data.os_version = publicData.os_version; |
|
// config.data.device_platform = publicData.device_platform; |
|
// config.data.device_model = publicData.device_model; |
|
// config.data.device_number = publicData.device_number; |
|
// config.data.device_fingerprint = publicData.device_fingerprint; |
|
// } |
|
// |
|
// console.log('config.data', config.data); |
|
// } |
|
|
|
const sendStr = enD(rk, formatSendData(config.data, toNumber(paramType))); |
|
const sendDateStr = enD(rk, t.toString()); |
|
const checkOr = enC(rk, vk, sendDateStr); |
|
|
|
headers.cmdId = cmdId; |
|
headers.aseqId = appConfig.app.aseqId; |
|
headers.nc = appConfig.app.nc; |
|
headers.tid = tid ?? tenantInfo.tid ?? ''; |
|
// 试玩游戏cust_id=0 header需要保持一致 |
|
headers.custId = (config.data?.cust_id === 0 ? '0' : '') || userInfo?.cust_id || ''; |
|
headers.reqId = uuid(32, 16); |
|
// headers.isMobileOpen = isMobile() ? '1' : '0'; |
|
headers.isMobileOpen = '1'; |
|
// headers.languageNum = langToNum(language.value); |
|
headers.languageNum = 0; |
|
headers.project = 'tiyu-app'; |
|
headers.platform = getBetPlatform(); // 哪端 |
|
headers.checkOr = checkOr; |
|
headers.pwds = pwds; |
|
headers.datetime = t; |
|
headers.tbc = md5(t + 'fT6phq0wkOPRlAoyToidAnkogUV7tBBD'); |
|
headers.reqKey = getRequestKey(cmdId, config.data); // 每一个接口请求的唯一key,前端用 |
|
|
|
if (toNumber(headerType) === 1) { |
|
const grantType = 'password'; |
|
const scope = 'read write'; |
|
const signature = `react_clientgrant_type=${grantType}scope=${scope}cmd_id=${cmdId}react`; |
|
headers.signature = md5(signature); |
|
} else if (toNumber(headerType) === 2) { |
|
const authorization = `Bearer ${userInfo?.access_token || ''}`; |
|
const signature = `react_clientauthorization=${authorization}cmd_id=${cmdId}react`; |
|
headers.authorization = authorization; |
|
headers.signature = md5(signature); |
|
} else if (toNumber(headerType) === 3) { |
|
const grantType = 'refresh_token'; |
|
const scope = ''; |
|
const signature = `react_clientgrant_type=${grantType}scope=${scope}cmd_id=${cmdId}react`; |
|
headers.signature = md5(signature); |
|
} |
|
|
|
// console.log(headers, cmdId, '<------ request headers'); |
|
// localStorage.getItem('SHOW_DATA') && |
|
// console.error(cmdId, '最终请求参数', formatSendData(config.data, toNumber(paramType))); // 查看最终请求参数 |
|
console.log(cmdId, 'request data --->', config.data); |
|
return { |
|
headers: { ...reset, ...headers }, |
|
data: sendStr, |
|
}; |
|
}; |
|
|
|
// 解释响应数据 |
|
export const parseResponse = (response: AxiosResponse): Promise<NetworkResponse<any>> => { |
|
try { |
|
const { headers, data } = response; |
|
const reqHeaders = response.config?.headers || {}; |
|
// if (reqHeaders.cmdId == 310122) { |
|
// console.log(data, reqHeaders.cmdId, '<<<<<<<<<<<<<<<<<<<<<<<<<< parseResponse data'); |
|
// } |
|
if (isString(data) && data.length > 0 && !startsWith(data, '<html>')) { |
|
// 检查 headers 是否存在必要的属性 |
|
if (!headers || !headers.pwds || !headers.datetime) { |
|
console.error('Response headers missing required fields:', headers); |
|
throw new NetworkError({ |
|
key: '', |
|
tag: 'Network error 0', |
|
info: '响应头缺少必要字段', |
|
origin: '', |
|
cmd: reqHeaders.cmdId, |
|
}); |
|
} |
|
|
|
const drk = dnP(appConfig.app.vk, headers.pwds).substring(0, 8); |
|
const dm = dnD(drk, data); |
|
const dc = enC(drk, appConfig.app.vk, enD(drk, toString(headers.datetime))); |
|
// if (reqHeaders.cmdId == 310122) { |
|
// console.log(dm, JSON.parse(dm), reqHeaders.cmdId); |
|
// } |
|
// localStorage.getItem('SHOW_DATA') && |
|
// console.error(reqHeaders.cmdId, dm ? JSON.parse(dm) : dm); // 查看请求返回的数据 |
|
if (!dm) { |
|
throw new NetworkError({ |
|
key: '', |
|
tag: 'Network error 1', |
|
info: '数据为空', |
|
origin: '', |
|
cmd: reqHeaders.cmdId, |
|
}); |
|
} |
|
if (dc !== headers.checkor) { |
|
throw new NetworkError({ |
|
key: '', |
|
tag: 'Network error 2', |
|
info: '返回数据异常', |
|
origin: '', |
|
cmd: reqHeaders.cmdId, |
|
}); |
|
} |
|
|
|
const resData: any = JSON.parse(dm); |
|
console.log( |
|
JSON.parse(JSON.stringify(resData)), |
|
reqHeaders.cmdId, |
|
'<<<<<<<<<<<<<<<<<<<<<<<<<< parseResponse resData' |
|
); |
|
if (resData) { |
|
if (resData.exLevel) { |
|
// 接口请求的错误处理 |
|
let err: any; |
|
// 预存奖励领取的时候 返回'0'提示 |
|
if ([724209].includes(+reqHeaders.cmdId)) { |
|
throw { |
|
key: '', |
|
tag: 'Network error 3', |
|
info: resData.exMessage, |
|
origin: resData, |
|
cmd: reqHeaders.cmdId, |
|
code: resData.exCode, |
|
}; |
|
} else { |
|
err = new NetworkError({ |
|
key: '', |
|
tag: 'Network error 3', |
|
info: resData.exMessage, |
|
origin: resData, |
|
cmd: reqHeaders.cmdId, |
|
code: resData.exCode, |
|
}); |
|
} |
|
// 版本号不对,强制更新 |
|
if (err.code === 1108) { |
|
err.update = true; |
|
} else if ([1200, 1201, 1109, 1112, 1202, 1007].includes(+err.code)) { |
|
// 1200 refresh_token错误 |
|
// 1201 access_token错误 |
|
// 1112 IP限制 |
|
err.logout = true; // 退出登录 |
|
err.tag = 'Network error 4'; |
|
err.logoutMessage = '返回异常'; |
|
} |
|
throw err; |
|
} else if (resData.error) { |
|
throw new NetworkError({ |
|
key: '', |
|
tag: 'Network error 5', |
|
info: resData.error_description, |
|
origin: resData, |
|
cmd: reqHeaders.cmdId, |
|
code: resData.exCode, |
|
}); |
|
} else if (resData.response_code === '0') { |
|
// 回收第三方金额 没有的的时候 也是返回'0' |
|
// 预存奖励领取的时候 返回'0'提示 |
|
if ([3911381, 724209].includes(+reqHeaders.cmdId)) { |
|
resData.response_code = '1'; |
|
} else { |
|
throw new NetworkError({ |
|
key: '', |
|
tag: 'Network error 8', |
|
info: resData.msg || '操作失败', |
|
origin: resData, |
|
cmd: reqHeaders.cmdId, |
|
code: resData.exCode, |
|
}); |
|
} |
|
} |
|
} else { |
|
if (!isNumber(toNumber(resData))) { |
|
throw new NetworkError({ |
|
key: '', |
|
tag: 'Network error 1', |
|
info: '数据为空', |
|
origin: '', |
|
cmd: reqHeaders.cmdId, |
|
}); |
|
} |
|
} |
|
return Promise.resolve({ type: NetworkTypeEnum.SUCCESS, data: resData }); |
|
} else { |
|
localStorage.getItem('SHOW_DATA') && console.error(reqHeaders.cmdId, data); // 查看请求返回的原始数据 |
|
throw new NetworkError({ |
|
key: '', |
|
tag: 'Network error 7', |
|
info: '请求没有返回任何数据', |
|
// origin: context || response.toString(), |
|
cmd: reqHeaders.cmdId, |
|
code: -1, |
|
}); |
|
} |
|
} catch (e) { |
|
// // 404等错误处理 |
|
// if (typeof context === 'object') { |
|
// errStr = JSON.stringify(context); |
|
// } else { |
|
// const arr = context.match(/title[\s\S]*?title/g); |
|
// if (arr && arr.length !== 0) { |
|
// errStr = arr[0].replace(/title>/g, '').replace(/<\/title/g, ''); |
|
// } |
|
// } |
|
// let logout = false; |
|
// if (errStr.indexOf('invalid_token') !== -1) { |
|
// logout = true; |
|
// } |
|
// // 类似这种错误的时候 跳到登录页 "error":"access_denied" "error":"unauthorized" |
|
// if (errStr.indexOf('access_denied') !== -1 || errStr.indexOf('unauthorized') !== -1) { |
|
// logout = true; |
|
// } |
|
// err = new NetworkError({ |
|
// key: key, |
|
// tag: 'Network error 6', |
|
// info: errStr, |
|
// origin: context, |
|
// cmd: reqHeaders.cmdId, |
|
// code: -1, |
|
// logout: logout, |
|
// }); |
|
return Promise.reject({ type: NetworkTypeEnum.ERROR, data: e }); |
|
} |
|
};
|
|
|