<template>
|
<div :key="symbol" class="pb-108 no_touch">
|
<!-- 头部区 -->
|
<ContractHeader :symbol="symbol" :range="range" :selectIndex="selectIndex" :balance="userInfo.balance"
|
@tab="onTopTab" @update-coin="onUpdate">
|
</ContractHeader>
|
|
<div :class="{ slide2: animated1 }" v-if="selectIndex === 1">
|
<div class="mainBackground" key="x">
|
<PerpetualOpen class="pl-30 pr-30" :key="keyIndex + 'a'" :selectIndex="selectIndex" :symbol="symbol"
|
:green-data="bids" :red-data="asks" :price="price" :init-open="initOpen" :init-close="initClose"
|
:init-futrue="initFutrue" @ordered="onOrdered" :currentType="currentType"
|
@changeCurrentType="changeCurrentType" @changeValueBack="changeValueBack">
|
</PerpetualOpen>
|
<div class="line"></div>
|
<!-- 委托/持仓-->
|
<PerpetualOrder class="pl-30 pr-30" :key="keyIndex + 'b'" :symbol="symbol" :order-cur="orderCur"
|
:order-hold="orderHold" :topIndex="selectIndex" :futrue-hold="futrueHold"
|
:futrue-histroy="futrueHistroy" @tab="onTab" @recall="onRecall">
|
</PerpetualOrder>
|
</div>
|
</div>
|
<div :class="{ slide1: animated2 }" v-else>
|
<div class="mainBackground" key="y">
|
<PerpetualOpen class="pl-30 pr-30" :key="keyIndex + 'c'" :selectIndex="selectIndex" :symbol="symbol"
|
:green-data="bids" :red-data="asks" :price="price" :init-open="initOpen" :init-close="initClose"
|
:init-futrue="initFutrue" @ordered="onOrdered" @changeValueBack="changeValueBack">
|
</PerpetualOpen>
|
<div class="line"></div>
|
<!-- 委托/持仓-->
|
<PerpetualOrder class="pl-30 pr-30" :key="keyIndex + 'd'" :symbol="symbol" :order-cur="orderCur"
|
:order-hold="orderHold" :price="price" :topIndex="selectIndex" :futrue-hold="futrueHold"
|
:futrue-histroy="futrueHistroy" @tab="onTab" @recall="onRecall">
|
</PerpetualOrder>
|
</div>
|
</div>
|
<!-- <div class="fixed w-full shadow z-10 tabBackground1"> -->
|
<div class="flex justify-between px-30 py-10">
|
<span class="font-24 textColor2" >{{ symbolname }} {{ $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"
|
:showBottom="false" />
|
<!-- </div> -->
|
</div>
|
</template>
|
|
<script>
|
import ContractHeader from '@/components/contract-header/index.vue'
|
import PerpetualOpen from '@/components/perpetual-open/index.vue'
|
import PerpetualOrder from '@/components/perpetual-order/index.vue'
|
|
import { _getBalance, _getDeepData, _initOpen, _initClose, _orderListCur, _orderListHold, _futrueOrderInit, _futrueOrderList } from '@/API/trade.api'
|
import { _getHomeList } from '@/API/home.api'
|
import { Popup, Swipe, SwipeItem } from 'vant';
|
import { mapActions, mapGetters } from 'vuex'
|
import { SET_COIN_LIST } from '@/store/const.store'
|
import { WS_URL } from '@/config'
|
import { getStorage } from '@/utils/utis'
|
import KLineCharts from '@/components/kline-charts'
|
var showLength = 7
|
export default {
|
name: "perpetualContract",
|
components: {
|
ContractHeader,
|
PerpetualOpen,
|
PerpetualOrder,
|
[Popup.name]: Popup,
|
[Swipe.name]: Swipe,
|
[SwipeItem.name]: SwipeItem,
|
KLineCharts
|
},
|
computed: {
|
...mapGetters('user', ['userInfo']),
|
...mapGetters({
|
coinList: 'home/coinList',
|
}),
|
},
|
watch: {
|
selectIndex(val) {
|
showLength = 7
|
}
|
},
|
data() {
|
const initArr = []
|
for (let i = 0; i < showLength; i++) {
|
initArr.push({
|
amount: '--',
|
price: '--'
|
})
|
}
|
return {
|
quote: {},
|
initTimer: null,
|
keyIndex: 0,
|
timeout: null,
|
timer: null, // 底部持仓等的公用定时器
|
timer1: null, // tab切换动画
|
timer2: null, // 交割合约底部持仓等的公用定时器
|
balance: 0,
|
symbol: '',
|
price: '',
|
range: '',
|
stop_price_profit:'',
|
stop_price_loss:'',
|
initOpen: {},
|
initClose: {},
|
asks: initArr, // 卖单
|
bids: initArr, // 买单
|
orderCur: [], // 当前委托
|
orderHold: [], // 持有仓位
|
futrueHold: [], // 交割持仓
|
futrueHistroy: [], // 交割历史
|
sockets: {
|
quotes: null, // 行情
|
deep: null /// 深度
|
},
|
curTab: '', // 当前委托还是持有仓位
|
selectIndex: 1, // 当前tab
|
initFutrue: {}, /// 交割合约
|
show: false, // popup
|
animated1: false,
|
animated2: false,
|
currentType: '',
|
showCharts: false,
|
symbolname:'',
|
// curRequest: [], //
|
}
|
},
|
async created() {
|
|
if (!this.coinList.length) {
|
await this.SET_COIN_LIST()
|
}
|
this.symbolname = getStorage('symbolname')
|
_getBalance().then(data => { // 获取用户余额
|
this.$store.commit('user/SET_USERINFO', { balance: data.money })
|
// const { money } = data
|
// this.balance = money
|
})
|
},
|
methods: {
|
...mapActions('home', [SET_COIN_LIST]),
|
onUpdate(symbol) { // 更新
|
this.symbol = symbol
|
this.closeSocket()
|
this.init(symbol)
|
},
|
onRecall() { // 撤单or 平仓 evt
|
this.clearTimer()
|
_orderListHold(this.symbol).then(data => {
|
|
this.orderHold = data
|
})
|
this[this.curTab](this.symbol)
|
_initOpen(this.symbol).then(data => {
|
this.initOpen = data
|
})
|
},
|
onTopTab(evt) { // 当前tab 永续/交割
|
this.keyIndex += 1
|
this.selectIndex = evt
|
this.clearTimer()
|
if (this.selectIndex / 1 === 1) {
|
//this.curTab = 'fetchOrderListCur'
|
this.curTab = 'fetchOrderListHold'
|
// this.animated1 = true
|
// this.timer = setTimeout(() => {
|
// this.animated1 = false
|
// clearTimeout(this.timer)
|
// }, 200)
|
this.animated2 = true
|
this.timer1 = setTimeout(() => {
|
this.animated2 = false
|
clearTimeout(this.timer1)
|
}, 200)
|
} else {
|
// this.animated2 = true
|
// this.timer = setTimeout(() => {
|
// this.animated2 = false
|
// clearTimeout(this.timer)
|
// }, 200)
|
this.animated1 = true
|
this.timer1 = setTimeout(() => {
|
this.animated1 = false
|
clearTimeout(this.timer1)
|
}, 200)
|
}
|
console.log(this.curTab)
|
this[this.curTab](this.symbol)
|
},
|
onOrdered(evt) { // 下单过后的回调
|
this.clearTimer()
|
// this.clearTimeout()
|
this.initParam(this.symbol, evt) // 重新初始化
|
// TODO: 这里要做判断
|
if (this.selectIndex / 1 === 1) {
|
this[this.curTab](this.symbol) // 重新调取记录
|
console.log('this.curTab', this.curTab)
|
} else { // 交割合约
|
this[this.curTab](this.symbol)
|
// this.show = true
|
console.log('curTab', evt, this.curTab)
|
|
}
|
//console.log('下单后更新数据')
|
},
|
onTab(evt) { // 点击tab后的回调
|
console.log('evt', evt)
|
this.clearTimer()
|
// this.clearTimeout()
|
this.curTab = evt
|
this[evt](this.symbol)
|
},
|
fetchQoutes(symbol) { // 获取当前行情
|
_getHomeList(symbol).then(data => { // 获取行情
|
this.handleQoutes(data)
|
this.startQuoteSocket() // socket
|
})
|
},
|
handleQoutes(data) {
|
if (data && data.length) {
|
const cur = data[0]
|
this.price = cur.close
|
this.range = cur.change_ratio + ''
|
this.quote = cur
|
this.updateKey++
|
}
|
},
|
fetchDeepData(symbol) {
|
console.log('sd')
|
_getDeepData(symbol).then(data => { // 获取深度
|
console.log(data)
|
this.handleDeep(data)
|
this.startDeepSocket() // socket
|
})
|
},
|
handleDeep(data) {
|
this.deepData = data
|
const { asks, bids } = data
|
this.asks = asks.sort((a, b) => a.price - b.price).slice(0, showLength)
|
this.bids = bids.sort((a, b) => a.price - b.price).slice(-showLength)
|
},
|
startQuoteSocket() { // 行情socket
|
this.sockets.quotes = new WebSocket(`${WS_URL}/1/${this.symbol}`)
|
// socket.onopen = () => {
|
// console.log('open')
|
// socket.send('hello')
|
// }
|
this.sockets.quotes.onmessage = (evt) => {
|
const { data } = evt
|
const { code, data: _data } = JSON.parse(data)
|
if (code / 1 === 0) {
|
this.handleQoutes(_data)
|
}
|
}
|
},
|
startDeepSocket() {
|
this.sockets.deep = new WebSocket(`${WS_URL}/3/${this.symbol}`)
|
this.sockets.deep.onmessage = (evt) => {
|
const { data } = evt
|
const { code, data: _data } = JSON.parse(data)
|
if (code / 1 === 0) {
|
this.handleDeep(_data)
|
}
|
}
|
},
|
initParam(symbol, type) { // 初始化参数
|
if (type === 'open' || type === 'long' || type === 'short' || !type) {
|
let initFunTimer = null;
|
let initFun = () => {
|
_initOpen(symbol).then(data => {
|
this.initOpen = data
|
clearTimeout(initFunTimer)
|
initFunTimer = null
|
}).catch(err => {
|
initFunTimer = setTimeout(() => {
|
initFun()
|
}, 3000);
|
})
|
}
|
initFun()
|
}
|
if (type === 'close' || !type) {
|
let initFunTimer = null;
|
let initFun = () => {
|
_initClose(symbol).then(data => {
|
this.initClose = data
|
console.log(this.initClose)
|
clearTimeout(initFunTimer)
|
initFunTimer = null
|
}).catch(err => {
|
initFunTimer = setTimeout(() => {
|
initFun()
|
}, 3000);
|
})
|
}
|
initFunTimer = setTimeout(() => {
|
initFun()
|
}, 600);
|
}
|
if (type === 'futrue' || !type) {
|
_futrueOrderInit(symbol).then(data => {
|
this.initFutrue = data
|
})
|
}
|
},
|
fetchOrderListCur(symbol) { // 当前委托
|
//console.log('当前委托')
|
if (this.userInfo.token) {
|
_orderListCur(symbol).then(data => {
|
this.orderCur = data
|
})
|
this.clearTimer()
|
this.timer = setInterval(() => {
|
_orderListCur(symbol).then(data => {
|
// if (typeof this.timer === 'string') {
|
// this.timer = null
|
// return
|
// }
|
this.orderCur = data
|
})
|
}, 1000)
|
} else {
|
this.orderCur = []
|
}
|
},
|
fetchOrderListHold(symbol) { // 当前持仓
|
if (this.userInfo.token) {
|
_orderListHold(symbol).then(data => {
|
// this.orderHold = data
|
this.orderHold = data.sort(this.sortData);
|
})
|
this.timer = setInterval(() => {
|
_orderListHold(symbol).then(data => {
|
// if (typeof this.timer === 'string') {
|
// this.timer = null
|
// return
|
// }
|
// this.orderHold = data
|
this.orderHold = data.sort(this.sortData);
|
})
|
}, 1000)
|
} else {
|
this.orderHold = []
|
}
|
},
|
fetchFutrueHoldList(symbol) { // 交割持仓
|
if (this.userInfo.token) {
|
let length = 0
|
_futrueOrderList(symbol).then(data => {
|
// this.futrueHold = data
|
this.futrueHold = data.sort(this.sortData);
|
length = data.length
|
})
|
this.timer = setInterval(() => {
|
_futrueOrderList(symbol).then(data => {
|
// if (typeof this.timer === 'string') {
|
// this.timer = null
|
// return
|
// }
|
|
this.futrueHold = data.sort(this.sortData);
|
if (length != data.length) {
|
length = data.length
|
_futrueOrderInit(symbol).then(dataList => {
|
this.initFutrue = dataList
|
})
|
}
|
})
|
}, 1000)
|
} else {
|
this.futrueHold = []
|
}
|
},
|
fetchFutrueHistory(symbol) { // 交割历史持仓
|
_futrueOrderList(symbol, 'hisorders').then(data => {
|
this.futrueHistroy = data
|
// this.clearTimeout()
|
})
|
},
|
init(symbol) { // 初始化页面
|
this.symbol = symbol.toLowerCase()
|
this.fetchQoutes(symbol)
|
this.fetchDeepData(symbol)
|
this.initParam(symbol) // 'open'
|
this.clearTimer()
|
//if (this.curTab === 'fetchOrderListCur') {
|
if (this.curTab === 'fetchOrderListHold') {
|
//this.fetchOrderListCur(symbol)
|
this.fetchOrderListHold(symbol)
|
} else {
|
this.fetchFutrueHoldList(symbol)
|
}
|
},
|
closeSocket() {
|
this.sockets.quotes && this.sockets.quotes.close()
|
this.sockets.deep && this.sockets.deep.close()
|
this.sockets.quotes = null
|
this.sockets.deep = null
|
},
|
// clearTimeout(noNeed) {
|
// clearTimeout(this.timeout)
|
// if (noNeed) { // 防止timout定时器因接口返回继续触发
|
// this.timeout = ''
|
// return
|
// }
|
// this.timeout = null
|
// },
|
clearTimer() {
|
clearInterval(this.timer)
|
// if (isNeed) {
|
// this.timer = ''
|
// return
|
// }
|
this.timer = null
|
},
|
changeCurrentType(type) {
|
this.currentType = type
|
},
|
changeValueBack(val) {
|
if (val == 0) {
|
showLength = 7
|
} else {
|
showLength = 13
|
}
|
},
|
sortData(a, b) {
|
return new Date(b.open_time).getTime() - new Date(a.open_time).getTime()
|
}
|
},
|
mounted() {
|
let symbol = this.$route.params.symbol
|
let catchSymbol = getStorage('symbol')
|
if (!symbol && catchSymbol) {
|
symbol = catchSymbol
|
}
|
if (this.selectIndex / 1 === 2) {
|
this.curTab = 'fetchFutrueHoldList'
|
} else {
|
this.curTab = 'fetchOrderListHold'
|
}
|
this.symbol = symbol
|
this.init(symbol)
|
},
|
activated() {
|
let symbol = this.$route.params.symbol
|
let catchSymbol = getStorage('symbol')
|
if (!symbol && catchSymbol) {
|
symbol = catchSymbol
|
}
|
if (this.selectIndex / 1 === 2) {
|
this.curTab = 'fetchFutrueHoldList'
|
} else {
|
this.curTab = 'fetchOrderListHold'
|
}
|
this.symbol = symbol
|
this.init(symbol)
|
},
|
// beforeRouteEnter(to, from, next) {
|
// let { params: { symbol }, query: { selectIndex } } = to
|
// // if(this.$route.query.selectIndex) {
|
// // this.selectIndex = this.$route.query.selectIndex
|
// // }
|
// let catchSymbol = getStorage('symbol')
|
// if (!symbol && catchSymbol) {
|
// symbol = catchSymbol
|
// }
|
// if (symbol) {
|
// next(vm => {
|
// if (selectIndex) {
|
// vm.selectIndex = selectIndex
|
// if (vm.selectIndex / 1 === 2) {
|
// vm.curTab = 'fetchFutrueHoldList'
|
// } else {
|
// //vm.curTab = 'fetchOrderListCur'
|
// vm.curTab = 'fetchOrderListHold'
|
// }
|
// } else {
|
// //vm.curTab = 'fetchOrderListCur'
|
// vm.curTab = 'fetchOrderListHold'
|
// }
|
// vm.symbol = symbol
|
// vm.init(symbol)
|
// })
|
// } else {
|
// next()
|
// }
|
// },
|
deactivated() {
|
this.closeSocket()
|
this.clearTimer()
|
},
|
activated() {
|
this.currentType = this.$route.query.currentType ? this.$route.query.currentType : 'long'
|
},
|
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;
|
padding-bottom: 150px !important;
|
}
|
|
.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;
|
box-sizing: border-box;
|
}
|
|
.my-swipe {
|
width: 100%;
|
}
|
|
.my-swipe .van-swipe-item {}
|
|
.line {
|
height: 13px;
|
|
@include themify() {
|
background: themed("tab_background");
|
}
|
}
|
|
@keyframes animate1 {
|
0% {
|
opacity: 1;
|
transform: translate3d(100%, 0, 0);
|
}
|
|
// 40% {
|
// opacity: 1;
|
// transform: translate3d(50%, 0, 0);
|
// }
|
100% {
|
opacity: 1;
|
transform: translate3d(0%, 0, 0);
|
}
|
}
|
|
@keyframes animate2 {
|
0% {
|
opacity: 1;
|
transform: translate3d(-100%, 0, 0);
|
}
|
|
// 40% {
|
// opacity: 1;
|
// transform: translate3d(50%, 0, 0);
|
// }
|
100% {
|
opacity: 1;
|
transform: translate3d(0%, 0, 0);
|
}
|
}
|
|
.slide1 {
|
animation: animate1 200ms linear;
|
}
|
|
.slide2 {
|
animation: animate2 200ms linear;
|
}
|
|
.line {
|
@include themify() {
|
background: themed("divi_line");
|
}
|
}
|
|
::v-deep .contract-header {
|
@include themify() {
|
background: themed("main_background");
|
}
|
}
|
|
.tabBackground1 {
|
@include themify() {
|
border: 1px solid themed("border_color1");
|
}
|
}
|
|
.shadow {
|
bottom: 108px;
|
box-sizing: border-box;
|
}
|
</style>
|