(function () { 'use strict'; var PROD_API_BASE = 'https://api.atuchat.com/'; var LOCAL_API_BASE = 'http://127.0.0.1:1100/'; var APP_CODE = 'aslan'; var DEFAULT_ORIGIN = 'ATYOU'; var readyPromise = null; var headers = { authorization: '', 'req-app-intel': 'version=1.0.0;build=1;model=H5;sysVersion=web;channel=Web', 'req-client': 'H5', 'req-imei': 'H5-STATIC', 'req-lang': 'en', 'req-sys-origin': 'origin=ATYOU;originChild=ATYOU', 'req-version': 'V2', 'req-zone': 'Asia/Shanghai', }; function currentParams() { var params = new URLSearchParams(window.location.search || ''); var hash = window.location.hash || ''; if (hash.indexOf('?') >= 0) { new URLSearchParams(hash.split('?').slice(1).join('?')).forEach( function (value, key) { if (!params.has(key)) params.set(key, value); } ); } return params; } function query(name) { return currentParams().get(name); } function normalizeBaseURL(value) { return String(value || '').replace(/\/+$/, ''); } function resolveEnv() { var env = String(query('env') || '') .trim() .toLowerCase(); return env === 'local' || env === 'test' || env === 'dev' ? env : ''; } function baseURL() { var override = query('apiBase') || query('api_base') || query('aslan_api_base') || window.ASLAN_API_BASE_URL || (window.AslanCommonConfig && window.AslanCommonConfig.apiBase); if (override) return normalizeBaseURL(override); return resolveEnv() === 'local' ? normalizeBaseURL(LOCAL_API_BASE) : normalizeBaseURL(PROD_API_BASE); } function buildURL(path, queryData) { var url = new URL( String(path || '').replace(/^\/+/, ''), baseURL() + '/' ); Object.keys(queryData || {}).forEach(function (key) { var value = queryData[key]; if (value === undefined || value === null || value === '') return; url.searchParams.set(key, value); }); return url.toString(); } function normalizeAuthorization(value) { var text = String(value || '').trim(); if (!text) return ''; return /^Bearer\s+/i.test(text) ? text : 'Bearer ' + text; } function splitHeaderPairs(value) { var result = {}; String(value || '') .split(';') .forEach(function (item) { var index = item.indexOf('='); if (index > -1) { result[item.slice(0, index).trim()] = item .slice(index + 1) .trim(); } }); return result; } function putHeader(target, key, value) { if ( value === undefined || value === null || value === '' || target[key] ) { return; } target[key] = String(value); } function normalizeHeaderCandidate(value, depth) { depth = depth || 0; if (depth > 4 || value === null || value === undefined) return {}; if (typeof value === 'string') { var trimmed = value.trim(); if (!trimmed) return {}; if (trimmed.charAt(0) === '{' || trimmed.charAt(0) === '[') { try { return normalizeHeaderCandidate( JSON.parse(trimmed), depth + 1 ); } catch (_) { return {}; } } return { authorization: trimmed }; } if (Array.isArray(value)) { return value.reduce(function (result, item) { return Object.assign( result, normalizeHeaderCandidate(item, depth + 1) ); }, {}); } if (typeof value !== 'object') return {}; var appIntel = splitHeaderPairs( value['Req-App-Intel'] || value['req-app-intel'] ); var sysOrigin = splitHeaderPairs( value['Req-Sys-Origin'] || value['req-sys-origin'] ); var normalized = {}; putHeader( normalized, 'authorization', value.Authorization || value.authorization || value.token || value.accessToken ); putHeader( normalized, 'reqLang', value['Req-Lang'] || value['req-lang'] || value.reqLang || value.lang ); putHeader( normalized, 'appVersion', appIntel.version || value.appVersion || value['App-Version'] ); putHeader( normalized, 'buildVersion', appIntel.build || value.buildVersion ); putHeader(normalized, 'model', appIntel.model || value.model); putHeader(normalized, 'channel', appIntel.channel || value.channel); putHeader( normalized, 'reqImei', appIntel['Req-Imei'] || appIntel.imei || value['Req-Imei'] || value['req-imei'] || value.reqImei ); putHeader( normalized, 'origin', sysOrigin.origin || value.sysOrigin || value.origin ); putHeader( normalized, 'child', sysOrigin.originChild || sysOrigin.child || value.sysOriginChild || value.child ); ['headerInfo', 'headers', 'auth', 'data', 'state'].forEach( function (key) { Object.assign( normalized, normalizeHeaderCandidate(value[key], depth + 1) ); } ); return normalized; } function setHeadersFromApp(rawOrObject) { var data = normalizeHeaderCandidate(rawOrObject || {}); var next = {}; if (data.authorization) { next.authorization = normalizeAuthorization(data.authorization); } if (data.reqLang) next['req-lang'] = data.reqLang; if ( data.appVersion || data.buildVersion || data.model || data.channel ) { next['req-app-intel'] = [ data.appVersion ? 'version=' + data.appVersion : '', data.buildVersion ? 'build=' + data.buildVersion : '', data.model ? 'model=' + data.model : '', data.channel ? 'channel=' + data.channel : '', ] .filter(Boolean) .join(';'); } if (data.reqImei) next['req-imei'] = data.reqImei; if (data.origin) { next['req-sys-origin'] = [ 'origin=' + data.origin, 'originChild=' + (data.child || data.origin), ].join(';'); } headers = Object.assign(headers, next); return headers; } function discoverQueryHeaders() { return { authorization: query('authorization') || query('Authorization') || query('token') || query('accessToken') || query('access_token'), reqLang: query('lang') || query('language') || query('locale'), origin: query('sysOrigin') || query('origin') || DEFAULT_ORIGIN, child: query('sysOriginChild') || query('originChild') || DEFAULT_ORIGIN, channel: query('channel') || query('appChannel'), }; } function readStorageHeaders(storage) { var collected = {}; if (!storage) return collected; [ 'authorization', 'Authorization', 'token', 'accessToken', 'headerInfo', 'headersFromApp', 'appHeaders', 'user', 'userInfo', ].forEach(function (key) { try { Object.assign( collected, normalizeHeaderCandidate(storage.getItem(key)) ); } catch (_) {} }); return collected; } function applyDiscoveredHeaders() { setHeadersFromApp(discoverQueryHeaders()); setHeadersFromApp(window.__APP_HEADERS__); setHeadersFromApp(window.__HEADER_INFO__); setHeadersFromApp(window.headerInfo); try { setHeadersFromApp(readStorageHeaders(window.localStorage)); setHeadersFromApp(readStorageHeaders(window.sessionStorage)); } catch (_) {} } function ensureAslanAppCode() { document.documentElement.dataset.hyAppCode = APP_CODE; var params = currentParams(); if ( params.get('app_code') || params.get('app') || params.get('appCode') || !window.history || !window.history.replaceState ) { return; } var url = new URL(window.location.href); url.searchParams.set('app_code', APP_CODE); window.history.replaceState(null, '', url.toString()); } function isAppEnvironment() { return Boolean( window.app || window.FlutterApp || window.FlutterPageControl || window.webkit ); } function requestAccessOrigin() { return new Promise(function (resolve) { var settled = false; var timeoutId = null; function finish(raw) { if (raw) setHeadersFromApp(raw); if (settled) return; settled = true; if (timeoutId) window.clearTimeout(timeoutId); resolve(raw || null); } window.renderData = finish; window.getIosAccessOriginParam = finish; if (!isAppEnvironment()) { finish(null); return; } // Aslan Flutter 在页面完成后注入 window.app.getAccessOrigin;这里轮询短时间等待,避免首屏请求早于注入而丢登录态。 if ( window.app && typeof window.app.getAccessOrigin === 'function' ) { try { finish(window.app.getAccessOrigin()); return; } catch (_) {} } if ( window.FlutterApp && typeof window.FlutterApp.postMessage === 'function' ) { try { window.FlutterApp.postMessage('requestAccessOrigin'); } catch (_) {} } var attempt = 0; var poll = function () { attempt += 1; if ( window.app && typeof window.app.getAccessOrigin === 'function' ) { try { finish(window.app.getAccessOrigin()); return; } catch (_) {} } if (!settled && attempt < 30) window.setTimeout(poll, 80); }; poll(); timeoutId = window.setTimeout(function () { finish(null); }, 2400); }); } function connectToApp() { if (readyPromise) return readyPromise; ensureAslanAppCode(); applyDiscoveredHeaders(); readyPromise = requestAccessOrigin().then(function () { return { baseURL: baseURL(), headers: Object.assign({}, headers), authenticated: Boolean(headers.authorization), }; }); return readyPromise; } function parseResponse(response) { return response.text().then(function (text) { var payload = text ? JSON.parse(text) : {}; if (!response.ok) { var httpError = new Error( payload.message || payload.errorMsg || response.statusText || 'request_failed' ); httpError.status = response.status; httpError.payload = payload; throw httpError; } if (payload && payload.status === false) { var apiError = new Error( payload.message || payload.errorMsg || payload.error || 'api_request_failed' ); apiError.payload = payload; apiError.code = payload.errorCode || payload.code; throw apiError; } if ( payload && Object.prototype.hasOwnProperty.call(payload, 'body') ) { return payload.body; } if ( payload && Object.prototype.hasOwnProperty.call(payload, 'data') ) { return payload.data; } return payload; }); } function stripAppEncryptedHeaders(target) { // H5 WebView 只复用 App 登录态,不参与 App Dio 加密;带 Req-Atyou 会让网关按密文解码普通 H5 请求。 Object.keys(target || {}).forEach(function (key) { if (String(key).toLowerCase() === 'req-atyou') delete target[key]; }); } function request(path, options) { var opts = options || {}; var body = opts.body; if (body && typeof body === 'object' && !(body instanceof FormData)) { body = JSON.stringify(body); } return connectToApp().then(function () { var requestHeaders = Object.assign({}, headers, opts.headers || {}); stripAppEncryptedHeaders(requestHeaders); if (!requestHeaders.authorization) delete requestHeaders.authorization; if (body) { requestHeaders['content-type'] = requestHeaders['content-type'] || 'application/json'; } return window .fetch(buildURL(path, opts.query), { method: opts.method || 'GET', headers: requestHeaders, body: body, credentials: 'omit', cache: 'no-store', }) .then(parseResponse); }); } function back() { if ( window.FlutterPageControl && window.FlutterPageControl.postMessage ) { window.FlutterPageControl.postMessage('close_page'); return; } if (window.HyAppBridge && window.HyAppBridge.back) { window.HyAppBridge.back(); return; } window.history.back(); } window.AslanCommon = { baseURL: baseURL, buildURL: buildURL, headers: function () { return Object.assign({}, headers); }, connectToApp: connectToApp, setHeadersFromApp: setHeadersFromApp, request: request, get: function (path, queryData) { return request(path, { method: 'GET', query: queryData }); }, post: function (path, body, queryData) { return request(path, { method: 'POST', body: body, query: queryData, }); }, back: back, user: { profile: function () { return request('/user/user-profile/user-id', { method: 'GET' }); }, }, rechargeReward: { status: function () { return request( '/activity/cumulative-recharge/recharge-reward', { method: 'GET', } ); }, claim: function (ruleId) { return request('/activity/cumulative-recharge', { method: 'POST', body: { id: String(ruleId || '') }, }); }, }, }; })();