<template>
|
<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="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="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>
|
|
<!-- 展开后: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-expand-btn" @click="expanded = !expanded">
|
<van-icon :name="expanded ? 'arrow-up' : 'arrow-down'" class="assets-chevron" />
|
</div>
|
</div>
|
|
|
<!-- 资产列表 -->
|
<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>
|
</div>
|
</template>
|
|
<script setup>
|
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 { 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 { dispatch } = useStore();
|
|
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 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) => {
|
const item = pricingList.find((i) => i.value === e);
|
if (item) {
|
_exchangerateuserconfig({ rateId: item.key }).then(() => {
|
dispatch(`home/${SET_CURRENCY}`);
|
getCurrency();
|
getContractBySymbolType();
|
});
|
}
|
};
|
|
getList();
|
getassets();
|
getCurrency();
|
getContractBySymbolType();
|
</script>
|
|
<style lang="scss" scoped>
|
@import '@/assets/theme/index.scss';
|
|
.assets-page {
|
min-height: 100vh;
|
padding-bottom: 4rem;
|
|
@include themify() {
|
background-color: #f6f5fa;
|
color: themed("text_color2");
|
}
|
}
|
|
.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>
|