<template>
|
<div class="pb-108 no_touch trade">
|
<!-- <div class="px-30 pt-20">
|
<div class="flex h-88 w-full box-border border-solid-grey rounded-lg">
|
<div @click="$router.push('/exchange/exchangePage')"
|
class="font-bold font-32 flex justify-center items-center flex-1">
|
<span class="h-60 lh-60 font-16 px-40 borderColor rounded-lg textColor">{{ $t('闪兑') }}</span>
|
</div>
|
<div class="font-bold flex font-32 justify-center items-center flex-1">
|
<span class="h-60 lh-60 btnMain px-40 rounded-lg text-white font-16">{{ $t('现货') }}</span>
|
</div>
|
<div @click="$router.push({ path: '/wantBuy', query: { frompath: `/trade/${symbol}` } })"
|
class="font-bold font-32 flex justify-center items-center flex-1">
|
<span class="h-60 lh-60 font-16 px-40 borderColor rounded-lg textColor">c2c</span>
|
</div>
|
</div>
|
</div> -->
|
<!-- :key="symbol"-->
|
<!-- 头部区 -->
|
<trade-head :backFunc="() => $router.push('/')" :symbol="symbol" :price="price" :range="range" :isTrade="true"
|
@update-coin="onUpdate" @data="quote = $event" />
|
|
<div class="trade-buy-sell flex justify-between px-30 py-30">
|
<trade-order-area :symbol="symbol" :init-open="initOpen" :init-close="initClose" :price="price"
|
@ordered="onOrdered" />
|
<keep-alive>
|
<trade-deep-data :selectValue="selectValue" @getList="getList" :showType="showType" :symbol="symbol"
|
v-if="symbol" :price="price" class="w-290 ml-30" />
|
</keep-alive>
|
</div>
|
<div class="flex k-select-box">
|
<div class="mt-20 mb-22 select-box" style="position:relative;">
|
<div class=" flex justify-between items-center w-full h-70" @click="selectBtn">
|
<!-- <img src="@/assets/image/public/warn.png" alt="warn-icon" class="w-25 h-25 pl-20"/> -->
|
<div class="pl-16 textColor" style="width:80%;">{{ title }}</div>
|
<img src="@/assets/image/public/grey-select.png" alt="select-icon" class="w-22 h-11 pr-20" />
|
</div>
|
<div class="option-box" v-show="isShow">
|
<div class="font-30" v-for="(item, index) in sortList" :key="index" @click="selectItem(item)">{{
|
item.name
|
}}
|
</div>
|
</div>
|
</div>
|
<div @click="isSelectShow = true">
|
<img src="@/assets/image/selectIcon.png" alt="warn-icon" class="w-36 h-30" />
|
</div>
|
</div>
|
<div class="h-16 diviLine"></div>
|
<div>
|
<div class="flex justify-between pb-20 border-b-color items-center">
|
<div class="flex pl-30">
|
<template>
|
<div class="px-10 py-10 flex items-center text-grey" @click="tabClick('1')"
|
:class="tabType == '1' ? 'active-line' : ''">{{ $t('当前委托') }}<span v-if="tabType == '1'">({{
|
entrustList.length }})</span></div>
|
<div class="px-10 ml-50 py-10 flex items-center text-grey" @click="tabClick('3')"
|
:class="tabType == '3' ? 'active-line' : ''">{{ $t('历史委托') }}</div>
|
<div class="px-10 py-10 flex items-center ml-50 text-grey" @click="tabClick('2')"
|
:class="tabType == '2' ? 'active-line' : ''">{{ $t('资产') }}</div>
|
</template>
|
</div>
|
<img src="../../assets/image/public/record.png" alt="record-img" class="w-32 h-35 pr-30 "
|
@click="goHistory" />
|
</div>
|
</div>
|
<div class="pl-32 pr-32 pb-100" v-if="tabType == '1'">
|
<entrust-item v-for="item in entrustList" :key="item.order_no" :entrust="item" state="submitted"
|
@cancelOrder="cancelOrder" />
|
</div>
|
<div class="pl-32 pr-32 pb-100" v-else-if="tabType == '3'">
|
<history-item v-for="item in entrustList" :key="item.order_no" :coinPrice="coinPrice" :entrust="item"
|
:state="item.state" @cancelOrder="cancelOrder" />
|
</div>
|
<div class="pl-32 pr-32" v-else>
|
<div class="mb-20 border-b">
|
<p class="font-28 text-grey mt-24 mb-42">{{ $t('当前币对资产') }}</p>
|
<ul>
|
<li v-for="item in pairsList" :key="item.symbol" class="flex justify-between py-10">
|
<div class="flex items-center">
|
<img :src="item.symbol ? `${HOST_URL}/symbol/${item.symbol}.png` : require('@/assets/loading-default.png')"
|
class="w-52 h-52 rounded-full mr-16" />
|
<p class="flex flex-col">
|
<strong class="font-28 textColor mb-6">{{ item.symbol.toUpperCase() }}</strong>
|
<span class="font-20 text-grey">{{ item.full_name }}</span>
|
</p>
|
</div>
|
<div class="flex flex-col items-end text-grey">
|
<strong class="font-28 textColor mb-6">{{ item.volume }}</strong>
|
<span class="font-20 text-grey">
|
{{ currency.currency_symbol }}
|
{{ item.usdt ? (item.usdt * currency.rate).toFixed(2) : '0.0' }}
|
</span>
|
</div>
|
</li>
|
</ul>
|
</div>
|
<div class="mb-60 border-b">
|
<p class="font-28 text-grey mt-24 mb-42">{{ $t('其他非0资产') }}</p>
|
<ul>
|
<li v-for="item in no_zeroList" :key="item.symbol" class="flex justify-between py-10">
|
<div class="flex items-center">
|
<img :src="item.symbol ? `${HOST_URL}/symbol/${item.symbol}.png` : require('@/assets/loading-default.png')"
|
class="w-52 h-52 rounded-full mr-16" />
|
<p class="flex flex-col">
|
<strong class="font-28 textColor mb-6">{{ item.symbol.toUpperCase() }}</strong>
|
<span class="font-20 text-grey">{{ item.full_name }}</span>
|
</p>
|
</div>
|
<div class="flex flex-col items-end">
|
<strong class="font-28 textColor mb-6">{{ item.volume }}</strong>
|
<span class="font-20 text-grey">
|
{{ currency.currency_symbol }}
|
{{ item.usdt ? (item.usdt * currency.rate).toFixed(2) : '0.0' }}
|
</span>
|
</div>
|
</li>
|
</ul>
|
</div>
|
</div>
|
<div v-if="tabType == '1' && !entrustList.length" class="flex flex-col justify-center items-center pt-185 pb-100">
|
<img src="@/assets/image/assets-center/no-data.png" alt="no-date" class="w-180 h-180" />
|
<p class="textColor">{{ $t('暂无数据') }}</p>
|
</div>
|
<div class="fixed w-full shadow z-10 tabBackground1">
|
<div class="flex justify-between px-30 py-10">
|
<span class="font-24 textColor2">{{ symbol.toUpperCase() }}/USDT {{ $t('k线图表') }}</span>
|
<van-icon class="textColor" @click.stop="showCharts = !showCharts"
|
:name="showCharts ? 'arrow-down' : 'arrow-up'"></van-icon>
|
</div>
|
<k-line-charts :update-key="updateKey" :update-data="quote" :symbol="symbol" v-if="symbol && showCharts"
|
:showBottom="false" />
|
</div>
|
<van-action-sheet v-model="isSelectShow" @select="onSelect" :actions="actions" :cancel-text="$t('取消')"
|
close-on-click-action @cancel="onCancel" />
|
</div>
|
</template>
|
|
<script>
|
import TradeHead from '@/components/trade-head/index.vue'
|
import TradeOrderArea from '@/components/trade-order-area/index.vue'
|
import TradeDeepData from '@/components/trade-deep-data/index.vue'
|
import EntrustItem from '@/components/entrust-item'
|
import KLineCharts from '@/components/kline-charts'
|
import historyItem from '@/components/history-item'
|
|
import Axios from '@/API/trading'
|
import { _getHomeList } from '@/API/home.api'
|
import { Popup, Swipe, SwipeItem, Circle, Icon, ActionSheet } from 'vant';
|
import { mapActions, mapGetters } from 'vuex'
|
import { SET_COIN_LIST } from '@/store/const.store'
|
import { WS_URL, HOST_URL } from '@/config'
|
import TradeApi from "@/API/trading.js";
|
import { getStorage } from '@/utils/utis'
|
|
export default {
|
name: "TradePage",
|
components: {
|
TradeHead,
|
TradeOrderArea,
|
TradeDeepData,
|
[Popup.name]: Popup,
|
[Swipe.name]: Swipe,
|
[SwipeItem.name]: SwipeItem,
|
[Circle.name]: Circle,
|
[Icon.name]: Icon,
|
[ActionSheet.name]: ActionSheet,
|
EntrustItem,
|
KLineCharts,
|
historyItem
|
},
|
computed: {
|
...mapGetters('user', ['userInfo']),
|
...mapGetters({
|
coinList: 'home/coinList',
|
currency: 'home/currency'
|
}),
|
},
|
data() {
|
const initArr = []
|
for (let i = 0; i < 8; i++) {
|
initArr.push({
|
volume: '--',
|
price: '--'
|
})
|
}
|
return {
|
HOST_URL,
|
quote: {},
|
showCharts: false,
|
updateKey: 1,
|
initTimer: null,
|
keyIndex: 0,
|
timeout: null,
|
timer: null, // 底部持仓等的公用定时器
|
timer2: null, // 交割合约底部持仓等的公用定时器
|
symbol: '',
|
price: '',
|
range: '',
|
initOpen: {},
|
initClose: {},
|
asks: initArr, // 卖单
|
bids: initArr, // 买单
|
orderCur: [], // 当前委托
|
orderHold: [], // 持有仓位
|
futrueHold: [], // 交割持仓
|
futrueHistroy: [], // 交割历史
|
socket: null, // 行情
|
sockets: {
|
quotes: null, // 行情
|
deep: null /// 深度
|
},
|
curTab: '', // 当前委托还是持有仓位
|
selectIndex: 1, // 当前tab
|
initFutrue: {}, /// 交割合约
|
show: false, // popup
|
entrustList: [], //当前委托订单
|
tabType: 1,
|
no_zeroList: [], //其他非0资产数组
|
pairsList: {}, //当前资产
|
// curRequest: [], //
|
isShow: false,
|
title: 1,
|
isSelectShow: false,
|
actions: [{ name: this.$t('默认'), value: 0, className: 'actions-active' }, { name: this.$t('展示买单'), value: 1, className: "" }, { name: this.$t('展示卖单'), value: 2, className: '' }],
|
showType: 0,
|
sortList: [],
|
selectValue: 0,
|
coinPrice: 0
|
|
}
|
},
|
async created() {
|
if (!this.coinList.length) {
|
await this.SET_COIN_LIST()
|
}
|
},
|
methods: {
|
...mapActions('home', [SET_COIN_LIST]),
|
onUpdate(symbol) { // 更新
|
this.symbol = symbol
|
this.closeSocket()
|
this.init(symbol)
|
},
|
getCoinPrce(val) {
|
_getHomeList(val).then((res) => {
|
this.coinPrice = res[0].close
|
})
|
},
|
tabClick(type) {
|
this.tabType = type;
|
if (type == 2 && !this.userInfo.token) {
|
this.$router.push('/login')
|
return
|
}
|
this.entrustList = []
|
this.getOrderList()
|
},
|
onOrdered(evt) { // 下单过后的回调
|
this.clearTimer()
|
// this.clearTimeout()
|
this.initParam(this.symbol, evt) // 重新初始化
|
//console.log('下单后更新数据')
|
},
|
onTab(evt) { // 点击tab后的回调
|
console.log('evt', evt)
|
this.clearTimer()
|
// this.clearTimeout()
|
this.curTab = evt
|
this[evt](this.symbol)
|
},
|
handleQoutes(data) {
|
if (data && data.length) {
|
const cur = data[0]
|
this.price = cur.close
|
this.range = cur.change_ratio + ''
|
this.quote = cur
|
this.updateKey++
|
}
|
},
|
startQuoteSocket() { // 行情socket
|
console.log('symbol', this.symbol)
|
if (!this.symbol) {
|
return
|
}
|
this.socket = new WebSocket(`${WS_URL}/1/${this.symbol}`)
|
this.socket.onmessage = (evt) => {
|
const { data } = evt
|
const { code, data: _data } = JSON.parse(data)
|
if (code / 1 === 0) {
|
this.handleQoutes(_data)
|
}
|
}
|
},
|
initParam(symbol, type) { // 初始化参数
|
if (type === 'open' || !type) {
|
//console.log('开仓数据')
|
Axios.tradeBuyToken({})
|
.then(res => {
|
this.initOpen = res.data
|
console.log(this.initOpen.volume, res.data.volume, type)
|
})
|
}
|
if (type === 'close' || !type) {
|
Axios.tradeSellToken({
|
symbol
|
}).then(res => {
|
this.initClose = res.data
|
})
|
}
|
this.getWallet()
|
if (this.userInfo.token) {
|
this.getOrderList();
|
}
|
},
|
init(symbol) { // 初始化页面
|
this.symbol = symbol.toLowerCase()
|
if (!this.socket) {
|
this.startQuoteSocket()
|
}
|
this.initParam(symbol) // 'open'
|
this.clearTimer()
|
this.getCoinPrce(symbol)
|
},
|
closeSocket() {
|
this.socket && this.socket.close()
|
this.socket = null
|
},
|
clearTimer() {
|
clearInterval(this.timer)
|
this.timer = null
|
},
|
tradeBuy() {
|
Axios.tradeBuy({
|
volume: 1,
|
session_token: '',
|
symbol: '',
|
price: 1,
|
order_price_type: '' //limit限价 opponent市价
|
}).then((res) => {
|
console.log(res);
|
}).catch((error) => {
|
if (error.code === 'ECONNABORTED') { this.$toast(this.$t('网络超时!')); }
|
else if (error.msg !== undefined) { this.$toast(this.$t(error.msg)); }
|
});
|
},
|
getOrderList() {
|
TradeApi.tradeRecord({
|
page_no: 1,
|
symbol: this.$route.params.symbol,
|
type: this.tabType == 1 ? 'orders' : 'hisorders'
|
}).then(res => {
|
console.log(res.data);
|
this.entrustList = res.data
|
}).catch(() => {
|
|
})
|
},
|
cancelOrder(order) {
|
TradeApi.tradeCancel({
|
order_no: order,
|
}).then(res => {
|
this.initParam(this.symbol)
|
this.$toast(this.$t('成功'))
|
}).catch(() => {
|
|
})
|
},
|
getWallet() {
|
TradeApi.getPairs({
|
pairs: `${this.symbol}/usdt`
|
})
|
.then(res => {
|
this.pairsList = res.data.pairs;
|
this.no_zeroList = res.data.no_zero;
|
})
|
},
|
goHistory() {
|
this.$router.push(`/tradeRecord/${this.symbol}`)
|
},
|
//价格类型下拉框切换
|
selectBtn() {
|
this.isShow = !this.isShow;
|
},
|
//选择价格类型
|
selectItem(item) {
|
this.title = item.name;
|
this.isShow = false;
|
this.selectValue = item.value
|
},
|
onSelect(item) {
|
this.showType = item.value
|
this.actions.map((item) => {
|
item.className = ''
|
})
|
item.className = 'actions-active'
|
},
|
onCancel() {
|
this.isSelectShow = false
|
},
|
getList(val) {
|
if (val.numberLength <= 2) {
|
this.title = val.arry[0].name
|
} else {
|
this.title = val.arry[val.arry.length - 1].name
|
}
|
this.sortList = val.arry
|
}
|
},
|
beforeRouteEnter(to, from, next) {
|
let { params: { symbol } } = to
|
console.log('to', to)
|
let catchTradeSymbol = getStorage('tradeSymbol')
|
if (catchTradeSymbol) {
|
symbol = catchTradeSymbol
|
}
|
console.log(catchTradeSymbol)
|
if (symbol) {
|
next(vm => {
|
vm.symbol = symbol
|
vm.init(symbol)
|
})
|
} else {
|
next()
|
}
|
},
|
activated() {
|
// if (!this.socket) {
|
// this.startQuoteSocket()
|
// }
|
},
|
deactivated() {
|
this.closeSocket()
|
this.clearTimer()
|
},
|
beforeDestroy() {
|
this.closeSocket()
|
// this.clearTimeout(true)
|
this.clearTimer()
|
}
|
}
|
|
</script>
|
|
<style lang="scss" scoped>
|
//.list-enter-active, .list-leave-active {
|
// transition: all .5s;
|
// transform: translateY(30px)
|
//}
|
//.list-enter, .list-leave-to
|
// /* .list-leave-active for below version 2.1.8 */ {
|
// transform: translateY(0)
|
//}
|
|
.no_touch {
|
-webkit-user-select: none;
|
user-select: none;
|
-ms-user-select: none;
|
-moz-user-select: none;
|
|
@include themify() {
|
background: themed("main_background");
|
}
|
|
min-height: 100vh;
|
}
|
|
.list-enter-active,
|
.list-leave-active {
|
will-change: transform;
|
transition: all 250ms;
|
}
|
|
.list-enter {
|
opacity: 0;
|
transform: translate3d(-100%, 0, 0);
|
}
|
|
.list-leave {
|
opacity: 0;
|
transform: translate3d(100%, 0, 0);
|
}
|
|
.rounded-view {
|
border-top-left-radius: 20px;
|
border-top-right-radius: 20px;
|
padding: 0 30px;
|
box-sizing: border-box;
|
}
|
|
.my-swipe {
|
width: 100%;
|
}
|
|
.active-line {
|
position: relative;
|
// padding: 15px 0;
|
color: #fff;
|
|
@include themify() {
|
background-color: themed("color_main");
|
}
|
}
|
|
// .active-line::after {
|
// content: '';
|
// position: absolute;
|
// left: 50%;
|
// transform: translateX(-50%);
|
// bottom: 0;
|
// right: 0;
|
// width: 280px;
|
// height: 8px;
|
// @include themify() {
|
// background-color: themed("color_main");
|
// }
|
// }
|
|
.shadow {
|
bottom: 108px;
|
box-sizing: border-box;
|
}
|
|
// .textColor {
|
// color: #DAD5DC;
|
// }
|
|
.borderColor,
|
.border-solid-grey {
|
@include themify() {
|
border: 1px solid themed("border_color");
|
}
|
}
|
|
|
.tabBackground1 {
|
@include themify() {
|
border: 1px solid themed("border_color1");
|
}
|
}
|
|
// 下拉
|
.option-box {
|
position: absolute;
|
left: 0;
|
right: 0;
|
top: 90px;
|
width: 100%;
|
|
@include themify() {
|
background: themed("grey_bg");
|
}
|
|
text-align: center;
|
border-radius: 4px;
|
|
@include themify() {
|
color: themed("text_color3");
|
}
|
|
z-index: 10;
|
}
|
|
.option-box>div {
|
padding: 30px 0;
|
}
|
|
.option-box>div:hover {
|
// background-color: #F5F5F5;
|
}
|
|
.k-select-box {
|
position: relative;
|
top: -130px;
|
justify-content: flex-end;
|
padding: 0 30px;
|
align-items: center;
|
|
.select-box {
|
width: 220px;
|
|
@include themify() {
|
background: themed("input_background");
|
}
|
|
margin-right: 20px;
|
}
|
|
}
|
|
.van-popup {
|
@include themify() {
|
background: themed("color_main");
|
}
|
}
|
|
.actions-active {
|
@include themify() {
|
background: themed("color_main") !important;
|
}
|
}
|
|
.trade {
|
|
::v-deep .van-action-sheet__item,
|
::v-deep .van-action-sheet__cancel {
|
|
@include themify() {
|
background: themed("input_background1");
|
}
|
|
@include themify() {
|
color: themed("text_color");
|
}
|
}
|
|
::v-deep .van-action-sheet__gap {
|
@include themify() {
|
background: themed("cont_background");
|
}
|
}
|
}
|
</style>
|