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 config 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 = { 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) => { return HmacMD5(p, '7NEkojNzfkk=').toString(); }; export const enD = (rk, str) => { const enc = des.des(rk, str, 1, 0, null, 1); return Base64.stringify(Latin1.parse(enc)); }; export const dnD = (rk, str) => { const s = Latin1.stringify(Base64.parse(str)); const d = des.des(rk, s, 0, 0, null, 1); return d; }; export const enP = (rk, vk, t) => { const enc = des.des(vk, rk + t, 1, 0, null, 1); return Base64.stringify(Latin1.parse(enc)); }; export const dnP = (vk, str) => { const s = Latin1.stringify(Base64.parse(str)); const p = des.des(vk, s, 0, 0, null, 1); return p; }; export const enC = (rk, vk, m) => { 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 = {}; // 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 = config.app.vk; const pwds = enP(rk, vk, t); const tenantInfo = { tid: 3, }; let userInfo = { cust_id: 1, cust_name: 'test', }; // 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 = config.app.aseqId; headers.nc = config.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> => { 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, '')) { const drk = dnP(config.app.vk, headers.pwds ?? '').substring(0, 8); const dm = dnD(drk, data); const dc = enC(drk, config.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 }); } };