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.
657 lines
22 KiB
657 lines
22 KiB
<template>
|
|
<div>
|
|
<!-- <div class="banner-block col-xs-8">-->
|
|
<!-- <el-carousel :interval="6000" height="450px">-->
|
|
<!-- <el-carousel-item v-for="item in pcBannerList" :key="item.id">-->
|
|
<!-- <img :src="item.imgurl" width="100%" height="100%" />-->
|
|
<!-- </el-carousel-item>-->
|
|
<!-- </el-carousel>-->
|
|
<!-- </div>-->
|
|
<div class="container-fluid no-fluid" style="background-color: #f5f5f5;padding: 15px 15px;">
|
|
<div class="row sm-gutters">
|
|
|
|
<div class="col-md-9" style="padding-right:0px!important;margin-right: 15px;">
|
|
<div class="row">
|
|
<div class="col-md-12" style="padding-right: 0px!important;">
|
|
<div class="px-4 py-3 heading">
|
|
<div class="d-flex align-items-center">
|
|
<div class="price px-3 border-right">
|
|
<div class="item fn-28">{{ activeContract.pair_name }}</div>
|
|
</div>
|
|
<div class="d-flex fn-16 px-3 p-l-A align-items-center">
|
|
<div class="item px-3 min-width-B">
|
|
<div class="title mb-1" :class="{
|
|
decreace: activeContract.increase < 0,
|
|
increase: activeContract.increase >= 0
|
|
}">
|
|
{{ activeContract.price }}
|
|
</div>
|
|
<!-- <div>
|
|
${{ activeContract.price }}
|
|
</div> -->
|
|
</div>
|
|
<div class="item px-2 min-width-A">
|
|
<div class="title mb-1 text-secondary">
|
|
{{ $t("contract.h6") }}
|
|
</div>
|
|
<div :class="{
|
|
decreace: activeContract.increase < 0,
|
|
increase: activeContract.increase >= 0
|
|
}">
|
|
{{ activeContract.increaseStr }}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<!-- 币种价值数据 -->
|
|
<div class="d-flex fn-16">
|
|
<div class="item px-2 min-width-B">
|
|
<div class="title mb-1 text-secondary">
|
|
24h {{ $t("contract.h7") }}
|
|
</div>
|
|
<div>
|
|
{{ activeContract.high }}
|
|
</div>
|
|
</div>
|
|
<div class="item px-2 min-width-B">
|
|
<div class="title mb-1 text-secondary">
|
|
24h {{ $t("contract.h8") }}
|
|
</div>
|
|
<div>
|
|
{{ activeContract.low }}
|
|
</div>
|
|
</div>
|
|
<div class="item px-2 min-width-B">
|
|
<div class="title mb-1 text-secondary">
|
|
24h {{ $t("contract.h9") }}
|
|
<!-- ({{ $t("contract.e2") }}) -->
|
|
(USDT)
|
|
</div>
|
|
<div>
|
|
{{ activeContract.vol }}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<!-- symbols -->
|
|
<symbols :marketList="marketList" :marketId="marketId" :isLogin="isLogin" :symbol.sync="symbol"></symbols>
|
|
|
|
<!-- kline -->
|
|
<make-deal :isLogin="isLogin" :pair="pair" :socket="ws.socket" :symbol="symbol" :buyorder="buyorder" :sellorder="sellorder" :fromBalance="fromBalance" :toBalance="toBalance" :newTrade="newTrade" :minQty="minQty" :minTotal="minTotal" :priceDecimals="priceDecimals" :qtyDecimals="qtyDecimals" @update="update"></make-deal>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- order book -->
|
|
<book-trades :priceCny="price_cny" :activeContract="activeContract"></book-trades>
|
|
|
|
<!-- market news -->
|
|
<!-- <market-news></market-news> -->
|
|
|
|
<!-- order list -->
|
|
<order-list ref="Order" :ordersOpen="ordersOpen" :conditionOrders="conditionOrders" :ordersHistory="ordersHistory" :priceDecimals="priceDecimals" :qtyDecimals="qtyDecimals" :isLogin="isLogin" :pair="pair" @change="currentTab = $event" @update="update"></order-list>
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
import Socket from '@/api/server/Socket.js';
|
|
import Market from '@/api/market.js';
|
|
import Exchange from "@/api/exchange";
|
|
import Order from "@/api/order"
|
|
import Home from "@/api/home";
|
|
import bus from "@/components/bus.js";
|
|
export default {
|
|
|
|
components: {
|
|
"Symbols": () => import( /* webpackChunkName:"symbols" */ "./symbols"),
|
|
"MakeDeal": () => import( /* webpackChunkName:"chart-deal" */ "./make-deal"),
|
|
"BookTrades": () => import( /* webpackChunkName:"order-book" */ "./book-trades"),
|
|
"MarketNews": () => import( /* webpackChunkName:"market-news" */ "./market-news"),
|
|
"OrderList": () => import( /* webpackChunkName:"order-list" */ "./order-list")
|
|
},
|
|
|
|
beforeCreate() {
|
|
|
|
// this.ws = new Socket(`${this.Globals.Server.Path.WS}`);
|
|
|
|
},
|
|
|
|
data() {
|
|
|
|
return {
|
|
isLianjie:false,
|
|
// `btcusdt` 不含`/`的小写
|
|
symbol: this.$route.params.symbol || null,
|
|
marketId: null,
|
|
marketInfo: null, // 交易对基本信息
|
|
pair: {
|
|
from: '-',
|
|
to: '-',
|
|
},
|
|
marketList: [], // 在symbol组件中 需要遍历 因此默认数组避免出错
|
|
trade: [],
|
|
pcBannerList:[],
|
|
newTrade: null,
|
|
|
|
// 所有的数据 都统一按照价格从小到大排序
|
|
buyList: [],
|
|
sellList: [],
|
|
|
|
// 初始化精度值和交易
|
|
priceDecimals: 0,
|
|
qtyDecimals: 0,
|
|
minQty: 0,
|
|
minTotal: 0,
|
|
|
|
now: null,
|
|
|
|
// 下单情况 可由orderbook跨页面定制
|
|
buyorder: {
|
|
trigger_price: '', // 触发价
|
|
entrust_price: '', // 委托价
|
|
amount: 0, // 数量
|
|
direction: "buy", // 方向
|
|
},
|
|
|
|
sellorder: {
|
|
entrust_price: '',
|
|
trigger_price: '',
|
|
amount: 0,
|
|
direction: "sell",
|
|
},
|
|
|
|
// 从order传递price
|
|
passOrderPrice: true,
|
|
|
|
// 各种委托单
|
|
ordersOpen: {
|
|
total: 0,
|
|
},
|
|
|
|
ordersHistory: {
|
|
total: 0,
|
|
data: []
|
|
},
|
|
|
|
conditionOrders: {
|
|
total: 0,
|
|
},
|
|
|
|
// 用户钱包余额
|
|
fromBalance: 0,
|
|
toBalance: 0,
|
|
|
|
// 当前页面socket
|
|
// ws: null,
|
|
|
|
// 是否开启交易密码
|
|
transPwdEnabled: false,
|
|
|
|
currentTab: "opens", // orders显示的tab
|
|
price_cny:0,
|
|
activeContract:{},
|
|
ws: new Socket(this.Globals.Server.Path.WS1),
|
|
}
|
|
|
|
},
|
|
|
|
computed: {
|
|
|
|
// 当前语言
|
|
lang() {
|
|
let browser_Lang = navigator.language.includes('zh') ? 'cn' : 'en',
|
|
lang = localStorage.lang || browser_Lang;
|
|
return lang;
|
|
},
|
|
|
|
isLogin() {
|
|
return Boolean(this.userAuth);
|
|
},
|
|
|
|
userAuth() {
|
|
const auth = localStorage.getItem("auth");
|
|
let ret = "";
|
|
if (auth) {
|
|
let {
|
|
memberId,
|
|
accessToken
|
|
} = JSON.parse(auth);
|
|
ret = `?${accessToken}&${memberId}`;
|
|
}
|
|
return ret;
|
|
},
|
|
|
|
userInfo() {
|
|
if (this.isLogin) {
|
|
return JSON.parse(localStorage.getItem("auth"));
|
|
} else {
|
|
return {
|
|
user_id : 0,
|
|
};
|
|
}
|
|
}
|
|
},
|
|
|
|
watch: {
|
|
// 切换symbol时更新路由
|
|
symbol(newVal, oldVal) {
|
|
|
|
// 取消订阅 或者关闭连接 防止干扰下次值
|
|
if (oldVal) this.unsub(oldVal);
|
|
|
|
// 还原页面状态 避免造成数据值紊乱
|
|
this.trade = [];
|
|
this.sellList = [];
|
|
this.buyList = [];
|
|
this.newTrade = null;
|
|
|
|
// 买卖单数据结构
|
|
this.buyorder = {
|
|
trigger_price: '',
|
|
entrust_price: '',
|
|
amount: 0,
|
|
direction: "buy",
|
|
};
|
|
this.sellorder = {
|
|
trigger_price: '',
|
|
entrust_price: '',
|
|
amount: 0,
|
|
direction: "sell",
|
|
};
|
|
|
|
// 请求新的页面数据
|
|
if (newVal) this.$router.push(`/exchange/${newVal}`);
|
|
},
|
|
|
|
marketInfo(newVal, oldVal) {
|
|
if (newVal && !oldVal) { // 第一次取得marketInfo时 更新接口 主要针对刷新页面
|
|
this.update();
|
|
}
|
|
},
|
|
|
|
// 加载新页面 重新订阅所有数据
|
|
$route( /*newRouter, oldRouter*/ ) {
|
|
|
|
this.addSub();
|
|
|
|
// 初始化market信息
|
|
this.findMarketBySymbol();
|
|
|
|
// 更新所有接口数据
|
|
this.update();
|
|
|
|
},
|
|
|
|
currentTab() {
|
|
// tab切换时自动更新
|
|
this.getOrders();
|
|
}
|
|
},
|
|
|
|
methods: {
|
|
initMarket() {
|
|
// 初始化订阅marketList数据
|
|
this.ws.send({
|
|
"cmd": "sub",
|
|
"msg": 'exchangeMarketList',
|
|
})
|
|
},
|
|
|
|
// 订阅当前的symbol
|
|
addSub() {
|
|
|
|
this.ws.send([{
|
|
cmd: 'sub',
|
|
msg: `sellList_${this.symbol}`
|
|
}, {
|
|
cmd: 'sub',
|
|
msg: `buyList_${this.symbol}`
|
|
}, {
|
|
cmd: 'req',
|
|
msg: `tradeList_${this.symbol}`
|
|
}, {
|
|
cmd: 'sub',
|
|
msg: `tradeList_${this.symbol}`
|
|
}, {
|
|
cmd: 'sub',
|
|
msg: `swapMarketList`
|
|
}]);
|
|
|
|
},
|
|
|
|
// 取消指定的symbol
|
|
unsub(symbol) {
|
|
|
|
this.ws.send([{
|
|
cmd: 'unsub',
|
|
msg: `sellList_${symbol}`
|
|
}, {
|
|
cmd: 'unsub',
|
|
msg: `buyList_${symbol}`
|
|
}, {
|
|
cmd: 'req',
|
|
msg: `tradeList_${symbol}`// 切换币后成交记录不刷新,不知道这一段是什么意思,加了就可以了
|
|
}, {
|
|
cmd: 'unsub',
|
|
msg: `tradeList_${symbol}`
|
|
}, {
|
|
cmd: 'sub',
|
|
msg: `swapMarketList`
|
|
}]);
|
|
|
|
},
|
|
|
|
// 在交易列表中 查找当前id记录 并将行情信息写入全局
|
|
// 以便在其他组件中 直接使用
|
|
findMarketBySymbol() {
|
|
|
|
let isKeep = true; // 退出外层循环的标识符
|
|
|
|
for (let coin of this.marketList) {
|
|
|
|
for (let market of coin.marketInfoList) {
|
|
|
|
// 查询交易对名称
|
|
if (market.symbol === this.symbol) {
|
|
|
|
// 转化pair为集合 便于提取
|
|
this.pair = {
|
|
to: market.coin_name, // 右币
|
|
from: coin.coin_name // 左币
|
|
};
|
|
|
|
// 创建marketId
|
|
this.marketId = market.pair_id;
|
|
// console.log(this.marketId, 'marketId-p--------')
|
|
|
|
// 写入market信息
|
|
this.marketInfo = market;
|
|
|
|
// 未有选定Tab时 默认一个now 后期从子组件中取
|
|
if (!this.now) this.now = coin.coin_name;
|
|
|
|
// 写入数据值精度 用来显示截取长度
|
|
this.priceDecimals = market.price_decimals;
|
|
this.qtyDecimals = market.qty_decimals;
|
|
|
|
// 下单时 需要验证最小数量和最小总值
|
|
this.minTotal = market.min_total;
|
|
this.minQty = market.min_qty;
|
|
|
|
isKeep = false;
|
|
|
|
// 终止内部循环
|
|
break;
|
|
}
|
|
}
|
|
|
|
// 终止外部循环
|
|
if (!isKeep) break;
|
|
}
|
|
},
|
|
|
|
getBalance() {
|
|
|
|
if (this.isLogin) {
|
|
|
|
Exchange.getUserBalance(this.marketInfo.pair_name).then(data => {
|
|
|
|
this.fromBalance = data[this.pair.from.toUpperCase()].usable_balance;
|
|
this.toBalance = data[this.pair.to.toUpperCase()].usable_balance;
|
|
|
|
}).catch(err => {
|
|
|
|
});
|
|
}
|
|
|
|
},
|
|
|
|
// 更新接口数据
|
|
update() {
|
|
this.getBalance();
|
|
this.getOrders();
|
|
this.getCurrencyExCny();
|
|
},
|
|
// 获取汇率
|
|
getCurrencyExCny(){
|
|
if(!this.pair.from||this.pair.from=='-') return;
|
|
Exchange.getCurrencyExCny({
|
|
coin_name:this.pair.from
|
|
}).then(res=>{
|
|
this.price_cny = res.price_cny
|
|
})
|
|
},
|
|
getOrders() {
|
|
|
|
if (this.currentTab == "opens") { // 当前委托
|
|
|
|
this.getOpens();
|
|
|
|
} else if (this.currentTab == "conditions") { // 条件委托
|
|
|
|
this.getConditions();
|
|
|
|
} else if (this.currentTab == "histories") { // 历史委托
|
|
this.getHistories();
|
|
|
|
}
|
|
|
|
// console.log("---订单更新成功---");
|
|
|
|
},
|
|
|
|
getOpens() {
|
|
if (this.isLogin) {
|
|
Order.getCurrentEntrust({
|
|
symbol: this.marketInfo.pair_name,
|
|
}).then(data => {
|
|
this.ordersOpen = data
|
|
}).catch(err => {
|
|
console.log(err)
|
|
})
|
|
}
|
|
},
|
|
|
|
getConditions() {
|
|
if (this.isLogin) {
|
|
Order.getConditionEntrust({
|
|
symbol: this.marketInfo.pair_name,
|
|
}).then(data => {
|
|
this.conditionOrders = data;
|
|
}).catch(err => {
|
|
console.log(err)
|
|
})
|
|
}
|
|
},
|
|
|
|
getHistories() {
|
|
if (this.isLogin) {
|
|
Order.getHistoryEntrust({
|
|
symbol: this.marketInfo.pair_name,
|
|
})
|
|
.then(data => {
|
|
this.ordersHistory = data;
|
|
})
|
|
.catch(err => {})
|
|
}
|
|
},
|
|
indexList() {
|
|
Home.indexList().then((res) => {
|
|
this.pcBannerList = res.pcBannerList
|
|
setTimeout(() => {
|
|
this.skroll();
|
|
}, 100);
|
|
}).catch((res) => {});
|
|
},
|
|
initWs(){
|
|
this.ws = new Socket(`${this.Globals.Server.Path.WS}`);
|
|
this.ws.on("open", () => {
|
|
if(this.isLianjie){
|
|
bus.$emit('sendMsg',this.ws.socket);
|
|
this.isLianjie=false
|
|
}
|
|
// 连接成功后 初始化订阅市场信息
|
|
this.initMarket();
|
|
// 如果指定了id 订阅该行情的所有其他信息
|
|
if (this.symbol) this.addSub();
|
|
// this.getSwapMarketList();
|
|
})
|
|
|
|
this.ws.on("message", (response) => {
|
|
|
|
let {
|
|
data, // 返回数据
|
|
sub, // 订阅标签
|
|
type, // 返回类型
|
|
msg, // 提示信息
|
|
code, // 错误代号
|
|
} = response;
|
|
|
|
// 答复心跳 保持连接
|
|
if (type == "ping") this.ws.send({
|
|
type: "pong"
|
|
});
|
|
switch (sub) {
|
|
|
|
case "exchangeMarketList":
|
|
console.log(data,'----000---')
|
|
this.marketList = data;
|
|
// console.log(this.marketList[0].marketInfoList[0].close, '0000------------')
|
|
|
|
if (!this.symbol) { // 默认symbol 重新请求数据
|
|
this.symbol = _.nth(data).marketInfoList[0].symbol;
|
|
} else { // 找出该symbol对应的记录并更新页面
|
|
this.findMarketBySymbol();
|
|
}
|
|
|
|
this.activeContract = data
|
|
.map(item => item.marketInfoList)
|
|
.flat()
|
|
.find(item => {
|
|
return item.pair_name.replace('/', '').toLowerCase() == this.symbol
|
|
});
|
|
console.log(this.activeContract, this.activeContract.close, '122222--------', this.symbol+'symbol')
|
|
break;
|
|
|
|
case `buyList_${this.symbol}`:
|
|
|
|
this.buyList = data;
|
|
break;
|
|
|
|
case `sellList_${this.symbol}`:
|
|
|
|
this.sellList = data;
|
|
break;
|
|
|
|
case `tradeList_${this.symbol}`:
|
|
if (type == "history") { // 历史记录
|
|
this.trade = this.trade.concat(data);
|
|
} else if (type == "dynamic") { // 有更新就推送
|
|
this.trade.unshift(data);
|
|
}
|
|
// 最新交易 更新用于余额和订单记录
|
|
this.newTrade = _.nth(this.trade);
|
|
if (this.newTrade && this.newTrade.buy_user_id === this.userInfo.user_id || this.newTrade.sell_user_id == this.userInfo.user_id) this.update();
|
|
break;
|
|
case `swapMarketList`:
|
|
// 这个读不到
|
|
if( data.symbol=='BTC' )(data.price).toFixed(1)
|
|
let listA = data;
|
|
let listB = listA
|
|
.map(item => item.marketInfoList)
|
|
.flat()
|
|
.find(item => {
|
|
return item.pair_name.replace('/', '').toLowerCase() == this.symbol
|
|
});
|
|
this.activeContract = listB || {};
|
|
console.log(this.symbol, this.activeContract, 'ex-activeContract----------------')
|
|
break;
|
|
}
|
|
});
|
|
|
|
this.ws.on("close", () => {
|
|
// this.$message({
|
|
// type: "error",
|
|
// message: this.$t("nav.b8"),
|
|
// duration: 2000,
|
|
// });
|
|
this.isLianjie=true
|
|
this.initWs()
|
|
// if (this.symbol) this.getCurrencyExCny();
|
|
// this.indexList()
|
|
|
|
});
|
|
},
|
|
getSwapMarketList(){
|
|
let msg = "swapMarketList";
|
|
this.ws.send({
|
|
cmd: "sub",
|
|
msg: msg
|
|
});
|
|
this.ws.on("message", res => {
|
|
let { data, sub,cmd } = res;
|
|
console.log(data, sub,cmd, '000000000000000')
|
|
if (sub == msg) {
|
|
if( data.symbol=='BTC' )(data.price).toFixed(1)
|
|
let listA = data;
|
|
let listB = listA
|
|
.map(item => item.marketInfoList)
|
|
.flat()
|
|
.find(item => {
|
|
return item.pair_name.replace('/', '').toLowerCase() == this.symbol
|
|
});
|
|
this.activeContract = listB || {};
|
|
console.log(this.symbol, this.activeContract, 'ex-activeContract----------------')
|
|
}else if (cmd == "ping") {
|
|
this.ws.send({
|
|
cmd: "pong"
|
|
});
|
|
}
|
|
});
|
|
this.ws.on('close',()=>{
|
|
this.ws= new Socket(this.Globals.Server.Path.WS1),
|
|
console.log('链接关闭');
|
|
this.wsOpen();
|
|
})
|
|
}
|
|
},
|
|
|
|
created() {
|
|
|
|
this.initWs()
|
|
if (this.symbol) this.getCurrencyExCny();
|
|
this.indexList()
|
|
// this.update();
|
|
},
|
|
|
|
mounted() {
|
|
// if (this.symbol) this.update();
|
|
},
|
|
}
|
|
</script>
|
|
|
|
<style scoped>
|
|
.heading{
|
|
color: #333;
|
|
border: 1px solid #e5e5e5;
|
|
margin-bottom:10px;
|
|
background-color:#fff;
|
|
}
|
|
.p-l-A{
|
|
padding-left: 2rem!important;
|
|
}
|
|
.fn-28{
|
|
font-weight: bold;
|
|
padding-right: 1rem;
|
|
color: #444;
|
|
}
|
|
.min-width-A{
|
|
min-width: 120px;
|
|
}
|
|
.min-width-B{
|
|
min-width: 160px;
|
|
}
|
|
</style>
|
|
|