修改:改名,后端接口使用相对路径, 不写死域名
This commit is contained in:
parent
0d523ee5b8
commit
0f2c8d38e7
2
.env
2
.env
@ -1,6 +1,6 @@
|
|||||||
# API 基础地址,不设置时默认 https://api.xtrader.vip
|
# API 基础地址,不设置时默认 https://api.xtrader.vip
|
||||||
# 连接测试服务器 192.168.3.21:8888 时复制本文件为 .env 或 .env.local 并取消下一行注释:
|
# 连接测试服务器 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
|
# VITE_USE_MOCK_DATA=false # 全部关闭 mock
|
||||||
# SSH 部署(npm run deploy),可选覆盖
|
# SSH 部署(npm run deploy),可选覆盖
|
||||||
|
|||||||
@ -1,2 +1,2 @@
|
|||||||
# 生产环境 API 地址(npm run build / npm run deploy 时自动使用)
|
# 生产环境 API 地址(npm run build / npm run deploy 时自动使用)
|
||||||
VITE_API_BASE_URL=https://api.xtrader.vip
|
VITE_API_BASE_URL=/api
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<link rel="icon" href="/favicon.ico" />
|
<link rel="icon" href="/favicon.ico" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>TestMarket</title>
|
<title>Alpha Market</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="app"></div>
|
<div id="app"></div>
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
/**
|
/**
|
||||||
* 将项目打包并部署到远程服务器
|
* 将项目打包并部署到远程服务器
|
||||||
* 使用方式:npm run deploy
|
* 使用方式: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_HOST、DEPLOY_USER、DEPLOY_PATH
|
* 环境变量(可选):DEPLOY_HOST、DEPLOY_USER、DEPLOY_PATH
|
||||||
* 依赖:rsync(系统自带)、ssh 免密或密钥
|
* 依赖:rsync(系统自带)、ssh 免密或密钥
|
||||||
@ -18,13 +18,13 @@ const distDir = join(projectRoot, 'dist')
|
|||||||
const config = {
|
const config = {
|
||||||
host: process.env.DEPLOY_HOST || '38.246.250.238',
|
host: process.env.DEPLOY_HOST || '38.246.250.238',
|
||||||
user: process.env.DEPLOY_USER || 'root',
|
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}`
|
const target = `${config.user}@${config.host}:${config.path}`
|
||||||
|
|
||||||
function build() {
|
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})...`)
|
console.log(`📦 正在打包项目(.env.production API: ${apiUrl})...`)
|
||||||
execSync('npm run build', {
|
execSync('npm run build', {
|
||||||
cwd: projectRoot,
|
cwd: projectRoot,
|
||||||
|
|||||||
@ -87,7 +87,7 @@ watch(
|
|||||||
>
|
>
|
||||||
<v-icon>mdi-arrow-left</v-icon>
|
<v-icon>mdi-arrow-left</v-icon>
|
||||||
</v-btn>
|
</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>
|
<v-spacer></v-spacer>
|
||||||
<template v-if="!userStore.isLoggedIn">
|
<template v-if="!userStore.isLoggedIn">
|
||||||
<v-menu
|
<v-menu
|
||||||
|
|||||||
@ -31,20 +31,31 @@ async function parseJsonBody<T>(res: Response): Promise<T> {
|
|||||||
return res.json() as 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 =
|
export const BASE_URL =
|
||||||
(import.meta as { env?: { VITE_API_BASE_URL?: string } }).env?.VITE_API_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 =
|
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 同源 */
|
/** 生成 WebSocket URL,与 REST API 同源 */
|
||||||
function getWsUrl(path: string): string {
|
function getWsUrl(path: string): string {
|
||||||
const base = BASE_URL || FALLBACK_BASE
|
const url = buildFullUrl(path)
|
||||||
const url = new URL(base)
|
|
||||||
const protocol = url.protocol === 'https:' ? 'wss:' : 'ws:'
|
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 */
|
/** CLOB WebSocket URL */
|
||||||
@ -91,7 +102,7 @@ export async function get<T = unknown>(
|
|||||||
params?: Record<string, string | number | string[] | number[] | undefined>,
|
params?: Record<string, string | number | string[] | number[] | undefined>,
|
||||||
config?: RequestConfig,
|
config?: RequestConfig,
|
||||||
): Promise<T> {
|
): Promise<T> {
|
||||||
const url = new URL(path, BASE_URL || window.location.origin)
|
const url = buildFullUrl(path)
|
||||||
if (params) {
|
if (params) {
|
||||||
Object.entries(params).forEach(([key, value]) => {
|
Object.entries(params).forEach(([key, value]) => {
|
||||||
if (value === undefined) return
|
if (value === undefined) return
|
||||||
@ -119,7 +130,7 @@ export async function post<T = unknown>(
|
|||||||
body?: unknown,
|
body?: unknown,
|
||||||
config?: RequestConfig,
|
config?: RequestConfig,
|
||||||
): Promise<T> {
|
): Promise<T> {
|
||||||
const url = new URL(path, BASE_URL || window.location.origin)
|
const url = buildFullUrl(path)
|
||||||
const headers: Record<string, string> = {
|
const headers: Record<string, string> = {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
'Accept-Language': i18n.global.locale.value as string,
|
'Accept-Language': i18n.global.locale.value as string,
|
||||||
@ -141,7 +152,7 @@ export async function uploadFile<T = unknown>(
|
|||||||
file: File,
|
file: File,
|
||||||
config?: RequestConfig,
|
config?: RequestConfig,
|
||||||
): Promise<T> {
|
): Promise<T> {
|
||||||
const url = new URL(path, BASE_URL || window.location.origin)
|
const url = buildFullUrl(path)
|
||||||
const form = new FormData()
|
const form = new FormData()
|
||||||
form.append('file', file)
|
form.append('file', file)
|
||||||
const headers: Record<string, string> = {
|
const headers: Record<string, string> = {
|
||||||
@ -165,7 +176,7 @@ export async function put<T = unknown>(
|
|||||||
body?: unknown,
|
body?: unknown,
|
||||||
config?: RequestConfig,
|
config?: RequestConfig,
|
||||||
): Promise<T> {
|
): Promise<T> {
|
||||||
const url = new URL(path, BASE_URL || window.location.origin)
|
const url = buildFullUrl(path)
|
||||||
const headers: Record<string, string> = {
|
const headers: Record<string, string> = {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
'Accept-Language': i18n.global.locale.value as string,
|
'Accept-Language': i18n.global.locale.value as string,
|
||||||
@ -187,7 +198,7 @@ export async function httpDelete<T = unknown>(
|
|||||||
body?: unknown,
|
body?: unknown,
|
||||||
config?: RequestConfig,
|
config?: RequestConfig,
|
||||||
): Promise<T> {
|
): Promise<T> {
|
||||||
const url = new URL(path, BASE_URL || window.location.origin)
|
const url = buildFullUrl(path)
|
||||||
const headers: Record<string, string> = {
|
const headers: Record<string, string> = {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
'Accept-Language': i18n.global.locale.value as string,
|
'Accept-Language': i18n.global.locale.value as string,
|
||||||
|
|||||||
@ -149,7 +149,7 @@
|
|||||||
"walletNotInstalled": "Ethereum wallet is not installed. Please install MetaMask, TokenPocket or another Ethereum wallet to continue.",
|
"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.",
|
"invalidAddress": "Invalid wallet address format. Please check your wallet connection.",
|
||||||
"connectFailed": "Failed to connect with wallet. Please check your wallet and try again.",
|
"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": {
|
"apiKey": {
|
||||||
"title": "API Key Management",
|
"title": "API Key Management",
|
||||||
|
|||||||
@ -149,7 +149,7 @@
|
|||||||
"walletNotInstalled": "イーサリアムウォレットがインストールされていません。MetaMask、TokenPocket などのウォレットをインストールしてください。",
|
"walletNotInstalled": "イーサリアムウォレットがインストールされていません。MetaMask、TokenPocket などのウォレットをインストールしてください。",
|
||||||
"invalidAddress": "ウォレットアドレスの形式が無効です。接続を確認してください。",
|
"invalidAddress": "ウォレットアドレスの形式が無効です。接続を確認してください。",
|
||||||
"connectFailed": "ウォレットの接続に失敗しました。ウォレットを確認して再試行してください。",
|
"connectFailed": "ウォレットの接続に失敗しました。ウォレットを確認して再試行してください。",
|
||||||
"siweStatement": "TestMarket にサインイン"
|
"siweStatement": "Alpha Market にサインイン"
|
||||||
},
|
},
|
||||||
"apiKey": {
|
"apiKey": {
|
||||||
"title": "API Key 管理",
|
"title": "API Key 管理",
|
||||||
|
|||||||
@ -149,7 +149,7 @@
|
|||||||
"walletNotInstalled": "이더리움 지갑이 설치되어 있지 않습니다. MetaMask, TokenPocket 등 지갑을 설치해 주세요.",
|
"walletNotInstalled": "이더리움 지갑이 설치되어 있지 않습니다. MetaMask, TokenPocket 등 지갑을 설치해 주세요.",
|
||||||
"invalidAddress": "지갑 주소 형식이 올바르지 않습니다. 지갑 연결을 확인해 주세요.",
|
"invalidAddress": "지갑 주소 형식이 올바르지 않습니다. 지갑 연결을 확인해 주세요.",
|
||||||
"connectFailed": "지갑 연결에 실패했습니다. 지갑을 확인하고 다시 시도해 주세요.",
|
"connectFailed": "지갑 연결에 실패했습니다. 지갑을 확인하고 다시 시도해 주세요.",
|
||||||
"siweStatement": "TestMarket 로그인"
|
"siweStatement": "Alpha Market 로그인"
|
||||||
},
|
},
|
||||||
"apiKey": {
|
"apiKey": {
|
||||||
"title": "API Key 관리",
|
"title": "API Key 관리",
|
||||||
|
|||||||
@ -149,7 +149,7 @@
|
|||||||
"walletNotInstalled": "未检测到以太坊钱包。请安装 MetaMask、TokenPocket 或其他以太坊钱包后重试。",
|
"walletNotInstalled": "未检测到以太坊钱包。请安装 MetaMask、TokenPocket 或其他以太坊钱包后重试。",
|
||||||
"invalidAddress": "钱包地址格式无效,请检查钱包连接。",
|
"invalidAddress": "钱包地址格式无效,请检查钱包连接。",
|
||||||
"connectFailed": "连接钱包失败,请检查钱包后重试。",
|
"connectFailed": "连接钱包失败,请检查钱包后重试。",
|
||||||
"siweStatement": "登录 TestMarket"
|
"siweStatement": "登录 Alpha Market"
|
||||||
},
|
},
|
||||||
"apiKey": {
|
"apiKey": {
|
||||||
"title": "API Key 管理",
|
"title": "API Key 管理",
|
||||||
|
|||||||
@ -149,7 +149,7 @@
|
|||||||
"walletNotInstalled": "未偵測到以太坊錢包。請安裝 MetaMask、TokenPocket 或其他以太坊錢包後重試。",
|
"walletNotInstalled": "未偵測到以太坊錢包。請安裝 MetaMask、TokenPocket 或其他以太坊錢包後重試。",
|
||||||
"invalidAddress": "錢包地址格式無效,請檢查錢包連接。",
|
"invalidAddress": "錢包地址格式無效,請檢查錢包連接。",
|
||||||
"connectFailed": "連接錢包失敗,請檢查錢包後重試。",
|
"connectFailed": "連接錢包失敗,請檢查錢包後重試。",
|
||||||
"siweStatement": "登入 TestMarket"
|
"siweStatement": "登入 Alpha Market"
|
||||||
},
|
},
|
||||||
"apiKey": {
|
"apiKey": {
|
||||||
"title": "API Key 管理",
|
"title": "API Key 管理",
|
||||||
|
|||||||
@ -85,7 +85,7 @@ const connectWithWallet = async () => {
|
|||||||
scheme,
|
scheme,
|
||||||
domain,
|
domain,
|
||||||
address: signer.address,
|
address: signer.address,
|
||||||
statement: 'Sign in to TestMarket',
|
statement: 'Sign in to Alpha Market',
|
||||||
uri: origin,
|
uri: origin,
|
||||||
version: '1',
|
version: '1',
|
||||||
chainId: chainId,
|
chainId: chainId,
|
||||||
|
|||||||
@ -30,13 +30,13 @@
|
|||||||
{{ t('profile.edit') }}
|
{{ t('profile.edit') }}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</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-title">{{ t('profile.memberCenter') }}</span>
|
||||||
<span class="vip-entry-right">
|
<span class="vip-entry-right">
|
||||||
<span class="vip-pill">{{ t('memberCenter.vipLabel', { n: vipLevel }) }}</span>
|
<span class="vip-pill">{{ t('memberCenter.vipLabel', { n: vipLevel }) }}</span>
|
||||||
<span class="vip-chev" aria-hidden="true">›</span>
|
<span class="vip-chev" aria-hidden="true">›</span>
|
||||||
</span>
|
</span>
|
||||||
</button>
|
</button> -->
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section class="card wallet-card">
|
<section class="card wallet-card">
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user