<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">
|
<keep-alive>
|
<trade-deep-data
|
:selectValue="selectValue"
|
@getList="getList"
|
:showType="showType"
|
:symbol="symbol"
|
v-if="symbol"
|
:price="price"
|
class="w-290 mr-30"
|
/>
|
</keep-alive>
|
<trade-order-area
|
:symbol="symbol"
|
:init-open="initOpen"
|
:init-close="initClose"
|
:price="price"
|
@ordered="onOrdered"
|
/>
|
</div>
|
|
<!-- 2222 -->
|
<!-- <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"
|
>
|
<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 class="list-data">
|
<div>
|
<div class="flex justify-between pb-20 items-center pt-10">
|
<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}/wap/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}/wap/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-155 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>
|
<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: #9691fa;
|
font-weight: 600;
|
|
@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");
|
}
|
}
|
}
|
|
.list-data {
|
margin: 30px;
|
min-height: 550px;
|
box-shadow: 0px 0px 10px 5px rgba(0, 0, 0, 0.05);
|
//
|
}
|
</style>
|