| | |
| | | <template> |
| | | <section class="pb-fix"> |
| | | <van-loading color="#1194F7" class="loading-box" v-if="isLoading" /> |
| | | <van-loading color="#92D1FF" class="loading-box" v-if="isLoading" /> |
| | | <div class="trade-container-box"> |
| | | <header class="header"> |
| | | <div class="flex-l"> |
| | | <span class="title">{{ t("trade") }}</span> |
| | | </div> |
| | | <div class="flex-r"> |
| | | <van-icon name="service-o" size="26" @click="$router.push('/customerService')" /> |
| | | </div> |
| | | </header> |
| | | <section class="trade-tab-container"> |
| | | <van-tabs v-model:active="tabActive" shrink @click-tab="onClickTab"> |
| | | <van-tab v-for="(item) in listTab" :key="item.tabIndex" :name="item.tabIndex" :title="item.title"> |
| | | <van-tab v-for="item in listTab" :key="item.tabIndex" :name="item.tabIndex" :title="item.title"> |
| | | <div class="content-container"> |
| | | <div class="user-info px-4 mt-4"> |
| | | <div class="mt-8 flex"> |
| | |
| | | }} |
| | | {{ |
| | | assetsObj.totalAssets |
| | | ? formatNumberWithComma(assetsObj.totalAssets * (currency.rate ?? 0)) |
| | | : "0" |
| | | ? (assetsObj.totalAssets * (currency.rate ?? 0)).toFixed(2) |
| | | : "0" |
| | | }} |
| | | </p> |
| | | </div> |
| | |
| | | }} |
| | | {{ |
| | | assetsObj.profit |
| | | ? formatNumberWithComma(assetsObj.profit * (currency.rate ?? 0)) |
| | | : "0" |
| | | ? (assetsObj.profit * (currency.rate ?? 0)).toFixed(2) |
| | | : "0" |
| | | }} |
| | | </p> |
| | | </div> |
| | |
| | | }} |
| | | {{ |
| | | assetsObj.usdtBalance |
| | | ? formatNumberWithComma(assetsObj.usdtBalance * (currency.rate ?? 0)) |
| | | : "0" |
| | | ? (assetsObj.usdtBalance * (currency.rate ?? 0)).toFixed(2) |
| | | : "0" |
| | | }} |
| | | </p> |
| | | </div> |
| | |
| | | }} |
| | | {{ |
| | | assetsObj.profitToday |
| | | ? formatNumberWithComma(assetsObj.profitToday * (currency.rate ?? 0)) |
| | | : "0" |
| | | ? (assetsObj.profitToday * (currency.rate ?? 0)).toFixed(2) |
| | | : "0" |
| | | }} |
| | | </p> |
| | | </div> |
| | |
| | | </van-tabs> |
| | | </section> |
| | | <section class="content-container"> |
| | | <ex-nav :symbolType="symbolType" v-if="tabActive != 3" /> |
| | | <ex-nav :symbolType="symbolType" /> |
| | | <div class="quickly"> |
| | | <div class="quickBox chongbi" :class="[thStore.theme == 'dark' ? 'dark' : 'white']" |
| | | @click="$router.push('/exchange/channel-in')"> |
| | |
| | | </div> |
| | | <div class="flex-r"> |
| | | <div class="flex-r-item"> |
| | | <p :class="item.profitLoss < 0 ? 'text-down' : 'text-up'"> |
| | | <p :class="item.profitLoss < 1 ? 'text-up' : 'text-down'"> |
| | | {{ item.profitLoss }} |
| | | </p> |
| | | <p :class="item.profitLossPercentage < 0 ? 'text-down' : 'text-up'"> |
| | | <p :class="item.profitLossPercentage < 1 ? 'text-up' : 'text-down'"> |
| | | {{ |
| | | item.profitLossPercentage && item.profitLossPercentage !== 0 |
| | | ? `${item.profitLossPercentage}%` |
| | | : 0 |
| | | ? `${item.profitLossPercentage}%` |
| | | : 0 |
| | | }} |
| | | </p> |
| | | </div> |
| | |
| | | </p> |
| | | </div> |
| | | <div class="flex-r-item"> |
| | | <p :class="item.profitLoss < 0 ? 'text-down' : 'text-up'"> |
| | | <p :class="item.close < 1 ? 'text-up' : 'text-down'"> |
| | | {{ item.price }} |
| | | </p> |
| | | <p :class="item.profitLoss < 0 ? 'text-down' : 'text-up'"> |
| | | <p :class="item.close < 1 ? 'text-up' : 'text-down'"> |
| | | {{ item.currentPrice }} |
| | | </p> |
| | | </div> |
| | |
| | | <p class="gray-text"> |
| | | <span class="tip-text" :class="item.offset === 'close' ? 'text-down' : 'text-up'">{{ |
| | | item.offset === |
| | | "open" ? t("买") : t("卖") |
| | | "open" ? t("买") : t("卖") |
| | | }}</span> |
| | | {{ |
| | | item.create_time_ts |
| | | ? dayjs(item.create_time_ts * 1000) |
| | | .format("YYYY-MM-DD HH:mm:ss") |
| | | .slice(11) |
| | | : "--" |
| | | ? dayjs(item.create_time_ts * 1000) |
| | | .format("YYYY-MM-DD HH:mm:ss") |
| | | .slice(11) |
| | | : "--" |
| | | }} |
| | | </p> |
| | | </div> |
| | |
| | | </div> |
| | | <div class="flex-r-item"> |
| | | <p> |
| | | {{ item.state === "created" ? t("委托完成") : t(item.state) }} |
| | | {{ item.state === "created" ? t("createdNew") : t(item.state) }} |
| | | </p> |
| | | </div> |
| | | <div class="flex-r-item operate-btn" @click="cancelSingle(item.order_no)" |
| | | v-if="item.state == 'submitted'"> |
| | | <div class="flex-r-item operate-btn" @click="cancelSingle(item.order_no)"> |
| | | <span>{{ t("撤单") }}</span> |
| | | </div> |
| | | <div class="flex-r-item" v-else> |
| | | <span></span> |
| | | </div> |
| | | </div> |
| | | </template> |
| | |
| | | <p class="gray-text"> |
| | | <span class="tip-text" :class="item.offset === 'close' ? 'text-down' : 'text-up'">{{ |
| | | item.offset === |
| | | "open" ? t("买") : t("卖") |
| | | "open" ? t("买") : t("卖") |
| | | }}</span> |
| | | {{ |
| | | item.create_time_ts |
| | | ? dayjs(item.create_time_ts * 1000) |
| | | .format("YYYY-MM-DD HH:mm:ss") |
| | | .slice(11) |
| | | : "--" |
| | | ? dayjs(item.create_time_ts * 1000) |
| | | .format("YYYY-MM-DD HH:mm:ss") |
| | | .slice(11) |
| | | : "--" |
| | | }} |
| | | </p> |
| | | </div> |
| | |
| | | <p :class="item.changeRatio < 1 ? 'text-up' : 'text-down'"> |
| | | {{ |
| | | item.changeRatio === 0 |
| | | ? 0 |
| | | : item.changeRatio |
| | | ? item.changeRatio + "%" |
| | | : "--" |
| | | ? 0 |
| | | : item.changeRatio |
| | | ? item.changeRatio + "%" |
| | | : "--" |
| | | }} |
| | | </p> |
| | | </div> |
| | |
| | | <p> |
| | | {{ |
| | | item.turnoverRate === 0 |
| | | ? 0 |
| | | : item.turnoverRate |
| | | ? item.turnoverRate + "%" |
| | | : "--" |
| | | ? 0 |
| | | : item.turnoverRate |
| | | ? item.turnoverRate + "%" |
| | | : "--" |
| | | }} |
| | | </p> |
| | | </div> |
| | |
| | | <p> |
| | | {{ |
| | | item.volumeRatio === 0 |
| | | ? 0 |
| | | : item.volumeRatio |
| | | ? item.volumeRatio + "%" |
| | | : "--" |
| | | ? 0 |
| | | : item.volumeRatio |
| | | ? item.volumeRatio + "%" |
| | | : "--" |
| | | }} |
| | | </p> |
| | | </div> |
| | |
| | | import dayjs from "dayjs"; |
| | | import { themeStore } from "@/store/theme"; |
| | | import { useStore } from 'vuex'; |
| | | import { formatNumberWithComma } from '@/utils/utis'; |
| | | |
| | | const thStore = themeStore(); |
| | | const store = useStore() |
| | |
| | | const { toClipboard } = useClipboard(); |
| | | const router = useRouter(); |
| | | const route = useRoute(); |
| | | const defaultTabActive = +route.query.tabActive || 3; |
| | | const defaultTabActive = +route.query.tabActive || 1; |
| | | const tabActive = ref(defaultTabActive); |
| | | const navActive = ref(0); |
| | | const userStore = useUserStore(); |
| | |
| | | const isLoading = ref(false); |
| | | const assetsObj = ref({}) |
| | | const assets = ref({}) |
| | | const navTabV0 = ref([ |
| | | { |
| | | text: t("持仓"), |
| | | index: 0, |
| | | }, |
| | | { |
| | | text: t("entrust"), |
| | | index: 1, |
| | | }, |
| | | ]); |
| | | const navTabV1 = ref([ |
| | | { |
| | | text: t("持仓"), |
| | |
| | | |
| | | const listTab = ref([ |
| | | { |
| | | title: t('UsStocks'), |
| | | type: 'UsStock', |
| | | urlMatch: 'stock', |
| | | symbolType: 'US-stocks', |
| | | tabIndex: 3 |
| | | }, |
| | | { |
| | | title: t('加密货币'), |
| | | type: 'Cryptos', |
| | | urlMatch: 'crypto', |
| | |
| | | symbolType: 'indices', |
| | | tabIndex: 0 |
| | | }, |
| | | |
| | | { |
| | | title: t('外汇'), |
| | | type: 'Foreign', |
| | |
| | | // symbolType: 'INDIA-stocks', |
| | | // tabIndex: 8 |
| | | // }, |
| | | |
| | | // { |
| | | // title: t('UsStocks'), |
| | | // type: 'UsStock', |
| | | // urlMatch: 'stock', |
| | | // symbolType: 'US-stocks', |
| | | // tabIndex: 3 |
| | | // }, |
| | | // { |
| | | // title: t('港股'), |
| | | // type: 'HkStock', |
| | |
| | | ]) |
| | | |
| | | const navTabList = computed(() => { |
| | | return [1, 2].includes(tabActive.value) ? navTabV2.value : (tabActive.value == '3' ? navTabV0.value : navTabV1.value); |
| | | return [1, 2].includes(tabActive.value) ? navTabV2.value : navTabV1.value; |
| | | }); |
| | | |
| | | const getCurrency = async () => { |
| | |
| | | ); |
| | | break; |
| | | case "US-stocks": |
| | | // 跳转到对应的查询列表 |
| | | // if (item.state == 'submitted') { |
| | | // router.push( |
| | | // `/quotes/openTrade?tabActive=4&symbol=${item.symbol}&from=trade&type=US-stocks&tradeTabActive=3&navActive=1` |
| | | // ); |
| | | // } else { |
| | | // router.push( |
| | | // `/quotes/openTrade?tabActive=4&symbol=${item.symbol}&from=trade&type=US-stocks&tradeTabActive=3&navActive=1&invalidState=1` |
| | | // ); |
| | | // } |
| | | |
| | | // 直接跳转到详情,不再跳列表 |
| | | router.push( |
| | | `/cryptos/symbolOrderDetail?order_no=${item.order_no}` |
| | | `/quotes/openTrade?tabActive=4&symbol=${item.symbol}&from=trade&type=US-stocks&tradeTabActive=3&navActive=1` |
| | | ); |
| | | break; |
| | | case 'HK-stocks': |
| | |
| | | const itemClickSecondOrFourth = (item) => { |
| | | // 加密货币 |
| | | if (tabActive.value === 1) { |
| | | |
| | | switch (navActive.value) { |
| | | case 0: |
| | | router.push( |
| | |
| | | |
| | | .header { |
| | | display: flex; |
| | | height: 28px; |
| | | padding: 0 12px; |
| | | height: 56px; |
| | | padding: 0 20px; |
| | | align-items: center; |
| | | background: $main_background; |
| | | border-bottom: 1px solid rgba(118, 128, 143, 0.1); |
| | | box-shadow: 0 1px 4px rgba(0, 0, 0, 0.04); |
| | | |
| | | .flex-l { |
| | | flex: 1; |
| | | display: inline-flex; |
| | | align-items: center; |
| | | |
| | | .icon { |
| | | display: inline-block; |
| | |
| | | |
| | | .title { |
| | | font-weight: 700; |
| | | font-size: 20px; |
| | | line-height: 28px; |
| | | font-size: 24px; |
| | | line-height: 32px; |
| | | color: $mainTextColor; |
| | | letter-spacing: -0.5px; |
| | | } |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | .content-container { |
| | | padding: 0 12px; |
| | | padding: 0 20px; |
| | | |
| | | .user-info { |
| | | background: $main_background; |
| | | border-radius: 16px; |
| | | padding: 20px; |
| | | margin-bottom: 16px; |
| | | box-shadow: 0 2px 12px rgba(146, 209, 255, 0.08); |
| | | border: 1px solid rgba(118, 128, 143, 0.1); |
| | | } |
| | | |
| | | .name { |
| | | font-size: 14px; |
| | | font-size: 16px; |
| | | font-weight: 600; |
| | | color: $text_color; |
| | | } |
| | | |
| | | .ID { |
| | | font-size: 12px; |
| | | font-size: 13px; |
| | | color: $text_color1; |
| | | } |
| | | |
| | | .asset { |
| | | background: $main_background; |
| | | border-radius: 16px; |
| | | padding: 20px; |
| | | margin-bottom: 16px; |
| | | box-shadow: 0 2px 12px rgba(146, 209, 255, 0.08); |
| | | border: 1px solid rgba(118, 128, 143, 0.1); |
| | | } |
| | | |
| | | .line { |
| | | padding: 14px 12px; |
| | | padding: 16px 0; |
| | | display: flex; |
| | | align-items: center; |
| | | font-size: 12px; |
| | | line-height: 18px; |
| | | font-size: 13px; |
| | | line-height: 20px; |
| | | border-bottom: 1px solid rgba(118, 128, 143, 0.1); |
| | | |
| | | &:last-child { |
| | | border-bottom: none; |
| | | } |
| | | |
| | | .gray-text { |
| | | color: #bcbdc2; |
| | | color: $text_color1; |
| | | font-size: 12px; |
| | | } |
| | | |
| | | .value { |
| | | margin-top: 10px; |
| | | margin-top: 8px; |
| | | font-weight: 700; |
| | | font-size: 20px; |
| | | line-height: 24x; |
| | | font-size: 24px; |
| | | line-height: 32px; |
| | | color: $text_color; |
| | | letter-spacing: -0.5px; |
| | | } |
| | | |
| | | .profit { |
| | | margin-top: 10px; |
| | | font-size: 14px; |
| | | margin-top: 8px; |
| | | font-size: 16px; |
| | | font-weight: 600; |
| | | } |
| | | |
| | | .flex-l { |
| | |
| | | } |
| | | |
| | | .active { |
| | | background: $btn_main; |
| | | background: linear-gradient(135deg, #92D1FF 0%, #7BB8FF 100%); |
| | | color: $white; |
| | | box-shadow: 0 4px 12px rgba(146, 209, 255, 0.3); |
| | | font-weight: 600; |
| | | } |
| | | } |
| | | |
| | | .quickly { |
| | | width: 100%; |
| | | height: 72px; |
| | | height: 80px; |
| | | display: flex; |
| | | justify-content: space-between; |
| | | margin-bottom: 32px; |
| | | gap: 12px; |
| | | margin-bottom: 24px; |
| | | // padding: 0 20px; |
| | | |
| | | .quickBox { |
| | | flex: 1; |
| | |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | padding: 8px; |
| | | border-radius: 6px; |
| | | border: 1px solid $color_main; |
| | | padding: 16px; |
| | | border-radius: 16px; |
| | | background: $main_background; |
| | | border: 1px solid rgba(146, 209, 255, 0.2); |
| | | box-shadow: 0 2px 12px rgba(146, 209, 255, 0.08); |
| | | cursor: pointer; |
| | | transition: all 0.3s ease; |
| | | |
| | | &:hover { |
| | | box-shadow: 0 4px 20px rgba(146, 209, 255, 0.12); |
| | | transform: translateY(-2px); |
| | | border-color: rgba(146, 209, 255, 0.3); |
| | | } |
| | | |
| | | .left { |
| | | display: flex; |
| | |
| | | flex: 1; |
| | | |
| | | .leftBox { |
| | | width: 3rem; |
| | | height: 3rem; |
| | | width: 48px; |
| | | height: 48px; |
| | | border-radius: 12px; |
| | | background: rgba(146, 209, 255, 0.1); |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | |
| | | img { |
| | | width: 100%; |
| | | height: 100%; |
| | | width: 32px; |
| | | height: 32px; |
| | | } |
| | | } |
| | | } |
| | |
| | | margin-left: 12px; |
| | | |
| | | p { |
| | | font-size: 12px; |
| | | font-size: 14px; |
| | | color: $text_color; |
| | | line-height: 14px; |
| | | line-height: 20px; |
| | | font-weight: 600; |
| | | } |
| | | } |
| | | |
| | | .right { |
| | | width: 16px; |
| | | height: 16px; |
| | | width: 20px; |
| | | height: 20px; |
| | | opacity: 0.6; |
| | | transition: all 0.2s ease; |
| | | |
| | | img { |
| | | width: 100%; |
| | | height: 100%; |
| | | } |
| | | } |
| | | |
| | | &:hover .right { |
| | | opacity: 1; |
| | | transform: translateX(2px); |
| | | } |
| | | } |
| | | |
| | | .chongbi { |
| | | background: url("@/assets/theme/white/image/chongb.png"); |
| | | background-size: cover; |
| | | |
| | | &.dark { |
| | | background: url("@/assets/theme/dark/image/chongb.png"); |
| | | background-size: cover; |
| | | } |
| | | background: linear-gradient(135deg, rgba(146, 209, 255, 0.1) 0%, rgba(123, 184, 255, 0.05) 100%); |
| | | } |
| | | |
| | | .tibi { |
| | | // background: url("@/assets/theme/white/image/tib.png"); |
| | | // background-size: cover; |
| | | border: 1px solid var(--color_main); |
| | | border-radius: .625rem; |
| | | |
| | | &.dark { |
| | | background: url("@/assets/theme/dark/image/tib.png"); |
| | | background-size: cover; |
| | | } |
| | | background: linear-gradient(135deg, rgba(242, 73, 94, 0.1) 0%, rgba(242, 73, 94, 0.05) 100%); |
| | | border-color: rgba(242, 73, 94, 0.2); |
| | | } |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | li { |
| | | padding: 14px 12px; |
| | | padding: 16px 20px; |
| | | display: flex; |
| | | font-size: 12px; |
| | | line-height: 18px; |
| | | border-bottom: 1px solid $border_color; |
| | | font-size: 13px; |
| | | line-height: 20px; |
| | | border-bottom: 1px solid rgba(118, 128, 143, 0.1); |
| | | transition: all 0.2s ease; |
| | | cursor: pointer; |
| | | |
| | | &:hover { |
| | | background: rgba(146, 209, 255, 0.03); |
| | | } |
| | | |
| | | &:last-child { |
| | | border-bottom: none; |
| | | } |
| | | |
| | | .gray-text { |
| | | color: #bcbdc2; |
| | |
| | | margin-top: 10px; |
| | | |
| | | .symbol-list-item { |
| | | margin: 0 0 10px; |
| | | margin: 0 20px 16px; |
| | | justify-content: space-between; |
| | | padding: 10px; |
| | | font-size: 12px; |
| | | color: #989899; |
| | | font-weight: 600; |
| | | border-bottom: 1px solid $border_color; |
| | | padding: 20px; |
| | | font-size: 13px; |
| | | color: $text_color1; |
| | | font-weight: 500; |
| | | background: $main_background; |
| | | border-radius: 16px; |
| | | box-shadow: 0 2px 12px rgba(146, 209, 255, 0.08); |
| | | border: 1px solid rgba(118, 128, 143, 0.1); |
| | | transition: all 0.3s ease; |
| | | cursor: pointer; |
| | | |
| | | &:hover { |
| | | box-shadow: 0 4px 20px rgba(146, 209, 255, 0.12); |
| | | transform: translateY(-2px); |
| | | border-color: rgba(146, 209, 255, 0.2); |
| | | } |
| | | } |
| | | |
| | | .symbol-list-top { |