修改:改名,后端接口使用相对路径, 不写死域名

This commit is contained in:
马丁 2026-05-02 17:14:45 +08:00
parent 0d523ee5b8
commit 0f2c8d38e7
13 changed files with 37 additions and 26 deletions

2
.env
View File

@ -1,6 +1,6 @@
# API 基础地址,不设置时默认 https://api.xtrader.vip
# 连接测试服务器 192.168.3.21:8888 时复制本文件为 .env 或 .env.local 并取消下一行注释:
# VITE_API_BASE_URL=http://192.168.3.14:8888
VITE_API_BASE_URL=/api
# VITE_USE_MOCK_DATA=false # 全部关闭 mock
# SSH 部署npm run deploy可选覆盖

View File

@ -1,2 +1,2 @@
# 生产环境 API 地址npm run build / npm run deploy 时自动使用)
VITE_API_BASE_URL=https://api.xtrader.vip
VITE_API_BASE_URL=/api

View File

@ -4,7 +4,7 @@
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>TestMarket</title>
<title>Alpha Market</title>
</head>
<body>
<div id="app"></div>

View File

@ -2,7 +2,7 @@
/**
* 将项目打包并部署到远程服务器
* 使用方式npm run deploy
* 通过 SSH rsync 部署到 root@38.246.250.238:/opt/1panel/www/sites/pm.xtrader.vip/index
* 通过 SSH rsync 部署到 root@38.246.250.238:/opt/1panel/www/sites/pm.aaa.com/index
*
* 环境变量可选DEPLOY_HOSTDEPLOY_USERDEPLOY_PATH
* 依赖rsync系统自带ssh 免密或密钥
@ -18,13 +18,13 @@ const distDir = join(projectRoot, 'dist')
const config = {
host: process.env.DEPLOY_HOST || '38.246.250.238',
user: process.env.DEPLOY_USER || 'root',
path: process.env.DEPLOY_PATH || '/opt/1panel/www/sites/pm.xtrader.vip/index',
path: process.env.DEPLOY_PATH || '/opt/1panel/www/sites/pm.aaa.vip/index',
}
const target = `${config.user}@${config.host}:${config.path}`
function build() {
const apiUrl = process.env.VITE_API_BASE_URL || 'https://api.xtrader.vip'
const apiUrl = process.env.VITE_API_BASE_URL || 'https://api.aaa.vip'
console.log(`📦 正在打包项目(.env.production API: ${apiUrl}...`)
execSync('npm run build', {
cwd: projectRoot,

View File

@ -87,7 +87,7 @@ watch(
>
<v-icon>mdi-arrow-left</v-icon>
</v-btn>
<v-app-bar-title v-if="currentRoute === '/'">TestMarket</v-app-bar-title>
<v-app-bar-title v-if="currentRoute === '/'">Alpha Market</v-app-bar-title>
<v-spacer></v-spacer>
<template v-if="!userStore.isLoggedIn">
<v-menu

View File

@ -31,20 +31,31 @@ async function parseJsonBody<T>(res: Response): Promise<T> {
return res.json() as Promise<T>
}
/** 请求基础 URL默认 https://api.xtrader.vip,可通过环境变量 VITE_API_BASE_URL 覆盖 */
/** 请求基础 URL默认 https://api.aaa.com,可通过环境变量 VITE_API_BASE_URL 覆盖 */
export const BASE_URL =
(import.meta as { env?: { VITE_API_BASE_URL?: string } }).env?.VITE_API_BASE_URL ??
'https://api.xtrader.vip'
'https://api.aaa.com'
const FALLBACK_BASE =
typeof window !== 'undefined' ? window.location.origin : 'https://api.xtrader.vip'
typeof window !== 'undefined' ? window.location.origin : 'https://api.aaa.com'
/** 生成完整 URL支持相对路径的 BASE_URL */
function buildFullUrl(path: string): URL {
let base = BASE_URL || FALLBACK_BASE
if (!/^https?:\/\//i.test(base)) {
const origin = typeof window !== 'undefined' ? window.location.origin : 'http://localhost'
base = `${origin}${base.startsWith('/') ? '' : '/'}${base}`
}
const cleanBase = base.endsWith('/') ? base.slice(0, -1) : base
const cleanPath = path.startsWith('/') ? path : `/${path}`
return new URL(`${cleanBase}${cleanPath}`)
}
/** 生成 WebSocket URL与 REST API 同源 */
function getWsUrl(path: string): string {
const base = BASE_URL || FALLBACK_BASE
const url = new URL(base)
const url = buildFullUrl(path)
const protocol = url.protocol === 'https:' ? 'wss:' : 'ws:'
return `${protocol}//${url.host}${path.startsWith('/') ? path : `/${path}`}`
return `${protocol}//${url.host}${url.pathname}${url.search}`
}
/** CLOB WebSocket URL */
@ -91,7 +102,7 @@ export async function get<T = unknown>(
params?: Record<string, string | number | string[] | number[] | undefined>,
config?: RequestConfig,
): Promise<T> {
const url = new URL(path, BASE_URL || window.location.origin)
const url = buildFullUrl(path)
if (params) {
Object.entries(params).forEach(([key, value]) => {
if (value === undefined) return
@ -119,7 +130,7 @@ export async function post<T = unknown>(
body?: unknown,
config?: RequestConfig,
): Promise<T> {
const url = new URL(path, BASE_URL || window.location.origin)
const url = buildFullUrl(path)
const headers: Record<string, string> = {
'Content-Type': 'application/json',
'Accept-Language': i18n.global.locale.value as string,
@ -141,7 +152,7 @@ export async function uploadFile<T = unknown>(
file: File,
config?: RequestConfig,
): Promise<T> {
const url = new URL(path, BASE_URL || window.location.origin)
const url = buildFullUrl(path)
const form = new FormData()
form.append('file', file)
const headers: Record<string, string> = {
@ -165,7 +176,7 @@ export async function put<T = unknown>(
body?: unknown,
config?: RequestConfig,
): Promise<T> {
const url = new URL(path, BASE_URL || window.location.origin)
const url = buildFullUrl(path)
const headers: Record<string, string> = {
'Content-Type': 'application/json',
'Accept-Language': i18n.global.locale.value as string,
@ -187,7 +198,7 @@ export async function httpDelete<T = unknown>(
body?: unknown,
config?: RequestConfig,
): Promise<T> {
const url = new URL(path, BASE_URL || window.location.origin)
const url = buildFullUrl(path)
const headers: Record<string, string> = {
'Content-Type': 'application/json',
'Accept-Language': i18n.global.locale.value as string,

View File

@ -149,7 +149,7 @@
"walletNotInstalled": "Ethereum wallet is not installed. Please install MetaMask, TokenPocket or another Ethereum wallet to continue.",
"invalidAddress": "Invalid wallet address format. Please check your wallet connection.",
"connectFailed": "Failed to connect with wallet. Please check your wallet and try again.",
"siweStatement": "Sign in to TestMarket"
"siweStatement": "Sign in to Alpha Market"
},
"apiKey": {
"title": "API Key Management",

View File

@ -149,7 +149,7 @@
"walletNotInstalled": "イーサリアムウォレットがインストールされていません。MetaMask、TokenPocket などのウォレットをインストールしてください。",
"invalidAddress": "ウォレットアドレスの形式が無効です。接続を確認してください。",
"connectFailed": "ウォレットの接続に失敗しました。ウォレットを確認して再試行してください。",
"siweStatement": "TestMarket にサインイン"
"siweStatement": "Alpha Market にサインイン"
},
"apiKey": {
"title": "API Key 管理",

View File

@ -149,7 +149,7 @@
"walletNotInstalled": "이더리움 지갑이 설치되어 있지 않습니다. MetaMask, TokenPocket 등 지갑을 설치해 주세요.",
"invalidAddress": "지갑 주소 형식이 올바르지 않습니다. 지갑 연결을 확인해 주세요.",
"connectFailed": "지갑 연결에 실패했습니다. 지갑을 확인하고 다시 시도해 주세요.",
"siweStatement": "TestMarket 로그인"
"siweStatement": "Alpha Market 로그인"
},
"apiKey": {
"title": "API Key 관리",

View File

@ -149,7 +149,7 @@
"walletNotInstalled": "未检测到以太坊钱包。请安装 MetaMask、TokenPocket 或其他以太坊钱包后重试。",
"invalidAddress": "钱包地址格式无效,请检查钱包连接。",
"connectFailed": "连接钱包失败,请检查钱包后重试。",
"siweStatement": "登录 TestMarket"
"siweStatement": "登录 Alpha Market"
},
"apiKey": {
"title": "API Key 管理",

View File

@ -149,7 +149,7 @@
"walletNotInstalled": "未偵測到以太坊錢包。請安裝 MetaMask、TokenPocket 或其他以太坊錢包後重試。",
"invalidAddress": "錢包地址格式無效,請檢查錢包連接。",
"connectFailed": "連接錢包失敗,請檢查錢包後重試。",
"siweStatement": "登入 TestMarket"
"siweStatement": "登入 Alpha Market"
},
"apiKey": {
"title": "API Key 管理",

View File

@ -85,7 +85,7 @@ const connectWithWallet = async () => {
scheme,
domain,
address: signer.address,
statement: 'Sign in to TestMarket',
statement: 'Sign in to Alpha Market',
uri: origin,
version: '1',
chainId: chainId,

View File

@ -30,13 +30,13 @@
{{ t('profile.edit') }}
</button>
</div>
<button type="button" class="vip-entry" @click="goMemberCenter">
<!-- <button type="button" class="vip-entry" @click="goMemberCenter">
<span class="vip-entry-title">{{ t('profile.memberCenter') }}</span>
<span class="vip-entry-right">
<span class="vip-pill">{{ t('memberCenter.vipLabel', { n: vipLevel }) }}</span>
<span class="vip-chev" aria-hidden="true"></span>
</span>
</button>
</button> -->
</section>
<section class="card wallet-card">