Implement internationalization support by adding translation functionality and updating UI components to use translated strings. Add language configuration in .env.example and integrate translations across various strategy and UI components.

This commit is contained in:
discountry
2025-12-09 00:35:28 +08:00
parent 03df1006cc
commit 85e7f245c0
17 changed files with 1166 additions and 295 deletions
+48 -24
View File
@@ -6,6 +6,7 @@ import { buildAdapterFromEnv } from "../exchanges/resolve-from-env";
import { OffsetMakerEngine, type OffsetMakerEngineSnapshot } from "../strategy/offset-maker-engine";
import { DataTable, type TableColumn } from "./components/DataTable";
import { formatNumber } from "../utils/format";
import { t } from "../i18n";
interface OffsetMakerAppProps {
onExit: () => void;
@@ -54,8 +55,8 @@ export function OffsetMakerApp({ onExit }: OffsetMakerAppProps) {
if (error) {
return (
<Box flexDirection="column" padding={1}>
<Text color="red">: {error.message}</Text>
<Text color="gray"></Text>
<Text color="red">{t("common.startFailed", { message: error.message })}</Text>
<Text color="gray">{t("common.checkEnv")}</Text>
</Box>
);
}
@@ -63,7 +64,7 @@ export function OffsetMakerApp({ onExit }: OffsetMakerAppProps) {
if (!snapshot) {
return (
<Box padding={1}>
<Text></Text>
<Text>{t("offset.initializing")}</Text>
</Box>
);
}
@@ -113,68 +114,91 @@ export function OffsetMakerApp({ onExit }: OffsetMakerAppProps) {
];
const lastLogs = snapshot.tradeLog.slice(-5);
const imbalanceLabel = snapshot.depthImbalance === "balanced"
? "均衡"
: snapshot.depthImbalance === "buy_dominant"
? "买盘占优"
: "卖盘占优";
const imbalanceLabel =
snapshot.depthImbalance === "balanced"
? t("offset.imbalance.balanced")
: snapshot.depthImbalance === "buy_dominant"
? t("offset.imbalance.buy")
: t("offset.imbalance.sell");
const readyStatus = snapshot.ready ? t("status.live") : t("status.waitingData");
return (
<Box flexDirection="column" paddingX={1}>
<Box flexDirection="column" marginBottom={1}>
<Text color="cyanBright">Offset Maker Strategy Dashboard</Text>
<Text color="cyanBright">{t("offset.title")}</Text>
<Text>
: {exchangeName} : {snapshot.symbol} : {formatNumber(topBid, priceDigits)} : {formatNumber(topAsk, priceDigits)} : {spreadDisplay}
{t("offset.headerLine", {
exchange: exchangeName,
symbol: snapshot.symbol,
bid: formatNumber(topBid, priceDigits),
ask: formatNumber(topAsk, priceDigits),
spread: spreadDisplay,
})}
</Text>
<Text>
10: {formatNumber(snapshot.buyDepthSum10, 4)} 10: {formatNumber(snapshot.sellDepthSum10, 4)} : {imbalanceLabel}
{t("offset.depthLine", {
buy: formatNumber(snapshot.buyDepthSum10, 4),
sell: formatNumber(snapshot.sellDepthSum10, 4),
status: imbalanceLabel,
})}
</Text>
<Text color="gray">
当前挂单策略: BUY {snapshot.skipBuySide ? "暂停" : "启用"} SELL {snapshot.skipSellSide ? "暂停" : "启用"} Esc
{t("offset.strategyStatus", {
buyStatus: snapshot.skipBuySide ? t("common.disabled") : t("common.enabled"),
sellStatus: snapshot.skipSellSide ? t("common.disabled") : t("common.enabled"),
})}
</Text>
<Text color="gray">: {snapshot.ready ? "实时运行" : "等待市场数据"}</Text>
<Text color="gray">{t("trend.statusLine", { status: readyStatus })}</Text>
</Box>
<Box flexDirection="row" marginBottom={1}>
<Box flexDirection="column" marginRight={4}>
<Text color="greenBright"></Text>
<Text color="greenBright">{t("common.section.position")}</Text>
{hasPosition ? (
<>
<Text>
: {snapshot.position.positionAmt > 0 ? "多" : "空"} : {formatNumber(Math.abs(snapshot.position.positionAmt), 4)} : {formatNumber(snapshot.position.entryPrice, priceDigits)}
{t("maker.positionLine", {
direction:
snapshot.position.positionAmt > 0 ? t("common.direction.long") : t("common.direction.short"),
qty: formatNumber(Math.abs(snapshot.position.positionAmt), 4),
entry: formatNumber(snapshot.position.entryPrice, priceDigits),
})}
</Text>
<Text>
: {formatNumber(snapshot.pnl, 4)} USDT : {formatNumber(snapshot.accountUnrealized, 4)} USDT
{t("maker.pnlLine", {
pnl: formatNumber(snapshot.pnl, 4),
accountPnl: formatNumber(snapshot.accountUnrealized, 4),
})}
</Text>
</>
) : (
<Text color="gray"></Text>
<Text color="gray">{t("common.noPosition")}</Text>
)}
</Box>
<Box flexDirection="column">
<Text color="greenBright"></Text>
<Text color="greenBright">{t("maker.targetOrders")}</Text>
{desiredRows.length > 0 ? (
<DataTable columns={desiredColumns} rows={desiredRows} />
) : (
<Text color="gray"></Text>
<Text color="gray">{t("maker.noTargetOrders")}</Text>
)}
<Text>
: {formatNumber(snapshot.sessionVolume, 2)} USDT
{t("trend.volumeLine", { volume: formatNumber(snapshot.sessionVolume, 2) })}
</Text>
</Box>
</Box>
<Box flexDirection="column" marginBottom={1}>
<Text color="yellow"></Text>
<Text color="yellow">{t("common.section.orders")}</Text>
{openOrderRows.length > 0 ? (
<DataTable columns={openOrderColumns} rows={openOrderRows} />
) : (
<Text color="gray"></Text>
<Text color="gray">{t("common.noOrders")}</Text>
)}
</Box>
<Box flexDirection="column">
<Text color="yellow"></Text>
<Text color="yellow">{t("common.section.recent")}</Text>
{lastLogs.length > 0 ? (
lastLogs.map((item, index) => (
<Text key={`${item.time}-${index}`}>
@@ -182,7 +206,7 @@ export function OffsetMakerApp({ onExit }: OffsetMakerAppProps) {
</Text>
))
) : (
<Text color="gray"></Text>
<Text color="gray">{t("common.noLogs")}</Text>
)}
</Box>
</Box>