feat: 添加 TradingView 相关环境变量和初始化逻辑;重构交易视图组件

This commit is contained in:
2025-12-30 00:09:38 +07:00
parent 0741b7b507
commit 2402337162
9 changed files with 119 additions and 66 deletions

View File

@@ -0,0 +1,3 @@
export function useEnv(): ImportMetaEnv {
return import.meta.env;
}

View File

@@ -41,28 +41,51 @@ import "./theme/ionic.css";
useTheme();
function initTradingView() {
const { VITE_TRADINGVIEW_LIBRARY_URL } = useEnv();
const promise1 = new Promise((resolve) => {
const script = document.createElement("script");
script.type = "text/javascript";
script.src = `${VITE_TRADINGVIEW_LIBRARY_URL}/charting_library/charting_library.standalone.js`;
script.async = true;
document.body.appendChild(script);
script.onload = () => resolve(true);
});
const promise2 = new Promise((resolve) => {
const script = document.createElement("script");
script.type = "text/javascript";
script.src = `${VITE_TRADINGVIEW_LIBRARY_URL}/datafeeds/udf/bundle.js`;
script.async = true;
document.body.appendChild(script);
script.onload = () => resolve(true);
});
return Promise.all([promise1, promise2]);
}
function initApp() {
authClient.getSession().then((session) => {
const pinia = createPinia();
const userStore = useUserStore(pinia);
userStore.setToken(session.data?.session.token || "");
initTradingView().then(() => {
authClient.getSession().then((session) => {
const pinia = createPinia();
const userStore = useUserStore(pinia);
userStore.setToken(session.data?.session.token || "");
const app = createApp(App)
.use(IonicVue, {
backButtonText: "返回",
mode: "ios",
statusTap: true,
swipeBackEnabled: true,
// rippleEffect: true,
// animated: false,
})
.use(uiComponents)
.use(pinia)
.use(router)
.use(i18n);
const app = createApp(App)
.use(IonicVue, {
backButtonText: "返回",
mode: "ios",
statusTap: true,
swipeBackEnabled: true,
// rippleEffect: true,
// animated: false,
})
.use(uiComponents)
.use(pinia)
.use(router)
.use(i18n);
router.isReady().then(() => {
app.mount("#app");
router.isReady().then(() => {
app.mount("#app");
});
});
});
}

View File

@@ -1,22 +1,60 @@
import type { ChartingLibraryWidgetOptions } from "#/charting_library";
import type { ResolutionString } from "#/datafeed-api";
const { VITE_TRADINGVIEW_LIBRARY_URL, VITE_TRADINGVIEW_DATA_API_URL } = useEnv();
const defaultOptions = {
container: "tradingview_chart_container",
locale: "zh",
library_path: `${VITE_TRADINGVIEW_LIBRARY_URL}/charting_library/`,
datafeed: new Datafeeds.UDFCompatibleDatafeed(VITE_TRADINGVIEW_DATA_API_URL, 60000),
symbol: "AAPL",
interval: "1D" as ResolutionString,
debug: true,
autosize: true,
// 禁用移动端不友好的功能
disabled_features: [
"left_toolbar", // 隐藏左侧绘图工具栏
"timeframes_toolbar", // 隐藏底部时间框架工具栏
"volume_force_overlay", // 禁用成交量覆盖在价格图表上
// 禁用顶部工具栏
"header_widget",
"header_compare",
"header_symbol_search",
"header_fullscreen_button",
"header_settings",
],
// 启用移动端友好的功能
enabled_features: [
"show_zoom_and_move_buttons_on_touch", // 在触摸设备上显示缩放和移动按钮
"adaptive_logo", // 在小屏幕设备上隐藏 TradingView logo
],
} satisfies ChartingLibraryWidgetOptions;
export const TradingViewChart = defineComponent({
name: "TradingViewChart",
setup(props, ctx) {
const chartContainer = ref<HTMLDivElement>();
props: {
options: {
type: Object as PropType<Partial<ChartingLibraryWidgetOptions>>,
required: false,
},
},
setup(props) {
const el = ref<HTMLDivElement | null>(null);
onMounted(() => {
// eslint-disable-next-line new-cap
const tradingView = new TradingView.widget({
container: chartContainer.value!,
locale: "en",
library_path: "http://localhost:6173/charting_library/",
datafeed: new Datafeeds.UDFCompatibleDatafeed("https://demo-feed-data.tradingview.com"),
symbol: "AAPL",
interval: "1D" as ResolutionString,
debug: true,
const widget = new TradingView.widget({
...defaultOptions,
...props.options,
container: el.value!,
});
widget.onChartReady(() => {
widget.setDebugMode(true);
});
});
return () => <div ref={chartContainer} class="w-full h-150" />;
return () => <div ref={el} class="w-full h-70" />;
},
});

View File

@@ -7,35 +7,6 @@ import TradeSwitch from "./components/trade-switch.vue";
import TradeWay from "./components/trade-way.vue";
const mode = ref<"buy" | "sell">("buy");
const tradingViewContainer = useTemplateRef<HTMLDivElement>("tradingViewContainer");
const { chart, series } = useTradingView(tradingViewContainer, {
data: [
{ time: "2024-01-01", open: 42000, high: 43100, low: 41800, close: 42500 },
{ time: "2024-01-02", open: 42500, high: 43500, low: 42200, close: 43000 },
{ time: "2024-01-03", open: 43000, high: 44200, low: 42800, close: 43800 },
{ time: "2024-01-04", open: 43800, high: 44500, low: 43500, close: 44200 },
{ time: "2024-01-05", open: 44200, high: 44800, low: 43900, close: 44500 },
{ time: "2024-01-06", open: 44500, high: 45000, low: 44200, close: 44800 },
{ time: "2024-01-07", open: 44800, high: 45500, low: 44500, close: 45250 },
{ time: "2024-01-08", open: 45250, high: 46000, low: 45100, close: 45800 },
{ time: "2024-01-09", open: 45800, high: 46200, low: 45500, close: 45600 },
{ time: "2024-01-10", open: 45600, high: 45900, low: 45200, close: 45400 },
{ time: "2024-01-11", open: 45400, high: 45800, low: 44900, close: 45100 },
{ time: "2024-01-12", open: 45100, high: 45500, low: 44700, close: 45200 },
{ time: "2024-01-13", open: 45200, high: 45800, low: 45000, close: 45600 },
{ time: "2024-01-14", open: 45600, high: 46500, low: 45500, close: 46300 },
{ time: "2024-01-15", open: 46300, high: 47000, low: 46200, close: 46800 },
],
});
onMounted(() => {
const panes = chart.value?.panes();
series.value?.applyOptions({
upColor: "#3fba6e",
downColor: "#f45531",
});
});
</script>
<template>
@@ -62,8 +33,7 @@ onMounted(() => {
</ion-toolbar>
</ion-header>
<ion-content :fullscreen="true">
<!-- <div ref="tradingViewContainer" class="h-50" /> -->
<TradingViewChart />
<TradingViewChart class="mb-5" />
<div class="grid grid-cols-5">
<div class="col-span-3 space-y-2">
<TradeSwitch v-model:active="mode" />