You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

341 lines
9.3 KiB

<template>
<view class="page-container">
<!-- 1. 顶部搜索栏 -->
<view class="search-header">
<view class="search-box">
<!-- 搜索图标 (这里用简单的纯CSS画一个放大镜也可以替换为uni-icons) -->
<text class="search-icon"><i class="el-icon-search"></i></text>
<input
class="search-input"
type="text"
:placeholder="$t('base.d9')"
placeholder-class="placeholder-style"
/>
</view>
</view>
<!-- 2. 导航 Tabs -->
<view class="tab-header">
<view class="tab-list">
<view class="tab-item" v-for="tab in tabs" :key="tab.id" :class="{ active: activeTab === tab.id }" @click="switchTab(tab.id)">
{{ $t(tab.name) }}
</view>
</view>
</view>
<!-- 3. 主体白底卡片区 (占据剩余全部高度) -->
<view class="main-card">
<scroll-view class="scroll-area" scroll-y="true">
<view v-if="activeTab=='optional'"></view>
<view v-if="activeTab=='crypto'">
<view class="p-x-xs m-t-md">
<table class="w-max">
<thead v-if="heyue==0">
<tr class="fn-sm">
<th class="p-l-md p-y-xs fn-left">{{ $t("exchange.f7") }}</th>
<th class="fn-left">{{ $t("exchange.f8") }}</th>
<th class="p-y-xs fn-right" style="text-align: center;">{{ $t("exchange.f9") }}</th>
</tr>
</thead>
<tbody v-for="parentItem in marketList" :key="parentItem.coin_name">
<!-- :class="symbols==item.coin_name&&heyue==1?'bg-panel':''" v-show="isShow(item.pair_name)" -->
<tr class="p-y-md" v-for="item in parentItem.marketInfoList" :key="item.symbol" style="font-weight: bold;height: 100rpx;" @click="tosymbol(item,1)">
<td class="p-l-md w-40">
<template v-if="parentItem.isCollect">
<span class="color-light">{{ item.pair_name }}</span>
</template>
<template v-else>
<img :src="item.coin_icon" width="25" style="margin-right: 10rpx;" />
<span class="color-light">{{ item.coin_name||item.symbol }}/{{ parentItem.coin_name }}</span>
</template>
</td>
<td class="w-30">
<!-- fn-center -->
<template v-if="heyue==0" :class="item.increase < 0 ? 'color-sell' : 'color-buy'">
{{ item.price }}
</template>
<template v-else>
{{$t('first.b8')}}
</template>
</td>
<td v-if="heyue==0" :class="item.increase < 0 ? 'color-sell' : 'color-buy'" class=" p-y-xs fn-right w-30" style="text-align: center;">
<view :class="item.increase < 0 ? 'color-sell1' : 'color-buy1'">{{ item.increaseStr }}</view>
</td>
<td v-if="heyue==1" :class="item.increase < 0 ? 'color-sell' : 'color-buy'" class="p-r-md p-y-xs fn-right">
{{ item.price }}
</td>
</tr>
</tbody>
</table>
</view>
</view>
<view v-if="activeTab=='stock'">
<view class="p-x-xs m-t-md">
<table class="w-max">
<thead v-if="heyue==0">
<tr class="fn-sm">
<th class="p-l-md p-y-xs fn-left">{{ $t("exchange.f7") }}</th>
<th class="fn-left">{{ $t("exchange.f8") }}</th>
<th class="p-y-xs fn-right" style="text-align: center;">{{ $t("exchange.f9") }}</th>
</tr>
</thead>
<tbody v-for="parentItem in marketList1" :key="parentItem.coin_name">
<!-- :class="symbols==item.coin_name&&heyue==1?'bg-panel':''" v-show="isShow(item.pair_name)" @click="$emit('check-symbol', item)" -->
<tr class="p-y-md" v-for="item in parentItem.marketInfoList" :key="item.symbol" style="font-weight: bold;height: 100rpx;" @click="tosymbol(item,2)">
<td class="p-l-md w-40">
<template v-if="parentItem.isCollect">
<span class="color-light">{{ item.pair_name }}</span>
</template>
<template v-else>
<img :src="item.coin_icon" width="25" style="margin-right: 10rpx;" />
<span class="color-light">{{ item.coin_name||item.symbol }}/{{ parentItem.coin_name }}</span>
</template>
</td>
<td class="w-30">
<!-- fn-center -->
<template v-if="heyue==0" :class="item.increase < 0 ? 'color-sell' : 'color-buy'">
{{ item.price }}
</template>
<template v-else>
{{$t('first.b8')}}
</template>
</td>
<td v-if="heyue==0" :class="item.increase < 0 ? 'color-sell' : 'color-buy'" class=" p-y-xs fn-right w-30" style="text-align: center;">
<view :class="item.increase < 0 ? 'color-sell1' : 'color-buy1'">{{ item.increaseStr }}</view>
</td>
<td v-if="heyue==1" :class="item.increase < 0 ? 'color-sell' : 'color-buy'" class="p-r-md p-y-xs fn-right">
{{ item.price }}
</td>
</tr>
</tbody>
</table>
</view>
</view>
</scroll-view>
</view>
</view>
</template>
<script>
import Market from "@/api/market";
import { mapState } from "vuex";
import Contract from "@/api/contract";
export default {
props: {
isShow: {
default: false,
type: Boolean,
required: false,
},
tabChange: {
type: Function,
default: null
}
},
data() {
return {
activeTab: 'crypto', // 当前激活的 Tab
heyue: 0,
// Tabs 数据
tabs: [
// { id: 'optional', name: '自選' },
{ id: 'crypto', name: 'homeNewText.hh7' },
{ id: 'stock', name: 'homeNewText.hh6' }
],
marketList: [],
marketList1: [],
msg: "exchangeMarketList",
};
},
watch: {
isShow(n) {
if (n) {
setTimeout(() => {
this.ws.send({
cmd: "sub",
msg: this.msg,
});
}, 200);
} else {
this.ws.send({
cmd: "unsub",
msg: this.msg,
});
}
},
},
computed: {
...mapState({
ws: "ws",
}),
},
created() {
this.getMarketList();
this.getstockMarketList();
},
methods: {
// 切换 Tab 方法
switchTab(tabId) {
this.activeTab = tabId;
},
getMarketList() {
Contract.getMarketList().then((res) => {
this.marketList.push(res.data[0]);
this.$nextTick(() => {
this.linkSocket();
});
});
},
// 获取市场行情
getstockMarketList() {
Market.getstockMarketList().then((res) => {
// this.marketList = res.data;
this.marketList1.push(res.data[0]);
});
},
// 链接socket
linkSocket() {
let msg = this.msg;
this.ws.send({
cmd: "sub",
msg,
});
this.ws.on("message", (res) => {
let { data, sub } = res;
console.log(data)
if (sub == msg) {
this.marketList.push(res.data[0]);
// this.marketList = data;
// var symbol=this.query.symbol.split('/')
// var market=this.marketList.find((item) => item.coin_name == symbol[1])
// this.increase=market.marketInfoList.find((item) => item.coin_name == symbol[0])||{}
}
});
},
tosymbol(data,num){
// console.log(data.pair_name);
this.tabChange('TransactionList',data.pair_name,num)
}
}
};
</script>
<style scoped lang="scss">
/* 终极防挤压布局整个页面绝对不超出 100vh */
.page-container {
display: flex;
flex-direction: column;
height: 100vh;
overflow: hidden;
background-color: var(--panel-5);
height: 100%;
}
/* ================= 1. 搜索栏 ================= */
.search-header {
padding: 20rpx 30rpx;
background-color: var(--panel-3);
flex-shrink: 0; /* 保证不被压缩 */
}
.search-box {
background-color: #ececec; /* 浅灰搜索框底色 */
height: 72rpx;
border-radius: 36rpx;
display: flex;
align-items: center;
padding: 0 30rpx;
}
.search-icon {
font-size: 28rpx;
color: #999;
margin-right: 15rpx;
/* 如果是PC浏览器预览Emoji会有色彩真机上推荐换成图片或uni-icons */
filter: grayscale(100%);
}
.search-input {
flex: 1;
font-size: 28rpx;
color: #333;
}
.placeholder-style {
color: #999;
font-size: 28rpx;
}
/* ================= 2. 顶部 Tabs ================= */
.tab-header {
padding: 0 10rpx;
// background-color: #f7f8fa;
flex-shrink: 0;
}
.tab-list {
display: flex;
align-items: center;
}
.tab-item {
font-size: 32rpx;
color: #666;
padding: 20rpx 30rpx;
position: relative;
transition: all 0.2s;
}
.tab-item.active {
color: #00b578; /* 绿色文字 */
font-weight: bold;
}
/* 激活状态下的绿色小横线 */
.tab-item.active::after {
content: '';
position: absolute;
bottom: 0;
left: 30rpx;
right: 30rpx;
height: 4rpx;
background-color: #00b578;
border-radius: 4rpx;
}
/* ================= 3. 主体白底卡片区 ================= */
.main-card {
flex: 1; /* 撑满剩余全部高度 */
background-color: var(--panel-3);
border-radius: 30rpx 30rpx 0 0; /* 顶部圆角 */
// box-shadow: 0 -4rpx 20rpx rgba(0,0,0,0.03);
overflow: hidden; /* 防止内部内容撑破卡片 */
}
/* scroll-view 必须设置 100% 高度 */
.scroll-area {
height: 100%;
width: 100%;
}
.color-sell1{
background-color: rgba(223, 41, 74, 0.2);
color: #d62548;
border-radius: 10rpx;
height: 70rpx;
line-height: 70rpx;
}
.color-buy1{
background-color: rgba(46, 189, 133, 0.2);
color: #4bbd83;
border-radius: 10rpx;
height: 70rpx;
line-height: 70rpx;
}
</style>