| | |
| | | <template> |
| | | <div class="assets"> |
| | | <div class="assets_title">{{ $t('总资产估值') }}</div> |
| | | <div class="assets_money font-bold mt-5 flex justify-start items-end"> |
| | | {{ currency.currency_symbol }}{{ forexAssets?.money_contract ? |
| | | (forexAssets?.money_contract * (currency.rate ?? 0)).toFixed(2) : '0.00' }} |
| | | <div class="assets-page"> |
| | | <assets-head :title="$t('My assets')" :show-left="true" :back-func="goBack"> |
| | | <template #default> |
| | | <van-icon name="records-o" size="22" class="assets-head-menu" |
| | | @click="toPage('/cryptos/accountChange')" /> |
| | | </template> |
| | | </assets-head> |
| | | |
| | | <div class="pricing_jj ml-5"> |
| | | {{ pricing }} |
| | | </div> |
| | | <van-dropdown-menu> |
| | | <van-dropdown-item v-model="pricing" :options="pricingList" @change="changePricing"> |
| | | <div @click="toPage('/cryptos/exchangeRate')" class="text-center">{{ $t('更多') }}</div> |
| | | </van-dropdown-item> |
| | | </van-dropdown-menu> |
| | | </div> |
| | | <div class="assets_revenue mt-5"> |
| | | <span>{{ $t('ProfitDay') }}</span> |
| | | {{ currency.currency_symbol }}{{ forexAssets?.money_contract_profit_today ? |
| | | (forexAssets?.money_contract_profit_today * (currency.rate ?? 0)).toFixed(2) : |
| | | '--' }} |
| | | </div> |
| | | |
| | | <div class="tabbers flex justify-between mt-20 pl-1 pr-1"> |
| | | <div class="item" v-for="item in tabList" :key="item.key" @click="toPage(item.path)"> |
| | | <img style="width: 100px;" :src="item.icon" alt=""> |
| | | <div class="mt-3 text-center">{{ item.name }}</div> |
| | | </div> |
| | | </div> |
| | | |
| | | <van-collapse v-model="activeNames" class="mt-10"> |
| | | <van-collapse-item :title="$t('分布')" name="1"> |
| | | <!-- <div class="divider"></div> --> |
| | | <div class="percentage flex just-between items-center"> |
| | | <div :style="`width:${assetObj.capital / (assetObj.capital + assetObj.contract) * 100}%`"> |
| | | <div class="assets-body"> |
| | | <!-- 总资产估值卡片:圆角浅灰 --> |
| | | <div class="assets-total-card"> |
| | | <div class="assets-total-label">{{ $t('总资产估值') }}</div> |
| | | <div class="assets-total-value"> |
| | | {{ currency.currency_symbol }}{{ formatWithCommas(totalDisplay) }} |
| | | </div> |
| | | <div class="assets-futures-bonus-row"> |
| | | <div class="assets-futures-cell"> |
| | | <div class="assets-cell-label">{{ $t('永续') }}</div> |
| | | <div class="assets-cell-value">{{ formatWithCommas(futuresDisplay) }}</div> |
| | | </div> |
| | | <div class="flex-1"> |
| | | <div class="assets-bonus-cell" @click="toPage('/my/transfer')"> |
| | | <div> |
| | | <div class="assets-cell-label">{{ $t('Bonus') }}</div> |
| | | <div class="assets-cell-value">{{ formatWithCommas(bonusDisplay) }}</div> |
| | | </div> |
| | | <van-icon name="arrow" class="assets-cell-arrow" /> |
| | | </div> |
| | | </div> |
| | | <div class="assets_item flex justify-start items-center mt-14 font-bold"> |
| | | <div class="icon" style="background-color: #8A90FE;"></div> |
| | | <span class="ml-5 flex-1">{{ $t('资金账户') }}</span> |
| | | <span class="mr-5">{{ assetObj.capital }}</span> |
| | | <van-icon name="arrow" /> |
| | | </div> |
| | | <div class="assets_item flex justify-start items-center mt-14 font-bold"> |
| | | <div class="icon" style="background-color: #f7b600;"></div> |
| | | <span class="ml-5 flex-1">{{ $t('交易账户') }}</span> |
| | | <span class="mr-5">{{ assetObj.contract }}</span> |
| | | <van-icon name="arrow" /> |
| | | </div> |
| | | </van-collapse-item> |
| | | </van-collapse> |
| | | |
| | | <div class="assets_item flex font-bold justify-between items-center mt-14 mb-10"> |
| | | <span>{{ $t('资产') }}</span> |
| | | <van-icon name="exchange" size="3rem" /> |
| | | </div> |
| | | <!-- 展开后:BTC Price + ETH Price K 线图 --> |
| | | <div v-if="expanded" class="assets-chart-section"> |
| | | <div class="assets-chart-title">{{ $t('BTC Price') }}</div> |
| | | <div class="assets-kline-wrap"> |
| | | <fx-kline chart-id="kline-btc" :height="260" symbol="btcusdt" :show-bottom="false" |
| | | chart-type="candle_stroke" /> |
| | | </div> |
| | | </div> |
| | | <div v-if="expanded" class="assets-chart-section"> |
| | | <div class="assets-chart-title">{{ $t('ETH Price') }}</div> |
| | | <div class="assets-kline-wrap"> |
| | | <fx-kline chart-id="kline-eth" :height="260" symbol="ethusdt" :show-bottom="false" |
| | | chart-type="candle_stroke" /> |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="assets_item flex justify-start items-center mb-10 font-bold" v-for="item in assetList" |
| | | :key="item.id"> |
| | | <img :src="`${HOST_URL}/symbol/${item.symbol_data}.png`" /> |
| | | <div class="assets-expand-btn" @click="expanded = !expanded"> |
| | | <van-icon :name="expanded ? 'arrow-up' : 'arrow-down'" class="assets-chevron" /> |
| | | </div> |
| | | </div> |
| | | |
| | | <span class="ml-5 flex-1">{{ item.symbol_data.toUpperCase() }}/USDT</span> |
| | | |
| | | <div class="mr-3"> |
| | | <!-- <div class="text-right">0</div> |
| | | <div class="assets_item_light text-right">0.00</div> --> |
| | | <div class="text-right" v-if="item.symbol == 'btc'"> |
| | | {{ item.volume ? Number(item.volume).toFixed(8) : '0.0' }} |
| | | </div> |
| | | <div class="text-right" v-else-if="item.symbol == 'eth'"> |
| | | {{ item.volume ? Number(item.volume).toFixed(8) : '0.0' }} |
| | | </div> |
| | | <div class="text-right" v-else-if="item.symbol == 'usdt'"> |
| | | {{ item.volume ? Number(item.volume).toFixed(2) : '0.0' }} |
| | | </div> |
| | | <div class="text-right" v-else> |
| | | {{ item.volume ? Number(item.volume).toFixed(8) : '0.0' }} |
| | | </div> |
| | | <div class="assets_item_light text-right"> |
| | | ≈{{ currency.currency_symbol }} |
| | | {{ item.usdt ? Number(item.usdt).toFixed(2) : '0.0' }} |
| | | <!-- 资产列表 --> |
| | | <div class="assets-list-head">{{ $t('Asset list') }}</div> |
| | | <div class="assets-list"> |
| | | <div v-for="item in assetList" :key="item.id || item.symbol_data" class="assets-list-card"> |
| | | <div class="assets-list-top"> |
| | | <img :src="`${HOST_URL}/symbol/${item.symbol_data || item.symbol}.png`" alt="" |
| | | class="assets-list-icon" onerror="this.style.display='none'" /> |
| | | <span class="assets-list-symbol">{{ (item.name || item.symbol_data || item.symbol || |
| | | '').toUpperCase().split('/')[0] }}</span> |
| | | </div> |
| | | <div class="assets-list-bottom"> |
| | | <div class="assets-list-cell"> |
| | | <span class="assets-list-label">{{ $t('Usable') }}</span> |
| | | <span class="assets-list-num">{{ item.volume != null ? item.volume : 0 }}</span> |
| | | </div> |
| | | <div class="assets-list-cell"> |
| | | <span class="assets-list-label">{{ $t('Locked') }}</span> |
| | | <span class="assets-list-num">{{ item.locked != null ? item.locked : 0 }}</span> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref } from "vue"; |
| | | import { useI18n } from "vue-i18n"; |
| | | import { ref, computed } from "vue"; |
| | | import { useRouter } from 'vue-router'; |
| | | import { _getExchangeRate } from '@/service/cryptos.api' |
| | | import { _exchangerateuserconfig } from "@/service/trade.api"; |
| | | import store from '@/store/store' |
| | | import { useStore } from "vuex" |
| | | import { |
| | | _getContractBySymbolType |
| | | } from "@/service/etf.api"; |
| | | import { _getContractBySymbolType } from "@/service/etf.api"; |
| | | import { SET_CURRENCY } from "@/store/const.store"; |
| | | import { _getassets } from "@/service/user.api.js"; |
| | | import { _getAllWallet } from '@/service/fund.api'; |
| | | import { HOST_URL } from '@/config'; |
| | | import { formatWithCommas } from '@/utils'; |
| | | import AssetsHead from '@/components/Transform/assets-head/index.vue'; |
| | | import fxKline from '@/components/fx-kline/index.vue'; |
| | | |
| | | const router = useRouter() |
| | | const { t } = useI18n() |
| | | const activeNames = ref(['1']) |
| | | const router = useRouter(); |
| | | const { dispatch } = useStore(); |
| | | |
| | | const tabList = [ |
| | | { key: 1, name: t('充值'), icon: new URL('@/assets/imgs/assets/chonbi.png', import.meta.url), path: '/cryptos/recharge/rechargeList?isForeign=true' }, |
| | | { key: 2, name: t('提现'), icon: new URL('@/assets/imgs/assets/tibi.png', import.meta.url), path: '/cryptos/Withdraw/withdrawPage' }, |
| | | { key: 3, name: t('划转'), icon: new URL('@/assets/imgs/assets/huazhuan.png', import.meta.url), path: '/my/transfer' }, |
| | | { key: 4, name: t('账单'), icon: new URL('@/assets/imgs/assets/zd.png', import.meta.url), path: '/cryptos/accountChange' }, |
| | | ] |
| | | const expanded = ref(false); |
| | | |
| | | const goBack = () => router.go(-1); |
| | | const toPage = (path) => { |
| | | if (!path) return; |
| | | router.push(path); |
| | | }; |
| | | |
| | | // 计价与资产 |
| | | const currency = ref({}); |
| | | const forexAssets = ref({}); |
| | | const assetObj = ref({}); |
| | | const symbolType = ref('cryptos'); |
| | | |
| | | const totalDisplay = computed(() => { |
| | | const v = forexAssets.value?.money_contract; |
| | | const rate = currency.value?.rate ?? 0; |
| | | if (v == null) return '0.00'; |
| | | return (v * rate).toFixed(2); |
| | | }); |
| | | |
| | | const futuresDisplay = computed(() => { |
| | | const v = forexAssets.value?.money_wallet ?? assetObj.value?.contract; |
| | | if (v == null) return '0'; |
| | | return Number(v).toFixed(2); |
| | | }); |
| | | |
| | | const bonusDisplay = computed(() => { |
| | | const v = assetObj.value?.capitalUSDT ?? 0; |
| | | return Number(v).toFixed(2); |
| | | }); |
| | | |
| | | const getCurrency = async () => { |
| | | try { |
| | | const res = await _getExchangeRate({ token: store.state.user.userInfo?.token }); |
| | | currency.value = res; |
| | | } catch (e) { } |
| | | }; |
| | | |
| | | const getContractBySymbolType = () => { |
| | | _getContractBySymbolType(symbolType.value).then(res => { |
| | | forexAssets.value = res; |
| | | }); |
| | | }; |
| | | |
| | | const getassets = () => { |
| | | _getassets().then(res => { |
| | | assetObj.value = res; |
| | | }); |
| | | }; |
| | | |
| | | // 资产列表 |
| | | const assetList = ref([]); |
| | | const getList = () => { |
| | | _getAllWallet({ symbolType: 'cryptos' }).then((res) => { |
| | | assetList.value = res.extends || []; |
| | | }); |
| | | }; |
| | | |
| | | // 计价切换 |
| | | const pricing = ref('') |
| | | const pricing = ref(''); |
| | | const pricingList = [ |
| | | { text: 'USD', value: 'USD', key: 'USD_in' }, |
| | | { text: 'EUR', value: 'EUR', key: 'EUR_in' }, |
| | | { text: 'JPY', value: 'JPY', key: 'JPY_in' }, |
| | | ] |
| | | ]; |
| | | const changePricing = (e) => { |
| | | let item = pricingList.find((item) => item.value == e) |
| | | const item = pricingList.find((i) => i.value === e); |
| | | if (item) { |
| | | _exchangerateuserconfig({ rateId: item.key }).then(() => { |
| | | dispatch(`home/${SET_CURRENCY}`); |
| | | getCurrency(); |
| | | getContractBySymbolType(); |
| | | }); |
| | | } |
| | | }; |
| | | |
| | | _exchangerateuserconfig({ rateId: item.key }).then((res) => { |
| | | dispatch(`home/${SET_CURRENCY}`) |
| | | getCurrency() |
| | | getContractBySymbolType() |
| | | }) |
| | | } |
| | | |
| | | // 跳转页面 |
| | | const toPage = (path) => { |
| | | if (!path) return |
| | | router.push(path) |
| | | } |
| | | |
| | | // 资产信息获取 |
| | | const currency = ref({}) |
| | | const forexAssets = ref({}) |
| | | const symbolType = ref('cryptos') //默认etf |
| | | const getCurrency = async () => { |
| | | _getExchangeRate({ |
| | | token: store.state.user.userInfo.token |
| | | }).then(res => { |
| | | currency.value = res |
| | | pricing.value = res.currency |
| | | }).catch(err => Promise.reject(err)) |
| | | } |
| | | const getContractBySymbolType = () => { |
| | | _getContractBySymbolType(symbolType.value) |
| | | .then(res => { |
| | | forexAssets.value = res |
| | | }) |
| | | } |
| | | const assetObj = ref({}) |
| | | const getassets = () => { // 获取资产 |
| | | _getassets().then(res => { |
| | | assetObj.value = res |
| | | }) |
| | | } |
| | | |
| | | // 获取资产列表 |
| | | const assetList = ref([]) |
| | | const getList = () => { |
| | | _getAllWallet({ |
| | | symbolType: 'cryptos' |
| | | }).then((res) => { |
| | | assetList.value = res.extends |
| | | console.log("资产列表", assetList.value); |
| | | |
| | | }); |
| | | } |
| | | |
| | | getList() |
| | | getassets() |
| | | getCurrency() |
| | | getContractBySymbolType() |
| | | getList(); |
| | | getassets(); |
| | | getCurrency(); |
| | | getContractBySymbolType(); |
| | | </script> |
| | | |
| | | |
| | | <style lang="scss" scoped> |
| | | .assets { |
| | | @import '@/assets/theme/index.scss'; |
| | | |
| | | .assets-page { |
| | | min-height: 100vh; |
| | | background: $mainbgWhiteColor; |
| | | padding: 2.8rem 2rem 10rem 2rem; |
| | | $assets_title_color: #9a9a9a; |
| | | color: $assets_title_color; |
| | | padding-bottom: 4rem; |
| | | |
| | | :deep(.van-cell) { |
| | | padding-left: 0; |
| | | padding-right: 0; |
| | | } |
| | | |
| | | :deep(.van-cell:after) { |
| | | display: none; |
| | | } |
| | | |
| | | :deep(.van-collapse-item__content) { |
| | | padding-left: 0; |
| | | padding-right: 0; |
| | | } |
| | | |
| | | :deep(.van-cell__title) { |
| | | font-size: 2.1rem; |
| | | font-weight: 600; |
| | | } |
| | | |
| | | .assets_title { |
| | | font-size: 2.1rem; |
| | | } |
| | | |
| | | .assets_money { |
| | | color: $text_color4; |
| | | font-size: 3.4rem; |
| | | |
| | | .pricing_jj { |
| | | font-size: 1.6rem; |
| | | margin-right: -8px; |
| | | } |
| | | |
| | | :deep(.van-dropdown-menu__bar) { |
| | | height: auto; |
| | | box-shadow: none; |
| | | } |
| | | |
| | | :deep(.van-dropdown-menu__title--down:after) { |
| | | margin-top: -14px !important; |
| | | } |
| | | |
| | | :deep(.van-dropdown-menu__title:after) { |
| | | margin-top: -16px; |
| | | } |
| | | |
| | | :deep(.van-ellipsis) { |
| | | display: none; |
| | | } |
| | | |
| | | :deep(.van-popup--top) { |
| | | padding: 10px 20px; |
| | | font-size: 2rem; |
| | | } |
| | | } |
| | | |
| | | .assets_revenue { |
| | | font-size: 2rem; |
| | | color: #646464; |
| | | font-weight: 600; |
| | | |
| | | span { |
| | | color: #6e6e6e; |
| | | text-decoration: underline dotted; |
| | | font-weight: 400; |
| | | } |
| | | } |
| | | |
| | | .tabbers { |
| | | .item { |
| | | $item_width: 8.3rem; |
| | | width: $item_width; |
| | | font-size: 1.8rem; |
| | | color: $text_color4; |
| | | |
| | | img { |
| | | height: $item_width; |
| | | border-radius: 50%; |
| | | } |
| | | } |
| | | } |
| | | |
| | | // .divider { |
| | | // height: 1rem; |
| | | // border-radius: 0.5rem; |
| | | // background: $bg_yellow; |
| | | // } |
| | | |
| | | .percentage { |
| | | div { |
| | | height: 1rem; |
| | | border-radius: 0.5rem; |
| | | } |
| | | |
| | | &>div:last-child { |
| | | background: $bg_yellow; |
| | | } |
| | | |
| | | &>div:first-child { |
| | | background: #8A90FE; |
| | | margin-right: 0.2rem; |
| | | } |
| | | } |
| | | |
| | | .assets_item { |
| | | color: $text_color4; |
| | | font-size: 2.1rem; |
| | | |
| | | .icon { |
| | | width: 1.8rem; |
| | | height: 1.8rem; |
| | | border-radius: 50%; |
| | | background: $icon-bg; |
| | | } |
| | | |
| | | img { |
| | | width: 2.8rem; |
| | | height: 2.8rem; |
| | | border-radius: 50%; |
| | | } |
| | | |
| | | .assets_item_light { |
| | | color: #9b9b9b; |
| | | font-weight: 300; |
| | | } |
| | | @include themify() { |
| | | background-color: #f6f5fa; |
| | | color: themed("text_color2"); |
| | | } |
| | | } |
| | | </style> |
| | | |
| | | .assets-head-menu { |
| | | padding: 0 8px; |
| | | |
| | | @include themify() { |
| | | color: themed("text_color2"); |
| | | } |
| | | } |
| | | |
| | | .assets-body { |
| | | padding: 0; |
| | | } |
| | | |
| | | .assets-total-card { |
| | | background: #fff; |
| | | border-radius: 16px; |
| | | padding: 20px 20px 12px; |
| | | margin-top: 10px; |
| | | |
| | | @include themify() { |
| | | background: themed("card_bg"); |
| | | } |
| | | } |
| | | |
| | | .assets-total-label { |
| | | font-size: 1.6rem; |
| | | |
| | | @include themify() { |
| | | color: themed("text_color2"); |
| | | } |
| | | } |
| | | |
| | | .assets-total-value { |
| | | font-size: 2.6rem; |
| | | font-weight: 700; |
| | | margin-top: 8px; |
| | | |
| | | @include themify() { |
| | | color: themed("text_color"); |
| | | } |
| | | } |
| | | |
| | | .assets-futures-bonus-row { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | margin-top: 16px; |
| | | padding-top: 12px; |
| | | border-top: 1px solid rgba(0, 0, 0, 0.06); |
| | | |
| | | @include themify() { |
| | | border-top-color: themed("border_color"); |
| | | } |
| | | } |
| | | |
| | | .assets-futures-cell, |
| | | .assets-bonus-cell { |
| | | display: flex; |
| | | flex-direction: column; |
| | | align-items: flex-start; |
| | | } |
| | | |
| | | .assets-bonus-cell { |
| | | width: 50%; |
| | | flex-direction: row; |
| | | align-items: center; |
| | | gap: 6px; |
| | | cursor: pointer; |
| | | } |
| | | |
| | | .assets-cell-label { |
| | | font-size: 1.8rem; |
| | | |
| | | @include themify() { |
| | | color: themed("text_color2"); |
| | | } |
| | | } |
| | | |
| | | .assets-cell-value { |
| | | font-size: 2.2rem; |
| | | font-weight: 600; |
| | | margin-top: 4px; |
| | | |
| | | @include themify() { |
| | | color: themed("text_color"); |
| | | } |
| | | } |
| | | |
| | | .assets-cell-arrow { |
| | | font-size: 16px; |
| | | margin-top: 2px; |
| | | |
| | | @include themify() { |
| | | color: themed("text_color2"); |
| | | } |
| | | } |
| | | |
| | | .assets-expand-btn { |
| | | display: flex; |
| | | justify-content: center; |
| | | padding: 8px 0 4px; |
| | | } |
| | | |
| | | .assets-chevron { |
| | | font-size: 20px; |
| | | |
| | | @include themify() { |
| | | color: themed("text_color2"); |
| | | } |
| | | } |
| | | |
| | | .assets-chart-section { |
| | | margin-top: 16px; |
| | | border-radius: 16px; |
| | | |
| | | @include themify() { |
| | | background: themed("card_bg"); |
| | | } |
| | | } |
| | | |
| | | .assets-chart-title { |
| | | font-size: 1.8rem; |
| | | margin-bottom: 12px; |
| | | |
| | | @include themify() { |
| | | color: themed("text_color2"); |
| | | } |
| | | } |
| | | |
| | | .assets-kline-wrap { |
| | | border-radius: 8px; |
| | | overflow: hidden; |
| | | min-height: 260px; |
| | | } |
| | | |
| | | .assets-list-head { |
| | | font-size: 2.4rem; |
| | | font-weight: 700; |
| | | margin-top: 24px; |
| | | margin-bottom: 12px; |
| | | padding-left: 20px; |
| | | |
| | | @include themify() { |
| | | color: themed("text_color"); |
| | | } |
| | | } |
| | | |
| | | .assets-list { |
| | | display: flex; |
| | | flex-direction: column; |
| | | padding: 0 20px; |
| | | |
| | | } |
| | | |
| | | .assets-list-card { |
| | | display: flex; |
| | | flex-direction: column; |
| | | margin: 10px 0 0; |
| | | background-color: #fff; |
| | | border-radius: 16px; |
| | | padding: 20px 18px; |
| | | box-shadow: 0 1px 4px rgba(0, 0, 0, 0.06); |
| | | |
| | | @include themify() { |
| | | background: themed("card_bg"); |
| | | color: themed("text_color2"); |
| | | box-shadow: 0 1px 4px rgba(0, 0, 0, 0.06); |
| | | } |
| | | } |
| | | |
| | | .assets-list-top { |
| | | display: flex; |
| | | align-items: center; |
| | | gap: 8px; |
| | | } |
| | | |
| | | .assets-list-icon { |
| | | width: 22px; |
| | | height: 22px; |
| | | border-radius: 50%; |
| | | object-fit: cover; |
| | | flex-shrink: 0; |
| | | } |
| | | |
| | | .assets-list-symbol { |
| | | font-size: 2rem; |
| | | font-weight: 500; |
| | | |
| | | @include themify() { |
| | | color: themed("text_color"); |
| | | } |
| | | } |
| | | |
| | | .assets-list-bottom { |
| | | display: flex; |
| | | justify-content: space-around; |
| | | align-items: flex-start; |
| | | padding-top: 12px; |
| | | |
| | | @include themify() { |
| | | border-top-color: themed("border_color"); |
| | | } |
| | | } |
| | | |
| | | .assets-list-cell { |
| | | display: flex; |
| | | flex-direction: column; |
| | | align-items: center; |
| | | gap: 4px; |
| | | } |
| | | |
| | | .assets-list-label { |
| | | font-size: 1.4rem; |
| | | font-weight: 400; |
| | | text-align: center; |
| | | |
| | | @include themify() { |
| | | color: themed("text_color2"); |
| | | } |
| | | } |
| | | |
| | | .assets-list-num { |
| | | font-size: 2.2rem; |
| | | font-weight: 700; |
| | | text-align: center; |
| | | |
| | | @include themify() { |
| | | color: themed("text_color"); |
| | | } |
| | | } |
| | | </style> |