From 6cb7132e2259e3049b33cc881e813bcf04f4401b Mon Sep 17 00:00:00 2001 From: zhx Date: Tue, 21 Jul 2026 14:36:20 +0800 Subject: [PATCH] =?UTF-8?q?h5=E7=9B=B8=E5=85=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../GeneralHeader.vue | 292 +++++++++ .../ItemDistribution.vue | 392 +++++++++++ .../admin-center-ui-20260709/MaskLayer.vue | 145 +++++ .../MyAgencyTeams.vue | 522 +++++++++++++++ .../MyBDLeaderTeams.vue | 524 +++++++++++++++ .../admin-center-ui-20260709/MyBDTeams.vue | 519 +++++++++++++++ .../MyRechargeAgency.vue | 320 +++++++++ .../components/historySalary.vue | 172 +++++ backups/admin-center-ui-20260709/index.vue | 609 ++++++++++++++++++ backups/admin-center-ui-20260709/policy.vue | 94 +++ package.json | 3 +- scripts/aslan-webview-sim.mjs | 176 +++++ src/views/PlatformPolicy/PlatformPolicy.vue | 14 +- 13 files changed, 3770 insertions(+), 12 deletions(-) create mode 100644 backups/admin-center-ui-20260709/GeneralHeader.vue create mode 100644 backups/admin-center-ui-20260709/ItemDistribution.vue create mode 100644 backups/admin-center-ui-20260709/MaskLayer.vue create mode 100644 backups/admin-center-ui-20260709/MyAgencyTeams.vue create mode 100644 backups/admin-center-ui-20260709/MyBDLeaderTeams.vue create mode 100644 backups/admin-center-ui-20260709/MyBDTeams.vue create mode 100644 backups/admin-center-ui-20260709/MyRechargeAgency.vue create mode 100644 backups/admin-center-ui-20260709/components/historySalary.vue create mode 100644 backups/admin-center-ui-20260709/index.vue create mode 100644 backups/admin-center-ui-20260709/policy.vue create mode 100644 scripts/aslan-webview-sim.mjs diff --git a/backups/admin-center-ui-20260709/GeneralHeader.vue b/backups/admin-center-ui-20260709/GeneralHeader.vue new file mode 100644 index 0000000..5847dba --- /dev/null +++ b/backups/admin-center-ui-20260709/GeneralHeader.vue @@ -0,0 +1,292 @@ + + + + + diff --git a/backups/admin-center-ui-20260709/ItemDistribution.vue b/backups/admin-center-ui-20260709/ItemDistribution.vue new file mode 100644 index 0000000..2fdf921 --- /dev/null +++ b/backups/admin-center-ui-20260709/ItemDistribution.vue @@ -0,0 +1,392 @@ + + + + + diff --git a/backups/admin-center-ui-20260709/MaskLayer.vue b/backups/admin-center-ui-20260709/MaskLayer.vue new file mode 100644 index 0000000..1ad78d6 --- /dev/null +++ b/backups/admin-center-ui-20260709/MaskLayer.vue @@ -0,0 +1,145 @@ + + + + + diff --git a/backups/admin-center-ui-20260709/MyAgencyTeams.vue b/backups/admin-center-ui-20260709/MyAgencyTeams.vue new file mode 100644 index 0000000..2bce2be --- /dev/null +++ b/backups/admin-center-ui-20260709/MyAgencyTeams.vue @@ -0,0 +1,522 @@ + + + + + diff --git a/backups/admin-center-ui-20260709/MyBDLeaderTeams.vue b/backups/admin-center-ui-20260709/MyBDLeaderTeams.vue new file mode 100644 index 0000000..4e6141e --- /dev/null +++ b/backups/admin-center-ui-20260709/MyBDLeaderTeams.vue @@ -0,0 +1,524 @@ + + + + + diff --git a/backups/admin-center-ui-20260709/MyBDTeams.vue b/backups/admin-center-ui-20260709/MyBDTeams.vue new file mode 100644 index 0000000..c75a6f3 --- /dev/null +++ b/backups/admin-center-ui-20260709/MyBDTeams.vue @@ -0,0 +1,519 @@ + + + + + diff --git a/backups/admin-center-ui-20260709/MyRechargeAgency.vue b/backups/admin-center-ui-20260709/MyRechargeAgency.vue new file mode 100644 index 0000000..458193f --- /dev/null +++ b/backups/admin-center-ui-20260709/MyRechargeAgency.vue @@ -0,0 +1,320 @@ + + + + + diff --git a/backups/admin-center-ui-20260709/components/historySalary.vue b/backups/admin-center-ui-20260709/components/historySalary.vue new file mode 100644 index 0000000..fe0db02 --- /dev/null +++ b/backups/admin-center-ui-20260709/components/historySalary.vue @@ -0,0 +1,172 @@ + + + + + diff --git a/backups/admin-center-ui-20260709/index.vue b/backups/admin-center-ui-20260709/index.vue new file mode 100644 index 0000000..acb1fda --- /dev/null +++ b/backups/admin-center-ui-20260709/index.vue @@ -0,0 +1,609 @@ + + + + + diff --git a/backups/admin-center-ui-20260709/policy.vue b/backups/admin-center-ui-20260709/policy.vue new file mode 100644 index 0000000..a1f7cbb --- /dev/null +++ b/backups/admin-center-ui-20260709/policy.vue @@ -0,0 +1,94 @@ + + + + + diff --git a/package.json b/package.json index 66761be..97b971b 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,8 @@ "build:azizi-prod": "vite build --mode production-azizi && node scripts/generate-version.js", "preview": "vite preview", "lint": "eslint . --fix", - "docs:sync:security": "node scripts/sync-security-docs.js" + "docs:sync:security": "node scripts/sync-security-docs.js", + "aslan:webview": "node scripts/aslan-webview-sim.mjs" }, "dependencies": { "@vueuse/core": "^13.9.0", diff --git a/scripts/aslan-webview-sim.mjs b/scripts/aslan-webview-sim.mjs new file mode 100644 index 0000000..fc0cccc --- /dev/null +++ b/scripts/aslan-webview-sim.mjs @@ -0,0 +1,176 @@ +#!/usr/bin/env node + +const LOGIN_URL = + 'https://api.atuchat.com/e64f27b9ba6b37881120f4584a5444a5c684d8491b703d0af953e5cc6a5f4cec' + +const account = process.env.ASLAN_ACCOUNT || '6666' +const password = process.env.ASLAN_PASSWORD || '123456' +const targetUrl = + process.env.ASLAN_URL || 'https://h5.atuchat.com/#/admin-center?lang=en' +const chromePath = + process.env.CHROME_PATH || '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome' +const headless = process.env.ASLAN_HEADLESS === '1' +const exitAfterLoad = process.env.ASLAN_EXIT_AFTER_LOAD === '1' + +async function loadPlaywright() { + try { + return await import('playwright') + } catch { + return await import( + '/Users/hy/.cache/codex-runtimes/codex-primary-runtime/dependencies/node/node_modules/playwright/index.mjs' + ) + } +} + +function appHeaders(imei = 'aslan-webview-sim') { + return { + 'req-lang': 'en', + 'X-Forwarded-Proto': 'http', + 'User-Agent': 'Dart/3.7.2 (dart:io)', + 'req-imei': imei, + 'req-app-intel': + 'version=1.0.0;build=1;model=CodexWebView;sysVersion=1;channel=Google', + 'req-client': 'Android', + 'req-sys-origin': 'origin=ATYOU;originChild=ATYOU', + 'Req-Atyou': 'true', + } +} + +function publicUserProfile(profile = {}) { + return { + id: profile.id || profile.userId, + account: profile.account, + specialAccount: profile.ownSpecialId?.account, + userNickname: profile.userNickname, + countryName: profile.countryName, + originSys: profile.originSys || profile.sysOrigin, + sysOriginChild: profile.sysOriginChild, + } +} + +async function login() { + const response = await fetch(LOGIN_URL, { + method: 'POST', + headers: { + ...appHeaders('aslan-webview-sim-login'), + 'content-type': 'application/json', + }, + body: JSON.stringify({ account, pwd: password }), + }) + + const data = await response.json() + if (!response.ok || !data.status || !data.body?.token) { + const error = { + httpStatus: response.status, + status: data.status, + errorCode: data.errorCode, + errorMsg: data.errorMsg, + } + throw new Error(`Aslan login failed: ${JSON.stringify(error)}`) + } + + return data.body +} + +async function main() { + const auth = await login() + const profile = auth.userProfile || {} + const { chromium } = await loadPlaywright() + + const browser = await chromium.launch({ + headless, + executablePath: chromePath, + args: ['--no-sandbox'], + }) + + const context = await browser.newContext({ + viewport: { width: 390, height: 844 }, + isMobile: true, + hasTouch: true, + userAgent: + 'Mozilla/5.0 (Linux; Android 12; Pixel 5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Mobile Safari/537.36', + }) + + await context.addInitScript( + ({ token, profile }) => { + window.__aslanWebViewMessages = [] + + const postBridgeMessage = (message) => { + const text = String(message) + window.__aslanWebViewMessages.push(text) + console.info(`[AslanWebViewSim] FlutterPageControl.postMessage: ${text}`) + } + + window.FlutterPageControl = { + postMessage: postBridgeMessage, + } + + window.app = { + getAccessOrigin: () => + JSON.stringify({ + Authorization: `Bearer ${token}`, + 'Req-Lang': 'en', + 'Req-App-Intel': + 'build=1;version=1.0.0;model=CodexWebView;channel=Google;Req-Imei=aslan-webview-sim', + 'Req-Sys-Origin': 'origin=ATYOU;originChild=ATYOU', + }), + closePage: () => postBridgeMessage('close_page'), + back: () => history.back(), + gotoRoom: (roomId) => postBridgeMessage(`go_to_room:${roomId}`), + gotoPrivateChat: (userId) => postBridgeMessage(`private_chat:${userId}`), + openUserInfo: (userId) => postBridgeMessage(`view_user_info:${userId}`), + gotoAppPage: (pageName) => postBridgeMessage(pageName), + goToFlutterPage: (pageName) => postBridgeMessage(pageName), + uploadImgFile: () => postBridgeMessage('uploadImgFile'), + } + + try { + localStorage.setItem('userProfile', JSON.stringify(profile)) + } catch {} + }, + { token: auth.token, profile }, + ) + + const page = await context.newPage() + page.on('console', (msg) => { + const text = msg.text() + if ( + text.includes('[AslanWebViewSim]') || + /error|warn|Route|Permission|APP|Failed|identity/i.test(text) + ) { + console.log(`[browser:${msg.type()}] ${text}`) + } + }) + page.on('pageerror', (error) => { + console.log(`[browser:pageerror] ${error.message}`) + }) + + console.log('Aslan WebView simulator started') + console.log(`account=${account}`) + console.log(`profile=${JSON.stringify(publicUserProfile(profile))}`) + console.log(`url=${targetUrl}`) + console.log('Close the Chrome window to stop the simulator.') + + await page.goto(targetUrl, { waitUntil: 'domcontentloaded', timeout: 45_000 }) + + if (exitAfterLoad) { + await page.waitForTimeout(6_000) + const state = await page.evaluate(() => ({ + href: location.href, + text: (document.body?.innerText || '').replace(/\s+/g, ' ').slice(0, 800), + bridgeMessages: window.__aslanWebViewMessages || [], + })) + console.log(`loaded=${JSON.stringify(state)}`) + await browser.close() + return + } + + await new Promise((resolve) => { + browser.on('disconnected', resolve) + }) +} + +main().catch((error) => { + console.error(error.message || error) + process.exit(1) +}) diff --git a/src/views/PlatformPolicy/PlatformPolicy.vue b/src/views/PlatformPolicy/PlatformPolicy.vue index bf6de71..b79d7c6 100644 --- a/src/views/PlatformPolicy/PlatformPolicy.vue +++ b/src/views/PlatformPolicy/PlatformPolicy.vue @@ -138,18 +138,10 @@ const fetchTeamPolicy = async () => { } } -// 格式化目标值显示 +// Target 必须展示接口返回的完整数值,不能使用 K/M 等单位缩写。 const formatTarget = (target) => { - if (!target) return '0' - const numTarget = parseFloat(target) - if (isNaN(numTarget)) return target - - if (numTarget >= 1000000) { - return `${(numTarget / 1000000).toFixed(1)}M` - } else if (numTarget >= 1000) { - return `${(numTarget / 1000).toFixed(1)}K` - } - return numTarget.toString() + if (target === null || target === undefined || target === '') return '0' + return String(target) } // 格式化奖励类型