新增:合单拆单部分国际化
This commit is contained in:
parent
ddca28e51c
commit
6e3981a637
@ -14,6 +14,7 @@ HTTP 请求基础封装,提供 `get` 和 `post` 方法,支持自定义请求
|
||||
- GET 请求:支持 query 参数,自动序列化
|
||||
- POST 请求:支持 JSON body
|
||||
- 自定义 headers:通过 `RequestConfig.headers` 传入
|
||||
- **Accept-Language**:所有 GET/POST 请求自动附带标准 `Accept-Language` 头,值为当前 vue-i18n 的 `locale`(如 `zh-CN`、`en`),可在 `config.headers` 中覆盖
|
||||
|
||||
## 使用方式
|
||||
|
||||
|
||||
@ -11,7 +11,7 @@
|
||||
- Trade Up / Trade Down Tab
|
||||
- Asks、Bids 列表,带 `HorizontalProgressBar` 深度条
|
||||
- Last price、Spread 展示
|
||||
- Live / 连接中 状态展示
|
||||
- Live / 连接中 状态展示(均通过 i18n 国际化)
|
||||
|
||||
## Props
|
||||
|
||||
@ -41,6 +41,14 @@
|
||||
<OrderBook />
|
||||
```
|
||||
|
||||
## 国际化
|
||||
|
||||
组件内所有展示文案均使用 `trade.*` 与 `activity.live` 键:
|
||||
|
||||
- `trade.orderBook`、`trade.orderBookConnecting`、`trade.orderBookPrice`、`trade.orderBookShares`、`trade.orderBookTotal`
|
||||
- `trade.orderBookAsks`、`trade.orderBookBids`、`trade.orderBookLast`、`trade.orderBookSpread`
|
||||
- `activity.live`(实时状态)
|
||||
|
||||
## 扩展方式
|
||||
|
||||
1. **点击下单**:点击某行价格时,将价格传入 TradeComponent
|
||||
|
||||
@ -33,6 +33,15 @@
|
||||
/>
|
||||
```
|
||||
|
||||
## 国际化
|
||||
|
||||
Merge/Split 弹窗文案均通过 `trade.*` 键国际化:
|
||||
|
||||
- **Merge 弹窗**:`mergeDialogTitle`、`mergeDialogDesc`、`mergeAvailableShares`、`mergeNoMarket`、`mergeSubmitBtn`;复用 `trade.amount`、`trade.max`
|
||||
- **Split 弹窗**:`splitDialogTitle`、`splitDialogDesc`、`splitAmountLabel`、`splitNoMarket`、`splitSubmitBtn`
|
||||
|
||||
`mergeDialogDesc`、`splitDialogDesc`、`mergeNoMarket`、`splitNoMarket` 支持 `{yesLabel}`、`{noLabel}` 插值。
|
||||
|
||||
## 扩展方式
|
||||
|
||||
1. **Limit 单**:完善 Limit 模式下的价格输入与下单逻辑
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
import { i18n } from '@/plugins/i18n'
|
||||
|
||||
/**
|
||||
* 请求基础 URL,默认 https://api.xtrader.vip,可通过环境变量 VITE_API_BASE_URL 覆盖
|
||||
*/
|
||||
@ -49,6 +51,7 @@ export async function get<T = unknown>(
|
||||
}
|
||||
const headers: Record<string, string> = {
|
||||
'Content-Type': 'application/json',
|
||||
'Accept-Language': i18n.global.locale.value as string,
|
||||
...config?.headers,
|
||||
}
|
||||
const res = await fetch(url.toString(), { method: 'GET', headers })
|
||||
@ -69,6 +72,7 @@ export async function post<T = unknown>(
|
||||
const url = new URL(path, BASE_URL || window.location.origin)
|
||||
const headers: Record<string, string> = {
|
||||
'Content-Type': 'application/json',
|
||||
'Accept-Language': i18n.global.locale.value as string,
|
||||
...config?.headers,
|
||||
}
|
||||
const res = await fetch(url.toString(), {
|
||||
|
||||
@ -8,7 +8,7 @@
|
||||
<span class="live-dot"></span>
|
||||
{{ t('activity.live') }}
|
||||
</span>
|
||||
<span v-else-if="loading" class="loading-badge">连接中...</span>
|
||||
<span v-else-if="loading" class="loading-badge">{{ t('trade.orderBookConnecting') }}</span>
|
||||
<span v-else class="vol-text">$4.4k Vol.</span>
|
||||
<v-icon size="14" class="order-book-icon">mdi-chevron-up</v-icon>
|
||||
</div>
|
||||
@ -28,9 +28,9 @@
|
||||
<div class="order-list">
|
||||
<div class="order-list-header">
|
||||
<div class="order-list-header-spacer"></div>
|
||||
<div class="order-list-header-price">PRICE</div>
|
||||
<div class="order-list-header-shares">SHARES</div>
|
||||
<div class="order-list-header-total">TOTAL</div>
|
||||
<div class="order-list-header-price">{{ t('trade.orderBookPrice') }}</div>
|
||||
<div class="order-list-header-shares">{{ t('trade.orderBookShares') }}</div>
|
||||
<div class="order-list-header-total">{{ t('trade.orderBookTotal') }}</div>
|
||||
</div>
|
||||
<!-- Asks Orders -->
|
||||
|
||||
@ -48,8 +48,8 @@
|
||||
<div class="order-total">{{ ask.cumulativeTotal.toFixed(2) }}</div>
|
||||
</div>
|
||||
<!-- Bids Orders -->
|
||||
<div class="asks-label">Asks</div>
|
||||
<div class="bids-label">Bids</div>
|
||||
<div class="asks-label">{{ t('trade.orderBookAsks') }}</div>
|
||||
<div class="bids-label">{{ t('trade.orderBookBids') }}</div>
|
||||
<div
|
||||
v-for="(bid, index) in bidsWithCumulativeTotal"
|
||||
:key="index"
|
||||
@ -72,8 +72,8 @@
|
||||
|
||||
<!-- Footer -->
|
||||
<div class="order-book-footer">
|
||||
<div class="last-price">Last: {{ displayLastPrice }}¢</div>
|
||||
<div class="spread">Spread: {{ displaySpread }}¢</div>
|
||||
<div class="last-price">{{ t('trade.orderBookLast') }}: {{ displayLastPrice }}¢</div>
|
||||
<div class="spread">{{ t('trade.orderBookSpread') }}: {{ displaySpread }}¢</div>
|
||||
</div>
|
||||
</v-card>
|
||||
</template>
|
||||
|
||||
@ -1174,7 +1174,7 @@
|
||||
>
|
||||
<v-card class="merge-dialog-card" rounded="lg" elevation="0">
|
||||
<div class="merge-dialog-header">
|
||||
<h3 class="merge-dialog-title">Merge shares</h3>
|
||||
<h3 class="merge-dialog-title">{{ t('trade.mergeDialogTitle') }}</h3>
|
||||
<v-btn
|
||||
icon
|
||||
variant="text"
|
||||
@ -1187,11 +1187,10 @@
|
||||
</div>
|
||||
<v-card-text class="merge-dialog-body">
|
||||
<p class="merge-dialog-desc">
|
||||
Merge a share of {{ yesLabel }} and {{ noLabel }} to get 1 USDC. You can do this to save
|
||||
cost when trying to get rid of a position.
|
||||
{{ t('trade.mergeDialogDesc', { yesLabel, noLabel }) }}
|
||||
</p>
|
||||
<div class="merge-amount-row">
|
||||
<label class="merge-amount-label">Amount</label>
|
||||
<label class="merge-amount-label">{{ t('trade.amount') }}</label>
|
||||
<v-text-field
|
||||
v-model.number="mergeAmount"
|
||||
type="number"
|
||||
@ -1203,11 +1202,11 @@
|
||||
/>
|
||||
</div>
|
||||
<p class="merge-available">
|
||||
Available shares: {{ availableMergeShares }}
|
||||
<button type="button" class="merge-max-link" @click="setMergeMax">Max</button>
|
||||
{{ t('trade.mergeAvailableShares') }} {{ availableMergeShares }}
|
||||
<button type="button" class="merge-max-link" @click="setMergeMax">{{ t('trade.max') }}</button>
|
||||
</p>
|
||||
<p v-if="!props.market?.marketId" class="merge-no-market">
|
||||
Please select a market first (e.g. click Buy {{ yesLabel }}/{{ noLabel }} on a market).
|
||||
{{ t('trade.mergeNoMarket', { yesLabel, noLabel }) }}
|
||||
</p>
|
||||
<p v-if="mergeError" class="merge-error">{{ mergeError }}</p>
|
||||
</v-card-text>
|
||||
@ -1221,7 +1220,7 @@
|
||||
:disabled="mergeLoading || mergeAmount <= 0"
|
||||
@click="submitMerge"
|
||||
>
|
||||
Merge Shares
|
||||
{{ t('trade.mergeSubmitBtn') }}
|
||||
</v-btn>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
@ -1237,7 +1236,7 @@
|
||||
>
|
||||
<v-card class="split-dialog-card" rounded="lg" elevation="0">
|
||||
<div class="split-dialog-header">
|
||||
<h3 class="split-dialog-title">Split</h3>
|
||||
<h3 class="split-dialog-title">{{ t('trade.splitDialogTitle') }}</h3>
|
||||
<v-btn
|
||||
icon
|
||||
variant="text"
|
||||
@ -1250,11 +1249,10 @@
|
||||
</div>
|
||||
<v-card-text class="split-dialog-body">
|
||||
<p class="split-dialog-desc">
|
||||
Use USDC to get one share of {{ yesLabel }} and one share of {{ noLabel }} for this
|
||||
market. 1 USDC ≈ 1 complete set.
|
||||
{{ t('trade.splitDialogDesc', { yesLabel, noLabel }) }}
|
||||
</p>
|
||||
<div class="split-amount-row">
|
||||
<label class="split-amount-label">Amount (USDC)</label>
|
||||
<label class="split-amount-label">{{ t('trade.splitAmountLabel') }}</label>
|
||||
<v-text-field
|
||||
v-model.number="splitAmount"
|
||||
type="number"
|
||||
@ -1267,7 +1265,7 @@
|
||||
/>
|
||||
</div>
|
||||
<p v-if="!props.market?.marketId" class="split-no-market">
|
||||
Please select a market first (e.g. click Buy {{ yesLabel }}/{{ noLabel }} on a market).
|
||||
{{ t('trade.splitNoMarket', { yesLabel, noLabel }) }}
|
||||
</p>
|
||||
<p v-if="splitError" class="split-error">{{ splitError }}</p>
|
||||
</v-card-text>
|
||||
@ -1281,7 +1279,7 @@
|
||||
:disabled="splitLoading || splitAmount <= 0"
|
||||
@click="submitSplit"
|
||||
>
|
||||
Split
|
||||
{{ t('trade.splitSubmitBtn') }}
|
||||
</v-btn>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
|
||||
@ -21,10 +21,28 @@
|
||||
"buy": "Buy",
|
||||
"sell": "Sell",
|
||||
"orderBook": "Order Book",
|
||||
"orderBookConnecting": "Connecting...",
|
||||
"orderBookPrice": "PRICE",
|
||||
"orderBookShares": "SHARES",
|
||||
"orderBookTotal": "TOTAL",
|
||||
"orderBookAsks": "Asks",
|
||||
"orderBookBids": "Bids",
|
||||
"orderBookLast": "Last",
|
||||
"orderBookSpread": "Spread",
|
||||
"buyLabel": "Trade {label}",
|
||||
"sellLabel": "Sell {label}",
|
||||
"merge": "Merge",
|
||||
"mergeDialogTitle": "Merge shares",
|
||||
"mergeDialogDesc": "Merge a share of {yesLabel} and {noLabel} to get 1 USDC. You can do this to save cost when trying to get rid of a position.",
|
||||
"mergeAvailableShares": "Available shares:",
|
||||
"mergeNoMarket": "Please select a market first (e.g. click Buy {yesLabel}/{noLabel} on a market).",
|
||||
"mergeSubmitBtn": "Merge Shares",
|
||||
"split": "Split",
|
||||
"splitDialogTitle": "Split",
|
||||
"splitDialogDesc": "Use USDC to get one share of {yesLabel} and one share of {noLabel} for this market. 1 USDC ≈ 1 complete set.",
|
||||
"splitAmountLabel": "Amount (USDC)",
|
||||
"splitNoMarket": "Please select a market first (e.g. click Buy {yesLabel}/{noLabel} on a market).",
|
||||
"splitSubmitBtn": "Split",
|
||||
"market": "Market",
|
||||
"limit": "Limit",
|
||||
"deposit": "Deposit",
|
||||
|
||||
@ -21,10 +21,28 @@
|
||||
"buy": "買う",
|
||||
"sell": "売る",
|
||||
"orderBook": "オーダーブック",
|
||||
"orderBookConnecting": "接続中...",
|
||||
"orderBookPrice": "価格",
|
||||
"orderBookShares": "数量",
|
||||
"orderBookTotal": "合計",
|
||||
"orderBookAsks": "売り",
|
||||
"orderBookBids": "買い",
|
||||
"orderBookLast": "最新",
|
||||
"orderBookSpread": "スプレッド",
|
||||
"buyLabel": "{label}を取引",
|
||||
"sellLabel": "{label}を売る",
|
||||
"merge": "マージ",
|
||||
"mergeDialogTitle": "シェアをマージ",
|
||||
"mergeDialogDesc": "{yesLabel} と {noLabel} のシェアを 1 つずつマージすると 1 USDC を獲得できます。ポジションを解消する際のコスト削減に使えます。",
|
||||
"mergeAvailableShares": "利用可能シェア:",
|
||||
"mergeNoMarket": "先に市場を選択してください(例:市場の 買 {yesLabel}/{noLabel} をクリック)。",
|
||||
"mergeSubmitBtn": "シェアをマージ",
|
||||
"split": "スプリット",
|
||||
"splitDialogTitle": "スプリット",
|
||||
"splitDialogDesc": "USDC でこの市場の {yesLabel} と {noLabel} のシェアを 1 つずつ獲得できます。1 USDC ≈ 1 セット。",
|
||||
"splitAmountLabel": "金額 (USDC)",
|
||||
"splitNoMarket": "先に市場を選択してください(例:市場の 買 {yesLabel}/{noLabel} をクリック)。",
|
||||
"splitSubmitBtn": "スプリット",
|
||||
"market": "成行",
|
||||
"limit": "指値",
|
||||
"deposit": "入金",
|
||||
|
||||
@ -21,10 +21,28 @@
|
||||
"buy": "매수",
|
||||
"sell": "매도",
|
||||
"orderBook": "호가창",
|
||||
"orderBookConnecting": "연결 중...",
|
||||
"orderBookPrice": "가격",
|
||||
"orderBookShares": "수량",
|
||||
"orderBookTotal": "합계",
|
||||
"orderBookAsks": "매도",
|
||||
"orderBookBids": "매수",
|
||||
"orderBookLast": "최신",
|
||||
"orderBookSpread": "스프레드",
|
||||
"buyLabel": "{label} 거래",
|
||||
"sellLabel": "{label} 매도",
|
||||
"merge": "병합",
|
||||
"mergeDialogTitle": "주식 병합",
|
||||
"mergeDialogDesc": "{yesLabel} 1주와 {noLabel} 1주를 병합하면 1 USDC를 받습니다. 포지션 청산 시 비용 절감에 사용할 수 있습니다.",
|
||||
"mergeAvailableShares": "사용 가능 주식:",
|
||||
"mergeNoMarket": "먼저 시장을 선택하세요 (예: 시장에서 {yesLabel}/{noLabel} 매수 클릭).",
|
||||
"mergeSubmitBtn": "주식 병합",
|
||||
"split": "분할",
|
||||
"splitDialogTitle": "분할",
|
||||
"splitDialogDesc": "USDC로 이 시장의 {yesLabel} 1주와 {noLabel} 1주를 받을 수 있습니다. 1 USDC ≈ 1 세트.",
|
||||
"splitAmountLabel": "금액 (USDC)",
|
||||
"splitNoMarket": "먼저 시장을 선택하세요 (예: 시장에서 {yesLabel}/{noLabel} 매수 클릭).",
|
||||
"splitSubmitBtn": "분할",
|
||||
"market": "시장가",
|
||||
"limit": "지정가",
|
||||
"deposit": "입금",
|
||||
|
||||
@ -21,10 +21,28 @@
|
||||
"buy": "买入",
|
||||
"sell": "卖出",
|
||||
"orderBook": "订单簿",
|
||||
"buyLabel": "交易{label}",
|
||||
"orderBookConnecting": "连接中...",
|
||||
"orderBookPrice": "价格",
|
||||
"orderBookShares": "份额",
|
||||
"orderBookTotal": "合计",
|
||||
"orderBookAsks": "卖单",
|
||||
"orderBookBids": "买单",
|
||||
"orderBookLast": "最新",
|
||||
"orderBookSpread": "价差",
|
||||
"buyLabel": "{label} 交易",
|
||||
"sellLabel": "卖{label}",
|
||||
"merge": "合并",
|
||||
"mergeDialogTitle": "合并份额",
|
||||
"mergeDialogDesc": "将 1 份 {yesLabel} 和 1 份 {noLabel} 合并可获得 1 USDC。可用于平仓时降低成本。",
|
||||
"mergeAvailableShares": "可用份额:",
|
||||
"mergeNoMarket": "请先选择市场(例如点击某市场的买入 {yesLabel}/{noLabel})。",
|
||||
"mergeSubmitBtn": "合并份额",
|
||||
"split": "拆分",
|
||||
"splitDialogTitle": "拆分",
|
||||
"splitDialogDesc": "使用 USDC 可获得 1 份 {yesLabel} 和 1 份 {noLabel}。1 USDC ≈ 1 完整套。",
|
||||
"splitAmountLabel": "金额 (USDC)",
|
||||
"splitNoMarket": "请先选择市场(例如点击某市场的买入 {yesLabel}/{noLabel})。",
|
||||
"splitSubmitBtn": "拆分",
|
||||
"market": "市价",
|
||||
"limit": "限价",
|
||||
"deposit": "入金",
|
||||
@ -169,4 +187,4 @@
|
||||
"ja": "日本語",
|
||||
"ko": "한국어"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -21,10 +21,28 @@
|
||||
"buy": "買入",
|
||||
"sell": "賣出",
|
||||
"orderBook": "訂單簿",
|
||||
"orderBookConnecting": "連接中...",
|
||||
"orderBookPrice": "價格",
|
||||
"orderBookShares": "份額",
|
||||
"orderBookTotal": "合計",
|
||||
"orderBookAsks": "賣單",
|
||||
"orderBookBids": "買單",
|
||||
"orderBookLast": "最新",
|
||||
"orderBookSpread": "價差",
|
||||
"buyLabel": "交易{label}",
|
||||
"sellLabel": "賣{label}",
|
||||
"merge": "合併",
|
||||
"mergeDialogTitle": "合併份額",
|
||||
"mergeDialogDesc": "將 1 份 {yesLabel} 和 1 份 {noLabel} 合併可獲得 1 USDC。可用於平倉時降低成本。",
|
||||
"mergeAvailableShares": "可用份額:",
|
||||
"mergeNoMarket": "請先選擇市場(例如點擊某市場的買入 {yesLabel}/{noLabel})。",
|
||||
"mergeSubmitBtn": "合併份額",
|
||||
"split": "拆分",
|
||||
"splitDialogTitle": "拆分",
|
||||
"splitDialogDesc": "使用 USDC 可獲得 1 份 {yesLabel} 和 1 份 {noLabel}。1 USDC ≈ 1 完整套。",
|
||||
"splitAmountLabel": "金額 (USDC)",
|
||||
"splitNoMarket": "請先選擇市場(例如點擊某市場的買入 {yesLabel}/{noLabel})。",
|
||||
"splitSubmitBtn": "拆分",
|
||||
"market": "市價",
|
||||
"limit": "限價",
|
||||
"deposit": "入金",
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user