18 changed files with 3771 additions and 9 deletions
@ -0,0 +1,461 @@ |
|||||
|
<template> |
||||
|
<div class="main-chart mb5" style="height: 100%;"> |
||||
|
<!-- TradingView Widget BEGIN --> |
||||
|
<div class="tradingview-widget-container" style="height: 100%;"> |
||||
|
<div id="tradingview_lautin" style="height: 100%;"> |
||||
|
<!-- 存放图表库容器 --> |
||||
|
</div> |
||||
|
</div> |
||||
|
<!-- TradingView Widget END --> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
import Model from "@/api/custom/Model"; |
||||
|
import Option from "@/api/option"; |
||||
|
import Exchange from "@/api/exchange"; |
||||
|
import tvStyle from "@/assets/js/tvStyle.js"; |
||||
|
import { mapState } from "vuex"; |
||||
|
import bus from "@/components/bus.js"; |
||||
|
|
||||
|
export default { |
||||
|
props: ["socket", "symbol", "priceDecimals"], |
||||
|
|
||||
|
data() { |
||||
|
return { |
||||
|
model: null, // 数据模型 |
||||
|
interval: "D" ,// [字符串格式]和TV的resolution同步 |
||||
|
// interval: "60" ,// [字符串格式]和TV的resolution同步 |
||||
|
theme:localStorage.getItem('theme')||'dark', |
||||
|
intertime: '' |
||||
|
}; |
||||
|
}, |
||||
|
|
||||
|
computed: { |
||||
|
lang() { |
||||
|
let local; |
||||
|
// console.log(localStorage.lang) |
||||
|
if (localStorage.lang) { |
||||
|
if (localStorage.lang == "tw") { |
||||
|
local = "zh_TW"; |
||||
|
} else if (localStorage.lang == "cn") { |
||||
|
local = "zh"; |
||||
|
} else if (localStorage.lang == "kor") { |
||||
|
local = "ko"; |
||||
|
} else if (localStorage.lang == "jp") { |
||||
|
local = "ja"; |
||||
|
} else if (localStorage.lang == "de") { |
||||
|
local = "de_DE"; |
||||
|
} else if (localStorage.lang == "fra") { |
||||
|
local = "fr"; |
||||
|
} else if (localStorage.lang == "it") { |
||||
|
local = "it"; |
||||
|
} else if (localStorage.lang == "pt") { |
||||
|
local = "pt"; |
||||
|
} else if (localStorage.lang == "spa") { |
||||
|
local = "es"; |
||||
|
} else if (localStorage.lang == "en") { |
||||
|
local = "en"; |
||||
|
}else { |
||||
|
local = "en"; |
||||
|
} |
||||
|
} |
||||
|
return local; |
||||
|
}, |
||||
|
// ...mapState({ |
||||
|
// theme: "theme" |
||||
|
// }) |
||||
|
}, |
||||
|
methods: { |
||||
|
translateInterval2Period() { |
||||
|
let period; |
||||
|
switch (this.interval) { |
||||
|
case "1": |
||||
|
period = "1min"; |
||||
|
break; |
||||
|
case "5": |
||||
|
period = "5min"; |
||||
|
break; |
||||
|
case "15": |
||||
|
period = "15min"; |
||||
|
break; |
||||
|
case "30": |
||||
|
period = "30min"; |
||||
|
break; |
||||
|
case "60": |
||||
|
period = "60min"; |
||||
|
break; |
||||
|
case "D": |
||||
|
case "1D": |
||||
|
period = "1day"; |
||||
|
break; |
||||
|
case "W": |
||||
|
case "1W": |
||||
|
period = "1week"; |
||||
|
break; |
||||
|
case "M": |
||||
|
case "1M": |
||||
|
period = "1mon"; |
||||
|
break; |
||||
|
} |
||||
|
return period; |
||||
|
}, |
||||
|
translateInterval2Period1() { |
||||
|
let period1; |
||||
|
switch (this.intertime) { |
||||
|
case "1": |
||||
|
period1 = "1min"; |
||||
|
break; |
||||
|
case "5": |
||||
|
period1 = "5min"; |
||||
|
break; |
||||
|
case "15": |
||||
|
period1 = "15min"; |
||||
|
break; |
||||
|
case "30": |
||||
|
period1 = "30min"; |
||||
|
break; |
||||
|
case "60": |
||||
|
period1 = "60min"; |
||||
|
break; |
||||
|
case "D": |
||||
|
case "1D": |
||||
|
period1 = "1day"; |
||||
|
break; |
||||
|
case "W": |
||||
|
case "1W": |
||||
|
period1 = "1week"; |
||||
|
break; |
||||
|
case "M": |
||||
|
case "1M": |
||||
|
period1 = "1mon"; |
||||
|
break; |
||||
|
} |
||||
|
return period1; |
||||
|
}, |
||||
|
// 创建分时按钮 |
||||
|
createBtns() { |
||||
|
const model = this.model; |
||||
|
const widget = this.model.widget; |
||||
|
// widget.createButton() |
||||
|
// .addClass("my-theme") |
||||
|
// .text("主题") |
||||
|
// .on("click", function () { |
||||
|
// console.log(widget); |
||||
|
// widget.changeTheme("aa"); |
||||
|
|
||||
|
// }).parent().addClass('my-aa') |
||||
|
|
||||
|
// 创建分时按钮 |
||||
|
const resolutions = [ |
||||
|
// { |
||||
|
// title: 'Time', |
||||
|
// resolution: '1', |
||||
|
// chartType: 3 |
||||
|
// }, // 1,2,3几种类型 |
||||
|
{ |
||||
|
title: "1" + this.$t("exchange.min"), |
||||
|
resolution: "1", |
||||
|
chartType: 1 |
||||
|
}, |
||||
|
{ |
||||
|
title: "5" + this.$t("exchange.min"), |
||||
|
resolution: "5", |
||||
|
chartType: 1 |
||||
|
}, |
||||
|
{ |
||||
|
title: "15" + this.$t("exchange.min"), |
||||
|
resolution: "15", |
||||
|
chartType: 1 |
||||
|
}, |
||||
|
{ |
||||
|
title: "30" + this.$t("exchange.min"), |
||||
|
resolution: "30", |
||||
|
chartType: 1 |
||||
|
}, |
||||
|
{ |
||||
|
title: "1" + this.$t("exchange.hour"), |
||||
|
resolution: "60", |
||||
|
chartType: 1 |
||||
|
}, |
||||
|
{ |
||||
|
title: "1" + this.$t("exchange.day"), |
||||
|
resolution: "D", |
||||
|
chartType: 1 |
||||
|
}, |
||||
|
{ |
||||
|
title: "1" + this.$t("exchange.week"), |
||||
|
resolution: "W", |
||||
|
chartType: 1 |
||||
|
}, |
||||
|
{ |
||||
|
title: "1" + this.$t("exchange.month"), |
||||
|
resolution: "M", |
||||
|
chartType: 1 |
||||
|
} |
||||
|
]; |
||||
|
|
||||
|
let btns = [], // 存放所有按钮 |
||||
|
parents = []; |
||||
|
resolutions.forEach(item => { |
||||
|
// 生成按钮 |
||||
|
let $parent = widget |
||||
|
.createButton() |
||||
|
.attr("title", item.title) |
||||
|
.addClass("my-date") |
||||
|
.css({ |
||||
|
background: (index, value) => { |
||||
|
if (this.interval == item.resolution) { |
||||
|
return this.theme=='dark'?'#ccc':'#091722'; |
||||
|
} |
||||
|
}, |
||||
|
color: () => { |
||||
|
if (this.interval == item.resolution) { |
||||
|
return "#758696"; |
||||
|
} |
||||
|
} |
||||
|
}) |
||||
|
.text(item.title) |
||||
|
.on("click", function(e) { |
||||
|
const btns = this.parentNode.parentNode.querySelectorAll( |
||||
|
".my-date" |
||||
|
); |
||||
|
|
||||
|
btns.forEach(btn => { |
||||
|
if (btn === this) { |
||||
|
btn.style.cssText = `background : ${this.theme=='dark'?'#ccc':'#091722'}; |
||||
|
color:#758696;`; |
||||
|
} else btn.style.cssText = ``; |
||||
|
}); |
||||
|
|
||||
|
// widget.chart().setResolution(item.resolution, function onReadyCallback() {}); |
||||
|
model.setResolution(item.resolution, function onReadyCallback() {}); |
||||
|
}) |
||||
|
.parent() |
||||
|
.addClass("my-group"); |
||||
|
|
||||
|
parents.push($parent[0]); // 父节点集合 |
||||
|
}); |
||||
|
widget.chart() |
||||
|
.createStudy( |
||||
|
"Moving Average", |
||||
|
false, |
||||
|
true, |
||||
|
[5, "close", 0], |
||||
|
null, |
||||
|
{ |
||||
|
"Plot.color": "#e843da", |
||||
|
} |
||||
|
); |
||||
|
widget.chart() |
||||
|
.createStudy( |
||||
|
"Moving Average", |
||||
|
false, |
||||
|
true, |
||||
|
[10, "close", 0], |
||||
|
null, |
||||
|
{ |
||||
|
"Plot.color": "#53b987", |
||||
|
} |
||||
|
); |
||||
|
widget.chart() |
||||
|
.createStudy( |
||||
|
"Moving Average", |
||||
|
false, |
||||
|
true, |
||||
|
[30, "close", 0], |
||||
|
null, |
||||
|
{ |
||||
|
"Plot.color": "#ff231f", |
||||
|
} |
||||
|
); |
||||
|
|
||||
|
// setTimeout(function () { |
||||
|
// // 给my-group外层套一个DIV |
||||
|
// const resolution_container = document.createElement("div"); |
||||
|
// resolution_container.className = "resolution_container"; |
||||
|
// $(resolution_container).append($(parents).clone()); |
||||
|
// $(resolution_container).replaceAll($(parents[0])); |
||||
|
// // |
||||
|
// }, 50) |
||||
|
}, |
||||
|
|
||||
|
// 获取交易对基本信息 |
||||
|
getSymbol() { |
||||
|
if (this.priceDecimals) { |
||||
|
return Promise.resolve({ |
||||
|
pair_name: this.priceDecimals |
||||
|
}); |
||||
|
} else { |
||||
|
return Exchange.getSymbolInfo({ |
||||
|
symbol: this.symbol |
||||
|
}); |
||||
|
} |
||||
|
}, |
||||
|
// 解压 |
||||
|
unzip(b64Data) { |
||||
|
let u8 = window.atob(b64Data); |
||||
|
let jiya = window.pako.inflate(u8) |
||||
|
let str = this.Uint8ArrayToString(jiya); |
||||
|
return JSON.parse(str); |
||||
|
}, |
||||
|
Uint8ArrayToString(fileData) { |
||||
|
var dataString = ""; |
||||
|
for (var i = 0; i < fileData.length; i++) { |
||||
|
dataString += String.fromCharCode(fileData[i]); |
||||
|
} |
||||
|
return dataString; |
||||
|
}, |
||||
|
// 获取历史记录数据 |
||||
|
getHistoryCallback(onLoadCallback) { |
||||
|
// 取图表回传的solution |
||||
|
this.intertime = this.interval; |
||||
|
this.interval = this.model.interval; |
||||
|
|
||||
|
// 转化接口所需的period |
||||
|
let period1 = this.translateInterval2Period1(); |
||||
|
let period = this.translateInterval2Period(); |
||||
|
if(this.intertime!==this.model.interval){ |
||||
|
this.model.subscribe([ |
||||
|
{ |
||||
|
cmd: "unsub", |
||||
|
msg: `Kline_${this.symbol}_${period1}` |
||||
|
}, |
||||
|
{ |
||||
|
cmd: "sub", |
||||
|
msg: `Kline_${this.symbol}_${period}` |
||||
|
} |
||||
|
]); |
||||
|
|
||||
|
// 已有图表库 通过修改symbol触发图标库更新 重新执行getSymbol和getBar |
||||
|
this.model.setSymbol(this.symbol); |
||||
|
} |
||||
|
|
||||
|
Option.getStockKline({ |
||||
|
symbol: this.symbol, |
||||
|
period, |
||||
|
size: 500, |
||||
|
zip:1 |
||||
|
}) |
||||
|
.then(data => { |
||||
|
let list = []; |
||||
|
// 组装tv数据格式 |
||||
|
for (let item of this.unzip(data.data)) { |
||||
|
list.push({ |
||||
|
time: item.id * 1000, |
||||
|
open: item.open, |
||||
|
high: item.high, |
||||
|
low: item.low, |
||||
|
close: item.close, |
||||
|
volume: item.amount |
||||
|
}); |
||||
|
} |
||||
|
let lastTime = list[list.length - 1].time; |
||||
|
// console.log(lastTime,'--------') |
||||
|
onLoadCallback(list, lastTime); |
||||
|
}) |
||||
|
.catch(err => {}); |
||||
|
}, |
||||
|
|
||||
|
// 初始化图表 |
||||
|
initTV() { |
||||
|
// 先订阅数据 再创建图表库 |
||||
|
let period = this.translateInterval2Period(); |
||||
|
this.model.subscribe([ |
||||
|
{ |
||||
|
cmd: "sub", |
||||
|
msg: `Kline_${this.symbol}_${period}` |
||||
|
} |
||||
|
]); |
||||
|
// console.log(this.lang) |
||||
|
this.model.init( |
||||
|
{ |
||||
|
// 初始化交易对和分时 |
||||
|
symbol: this.symbol, |
||||
|
interval: this.interval, |
||||
|
container_id: "tradingview_lautin", // 设置容器 |
||||
|
height: 1000, |
||||
|
locale: this.lang, // 语言设置 |
||||
|
priceDecimals: this.priceDecimals, |
||||
|
disabled_features:['header_resolutions','header_symbol_search', "volume_force_overlay"], |
||||
|
enabled_features:['header_indicators'], |
||||
|
overrides: tvStyle[this.theme], |
||||
|
// toolbar_bg: this.theme == "dark" ? "#222e3d" : "#f1f3f6",#121212 |
||||
|
toolbar_bg: this.theme == "dark" ? "#121212" : "#f1f3f6", |
||||
|
custom_css_url: `/static/Kline/charting_library/static/css/tradingview_${ |
||||
|
this.theme == "dark" ? "black" : "white" |
||||
|
}.css`, |
||||
|
debug:false, |
||||
|
}, |
||||
|
this.getHistoryCallback |
||||
|
); |
||||
|
|
||||
|
// 创建分时和主题按钮 |
||||
|
this.model.widget.onChartReady(this.createBtns.bind(this)); |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
watch: { |
||||
|
// 渲染图表库内容 |
||||
|
symbol(newVal, oldVal) { |
||||
|
if (!oldVal) { |
||||
|
// 初始化订阅数据并渲染图表库 |
||||
|
this.initTV(); |
||||
|
} else { |
||||
|
// 切换交易对 取消旧数据 订阅新数据 |
||||
|
let period = this.translateInterval2Period(); |
||||
|
this.model.subscribe([ |
||||
|
{ |
||||
|
cmd: "unsub", |
||||
|
msg: `Kline_${oldVal}_${period}` |
||||
|
}, |
||||
|
{ |
||||
|
cmd: "sub", |
||||
|
msg: `Kline_${newVal}_${period}` |
||||
|
} |
||||
|
]); |
||||
|
|
||||
|
// 已有图表库 通过修改symbol触发图标库更新 重新执行getSymbol和getBar |
||||
|
this.model.setSymbol(newVal); |
||||
|
} |
||||
|
}, |
||||
|
}, |
||||
|
|
||||
|
created() { |
||||
|
bus.$on('sendMsg', msg => { |
||||
|
// console.info(msg) |
||||
|
// this.model = new Model(msg, this); |
||||
|
this.model.conglian(msg) |
||||
|
let period = this.translateInterval2Period(); |
||||
|
this.model.subscribe([ |
||||
|
{ |
||||
|
cmd: "sub", |
||||
|
msg: `Kline_${this.symbol}_${period}` |
||||
|
} |
||||
|
]); |
||||
|
|
||||
|
}); |
||||
|
}, |
||||
|
|
||||
|
mounted() { |
||||
|
// console.Info(this.socket) |
||||
|
// 初始化模型对象 建立ws连接 |
||||
|
this.model = new Model(this.socket, this); |
||||
|
|
||||
|
// 刷新页面时订阅数据并创建图表 |
||||
|
if (this.symbol) this.initTV(); // 必须在mounted之后 因为渲染tv时需要查找容器 |
||||
|
} |
||||
|
}; |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss"> |
||||
|
#tradingview_lautin { |
||||
|
height: 550px; |
||||
|
} |
||||
|
|
||||
|
// 分时按钮 |
||||
|
#tradingview_878d2 .my-group { |
||||
|
cursor: pointer !important; |
||||
|
border: 1px solid red !important; |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,390 @@ |
|||||
|
<template> |
||||
|
<div class="col-md-3" style="background-color: #121212;padding-left: 0px;padding-right: 0px;margin-right: 8px;"> |
||||
|
<div class="mb15"><!-- order-book --> |
||||
|
<div class="d-flex"> |
||||
|
<div class="heading" :class="tabcolor == 1 ?'textcolor':''" @click="tabcolor = 1">{{ $t("exchange.order-book") }}</div> |
||||
|
<div class="heading" :class="tabcolor == 2 ?'textcolor':''" @click="tabcolor = 2">{{ $t("exchange.recent-trades") }}</div> |
||||
|
</div> |
||||
|
<table class="table" v-if="tabcolor == 1"> |
||||
|
<thead> |
||||
|
<tr style="display:block;"> |
||||
|
<th class="w-33">{{ $t("exchange.price") }}({{pair.to}})</th> |
||||
|
<th class="w-33 text-right">{{ $t("exchange.amount") }} |
||||
|
<!-- ({{pair.from}}) --> |
||||
|
({{pair.to}}) |
||||
|
</th> |
||||
|
<th class="w-33 text-right">{{ $t("exchange.total") }}({{pair.from}})</th> |
||||
|
</tr> |
||||
|
</thead> |
||||
|
|
||||
|
<tbody class="sell-orders" v-if="symbol!='gitpusdt'"> |
||||
|
<div class="order-item" v-for="item in sellList" :key="item.id"> |
||||
|
<el-progress class="progress" type="line" :stroke-width="39" :percentage="getValue(item.amount)" :show-text="false" color="rgba(216,43,43,0.15)"> |
||||
|
</el-progress> |
||||
|
<!-- 卖单 使用弹性盒子倒序排列 --> |
||||
|
<tr style="display:block;" class="tb-cells" @click.stop="handleOrder(item.price)"> |
||||
|
<td class="w-33 red" title="pick this price to sell">{{ item.price|omitTo(priceDecimals) }}</td> |
||||
|
<td class="w-33 text-right">{{ item.amount|omitTo(qtyDecimals) }}</td> |
||||
|
<td class="w-33 text-right">{{ item.price|multiple(item.amount, priceDecimals) }}</td> |
||||
|
</tr> |
||||
|
</div> |
||||
|
</tbody> |
||||
|
|
||||
|
<tbody class="ob-heading"> |
||||
|
<tr style="display:block;" v-if="newTrade"> |
||||
|
<td class="w-33"> |
||||
|
<span>{{ $t("exchange.last-price") }}</span> |
||||
|
<i :class="newTrade.changeRate > 0 ? 'tri-inc' : 'tri-dec'"></i> |
||||
|
<b :class="newTrade.changeRate > 0 ? 'increace' : 'decreace'">{{ newTrade.price}}</b> |
||||
|
</td> |
||||
|
<td class="w-33 text-right"> |
||||
|
<span v-if="langs=='cn'">CNY</span> |
||||
|
<span v-else>$</span> |
||||
|
<!-- ≈ {{omitTo(newTrade.price*price_cny)}} --> |
||||
|
<span v-if="langs=='cn'">≈ {{newTrade.price*priceCny|omitTo(2)}}</span> |
||||
|
<span v-else>≈ {{newTrade.price|omitTo(2)}}</span> |
||||
|
</td> |
||||
|
<td class="w-33 text-right" :class="changeRate.startsWith('+') ? 'increace' : 'decreace'"> |
||||
|
<span>{{ $t("exchange.change") }}</span> |
||||
|
{{ changeRate }} |
||||
|
</td> |
||||
|
</tr> |
||||
|
<tr style="display:block;" v-else> |
||||
|
<td class="w-33"><span>{{ $t("exchange.last-price") }}</span> -</td> |
||||
|
<td class="w-33 text-right"> |
||||
|
<span>CNY</span> - |
||||
|
</td> |
||||
|
<td class="w-33 text-right"><span>{{ $t("exchange.change") }}</span> -</td> |
||||
|
</tr> |
||||
|
</tbody> |
||||
|
|
||||
|
<tbody class="buy-orders" :style="[{'height':symbol!='gitpusdt'?'':'470px!important'}]"> |
||||
|
<!-- 买单 反序数值 --> |
||||
|
<div class="order-item" v-for="item in reversed" :key="item.id"> |
||||
|
<el-progress class="progress" type="line" :stroke-width="39" :percentage="getValue(item.amount)" :show-text="false" color="rgba(37, 188, 103, 0.15)"> |
||||
|
</el-progress> |
||||
|
<!-- 卖单 使用弹性盒子倒序排列 --> |
||||
|
<tr style="display:block;" class="tb-cells" @click.stop="handleOrder(item.price)"> |
||||
|
<td class="w-33 green" title="pick this price to buy">{{ item.price|omitTo(priceDecimals) }}</td> |
||||
|
<td class="w-33 text-right">{{ item.amount|omitTo(qtyDecimals) }}</td> |
||||
|
<td class="w-33 text-right">{{ item.price|multiple(item.amount, priceDecimals) }}</td> |
||||
|
</tr> |
||||
|
</div> |
||||
|
|
||||
|
</tbody> |
||||
|
</table> |
||||
|
</div> |
||||
|
<div class="market-history" style="border: 0px;" v-if="tabcolor == 2"> |
||||
|
<ul class="nav nav-pills" role="tablist" v-if="0"> |
||||
|
<li class="nav-item"> |
||||
|
<a class="nav-link active" data-toggle="pill" href="#recent-trades" role="tab" aria-selected="true"> |
||||
|
{{ $t("exchange.recent-trades") }} |
||||
|
</a> |
||||
|
</li> |
||||
|
<!-- <li class="nav-item"> |
||||
|
<a class="nav-link" data-toggle="pill" href="#market-depth" role="tab" aria-selected="false">Market |
||||
|
Depth</a> |
||||
|
</li> --> |
||||
|
</ul> |
||||
|
<div class="tab-content"> |
||||
|
<div class="tab-pane fade show active" id="recent-trades" role="tabpanel"> |
||||
|
<table class="table trade-list"> |
||||
|
<thead> |
||||
|
<tr> |
||||
|
<th style="display:block;width:100%;"> |
||||
|
<div class="w-33"> |
||||
|
{{ $t("exchange.price") }}({{pair.to}}) |
||||
|
</div> |
||||
|
<div class="w-33 text-right"> |
||||
|
{{ $t("exchange.amount") }}({{pair.from}}) |
||||
|
</div> |
||||
|
<div class="w-33 text-right"> |
||||
|
{{ $t("exchange.time") }} |
||||
|
</div> |
||||
|
</th> |
||||
|
</tr> |
||||
|
</thead> |
||||
|
<tbody> |
||||
|
|
||||
|
<tr v-for="(item, index) in tradeList" :key="index"> |
||||
|
<td style="display:block;width:100%"> |
||||
|
<div class="w-33" :style="{color : item.color}">{{ item.price }}</div> |
||||
|
<div class="w-33 text-right">{{ item.amount }}</div> |
||||
|
<div class="w-33 text-right">{{ item.time }}</div> |
||||
|
</td> |
||||
|
</tr> |
||||
|
|
||||
|
</tbody> |
||||
|
</table> |
||||
|
</div> |
||||
|
<!-- <div class="tab-pane fade" id="market-depth" role="tabpanel"> |
||||
|
<div class="depth-chart-container"> |
||||
|
<div class="depth-chart-inner"> |
||||
|
<div id="lightDepthChart"></div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> --> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
|
||||
|
import Market from "@/api/market"; |
||||
|
|
||||
|
export default { |
||||
|
|
||||
|
// props : ["priceDecimals", "qtyDecimals"], |
||||
|
props:[ |
||||
|
'priceCny' |
||||
|
], |
||||
|
data() { |
||||
|
return this.$parent; |
||||
|
}, |
||||
|
|
||||
|
computed: { |
||||
|
langs(){ |
||||
|
return localStorage.getItem('lang')||'en' |
||||
|
}, |
||||
|
reversed() { |
||||
|
// 按给定值 倒序排列 |
||||
|
if (this.buyList && this.buyList.length) return this.buyList; |
||||
|
else return []; |
||||
|
|
||||
|
}, |
||||
|
|
||||
|
changeRate() { |
||||
|
|
||||
|
// 开盘价为0时 则返回0值 |
||||
|
if (!this.marketInfo || !this.marketInfo.open) return `+0.00%`; |
||||
|
|
||||
|
let val = Math.division( |
||||
|
Math.subtr(this.newTrade.price, this.marketInfo.open), |
||||
|
this.marketInfo.open); |
||||
|
|
||||
|
// 补充+号 |
||||
|
let sign = val >= 0 ? '+' : ''; |
||||
|
let percentage = `${sign}${Math.multiple(val, 100, 2)}%`; |
||||
|
|
||||
|
return percentage; |
||||
|
|
||||
|
}, |
||||
|
|
||||
|
tradeList() { |
||||
|
|
||||
|
let count = 0; |
||||
|
|
||||
|
// 处理第1~(n-1)条记录,第一条永远显示绿色 |
||||
|
if (this.trade && this.trade.length) { |
||||
|
|
||||
|
return this.trade.sort((m, n) => { |
||||
|
|
||||
|
let dm = Number(m.price), |
||||
|
dn = Number(n.price); |
||||
|
|
||||
|
if (dn >= dm) { |
||||
|
n.color = "#53b987"; |
||||
|
n.changeRate = 1; |
||||
|
} else { |
||||
|
n.color = "#ff231f"; |
||||
|
n.changeRate = -1; |
||||
|
} |
||||
|
|
||||
|
n.price = Math.omitTo(n.price, this.priceDecimals); |
||||
|
n.amount = Math.omitTo(n.amount, this.qtyDecimals); |
||||
|
n.time = Date.parseTime(n.ts, false, "{h}:{i}:{s}"); |
||||
|
|
||||
|
// 处理最后一个值 |
||||
|
if (++count == this.trade.length - 1) { |
||||
|
m.color = "#53b987"; |
||||
|
m.changeRate = 1; |
||||
|
m.price = Math.omitTo(m.price, this.priceDecimals); |
||||
|
m.amount = Math.omitTo(m.amount, this.qtyDecimals); |
||||
|
m.time = Date.parseTime(m.ts, false, "{h}:{i}:{s}"); |
||||
|
} |
||||
|
}); |
||||
|
} else { |
||||
|
return this.trade; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
}, |
||||
|
|
||||
|
methods: { |
||||
|
|
||||
|
// 计算深度 当前数量 / 买卖最大值 |
||||
|
getValue(amount) { |
||||
|
const arr = this.buyList.concat(this.sellList).map(item => item.amount); |
||||
|
let max = Math.max(...arr); |
||||
|
return Math.division(amount, max, 2) * 100; |
||||
|
}, |
||||
|
|
||||
|
// 将委托价带入交易控制面板中 |
||||
|
handleOrder(price, ordertype) { |
||||
|
// 修改父组件的order |
||||
|
if (this.passOrderPrice) { |
||||
|
this.buyorder.entrust_price = Math.omitTo(price, this.priceDecimals); |
||||
|
this.sellorder.entrust_price = Math.omitTo(price, this.priceDecimals); |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
// 测试方法 用于progress传入值 |
||||
|
format(item) { |
||||
|
return function (percentage) { |
||||
|
return `<span>${Math.omitTo(item.price, this.priceDecimals)}</span> |
||||
|
<span>${Math.omitTo(item.qty, this.qtyDecimals)}</span> |
||||
|
<span>${Math.multiple(item.price, item.qty, this.priceDecimals)}</span>`; |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
bookTrades() { |
||||
|
Market.getstockMarketInfo(this.symbol).then(response => { |
||||
|
// |
||||
|
this.sellList = response.sellList.sort((a, b) => b.price - a.price); |
||||
|
this.buyList = response.buyList; |
||||
|
this.trade = response.tradeList; |
||||
|
|
||||
|
}).catch(err => { |
||||
|
|
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
}, |
||||
|
|
||||
|
mounted() { |
||||
|
// 在mounted中重置初始化的[]值,如果在created之前的话 []会覆盖ajax查询的值 |
||||
|
this.bookTrades(); |
||||
|
}, |
||||
|
|
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss"> |
||||
|
.w-33 { |
||||
|
width: 32% !important; |
||||
|
display: inline-block !important; |
||||
|
vertical-align: text-top !important; |
||||
|
box-sizing: border-box !important; |
||||
|
} |
||||
|
|
||||
|
.buy-orders { |
||||
|
|
||||
|
height: 235px !important; |
||||
|
overflow: hidden !important; |
||||
|
|
||||
|
td { |
||||
|
@include ff(OpenSans-Regular); |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
.sell-orders { |
||||
|
|
||||
|
@extend .buy-orders; |
||||
|
|
||||
|
@include flexible(column-reverse, flex-start, flex-start, wrap); |
||||
|
|
||||
|
// flex-shrink: 0; // 不压缩 |
||||
|
display: flex !important; |
||||
|
overflow-x: hidden; // 重要 换行后 隐藏右侧内容 |
||||
|
|
||||
|
} |
||||
|
|
||||
|
.order-item { |
||||
|
|
||||
|
position: relative; |
||||
|
z-index: 1; |
||||
|
width: 100%; |
||||
|
height: 39px; |
||||
|
|
||||
|
.progress { |
||||
|
height: 100%; |
||||
|
border-radius: 0; |
||||
|
background: none; |
||||
|
} |
||||
|
|
||||
|
.tb-cells { |
||||
|
position: absolute; |
||||
|
left: 0; |
||||
|
top: 0; |
||||
|
height: 100%; |
||||
|
z-index: 100; |
||||
|
cursor: pointer; |
||||
|
|
||||
|
&:hover { |
||||
|
background: none; |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// 给外边框添加不同的底色 |
||||
|
&:nth-child(even) .progress .el-progress-bar__outer { |
||||
|
background: #F8F8FF; |
||||
|
// background: #f6f8f9; |
||||
|
|
||||
|
} |
||||
|
|
||||
|
&:nth-child(odd) .progress .el-progress-bar__outer { |
||||
|
background: #ffffff; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.el-progress { |
||||
|
|
||||
|
.el-progress-bar { |
||||
|
|
||||
|
/**重构progress的背景色 */ |
||||
|
.el-progress-bar__outer { |
||||
|
|
||||
|
// 去除外表框的圆角 |
||||
|
border-radius: 0 !important; |
||||
|
// background: #fff; |
||||
|
|
||||
|
.el-progress-bar__inner { |
||||
|
|
||||
|
border-radius: 0 !important; |
||||
|
|
||||
|
right: 0; // 将进度容器由左对齐变成右对齐 |
||||
|
left: auto; |
||||
|
|
||||
|
&::after {} |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.trade-list { |
||||
|
tbody { |
||||
|
// height: 279px; |
||||
|
height: 505px; |
||||
|
|
||||
|
tr { |
||||
|
|
||||
|
// @include flexible(); |
||||
|
// td:nth-last-child { |
||||
|
// flex-grow: 1; |
||||
|
// } |
||||
|
td { |
||||
|
cursor: text !important; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
#darkDepthChart, |
||||
|
#lightDepthChart { |
||||
|
height: 305px; |
||||
|
} |
||||
|
</style> |
||||
|
<style lang="scss" scoped> |
||||
|
.ob-heading { |
||||
|
border: 1px solid #333; |
||||
|
box-shadow: 0 0 5px #555; |
||||
|
} |
||||
|
.textcolor{ |
||||
|
color: #007bff; |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,618 @@ |
|||||
|
<template> |
||||
|
<div class="col-md-8"> |
||||
|
|
||||
|
<!-- 生成K线图 --> |
||||
|
<k-line :symbol="symbol" :marketId="marketId" :priceDecimals="priceDecimals"></k-line> |
||||
|
|
||||
|
<!-- 交易处理 --> |
||||
|
<div class="market-trade"> |
||||
|
<ul class="nav nav-pills"> |
||||
|
<li class="nav-item"> |
||||
|
<a href :class="[`nav-link`, {active:!isCondition&&!isMarket}]" @click.prevent="isCondition=false;isMarket=false;">Limit</a> |
||||
|
</li> |
||||
|
<li class="nav-item"> |
||||
|
<a href :class="[`nav-link`, {active:!isCondition&&isMarket}]" @click.prevent="isCondition=false;isMarket=true;">Market</a> |
||||
|
</li> |
||||
|
<li class="nav-item"> |
||||
|
<a href :class="[`nav-link`, {active:isCondition&&!isMarket}]" @click.prevent="isCondition=true;isMarket=false;">Stop Limit</a> |
||||
|
</li> |
||||
|
<li class="nav-item"> |
||||
|
<a href :class="[`nav-link`, {active:isCondition&&isMarket}]" @click.prevent="isCondition=true;isMarket=true;">Stop Market</a> |
||||
|
</li> |
||||
|
</ul> |
||||
|
<div class="tab-content"> |
||||
|
<div class="tab-pane fade show active"> |
||||
|
<div class="d-flex justify-content-between"> |
||||
|
<!------------- Buy Order --------------> |
||||
|
<div class="market-trade-buy"> |
||||
|
|
||||
|
<!-- Trigger Price --> |
||||
|
<el-popover popper-class='popover-tips' placement="top-start" trigger="manual" v-model="visibles.buy.trigger"> |
||||
|
<span class="content"> |
||||
|
<i class="el-icon-warning-outline"></i> |
||||
|
{{ msgList.buy[0] }} |
||||
|
</span> |
||||
|
<div class="input-group" v-if="isCondition" slot="reference"> |
||||
|
<input type="number" v-model="buyorder.trigger_price" class="form-control" placeholder="请输入触发价格"> |
||||
|
<div class="input-group-append"> |
||||
|
<span class="input-group-text">{{pair.from}}</span> |
||||
|
</div> |
||||
|
</div> |
||||
|
</el-popover> |
||||
|
|
||||
|
<template v-if="isMarket"> |
||||
|
<div class="input-group"> |
||||
|
<!-- Market Price --> |
||||
|
<input type="text" class="form-control" disabled placeholder="在最佳市场价格成交"> |
||||
|
</div> |
||||
|
</template> |
||||
|
<template v-else> |
||||
|
<el-popover popper-class='popover-tips' placement="top-start" trigger="manual" v-model="visibles.buy.limitPrice"> |
||||
|
<span class="content"> |
||||
|
<i class="el-icon-warning-outline"></i> |
||||
|
{{ msgList.buy[1] }} |
||||
|
</span> |
||||
|
<div class="input-group" slot="reference"> |
||||
|
<!-- Entrust Price --> |
||||
|
<input type="number" v-model="buyorder.entrust_price" class="form-control" placeholder="请输入价格"> |
||||
|
<div class="input-group-append"> |
||||
|
<span class="input-group-text">{{pair.from}}</span> |
||||
|
</div> |
||||
|
</div> |
||||
|
</el-popover> |
||||
|
</template> |
||||
|
|
||||
|
<!-- Amount/Total --> |
||||
|
<template v-if="isMarket"> |
||||
|
<el-popover popper-class='popover-tips' placement="top-start" trigger="manual" v-model="visibles.buy.marketTotal"> |
||||
|
<span class="content"> |
||||
|
<i class="el-icon-warning-outline"></i> |
||||
|
{{ msgList.buy[3] }} |
||||
|
</span> |
||||
|
<div class="input-group" slot="reference"> |
||||
|
<input type="number" v-model="buyTotal" class="form-control" min=0 placeholder="请输入总值"> |
||||
|
<div class="input-group-append"> |
||||
|
<span class="input-group-text">{{pair.to}}</span> |
||||
|
</div> |
||||
|
</div> |
||||
|
</el-popover> |
||||
|
</template> |
||||
|
<template v-else> |
||||
|
<el-popover popper-class='popover-tips' placement="top-start" trigger="manual" v-model="visibles.buy.limitAmount"> |
||||
|
<!-- 提示框的内容 --> |
||||
|
<span class="content"> |
||||
|
<!-- 图标 --> |
||||
|
<i class="el-icon-warning-outline"></i> |
||||
|
<!-- 提示 --> |
||||
|
{{ msgList.buy[2] }} |
||||
|
</span> |
||||
|
<div class="input-group" slot="reference"> |
||||
|
<input type="number" v-model="buyorder.amount" class="form-control" min=0 placeholder="请输入数量"> |
||||
|
<div class="input-group-append"> |
||||
|
<span class="input-group-text">{{pair.to}}</span> |
||||
|
</div> |
||||
|
</div> |
||||
|
</el-popover> |
||||
|
</template> |
||||
|
|
||||
|
<!-- Percent --> |
||||
|
<ul class="market-trade-list"> |
||||
|
<li v-for="(item,index) in percentage" :key="index" :class="{buyPercentActive:index == buyPercentIndex}" @click="renderBuyAmount(item.value, index)"> |
||||
|
<a href="javascript:void 0">{{ item.label }}</a> |
||||
|
</li> |
||||
|
</ul> |
||||
|
|
||||
|
<!-- Total --> |
||||
|
<el-popover popper-class='popover-tips' placement="top-start" trigger="manual" v-model="visibles.buy.orderTotal"> |
||||
|
<span class="content"> |
||||
|
<i class="el-icon-warning-outline"></i> |
||||
|
{{ msgList.buy[5] }} |
||||
|
</span> |
||||
|
<p slot="reference"> |
||||
|
{{$t('exchange.order-total')}}: |
||||
|
<span> <b>{{buyTotal}}</b> {{pair.from}} </span> |
||||
|
</p> |
||||
|
</el-popover> |
||||
|
|
||||
|
<!-- Available --> |
||||
|
<p>{{$t('otc.j3')}}: |
||||
|
<span> {{toBalance}} {{pair.to}}</span><br /> |
||||
|
<span> {{fromBalance}} {{pair.from}}</span> |
||||
|
</p> |
||||
|
<button class="btn buy" @click="handleBuyOrder">Buy {{pair.to}}</button> |
||||
|
</div> |
||||
|
|
||||
|
<!------------ Sell Order -----------> |
||||
|
<div class="market-trade-sell"> |
||||
|
<el-popover popper-class='popover-tips' placement="top-start" trigger="manual" v-model="visibles.sell.trigger"> |
||||
|
<span class="content"> |
||||
|
<i class="el-icon-warning-outline"></i> |
||||
|
{{ msgList.sell[0] }} |
||||
|
</span> |
||||
|
<!-- Trigger Price --> |
||||
|
<div class="input-group" v-if="isCondition" slot="reference"> |
||||
|
<input type="number" v-model="sellorder.trigger_price" class="form-control" min=0 placeholder="请输入触发价格"> |
||||
|
<div class="input-group-append"> |
||||
|
<span class="input-group-text">{{pair.from}}</span> |
||||
|
</div> |
||||
|
</div> |
||||
|
</el-popover> |
||||
|
|
||||
|
<template v-if="isMarket"> |
||||
|
<div class="input-group"> |
||||
|
<!-- Market Price --> |
||||
|
<input type="text" class="form-control" disabled placeholder="在最佳市场价格成交"> |
||||
|
</div> |
||||
|
</template> |
||||
|
<template v-else> |
||||
|
<el-popover popper-class='popover-tips' placement="top-start" trigger="manual" v-model="visibles.sell.limitPrice"> |
||||
|
<span class="content"> |
||||
|
<i class="el-icon-warning-outline"></i> |
||||
|
{{ msgList.sell[1] }} |
||||
|
</span> |
||||
|
<div class="input-group" slot="reference"> |
||||
|
<!-- Entrust Price --> |
||||
|
<input type="number" v-model="sellorder.entrust_price" class="form-control" min=0 placeholder="请输入价格"> |
||||
|
<div class="input-group-append"> |
||||
|
<span class="input-group-text">{{pair.from}}</span> |
||||
|
</div> |
||||
|
</div> |
||||
|
</el-popover> |
||||
|
</template> |
||||
|
|
||||
|
<!-- Amount --> |
||||
|
<el-popover popper-class='popover-tips' placement="top-start" trigger="manual" v-model="visibles.sell.marketAmount"> |
||||
|
<span class="content"> |
||||
|
<i class="el-icon-warning-outline"></i> |
||||
|
{{ msgList.sell[4] }} |
||||
|
</span> |
||||
|
<div class="input-group" slot="reference"> |
||||
|
<input type="number" v-model="sellorder.amount" class="form-control" min=0 placeholder="请输入数量"> |
||||
|
<div class="input-group-append"> |
||||
|
<span class="input-group-text">{{pair.to}}</span> |
||||
|
</div> |
||||
|
</div> |
||||
|
</el-popover> |
||||
|
|
||||
|
<ul class="market-trade-list"> |
||||
|
<li v-for="(item,index) in percentage" :key="index" :class="{sellPercentActive:index == sellPercentIndex}" @click="renderSellAmount(item.value, index)"> |
||||
|
<a href="javascript:void 0">{{ item.label }}</a> |
||||
|
</li> |
||||
|
</ul> |
||||
|
|
||||
|
<!-- Total --> |
||||
|
<el-popover popper-class='popover-tips' placement="top-start" trigger="manual" v-model="visibles.sell.orderTotal"> |
||||
|
<span class="content"> |
||||
|
<i class="el-icon-warning-outline"></i> |
||||
|
{{ msgList.sell[5] }} |
||||
|
</span> |
||||
|
<p slot="reference"> |
||||
|
{{$t('exchange.order-total')}}: |
||||
|
<span> |
||||
|
<b>{{sellTotal}}</b> {{pair.from}} </span> |
||||
|
</p> |
||||
|
</el-popover> |
||||
|
|
||||
|
<p>{{$t('otc.j3')}}: |
||||
|
<span> {{toBalance}} {{pair.to}} </span><br /> |
||||
|
<span> {{fromBalance}} {{pair.from}}</span> |
||||
|
</p> |
||||
|
<button class="btn sell" @click="handleSellOrder">Sell {{pair.to}}</button> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
|
||||
|
import Exchange from "@/api/exchange"; |
||||
|
|
||||
|
export default { |
||||
|
|
||||
|
props: ["pair", "buyorder", "marketId", "sellorder", "fromBalance", "toBalance", "symbol", "newTrade", "minQty", "minTotal", "priceDecimals", "qtyDecimals"], |
||||
|
data() { |
||||
|
return { |
||||
|
isMarket: false, |
||||
|
isCondition: false, |
||||
|
userBanlance: null, |
||||
|
|
||||
|
cacheTotal: 0, // 存放市价单输入的总值 |
||||
|
cachePrice: null, // 存放最新价格 |
||||
|
|
||||
|
// 气泡弹框内容和触发 |
||||
|
visibles: { |
||||
|
"buy": { |
||||
|
limitPrice: false, // 限制价格 |
||||
|
limitAmount: false, // 限制数量 |
||||
|
marketTotal: false, // 限制总额 |
||||
|
marketAmount: false, // 市价数量 |
||||
|
trigger: false, // 触发价格 |
||||
|
orderTotal: false, // 订单总额 |
||||
|
}, |
||||
|
"sell": { |
||||
|
limitPrice: false, |
||||
|
limitAmount: false, |
||||
|
marketTotal: false, |
||||
|
marketAmount: false, |
||||
|
trigger: false, |
||||
|
orderTotal: false, |
||||
|
}, |
||||
|
}, |
||||
|
msgList: { |
||||
|
"buy": Array(6).fill(''), // 5个空字符串的数组 |
||||
|
"sell": Array(6).fill('') |
||||
|
}, |
||||
|
// 百分比集合 |
||||
|
percentage: [{ |
||||
|
label: "25%", |
||||
|
value: 0.25 |
||||
|
}, |
||||
|
{ |
||||
|
label: "50%", |
||||
|
value: 0.5 |
||||
|
}, |
||||
|
{ |
||||
|
label: "75%", |
||||
|
value: 0.75 |
||||
|
}, |
||||
|
{ |
||||
|
label: "100%", |
||||
|
value: 1 |
||||
|
}, |
||||
|
], |
||||
|
// |
||||
|
buyPercentIndex: null, |
||||
|
sellPercentIndex: null, |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
computed: { |
||||
|
|
||||
|
// 获取type类型值 |
||||
|
type() { |
||||
|
if (!this.isCondition) { |
||||
|
return this.isMarket ? 2 : 1; |
||||
|
} else { |
||||
|
return this.isMarket ? 4 : 3; |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
theme() { |
||||
|
return localStorage.theme ? localStorage.theme : "light"; |
||||
|
}, |
||||
|
|
||||
|
buyTotal: { |
||||
|
get() { |
||||
|
if (!this.isMarket) { |
||||
|
return Math.multiple(this.buyorder.entrust_price, this.buyorder.amount); |
||||
|
} else { |
||||
|
return this.cacheTotal; |
||||
|
} |
||||
|
}, |
||||
|
set(val) { |
||||
|
// 根据总值 计算数量 |
||||
|
if (!this.isMarket) { |
||||
|
this.buyorder.amount = Math.division(val, this.buyorder.entrust_price); |
||||
|
} else { // 市价单 缓存总值 |
||||
|
this.cacheTotal = val; |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
sellTotal: { |
||||
|
get() { |
||||
|
return Math.multiple(this.sellorder.entrust_price, this.sellorder.amount); |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
// 当前语言 |
||||
|
lang() { |
||||
|
let browser_Lang = navigator.language.includes('zh') ? 'zh' : 'en'; |
||||
|
return localStorage.lang || browser_Lang; |
||||
|
}, |
||||
|
|
||||
|
}, |
||||
|
|
||||
|
watch: { |
||||
|
custom(newVal) { |
||||
|
// console.log(newVal) |
||||
|
}, |
||||
|
|
||||
|
type() { |
||||
|
// 切换订单类型时 清空价格和数量 |
||||
|
// 数量改变时 触发percentage更新 |
||||
|
this.reset(); |
||||
|
}, |
||||
|
|
||||
|
// 有新交易时触发 给限价单设定初始价格 |
||||
|
newTrade(newVal, oldVal) { |
||||
|
if (!this.isMarket) { |
||||
|
|
||||
|
// 新交易对有trade数据 |
||||
|
if (!oldVal && newVal) { // 没值到初始化值 |
||||
|
// 修改order里面price的值 |
||||
|
this.cachePrice = newVal.price; |
||||
|
this.reset(); |
||||
|
} |
||||
|
|
||||
|
// 切换交易对时 清空了数据 |
||||
|
if (oldVal && !newVal) { // 有值到没值的过程 |
||||
|
this.cachePrice = null; |
||||
|
this.reset(); |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
}, |
||||
|
|
||||
|
methods: { |
||||
|
|
||||
|
renderBuyAmount(val, index) { |
||||
|
if (!this.buyorder.entrust_price) { |
||||
|
this.visibles.buy.limitPrice = true; |
||||
|
this.msgList.buy[1] = this.$t('nav.tips'); |
||||
|
this.clearAll(); |
||||
|
return; |
||||
|
} |
||||
|
this.buyPercentIndex = index; |
||||
|
this.buyTotal = Math.multiple(this.fromBalance, val); |
||||
|
}, |
||||
|
|
||||
|
renderSellAmount(val, index) { |
||||
|
if (!this.sellorder.entrust_price) { |
||||
|
this.visibles.sell.limitPrice = true; |
||||
|
this.msgList.sell[1] = this.$t('nav.tips'); |
||||
|
this.clearAll(); |
||||
|
return; |
||||
|
} |
||||
|
this.sellPercentIndex = index; |
||||
|
this.sellorder.amount = Math.multiple(this.toBalance, val); |
||||
|
}, |
||||
|
|
||||
|
handleBuyOrder() { |
||||
|
|
||||
|
// 执行前端的有效性验证 |
||||
|
if (!this.chkValidate(this.buyorder, this.buyTotal, "buy")) return; |
||||
|
|
||||
|
const baseArgs = { |
||||
|
symbol: this.symbol, |
||||
|
type: this.type, |
||||
|
}; |
||||
|
|
||||
|
// 区分限价、市价和条件委托单 |
||||
|
// 1、限价单买入时 需要的参数:价格、数量、 |
||||
|
// 2、市价单买入时 需要的参数:总值 |
||||
|
// 3、条件单买入时 需要的参数:触发价、价格数量或者总值 |
||||
|
// 4、卖出时 需要价格和数量 |
||||
|
Exchange.storeEntrust(Object.assign(this.buyorder, { |
||||
|
total: this.buyTotal, |
||||
|
}, baseArgs)).then(data => { |
||||
|
// 触发父组件的方法 更新余额和订单 |
||||
|
this.$emit('update'); |
||||
|
// 清空表单 |
||||
|
this.reset(); |
||||
|
}).catch(err => { |
||||
|
|
||||
|
}); |
||||
|
}, |
||||
|
|
||||
|
handleSellOrder() { |
||||
|
// 执行前端的有效性验证 |
||||
|
if (!this.chkValidate(this.sellorder, this.sellTotal, "sell")) return; |
||||
|
|
||||
|
const baseArgs = { |
||||
|
symbol: this.symbol, |
||||
|
type: this.type, |
||||
|
}; |
||||
|
Exchange.storeEntrust(Object.assign(this.sellorder, { |
||||
|
total: this.sellTotal |
||||
|
}, baseArgs)).then(data => { |
||||
|
// 触发父组件的方法 更新余额和订单 |
||||
|
this.$emit('update'); |
||||
|
// 清空表单 |
||||
|
this.reset(); |
||||
|
}).catch(err => { |
||||
|
|
||||
|
}); |
||||
|
}, |
||||
|
|
||||
|
reset() { |
||||
|
|
||||
|
// 如果没有newTrade时 则没有缓存价格 重置为最小值0 |
||||
|
// 由于输入框去除了精度空值 这里还需要手动设置精度值 |
||||
|
let price = this.cachePrice || 0; |
||||
|
|
||||
|
this.buyorder.entrust_price = Math.omitTo(price, this.priceDecimals); |
||||
|
this.buyorder.trigger_price = Math.omitTo(price, this.priceDecimals); |
||||
|
|
||||
|
this.sellorder.entrust_price = Math.omitTo(price, this.priceDecimals); |
||||
|
this.sellorder.trigger_price = Math.omitTo(price, this.priceDecimals); |
||||
|
|
||||
|
// 清空数量 |
||||
|
this.buyorder.amount = 0; |
||||
|
this.sellorder.amount = 0; |
||||
|
|
||||
|
// total赋值会触发set方法 |
||||
|
// this.buyTotal = 0; |
||||
|
// this.cacheTotal = 0; |
||||
|
|
||||
|
// 去除百分比样式 |
||||
|
this.buyPercentIndex = -1; |
||||
|
this.sellPercentIndex = -1; |
||||
|
}, |
||||
|
|
||||
|
clearAll() { |
||||
|
// 5s后统一清除提示框 |
||||
|
setTimeout(function () { |
||||
|
Object.keys(this.visibles.buy).forEach(key => this.visibles.buy[key] = false); |
||||
|
Object.keys(this.visibles.sell).forEach(key => this.visibles.sell[key] = false); |
||||
|
}.bind(this), 5000); |
||||
|
}, |
||||
|
|
||||
|
empty(val) { |
||||
|
let ret; |
||||
|
switch (typeof val) { |
||||
|
case "number": |
||||
|
ret = val == 0; |
||||
|
break; |
||||
|
case "string": |
||||
|
ret = val == "0" || /^\s?$/.test(val); |
||||
|
break; |
||||
|
case "boolean": |
||||
|
ret = val; |
||||
|
break; |
||||
|
default: |
||||
|
ret = Boolean(val); |
||||
|
break; |
||||
|
} |
||||
|
return ret; |
||||
|
}, |
||||
|
|
||||
|
chkValidate(order, total, orderType) { |
||||
|
let flag = true; |
||||
|
|
||||
|
switch (this.type) { |
||||
|
|
||||
|
case 1: // limit |
||||
|
if (this.empty(order.entrust_price)) { |
||||
|
flag = false; |
||||
|
this.visibles[orderType].limitPrice = true; |
||||
|
this.msgList[orderType][1] = this.$t('nav.a1'); |
||||
|
} else if (this.empty(order.amount)) { |
||||
|
flag = false; |
||||
|
this.visibles[orderType].limitAmount = true; |
||||
|
this.msgList[orderType][2] = this.$t('nav.a2'); |
||||
|
} else { |
||||
|
if (order.amount < this.minQty) { |
||||
|
flag = false; |
||||
|
this.visibles[orderType].limitAmount = true; |
||||
|
this.msgList[orderType][2] = this.$t('nav.a3')+`${this.minQty}`; |
||||
|
} |
||||
|
|
||||
|
if (total < this.minTotal) { |
||||
|
flag = false; |
||||
|
this.visibles[orderType].orderTotal = true; |
||||
|
this.msgList[orderType][5] = this.$t('nav.b8')+`${this.minTotal}`; |
||||
|
} |
||||
|
} |
||||
|
break; |
||||
|
|
||||
|
case 2: // market |
||||
|
if (order.direction == "buy") { // 买 |
||||
|
if (this.empty(total)) { |
||||
|
flag = false; |
||||
|
this.visibles[orderType].marketTotal = true; |
||||
|
this.msgList[orderType][3] = this.$t('nav.a4'); |
||||
|
} else if (this.total < this.minTotal) { |
||||
|
flag = false; |
||||
|
this.visibles.marketTotal = true; |
||||
|
this.msgList[3] = this.$t('nav.a5')+`${this.minTotal}`; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if (order.direction == "sell") { // 卖 |
||||
|
if (this.empty(order.amount)) { |
||||
|
flag = false; |
||||
|
this.visibles[orderType].marketAmount = true; |
||||
|
this.msgList[orderType][4] = this.$t('nav.a6'); |
||||
|
} else if (order.amount < this.minQty) { |
||||
|
flag = false; |
||||
|
this.visibles[orderType].marketAmount = true; |
||||
|
this.msgList[orderType][4] = this.$t('nav.a7')+` ${this.minQty}`; |
||||
|
} |
||||
|
} |
||||
|
break; |
||||
|
|
||||
|
case 3: // stop-limit |
||||
|
|
||||
|
if (this.empty(order.trigger_price)) { |
||||
|
flag = false; |
||||
|
this.visibles[orderType].trigger = true; |
||||
|
this.msgList[orderType][0] = this.$t('nav.a8') |
||||
|
} else if (this.empty(order.entrust_price)) { |
||||
|
flag = false; |
||||
|
this.visibles[orderType].limitPrice = true; |
||||
|
this.msgList[orderType][1] = this.$t('nav.a9') |
||||
|
} else if (this.empty(order.amount)) { |
||||
|
flag = false; |
||||
|
this.visibles[orderType].limitAmount = true; |
||||
|
this.msgList[orderType][2] = this.$t('nav.b1') |
||||
|
} |
||||
|
break; |
||||
|
|
||||
|
case 4: // stop-market |
||||
|
if (this.empty(order.trigger_price)) { |
||||
|
flag = false; |
||||
|
this.visibles[orderType].trigger = true; |
||||
|
this.msgList[orderType][0] = this.$t('nav.b2') |
||||
|
} else { |
||||
|
|
||||
|
if (order.direction == "buy") { |
||||
|
if (this.empty(total)) { |
||||
|
flag = false; |
||||
|
this.visibles[orderType].marketTotal = true; |
||||
|
this.msgList[orderType][3] = this.$t('nav.b3') |
||||
|
} else if (total < this.minTotal) { |
||||
|
flag = false; |
||||
|
this.visibles[orderType].marketTotal = true; |
||||
|
this.msgList[orderType][3] = this.$t('nav.b5')+` ${this.minTotal}` |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if (order.direction == "sell") { |
||||
|
if (this.empty(order.amount)) { |
||||
|
flag = false; |
||||
|
this.visibles[orderType].marketAmount = true; |
||||
|
this.msgList[orderType][4] = this.$t('nav.b6') |
||||
|
} else if (order.amount < this.minQty) { |
||||
|
flag = false; |
||||
|
this.visibles[orderType].marketAmount = true; |
||||
|
this.msgList[orderType][4] = this.$t('nav.b7')+` ${this.minQty}` |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
break; |
||||
|
} |
||||
|
|
||||
|
// 清除所有样式 |
||||
|
this.clearAll(); |
||||
|
|
||||
|
// 返回验证结果 |
||||
|
return flag; |
||||
|
}, |
||||
|
|
||||
|
|
||||
|
}, |
||||
|
|
||||
|
created() { |
||||
|
|
||||
|
}, |
||||
|
|
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss" scoped> |
||||
|
.buyPercentActive { |
||||
|
a:link { |
||||
|
font-weight: bold; |
||||
|
background: #26a69a; |
||||
|
color: #fff; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.sellPercentActive { |
||||
|
a:link { |
||||
|
font-weight: bold; |
||||
|
background: #ef5350; |
||||
|
color: #fff; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.input-group-text { |
||||
|
width: 68px; |
||||
|
@include flexible(row, center, center); |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,706 @@ |
|||||
|
<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 mtb15 no-fluid"> |
||||
|
<div class="row sm-gutters"> --> |
||||
|
|
||||
|
<!-- symbols --> |
||||
|
<!-- <symbols :marketList="marketList" :marketId="marketId" :isLogin="isLogin" :symbol.sync="symbol"> |
||||
|
</symbols> --> |
||||
|
|
||||
|
<!-- kline --> |
||||
|
<!-- <stock-kline :symbol="symbol" :socket="ws.socket" :priceDecimals="priceDecimals"></stock-kline> --> |
||||
|
|
||||
|
<!-- order book --> |
||||
|
<!-- <book-trades :priceCny="price_cny"></book-trades> --> |
||||
|
|
||||
|
<!-- 交易布局 --> |
||||
|
<!-- <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> --> |
||||
|
|
||||
|
<!-- market news --> |
||||
|
<!-- <market-news></market-news> --> |
||||
|
|
||||
|
<!-- order list --> |
||||
|
<!-- <order-list ref="Order" :ordersOpen="ordersOpen" :conditionOrders="conditionOrders" |
||||
|
:ordersHistory="ordersHistory" :holdPositionList="holdPositionList" :priceDecimals="priceDecimals" :qtyDecimals="qtyDecimals" |
||||
|
:isLogin="isLogin" :pair="pair" @change="currentTab = $event" @update="update" |
||||
|
@Pagination="page = $event" @Pagination1="page1 = $event"></order-list> --> |
||||
|
|
||||
|
<!-- </div> |
||||
|
</div> |
||||
|
</div> --> |
||||
|
<div class="contract-page" style="background-color: #000;"> |
||||
|
<div class="coin-change d-flex align-items-center py-2 pl-4 heading justify-content-between" style="background-color: #121212;"> |
||||
|
<div class="d-flex align-items-center"> |
||||
|
<div class="coin d-flex align-items-center"> |
||||
|
<el-popover |
||||
|
placement="bottom" |
||||
|
ref="popover" |
||||
|
width="400" |
||||
|
trigger="click" |
||||
|
> |
||||
|
<div slot="reference"> |
||||
|
{{ activeContract.pair_name }} |
||||
|
<el-button size="mini"> |
||||
|
<i class="el-icon-arrow-down"></i> |
||||
|
</el-button> |
||||
|
</div> |
||||
|
<div |
||||
|
class="markets-pair-list" |
||||
|
style="max-height:300px;overflow:auto;" |
||||
|
> |
||||
|
<template v-for="parent in marketList"> |
||||
|
<div class="px-3 text-primary" :key="parent.coin_name"> |
||||
|
{{ parent.coin_name }} |
||||
|
</div> |
||||
|
<table class="table" :key="parent.coin_name + 1"> |
||||
|
<thead> |
||||
|
<tr class="text-secondary"> |
||||
|
<th class="w-10/24">{{ $t("contract.h5") }}</th> |
||||
|
<th class="w-7/24">{{ $t("contract.g3") }}</th> |
||||
|
<th class="w-7/24 text-right"> |
||||
|
{{ $t("contract.h6") }} |
||||
|
</th> |
||||
|
</tr> |
||||
|
</thead> |
||||
|
<tbody> |
||||
|
<!-- @click="symbol = item.symbol" --> |
||||
|
<tr |
||||
|
v-for="item in parent.marketInfoList" |
||||
|
:key="item.symbol" |
||||
|
:class="{ active: item.symbol == symbol }" |
||||
|
@click="ispopover1(item.symbol)" |
||||
|
> |
||||
|
<td class="w-10/24"> |
||||
|
{{ item.symbol }}/{{ parent.coin_name }} |
||||
|
</td> |
||||
|
<td |
||||
|
class="w-7/24 " |
||||
|
:class="item.increase < 0 ? 'decreace' : 'increace'" |
||||
|
> |
||||
|
{{item.price}} |
||||
|
<!-- item.symbol == symbol ? price1 : --> |
||||
|
</td> |
||||
|
<td |
||||
|
class="w-7/24" |
||||
|
:class="item.increase < 0 ? 'decreace' : 'increace'" |
||||
|
> |
||||
|
{{ item.increaseStr }} |
||||
|
</td> |
||||
|
</tr> |
||||
|
</tbody> |
||||
|
</table> |
||||
|
</template> |
||||
|
</div> |
||||
|
</el-popover> |
||||
|
</div> |
||||
|
<div |
||||
|
class="price px-3 border-right" |
||||
|
:class="{ |
||||
|
decreace: activeContract.increase < 0, |
||||
|
increace: activeContract.increase >= 0 |
||||
|
}" |
||||
|
> |
||||
|
<span class="current">{{ activeContract.price }}$</span> |
||||
|
<!-- <span class="current">{{price1}}$</span> --> |
||||
|
|
||||
|
<span class="zf">{{ activeContract.increaseStr }}</span> |
||||
|
</div> |
||||
|
<!-- 币种价值数据 --> |
||||
|
<div class="d-flex fn-12"> |
||||
|
<div class="item px-2"> |
||||
|
<div class="title mb-1 text-secondary"> |
||||
|
24h {{ $t("contract.h7") }} |
||||
|
</div> |
||||
|
<div> |
||||
|
{{ activeContract.high }} |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="item px-2"> |
||||
|
<div class="title mb-1 text-secondary"> |
||||
|
24h {{ $t("contract.h8") }} |
||||
|
</div> |
||||
|
<div> |
||||
|
{{ activeContract.low }} |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="item px-2"> |
||||
|
<div class="title mb-1 text-secondary"> |
||||
|
24h {{ $t("contract.h9") }} |
||||
|
<!-- ({{ $t("contract.e2") }}) --> |
||||
|
<!-- (USDT) --> |
||||
|
</div> |
||||
|
<div> |
||||
|
{{ activeContract.vol }} |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<!-- <div><theme-change /></div> --> |
||||
|
</div> |
||||
|
<div class="page-top d-flex pt-2"> |
||||
|
<div class="kline-box flex-fill mr-2"> |
||||
|
<stock-kline :symbol="symbol" :socket="ws.socket" :priceDecimals="priceDecimals"></stock-kline> |
||||
|
</div> |
||||
|
<!-- 盘口 --> |
||||
|
<book-trades :priceCny="price_cny"></book-trades> |
||||
|
<!-- 交易 --> |
||||
|
<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> |
||||
|
<order-list ref="Order" :ordersOpen="ordersOpen" :conditionOrders="conditionOrders" |
||||
|
:ordersHistory="ordersHistory" :holdPositionList="holdPositionList" :priceDecimals="priceDecimals" :qtyDecimals="qtyDecimals" |
||||
|
:isLogin="isLogin" :pair="pair" @change="currentTab = $event" @update="update" |
||||
|
@Pagination="page = $event" @Pagination1="page1 = $event"></order-list> |
||||
|
</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 { |
||||
|
tabcolor:1, |
||||
|
price1:0, |
||||
|
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, |
||||
|
}, |
||||
|
|
||||
|
holdPositionList: { |
||||
|
total: 0, |
||||
|
}, |
||||
|
|
||||
|
conditionOrders: { |
||||
|
total: 0, |
||||
|
}, |
||||
|
|
||||
|
// 用户钱包余额 |
||||
|
fromBalance: 0, |
||||
|
toBalance: 0, |
||||
|
|
||||
|
// 当前页面socket |
||||
|
ws: null, |
||||
|
|
||||
|
// 是否开启交易密码 |
||||
|
transPwdEnabled: false, |
||||
|
|
||||
|
currentTab: "stockholdPosition", // orders显示的tab |
||||
|
price_cny: 0, |
||||
|
page: 1, |
||||
|
page1: 1, |
||||
|
timer: null |
||||
|
} |
||||
|
|
||||
|
}, |
||||
|
|
||||
|
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, |
||||
|
}; |
||||
|
} |
||||
|
}, |
||||
|
activeContract(val) { |
||||
|
let marketList=this.marketList |
||||
|
.map(item => item.marketInfoList) |
||||
|
.flat() |
||||
|
.find(item => item.symbol == this.symbol) || {} |
||||
|
if(val.price){ |
||||
|
delete marketList.price |
||||
|
} |
||||
|
return marketList; |
||||
|
}, |
||||
|
}, |
||||
|
|
||||
|
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(`/exchangestock/${newVal}`); |
||||
|
}, |
||||
|
|
||||
|
marketInfo(newVal, oldVal) { |
||||
|
if (newVal && !oldVal) { // 第一次取得marketInfo时 更新接口 主要针对刷新页面 |
||||
|
this.update(); |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
// 加载新页面 重新订阅所有数据 |
||||
|
$route( /*newRouter, oldRouter*/ ) { |
||||
|
|
||||
|
this.addSub(); |
||||
|
|
||||
|
// 初始化market信息 |
||||
|
this.findMarketBySymbol(); |
||||
|
|
||||
|
// 更新所有接口数据 |
||||
|
this.update(); |
||||
|
|
||||
|
}, |
||||
|
|
||||
|
currentTab() { |
||||
|
// tab切换时自动更新 |
||||
|
this.getOrders(); |
||||
|
}, |
||||
|
page() { |
||||
|
if (this.currentTab == "histories") { // 历史委托 |
||||
|
this.getHistories(); |
||||
|
} |
||||
|
}, |
||||
|
// page1() { |
||||
|
// if (this.currentTab == "stockholdPosition") { // 目前持仓 |
||||
|
// this.stockholdPosition() |
||||
|
// } |
||||
|
// } |
||||
|
}, |
||||
|
|
||||
|
methods: { |
||||
|
ispopover1(item){ |
||||
|
this.symbol=item; |
||||
|
}, |
||||
|
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}` |
||||
|
}]); |
||||
|
|
||||
|
}, |
||||
|
|
||||
|
// 取消指定的symbol |
||||
|
unsub(symbol) { |
||||
|
|
||||
|
this.ws.send([{ |
||||
|
cmd: 'unsub', |
||||
|
msg: `sellList_${symbol}` |
||||
|
}, { |
||||
|
cmd: 'unsub', |
||||
|
msg: `buyList_${symbol}` |
||||
|
}, { |
||||
|
cmd: 'unsub', |
||||
|
msg: `tradeList_${symbol}` |
||||
|
}]); |
||||
|
|
||||
|
}, |
||||
|
|
||||
|
// 在交易列表中 查找当前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; |
||||
|
|
||||
|
// 写入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.getstockUserBalance(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(); |
||||
|
|
||||
|
} else if (this.currentTab == "stockholdPosition") { |
||||
|
this.stockholdPosition() |
||||
|
this.timer = setInterval(()=>{ |
||||
|
this.stockholdPosition() |
||||
|
}, 3000) |
||||
|
} |
||||
|
|
||||
|
// console.log("---订单更新成功---"); |
||||
|
|
||||
|
}, |
||||
|
|
||||
|
getOpens() { |
||||
|
if (this.isLogin) { |
||||
|
Order.getstockCurrentEntrust({ |
||||
|
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.getstockHistoryEntrust({ |
||||
|
symbol: this.marketInfo.pair_name, |
||||
|
page:this.page |
||||
|
}) |
||||
|
.then(data => { |
||||
|
this.ordersHistory = data; |
||||
|
}) |
||||
|
.catch(err => {}) |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
stockholdPosition(){ |
||||
|
if (this.isLogin) { |
||||
|
let data = { |
||||
|
symbol: this.marketInfo.pair_name, |
||||
|
page:this.page1 |
||||
|
}; |
||||
|
Exchange.stockholdPosition(data ,{ loading: false }).then(data => { |
||||
|
this.holdPositionList = 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 = new Socket(`${this.Globals.Server.Path.WS2}`); |
||||
|
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.ws.on("message", (response) => { |
||||
|
|
||||
|
let { |
||||
|
data, // 返回数据 |
||||
|
sub, // 订阅标签 |
||||
|
type, // 返回类型 |
||||
|
msg, // 提示信息 |
||||
|
code, // 错误代号 |
||||
|
} = response; |
||||
|
|
||||
|
// 答复心跳 保持连接 |
||||
|
if (type == "ping") this.ws.send({ |
||||
|
type: "pong" |
||||
|
}); |
||||
|
|
||||
|
switch (sub) { |
||||
|
|
||||
|
case "exchangeMarketList": |
||||
|
|
||||
|
this.marketList = data; |
||||
|
|
||||
|
if (!this.symbol) { // 默认symbol 重新请求数据 |
||||
|
this.symbol = _.nth(data).marketInfoList[0].symbol; |
||||
|
} else { // 找出该symbol对应的记录并更新页面 |
||||
|
this.findMarketBySymbol(); |
||||
|
} |
||||
|
|
||||
|
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; |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
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() |
||||
|
|
||||
|
}); |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
created() { |
||||
|
|
||||
|
this.initWs() |
||||
|
if (this.symbol) this.getCurrencyExCny(); |
||||
|
this.indexList() |
||||
|
|
||||
|
Market.getstockMarketList().then(data => { |
||||
|
this.marketList = data; |
||||
|
}).catch(err => {}); |
||||
|
// this.update(); |
||||
|
}, |
||||
|
beforeDestroy() { |
||||
|
clearInterval(this.timer); |
||||
|
}, |
||||
|
|
||||
|
mounted() { |
||||
|
// if (this.symbol) this.update(); |
||||
|
}, |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style> |
||||
|
.el-popover{ |
||||
|
background-color: #121212; |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,824 @@ |
|||||
|
<template> |
||||
|
<div class="col-md-3" style="background-color: #121212;"> |
||||
|
<div class="px-4 py-2 heading"> |
||||
|
<!-- <theme-change/> --> |
||||
|
<el-tooltip placement="bottom" effect="light"> |
||||
|
<div slot="content" class="market"> |
||||
|
<div class="coin p-md color-light fn-20"> |
||||
|
<img :src="detail.coin_icon" width="20" height="20" alt=""> |
||||
|
{{detail.full_name}} |
||||
|
</div> |
||||
|
<div class="list"> |
||||
|
<div class="d-flex justify-between p-x-md p-y-xs"> |
||||
|
<div>{{$t('nav.c3')}}:</div> |
||||
|
<div class="color-light"> |
||||
|
{{detail.total_issuance}} |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="d-flex justify-between p-x-md p-y-xs"> |
||||
|
<div>{{$t('nav.c4')}}:</div> |
||||
|
<div class="color-light"> |
||||
|
{{detail.total_circulation}} |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="d-flex justify-between p-x-md p-y-xs"> |
||||
|
<div>{{$t('nav.c5')}}:</div> |
||||
|
<div class="color-light"> |
||||
|
{{detail.crowdfunding_price}} |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="d-flex justify-between p-x-md p-y-xs"> |
||||
|
<div>{{$t('nav.c6')}}:</div> |
||||
|
<div class="color-light"> |
||||
|
{{detail.publish_time}} |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class=" p-x-md p-y-xs"> |
||||
|
<div>{{$t('nav.c7')}}:</div> |
||||
|
<div class="color-light ov"> |
||||
|
{{detail.white_paper_link}} |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class=" p-x-md p-y-xs"> |
||||
|
<div>{{$t('nav.c8')}}:</div> |
||||
|
<div class="color-light ov"> |
||||
|
{{detail.official_website_link}} |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="p-md"> |
||||
|
<div class="fn-20 color-light"> |
||||
|
{{$t('nav.c9')}} |
||||
|
</div> |
||||
|
<div class="p-y-md edit-content" v-html="detail.coin_content"> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<!-- <el-button><img src="../../assets/img/shuoming.png" width="20" height="20" alt=""></el-button> --> |
||||
|
</el-tooltip> |
||||
|
|
||||
|
</div> |
||||
|
<!-- 生成K线图 --> |
||||
|
<!-- <stock-kline :symbol="symbol" :socket="socket" :priceDecimals="priceDecimals"></stock-kline> --> |
||||
|
|
||||
|
<!-- 交易处理 --> |
||||
|
<div class="market-trade "> |
||||
|
<h4 style="text-align: center;">{{$t('nav.c12')}}</h4> |
||||
|
<div class="d-flex" style="margin: 14px;justify-content: space-around;border: 1px solid #b9b9b9;border-radius: 40px;"> |
||||
|
<div :class="Tab_buysell == 1?'Tab_buy':'Tab_buy1'" @click="Tab_buysell=1">{{$t('order.buy')}}</div> |
||||
|
<div :class="Tab_buysell == 2?'Tab_sell':'Tab_sell1'" @click="Tab_buysell=2">{{$t('order.sell')}}</div> |
||||
|
</div> |
||||
|
<ul class="nav nav-pills"> |
||||
|
<li class="nav-item"> |
||||
|
<a href :class="[`nav-link`, {active:!isCondition&&isMarket}]" @click.prevent="isCondition=false;isMarket=true;" style="background-color: transparent;"> |
||||
|
{{ $t("common.market") }} |
||||
|
</a> |
||||
|
</li> |
||||
|
<li class="nav-item"> |
||||
|
<a href :class="[`nav-link`, {active:!isCondition&&!isMarket}]" @click.prevent="isCondition=false;isMarket=false;" style="background-color: transparent;"> |
||||
|
{{ $t("common.limit") }}</a> |
||||
|
</li> |
||||
|
|
||||
|
<!-- <li class="nav-item"> |
||||
|
<a href :class="[`nav-link`, {active:isCondition&&!isMarket}]" @click.prevent="isCondition=true;isMarket=false;"> |
||||
|
{{ $t("common.stop-limit") }}</a> |
||||
|
</li> |
||||
|
<li class="nav-item"> |
||||
|
<a href :class="[`nav-link`, {active:isCondition&&isMarket}]" @click.prevent="isCondition=true;isMarket=true;"> |
||||
|
{{ $t("common.stop-market") }}</a> |
||||
|
</li> --> |
||||
|
</ul> |
||||
|
<div class="tab-content"> |
||||
|
<div class="tab-pane fade show active"> |
||||
|
<div class="d-flex justify-content-between"> |
||||
|
<!------------- Buy Order --------------> |
||||
|
<div class="market-trade-buy" v-if="Tab_buysell == 1"> |
||||
|
|
||||
|
<!-- Trigger Price --> |
||||
|
<el-popover popper-class='popover-tips' placement="top-start" trigger="manual" v-model="visibles.buy.trigger"> |
||||
|
<span class="content"> |
||||
|
<i class="el-icon-warning-outline"></i> |
||||
|
{{ msgList.buy[0] }} |
||||
|
</span> |
||||
|
<div class="input-group" v-if="isCondition" slot="reference"> |
||||
|
<input type="number" style="background-color: #121212;" v-model="buyorder.trigger_price" class="form-control" :placeholder="$t('exchange.trigger-price')"> |
||||
|
<div class="input-group-append"> |
||||
|
<span class="input-group-text">{{pair.from}}</span> |
||||
|
</div> |
||||
|
</div> |
||||
|
</el-popover> |
||||
|
|
||||
|
<template v-if="isMarket"> |
||||
|
<div class="input-group"> |
||||
|
<!-- Market Price --> |
||||
|
<input type="text" class="form-control" disabled :placeholder="$t('exchange.at-best-price')"> |
||||
|
</div> |
||||
|
</template> |
||||
|
<template v-else> |
||||
|
<el-popover popper-class='popover-tips' placement="top-start" trigger="manual" v-model="visibles.buy.limitPrice"> |
||||
|
<span class="content"> |
||||
|
<i class="el-icon-warning-outline"></i> |
||||
|
{{ msgList.buy[1] }} |
||||
|
</span> |
||||
|
<div class="input-group" slot="reference"> |
||||
|
<!-- Entrust Price --> |
||||
|
<input type="number" v-model="buyorder.entrust_price" class="form-control" :placeholder="$t('exchange.enter-price')"> |
||||
|
<div class="input-group-append"> |
||||
|
<span class="input-group-text">{{pair.from}}</span> |
||||
|
</div> |
||||
|
</div> |
||||
|
</el-popover> |
||||
|
</template> |
||||
|
|
||||
|
<!-- Amount/Total --> |
||||
|
<template v-if="isMarket"> |
||||
|
<el-popover popper-class='popover-tips' placement="top-start" trigger="manual" v-model="visibles.buy.marketTotal"> |
||||
|
<span class="content"> |
||||
|
<i class="el-icon-warning-outline"></i> |
||||
|
{{ msgList.buy[3] }} |
||||
|
</span> |
||||
|
<div class="input-group" slot="reference"> |
||||
|
<!-- <input type="number" v-model="buyTotal" class="form-control" min=0 :placeholder="$t('exchange.enter-total')"> --> |
||||
|
<input type="number" v-model="buyorder.amount" class="form-control" min=0 :placeholder="$t('exchange.enter-total')"> |
||||
|
<div class="input-group-append"> |
||||
|
<!-- <span class="input-group-text">{{pair.from}}</span> --> |
||||
|
<span class="input-group-text">{{pair.to}}</span> |
||||
|
</div> |
||||
|
</div> |
||||
|
</el-popover> |
||||
|
</template> |
||||
|
<template v-else> |
||||
|
<el-popover popper-class='popover-tips' placement="top-start" trigger="manual" v-model="visibles.buy.limitAmount"> |
||||
|
<!-- 提示框的内容 --> |
||||
|
<span class="content"> |
||||
|
<!-- 图标 --> |
||||
|
<i class="el-icon-warning-outline"></i> |
||||
|
<!-- 提示 --> |
||||
|
{{ msgList.buy[2] }} |
||||
|
</span> |
||||
|
<div class="input-group" slot="reference"> |
||||
|
<input type="number" v-model="buyorder.amount" class="form-control" min=0 :placeholder="$t('exchange.enter-amount')"> |
||||
|
<div class="input-group-append"> |
||||
|
<span class="input-group-text">{{pair.to}}</span> |
||||
|
</div> |
||||
|
</div> |
||||
|
</el-popover> |
||||
|
</template> |
||||
|
|
||||
|
<!-- Percent --> |
||||
|
<ul class="market-trade-list"> |
||||
|
<li v-for="(item,index) in percentage" :key="index" :class="{buyPercentActive:index == buyPercentIndex}" @click="renderBuyAmount(item.value, index)"> |
||||
|
<a href="javascript:void 0">{{ item.label }}</a> |
||||
|
</li> |
||||
|
</ul> |
||||
|
|
||||
|
<!-- Total --> |
||||
|
<el-popover popper-class='popover-tips' placement="top-start" trigger="manual" v-model="visibles.buy.orderTotal"> |
||||
|
<span class="content"> |
||||
|
<i class="el-icon-warning-outline"></i> |
||||
|
{{ msgList.buy[5] }} |
||||
|
</span> |
||||
|
<p slot="reference"> |
||||
|
{{$t('exchange.order-total')}} |
||||
|
<span> <b>{{buyTotal}}</b> {{pair.from}} </span> |
||||
|
</p> |
||||
|
</el-popover> |
||||
|
|
||||
|
<!-- Available --> |
||||
|
<p> |
||||
|
{{ $t('exchange.amount') }} |
||||
|
<span> {{toBalance}} {{pair.to}}</span><br /> |
||||
|
{{ $t('exchange.balance') }} |
||||
|
<span> {{fromBalance}} {{pair.from}}</span> |
||||
|
</p> |
||||
|
<button class="btn buy" @click="handleBuyOrder">{{ $t("common.buy") }} {{pair.to}}</button> |
||||
|
</div> |
||||
|
|
||||
|
<!-- Sell Order --> |
||||
|
<div class="market-trade-buy" v-if="Tab_buysell == 2"> |
||||
|
<!-- class="market-trade-sell" --> |
||||
|
<el-popover popper-class='popover-tips' placement="top-start" trigger="manual" v-model="visibles.sell.trigger"> |
||||
|
<span class="content"> |
||||
|
<i class="el-icon-warning-outline"></i> |
||||
|
{{ msgList.sell[0] }} |
||||
|
</span> |
||||
|
<!-- Trigger Price --> |
||||
|
<div class="input-group" v-if="isCondition" slot="reference"> |
||||
|
<input type="number" v-model="sellorder.trigger_price" class="form-control" min=0 :placeholder="$t('exchange.trigger-price')"> |
||||
|
<div class="input-group-append"> |
||||
|
<span class="input-group-text">{{pair.from}}</span> |
||||
|
</div> |
||||
|
</div> |
||||
|
</el-popover> |
||||
|
|
||||
|
<template v-if="isMarket"> |
||||
|
<div class="input-group"> |
||||
|
<!-- Market Price --> |
||||
|
<input type="text" class="form-control" disabled :placeholder="$t('exchange.at-best-price')"> |
||||
|
</div> |
||||
|
</template> |
||||
|
<template v-else> |
||||
|
<el-popover popper-class='popover-tips' placement="top-start" trigger="manual" v-model="visibles.sell.limitPrice"> |
||||
|
<span class="content"> |
||||
|
<i class="el-icon-warning-outline"></i> |
||||
|
{{ msgList.sell[1] }} |
||||
|
</span> |
||||
|
<div class="input-group" slot="reference"> |
||||
|
<!-- Entrust Price --> |
||||
|
<input type="number" v-model="sellorder.entrust_price" class="form-control" min=0 :placeholder="$t('exchange.enter-price')"> |
||||
|
<div class="input-group-append"> |
||||
|
<span class="input-group-text">{{pair.from}}</span> |
||||
|
</div> |
||||
|
</div> |
||||
|
</el-popover> |
||||
|
</template> |
||||
|
|
||||
|
<!-- Amount --> |
||||
|
<el-popover popper-class='popover-tips' placement="top-start" trigger="manual" v-model="visibles.sell.limitAmount"> |
||||
|
<span class="content"> |
||||
|
<i class="el-icon-warning-outline"></i> |
||||
|
{{ msgList.sell[2] }} |
||||
|
</span> |
||||
|
<div class="input-group" slot="reference"> |
||||
|
<input type="number" v-model="sellorder.amount" class="form-control" min=0 :placeholder="$t('exchange.enter-amount')"> |
||||
|
<div class="input-group-append"> |
||||
|
<span class="input-group-text">{{pair.to}}</span> |
||||
|
</div> |
||||
|
</div> |
||||
|
</el-popover> |
||||
|
|
||||
|
<ul class="market-trade-list"> |
||||
|
<li v-for="(item,index) in percentage" :key="index" :class="{sellPercentActive:index == sellPercentIndex}" @click="renderSellAmount(item.value, index)"> |
||||
|
<a href="javascript:void 0">{{ item.label }}</a> |
||||
|
</li> |
||||
|
</ul> |
||||
|
|
||||
|
<!-- Total --> |
||||
|
<el-popover popper-class='popover-tips' placement="top-start" trigger="manual" v-model="visibles.sell.orderTotal"> |
||||
|
<span class="content"> |
||||
|
<i class="el-icon-warning-outline"></i> |
||||
|
{{ msgList.sell[5] }} |
||||
|
</span> |
||||
|
<p slot="reference"> |
||||
|
{{ $t('exchange.order-total') }} |
||||
|
<span> |
||||
|
<b>{{sellTotal}}</b> {{pair.from}} </span> |
||||
|
</p> |
||||
|
</el-popover> |
||||
|
|
||||
|
<p> |
||||
|
{{$t('exchange.amount')}} |
||||
|
<span> {{toBalance}} {{pair.to}} </span><br /> |
||||
|
{{ $t('exchange.balance') }} |
||||
|
<span> {{fromBalance}} {{pair.from}}</span> |
||||
|
</p> |
||||
|
<button class="btn sell" @click="handleSellOrder">{{ $t("common.sell") }} {{pair.to}}</button> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
import Exchange from "@/api/exchange"; |
||||
|
import Market from "@/api/market"; |
||||
|
export default { |
||||
|
|
||||
|
props: ["isLogin", "socket", "symbol", "pair", "buyorder", "sellorder", "fromBalance", "toBalance", "newTrade", "minQty", "minTotal", "priceDecimals", "qtyDecimals"], |
||||
|
|
||||
|
data() { |
||||
|
return { |
||||
|
Tab_buysell:1, |
||||
|
detail:[], |
||||
|
isMarket: true, |
||||
|
isCondition: false, |
||||
|
userBanlance: null, |
||||
|
|
||||
|
cacheTotal: 0, // 存放市价单输入的总值 |
||||
|
cachePrice: null, // 存放最新价格 |
||||
|
|
||||
|
// 气泡弹框内容和触发 |
||||
|
visibles: { |
||||
|
"buy": { |
||||
|
limitPrice: false, // 限制价格 |
||||
|
limitAmount: false, // 限制数量 |
||||
|
marketTotal: false, // 限制总额 |
||||
|
marketAmount: false, // 市价数量 |
||||
|
trigger: false, // 触发价格 |
||||
|
orderTotal: false, // 订单总额 |
||||
|
}, |
||||
|
"sell": { |
||||
|
limitPrice: false, |
||||
|
limitAmount: false, |
||||
|
marketTotal: false, |
||||
|
marketAmount: false, |
||||
|
trigger: false, |
||||
|
orderTotal: false, |
||||
|
}, |
||||
|
}, |
||||
|
msgList: { |
||||
|
"buy": Array(6).fill(''), // 5个空字符串的数组 |
||||
|
"sell": Array(6).fill('') |
||||
|
}, |
||||
|
// 百分比集合 |
||||
|
percentage: [{ |
||||
|
label: "25%", |
||||
|
value: 0.25 |
||||
|
}, |
||||
|
{ |
||||
|
label: "50%", |
||||
|
value: 0.5 |
||||
|
}, |
||||
|
{ |
||||
|
label: "75%", |
||||
|
value: 0.75 |
||||
|
}, |
||||
|
{ |
||||
|
label: "100%", |
||||
|
value: 1 |
||||
|
}, |
||||
|
], |
||||
|
// |
||||
|
buyPercentIndex: null, |
||||
|
sellPercentIndex: null, |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
computed: { |
||||
|
|
||||
|
// 获取type类型值 |
||||
|
type() { |
||||
|
if (!this.isCondition) { |
||||
|
return this.isMarket ? 2 : 1; |
||||
|
} else { |
||||
|
return this.isMarket ? 4 : 3; |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
theme() { |
||||
|
return localStorage.theme ? localStorage.theme : "light"; |
||||
|
}, |
||||
|
|
||||
|
buyTotal: { |
||||
|
get() { |
||||
|
if (!this.isMarket) { |
||||
|
return Math.multiple(this.buyorder.entrust_price, this.buyorder.amount); |
||||
|
} else { |
||||
|
// return this.cacheTotal; |
||||
|
return Math.multiple(this.buyorder.entrust_price, this.buyorder.amount); |
||||
|
} |
||||
|
}, |
||||
|
set(val) { |
||||
|
// 根据总值 计算数量 |
||||
|
if (!this.isMarket) { |
||||
|
this.buyorder.amount = Math.division(val, this.buyorder.entrust_price); |
||||
|
} else { // 市价单 缓存总值 |
||||
|
this.cacheTotal = val; |
||||
|
this.buyorder.amount = this.cacheTotal |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
sellTotal: { |
||||
|
get() { |
||||
|
return Math.multiple(this.sellorder.entrust_price, this.sellorder.amount); |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
// 当前语言 |
||||
|
lang() { |
||||
|
let browser_Lang = navigator.language.includes('zh') ? 'zh' : 'en'; |
||||
|
return localStorage.lang || browser_Lang; |
||||
|
}, |
||||
|
|
||||
|
}, |
||||
|
|
||||
|
watch: { |
||||
|
custom(newVal) { |
||||
|
// console.log(newVal) |
||||
|
}, |
||||
|
|
||||
|
type() { |
||||
|
// 切换订单类型时 清空价格和数量 |
||||
|
// 数量改变时 触发percentage更新 |
||||
|
this.reset(); |
||||
|
}, |
||||
|
|
||||
|
// 有新交易时触发 给限价单设定初始价格 |
||||
|
newTrade(newVal, oldVal) { |
||||
|
// if (!this.isMarket ) { |
||||
|
|
||||
|
// 新交易对有trade数据 |
||||
|
if (!oldVal && newVal) { // 没值到初始化值 |
||||
|
// 修改order里面price的值 |
||||
|
this.cachePrice = newVal.price; |
||||
|
this.reset(); |
||||
|
} |
||||
|
|
||||
|
// 切换交易对时 清空了数据 |
||||
|
if (oldVal && !newVal) { // 有值到没值的过程 |
||||
|
this.cachePrice = null; |
||||
|
this.reset(); |
||||
|
} |
||||
|
// } |
||||
|
}, |
||||
|
symbol(){ |
||||
|
this.getCoinInfo() |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
methods: { |
||||
|
getCoinInfo(){ |
||||
|
// console.log(this.symbol.indexOf('usdt')!=-1) |
||||
|
|
||||
|
// if(!this.symbol){ |
||||
|
// return; |
||||
|
// } |
||||
|
if(this.symbol.indexOf('usdt')!=-1){ |
||||
|
var market=this.symbol.substring(0,this.symbol.length-4); |
||||
|
}else{ |
||||
|
var market=this.symbol.substring(0,this.symbol.length-3); |
||||
|
} |
||||
|
// console.log(market) |
||||
|
let data = { |
||||
|
coin_name:market, |
||||
|
// coin_name:this.symbol, |
||||
|
lang:this.lang |
||||
|
} |
||||
|
Market.getstockCoinInfo(data).then(res => { |
||||
|
this.detail = res |
||||
|
}).catch(err => { |
||||
|
|
||||
|
}); |
||||
|
}, |
||||
|
renderBuyAmount(val, index) { |
||||
|
// console.Info(val) |
||||
|
// console.Info(this.buyorder) |
||||
|
if (!this.buyorder.entrust_price) { |
||||
|
this.visibles.buy.limitPrice = true; |
||||
|
this.msgList.buy[1] = this.$t('nav.set'); |
||||
|
this.clearAll(); |
||||
|
return; |
||||
|
} |
||||
|
this.buyPercentIndex = index; |
||||
|
this.buyTotal = Math.multiple(this.fromBalance, val); |
||||
|
}, |
||||
|
|
||||
|
renderSellAmount(val, index) { |
||||
|
if (!this.sellorder.entrust_price) { |
||||
|
this.visibles.sell.limitPrice = true; |
||||
|
this.msgList.sell[1] = this.$t('nav.set'); |
||||
|
this.clearAll(); |
||||
|
return; |
||||
|
} |
||||
|
this.sellPercentIndex = index; |
||||
|
this.sellorder.amount = Math.multiple(this.toBalance, val); |
||||
|
}, |
||||
|
|
||||
|
handleBuyOrder() { |
||||
|
|
||||
|
// 执行前端的有效性验证 |
||||
|
if (!this.chkValidate(this.buyorder, this.buyTotal, "buy")) return; |
||||
|
|
||||
|
const baseArgs = { |
||||
|
symbol: this.pair.to.concat('/', this.pair.from), |
||||
|
type: this.type, |
||||
|
}; |
||||
|
|
||||
|
// 区分限价、市价和条件委托单 |
||||
|
// 1、限价单买入时 需要的参数:价格、数量、 |
||||
|
// 2、市价单买入时 需要的参数:总值 |
||||
|
// 3、条件单买入时 需要的参数:触发价、价格数量或者总值 |
||||
|
// 4、卖出时 需要价格和数量 |
||||
|
Exchange.stockstoreEntrust(Object.assign(this.buyorder, { |
||||
|
total: this.buyTotal, |
||||
|
}, baseArgs)).then(data => { |
||||
|
this.$message({ |
||||
|
message:'success', |
||||
|
type: "success" |
||||
|
}); |
||||
|
// 触发父组件的方法 更新余额和订单 |
||||
|
this.$emit('update'); |
||||
|
// 清空表单 |
||||
|
this.reset(); |
||||
|
}).catch(err => { |
||||
|
|
||||
|
}); |
||||
|
}, |
||||
|
|
||||
|
handleSellOrder() { |
||||
|
// 执行前端的有效性验证 |
||||
|
if (!this.chkValidate(this.sellorder, this.sellTotal, "sell")) return; |
||||
|
// console.info(this.sellTotal) |
||||
|
const baseArgs = { |
||||
|
symbol: this.pair.to.concat('/', this.pair.from), |
||||
|
type: this.type, |
||||
|
}; |
||||
|
Exchange.stockstoreEntrust(Object.assign(this.sellorder, { |
||||
|
total: this.sellTotal |
||||
|
}, baseArgs)).then(data => { |
||||
|
this.$message({ |
||||
|
message:'success', |
||||
|
type: "success" |
||||
|
}); |
||||
|
// 触发父组件的方法 更新余额和订单 |
||||
|
this.$emit('update'); |
||||
|
// 清空表单 |
||||
|
this.reset(); |
||||
|
}).catch(err => { |
||||
|
|
||||
|
}); |
||||
|
}, |
||||
|
|
||||
|
reset() { |
||||
|
|
||||
|
// 如果没有newTrade时 则没有缓存价格 重置为最小值0 |
||||
|
// 由于输入框去除了精度空值 这里还需要手动设置精度值 |
||||
|
let price = this.cachePrice || 0; |
||||
|
// console.info(price) |
||||
|
// console.info(this.priceDecimals) |
||||
|
this.buyorder.entrust_price = Math.omitTo(price, this.priceDecimals); |
||||
|
this.buyorder.trigger_price = Math.omitTo(price, this.priceDecimals); |
||||
|
|
||||
|
this.sellorder.entrust_price = Math.omitTo(price, this.priceDecimals); |
||||
|
// console.info(this.sellorder.entrust_price) |
||||
|
this.sellorder.trigger_price = Math.omitTo(price, this.priceDecimals); |
||||
|
|
||||
|
// 清空数量 |
||||
|
this.buyorder.amount = 0; |
||||
|
this.sellorder.amount = 0; |
||||
|
|
||||
|
// total赋值会触发set方法 |
||||
|
// this.buyTotal = 0; |
||||
|
// this.cacheTotal = 0; |
||||
|
|
||||
|
// 去除百分比样式 |
||||
|
this.buyPercentIndex = -1; |
||||
|
this.sellPercentIndex = -1; |
||||
|
}, |
||||
|
|
||||
|
clearAll() { |
||||
|
// 5s后统一清除提示框 |
||||
|
setTimeout(function () { |
||||
|
Object.keys(this.visibles.buy).forEach(key => this.visibles.buy[key] = false); |
||||
|
Object.keys(this.visibles.sell).forEach(key => this.visibles.sell[key] = false); |
||||
|
}.bind(this), 5000); |
||||
|
}, |
||||
|
|
||||
|
empty(val) { |
||||
|
let ret; |
||||
|
switch (typeof val) { |
||||
|
case "number": |
||||
|
ret = val == 0; |
||||
|
break; |
||||
|
case "string": |
||||
|
ret = val == "0" || /^\s?$/.test(val); |
||||
|
break; |
||||
|
case "boolean": |
||||
|
ret = val; |
||||
|
break; |
||||
|
default: |
||||
|
ret = Boolean(val); |
||||
|
break; |
||||
|
} |
||||
|
return ret; |
||||
|
}, |
||||
|
|
||||
|
chkValidate(order, total, orderType) { |
||||
|
// |
||||
|
// 验证登录 |
||||
|
if (!this.isLogin) { |
||||
|
this.$confirm(this.$t('nav.login'), { |
||||
|
confirmButtonText:this.$t('common.confirmBtn'), |
||||
|
cancelButtonText: this.$t('common.cancelBtn'), |
||||
|
type: 'warning' |
||||
|
}).then(() => { |
||||
|
this.$router.push(`/sign-in`); |
||||
|
}).catch(); |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
let flag = true; |
||||
|
|
||||
|
switch (this.type) { |
||||
|
|
||||
|
case 1: // limit |
||||
|
if (this.empty(order.entrust_price)) { |
||||
|
flag = false; |
||||
|
this.visibles[orderType].limitPrice = true; |
||||
|
this.msgList[orderType][1] = this.$t('nav.a1'); |
||||
|
} else if (this.empty(order.amount)) { |
||||
|
flag = false; |
||||
|
this.visibles[orderType].limitAmount = true; |
||||
|
this.msgList[orderType][2] = this.$t('nav.a2'); |
||||
|
} else { |
||||
|
if (order.amount < this.minQty) { |
||||
|
flag = false; |
||||
|
this.visibles[orderType].limitAmount = true; |
||||
|
this.msgList[orderType][2] = this.$t('nav.a3')+`${this.minQty}`; |
||||
|
} |
||||
|
|
||||
|
if (total < this.minTotal) { |
||||
|
flag = false; |
||||
|
this.visibles[orderType].orderTotal = true; |
||||
|
this.msgList[orderType][5] = this.$t('exchange.total')+`${this.minTotal}`; |
||||
|
} |
||||
|
} |
||||
|
break; |
||||
|
|
||||
|
case 2: // market |
||||
|
if (order.direction == "buy") { // 买 |
||||
|
if (this.empty(total)) { |
||||
|
flag = false; |
||||
|
this.visibles[orderType].marketTotal = true; |
||||
|
this.msgList[orderType][3] = this.$t('nav.a4'); |
||||
|
} else if (this.total < this.minTotal) { |
||||
|
flag = false; |
||||
|
this.visibles.marketTotal = true; |
||||
|
this.msgList[3] = this.$t('nav.a5')+` ${this.minTotal}`; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if (order.direction == "sell") { // 卖 |
||||
|
if (this.empty(order.amount)) { |
||||
|
flag = false; |
||||
|
this.visibles[orderType].marketAmount = true; |
||||
|
this.msgList[orderType][4] = this.$t('nav.a6'); |
||||
|
} else if (order.amount < this.minQty) { |
||||
|
flag = false; |
||||
|
this.visibles[orderType].marketAmount = true; |
||||
|
this.msgList[orderType][4] = this.$t('nav.a7')+` ${this.minQty}`; |
||||
|
} |
||||
|
} |
||||
|
break; |
||||
|
|
||||
|
case 3: // stop-limit |
||||
|
|
||||
|
if (this.empty(order.trigger_price)) { |
||||
|
flag = false; |
||||
|
this.visibles[orderType].trigger = true; |
||||
|
this.msgList[orderType][0] = this.$t('nav.a8') |
||||
|
} else if (this.empty(order.entrust_price)) { |
||||
|
flag = false; |
||||
|
this.visibles[orderType].limitPrice = true; |
||||
|
this.msgList[orderType][1] = this.$t('nav.a9') |
||||
|
} else if (this.empty(order.amount)) { |
||||
|
flag = false; |
||||
|
this.visibles[orderType].limitAmount = true; |
||||
|
this.msgList[orderType][2] = this.$t('nav.b1') |
||||
|
} |
||||
|
break; |
||||
|
|
||||
|
case 4: // stop-market |
||||
|
if (this.empty(order.trigger_price)) { |
||||
|
flag = false; |
||||
|
this.visibles[orderType].trigger = true; |
||||
|
this.msgList[orderType][0] = this.$t('nav.b2') |
||||
|
} else { |
||||
|
|
||||
|
if (order.direction == "buy") { |
||||
|
if (this.empty(total)) { |
||||
|
flag = false; |
||||
|
this.visibles[orderType].marketTotal = true; |
||||
|
this.msgList[orderType][3] = this.$t('nav.b3') |
||||
|
} else if (total < this.minTotal) { |
||||
|
flag = false; |
||||
|
this.visibles[orderType].marketTotal = true; |
||||
|
this.msgList[orderType][3] = this.$t('nav.b5')+` ${this.minTotal}` |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if (order.direction == "sell") { |
||||
|
if (this.empty(order.amount)) { |
||||
|
flag = false; |
||||
|
this.visibles[orderType].marketAmount = true; |
||||
|
this.msgList[orderType][4] = this.$t('nav.b6') |
||||
|
} else if (order.amount < this.minQty) { |
||||
|
flag = false; |
||||
|
this.visibles[orderType].marketAmount = true; |
||||
|
this.msgList[orderType][4] =this.$t('nav.b7')+ ` ${this.minQty}` |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
break; |
||||
|
} |
||||
|
|
||||
|
// 清除所有样式 |
||||
|
this.clearAll(); |
||||
|
|
||||
|
// 返回验证结果 |
||||
|
return flag; |
||||
|
}, |
||||
|
|
||||
|
}, |
||||
|
|
||||
|
created() { |
||||
|
this.getCoinInfo() |
||||
|
this.reset(); |
||||
|
}, |
||||
|
|
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss" scoped> |
||||
|
.buyPercentActive { |
||||
|
a:link { |
||||
|
font-weight: bold; |
||||
|
background: #26a69a; |
||||
|
color: #fff; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.sellPercentActive { |
||||
|
a:link { |
||||
|
font-weight: bold; |
||||
|
background: #ef5350; |
||||
|
color: #fff; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.input-group-text { |
||||
|
width: 68px; |
||||
|
@include flexible(row, center, center); |
||||
|
} |
||||
|
|
||||
|
.market-trade { |
||||
|
border: none; |
||||
|
border-color: transparent; |
||||
|
} |
||||
|
.market{ |
||||
|
width: 300px; |
||||
|
height: 500px; |
||||
|
overflow: scroll; |
||||
|
display: flex; |
||||
|
flex-wrap: wrap; |
||||
|
padding: 10px; |
||||
|
display: -webkit-box; |
||||
|
color: black; |
||||
|
.ov{ |
||||
|
width: 100%; |
||||
|
table-layout:fixed; |
||||
|
word-break:break-all; |
||||
|
overflow:hidden; |
||||
|
} |
||||
|
} |
||||
|
.p-y-xs{ |
||||
|
padding: 5px 0; |
||||
|
} |
||||
|
.el-button{ |
||||
|
padding: 0!important; |
||||
|
background: transparent!important; |
||||
|
} |
||||
|
|
||||
|
.Tab_buy{ |
||||
|
width: 50%; |
||||
|
height: 40px; |
||||
|
color: #ffffff; |
||||
|
line-height: 40px; |
||||
|
text-align: center; |
||||
|
border-radius: 40px; |
||||
|
background-color: #25a750; |
||||
|
} |
||||
|
.Tab_buy1{ |
||||
|
width: 50%; |
||||
|
height: 40px; |
||||
|
color: #ffffff; |
||||
|
line-height: 40px; |
||||
|
text-align: center; |
||||
|
border-radius: 40px; |
||||
|
} |
||||
|
.Tab_sell{ |
||||
|
width: 50%; |
||||
|
height: 40px; |
||||
|
color: #ffffff; |
||||
|
line-height: 40px; |
||||
|
text-align: center; |
||||
|
border-radius: 40px; |
||||
|
background-color: #ca3f64; |
||||
|
} |
||||
|
.Tab_sell1{ |
||||
|
width: 50%; |
||||
|
height: 40px; |
||||
|
color: #ffffff; |
||||
|
line-height: 40px; |
||||
|
text-align: center; |
||||
|
border-radius: 40px; |
||||
|
} |
||||
|
|
||||
|
.market-trade input{ |
||||
|
border: 1px solid #404040; |
||||
|
} |
||||
|
.input-group-text{ |
||||
|
border: 1px solid #404040; |
||||
|
background-color: #121212; |
||||
|
} |
||||
|
.form-control{ |
||||
|
background-color: #121212; |
||||
|
} |
||||
|
.market-trade p{ |
||||
|
color: #e7e7e7; |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,54 @@ |
|||||
|
<template> |
||||
|
<div class="col-md-3"> |
||||
|
<div class="market-news mt15"> |
||||
|
|
||||
|
<h2 class="heading">{{ $t("common.news") }}</h2> |
||||
|
<ul> |
||||
|
<li v-for="item in records" :key="item.id"> |
||||
|
|
||||
|
<router-link :to="`/college/detail/${item.category_id}/${item.id}`"> |
||||
|
<strong>{{ truncate(item.title, 25) }}</strong> |
||||
|
{{ truncate(item.excerpt, 50) }} |
||||
|
<span>{{ item.updated_at }}</span> |
||||
|
</router-link> |
||||
|
|
||||
|
</li> |
||||
|
</ul> |
||||
|
</div> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
import Exchange from "@/api/exchange"; |
||||
|
|
||||
|
export default { |
||||
|
data() { |
||||
|
return { |
||||
|
records: [], // 所有新动态 |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
methods: { |
||||
|
getDynamic() { |
||||
|
Exchange.newTrends(10).then(data => { |
||||
|
this.records = data; |
||||
|
}).catch(err => { |
||||
|
|
||||
|
}); |
||||
|
}, |
||||
|
truncate(str, length) { |
||||
|
return _.truncate(str, { |
||||
|
length |
||||
|
}); |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
created() { |
||||
|
this.getDynamic(); |
||||
|
}, |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style> |
||||
|
|
||||
|
</style> |
||||
@ -0,0 +1,358 @@ |
|||||
|
<template> |
||||
|
<div class="col-md-9"> |
||||
|
<div class="exchange-history order-history market-order mt15"> |
||||
|
<ul class="nav nav-pills" role="tablist"> |
||||
|
<li class="nav-item" @click="toggle('stockholdPosition')"> |
||||
|
<a class="nav-link active" data-toggle="pill" href="#stock-holdPosition" role="tab" aria-selected="true">{{$t("exchange.a2")}}</a> |
||||
|
</li> |
||||
|
<li class="nav-item" @click="toggle('opens')"> |
||||
|
<a class="nav-link" data-toggle="pill" href="#open-orders" role="tab" aria-selected="true"> |
||||
|
{{ $t("common.open-orders") }}</a> |
||||
|
</li> |
||||
|
<!-- <li class="nav-item" @click="toggle('conditions')"> |
||||
|
<a class="nav-link" data-toggle="pill" href="#stop-orders" role="tab" aria-selected="false"> |
||||
|
{{ $t("common.condition-orders") }}</a> |
||||
|
</li> --> |
||||
|
<li class="nav-item" @click="toggle('histories')"> |
||||
|
<a class="nav-link" data-toggle="pill" href="#order-history" role="tab" aria-selected="false"> |
||||
|
{{ $t("common.history-orders") }}</a> |
||||
|
</li> |
||||
|
</ul> |
||||
|
<div class="tab-content"> |
||||
|
<div class="tab-pane fade show active" id="open-orders" role="tabpanel"> |
||||
|
<table class="table" v-if="ordersOpen.total"> |
||||
|
<thead> |
||||
|
<tr class="text-nowrap"> |
||||
|
<th>{{ $t("common.created") }}</th> |
||||
|
<th>{{ $t("common.pair") }}</th> |
||||
|
<th>{{ $t("common.direction") }}</th> |
||||
|
<th>{{ $t("common.order-type") }}</th> |
||||
|
<th>{{ $t("common.order-price") }}</th> |
||||
|
<th>{{ $t("common.order-amount") }}</th> |
||||
|
<th>{{ $t("common.executed-amount") }}</th> |
||||
|
<th>{{ $t("common.executed-total") }}</th> |
||||
|
<th>{{ $t("common.outstanding") }}</th> |
||||
|
<th>{{ $t("common.order-total") }}</th> |
||||
|
<!-- <th>状态</th> --> |
||||
|
<th class="text-right">{{ $t("common.action") }}</th> |
||||
|
</tr> |
||||
|
</thead> |
||||
|
<tbody class="order-tbody"> |
||||
|
<tr v-for="(item,idx) in ordersOpen.data" :key="item.id" class="text-nowrap"> |
||||
|
<td>{{item.created_at}}</td> |
||||
|
<td>{{item.symbol}}</td> |
||||
|
|
||||
|
<template v-if="item.entrust_type == 1"> |
||||
|
<td class="green">{{$t("common.buy-in")}}</td> |
||||
|
</template> |
||||
|
<template v-else-if="item.entrust_type == 2"> |
||||
|
<td class="red">{{$t("common.sell-out")}}</td> |
||||
|
</template> |
||||
|
|
||||
|
<td> |
||||
|
<template v-if="item.type==1">{{ $t("common.limit-type") }}</template> |
||||
|
<template v-if="item.type==2">{{ $t("common.market-type") }}</template> |
||||
|
</td> |
||||
|
|
||||
|
<td>{{item.entrust_price|omitTo(priceDecimals)}}</td> |
||||
|
|
||||
|
<td>{{item.amount|omitTo(qtyDecimals)}}</td> |
||||
|
|
||||
|
<td>{{item.traded_amount|omitTo(priceDecimals)}}</td> |
||||
|
<td>{{item.traded_money|omitTo(priceDecimals)}}</td> |
||||
|
|
||||
|
<td>{{item.surplus_amount||omitTo(qtyDecimals)}}</td> |
||||
|
|
||||
|
<td>{{item.money ? Math.omitTo(item.money, priceDecimals) : '-'}}</td> |
||||
|
<!-- <td>完成</td> --> |
||||
|
<td class="text-nowrap"> |
||||
|
<button type="button" class="btn btn-sm btn-outline-danger" |
||||
|
@click="delOrder(item,idx)">{{ $t("common.cancel") }}</button> |
||||
|
</td> |
||||
|
</tr> |
||||
|
</tbody> |
||||
|
</table> |
||||
|
<div class="no-data" v-else> |
||||
|
<span> |
||||
|
<i class="icon ion-md-document"></i> |
||||
|
{{ $t("common.notData") }} |
||||
|
</span> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="tab-pane fade" id="stock-holdPosition" role="tabpanel"> |
||||
|
<table class="table" v-if="holdPositionList.length>0"> |
||||
|
<thead> |
||||
|
<tr class="text-nowrap"> |
||||
|
<th>{{$t("exchange.a3")}}</th> |
||||
|
<th>{{$t("exchange.a4")}}</th> |
||||
|
<th>{{$t("exchange.a5")}}</th> |
||||
|
<th>{{$t("exchange.a6")}}</th> |
||||
|
<th>{{$t("exchange.a7")}}</th> |
||||
|
<th>{{$t("exchange.a8")}}</th> |
||||
|
<th>{{$t("exchange.a9")}}</th> |
||||
|
<th>{{$t("exchange.a10")}}</th> |
||||
|
</tr> |
||||
|
</thead> |
||||
|
<tbody class="order-tbody"> |
||||
|
<tr v-for="(item,idx) in holdPositionList" :key="item.id" class="text-nowrap"> |
||||
|
<td>{{item.pair_name}}</td> |
||||
|
<td>{{item.market}}</td> |
||||
|
<td>{{item.usable_balance}}</td> |
||||
|
<td>{{item.realtimePrice}}</td> |
||||
|
<td>{{item.cost_price}}</td> |
||||
|
<td>{{item.dayProfit}}</td> |
||||
|
<td>{{item.unRealProfit}}</td> |
||||
|
<td>{{item.profitRate}}</td> |
||||
|
</tr> |
||||
|
</tbody> |
||||
|
</table> |
||||
|
<span class="no-data" v-else> |
||||
|
<i class="icon ion-md-document"></i> |
||||
|
{{ $t("common.notData") }} |
||||
|
</span> |
||||
|
<!-- <div class="p-2"> |
||||
|
<el-pagination layout="prev, pager, next" :page-size="holdPositionList.per_page" |
||||
|
@current-change="changePagination1" :total="holdPositionList.total"> |
||||
|
</el-pagination> |
||||
|
</div> --> |
||||
|
</div> |
||||
|
|
||||
|
<div class="tab-pane fade" id="stop-orders" role="tabpanel"> |
||||
|
<!-- <ul class="d-flex justify-content-between market-order-item"> |
||||
|
<li>{{ $t("common.created") }}</li> |
||||
|
<li>{{ $t("common.pair") }}</li> |
||||
|
<li>{{ $t("common.direction") }}</li> |
||||
|
<li>{{ $t("common.order-type") }}</li> |
||||
|
<li>{{ $t("common.avg-price") }}</li> |
||||
|
<li>{{ $t("common.executed") }}</li> |
||||
|
<li>{{ $t("common.order-total") }}</li> |
||||
|
<li>{{ $t("common.price-total") }}</li> |
||||
|
</ul> |
||||
|
<span class="no-data"> |
||||
|
<i class="icon ion-md-document"></i> |
||||
|
{{ $t("common.notData") }} |
||||
|
</span> --> |
||||
|
</div> |
||||
|
|
||||
|
<div class="tab-pane fade" id="order-history" role="tabpanel"> |
||||
|
<table class="table" v-if="ordersHistory.total"> |
||||
|
<thead> |
||||
|
<tr class="text-nowrap"> |
||||
|
<th>{{ $t("common.created") }}</th> |
||||
|
<th>{{ $t("common.pair") }}</th> |
||||
|
<th>{{ $t("common.direction") }}</th> |
||||
|
<th>{{ $t("common.order-type") }}</th> |
||||
|
<th>{{ $t("common.order-price") }}</th> |
||||
|
<th>{{ $t("common.order-amount") }}</th> |
||||
|
<th>{{ $t("common.executed-amount") }}</th> |
||||
|
<th>{{ $t("common.avg-price") }}</th> |
||||
|
|
||||
|
<th>{{ $t("common.order-total") }}</th> |
||||
|
<th>{{ $t("common.status") }}</th> |
||||
|
<th>{{ $t("common.details") }}</th> |
||||
|
</tr> |
||||
|
</thead> |
||||
|
<tbody> |
||||
|
<template v-for="(item,index) in ordersHistory.data"> |
||||
|
<tr class="text-nowrap" :key="item.id" :name="item.entrust_type+'_'+item.id+'_'+index" |
||||
|
slot="title" @click="handleChange(item)"> |
||||
|
<td>{{item.created_at}}</td> |
||||
|
<td>{{item.symbol}}</td> |
||||
|
<template v-if="item.entrust_type == 1"> |
||||
|
<td class="green">{{$t("common.buy-in")}}</td> |
||||
|
</template> |
||||
|
<template v-else-if="item.entrust_type == 2"> |
||||
|
<td class="red">{{$t("common.sell-out")}}</td> |
||||
|
</template> |
||||
|
<td> |
||||
|
<template v-if="item.type==1">{{ $t("common.limit-type") }}</template> |
||||
|
<template v-if="item.type==2">{{ $t("common.market-type") }}</template> |
||||
|
</td> |
||||
|
<td>{{item.entrust_price ? Math.omitTo(item.entrust_price, priceDecimals) : '-'}} |
||||
|
</td> |
||||
|
<td>{{item.amount|omitTo(qtyDecimals)}}</td> |
||||
|
|
||||
|
<td>{{ item.traded_amount|omitTo(qtyDecimals) }}</td> |
||||
|
|
||||
|
<td v-if="item.status"> |
||||
|
{{Math.division(item.traded_money,item.traded_amount,priceDecimals)}} |
||||
|
</td> |
||||
|
<td v-else>-</td> |
||||
|
<td>{{item.traded_money|omitTo(priceDecimals)}}</td> |
||||
|
<template v-if="item.status"> |
||||
|
<td v-if="item.status == 3"> |
||||
|
{{ $t("common.completed") }} |
||||
|
</td> |
||||
|
</template> |
||||
|
<template v-else> |
||||
|
<td>{{ $t("common.canceled") }}</td> |
||||
|
</template> |
||||
|
<td> |
||||
|
<i v-if="item.show" class="el-icon-arrow-down"></i> |
||||
|
<i v-else class="el-icon-arrow-right"></i> |
||||
|
</td> |
||||
|
</tr> |
||||
|
<tr :key="item.id+'t'" v-if="item.show"> |
||||
|
<td colspan="11"> |
||||
|
<template v-if="item.children && item.children.length"> |
||||
|
<div v-for="rec in item.children" :key="rec.order_id"> |
||||
|
<span> |
||||
|
<span class="text-secondary"> |
||||
|
{{ $t("common.id") }} |
||||
|
</span>:{{ rec.order_id}}   |
||||
|
</span> |
||||
|
<span><span class="text-secondary"> |
||||
|
{{ $t("common.created") }}</span>:{{ rec.created_at}} |
||||
|
 </span> |
||||
|
<span><span class="text-secondary"> |
||||
|
{{ $t("common.filled-price") }}</span>:{{ rec.unit_price|omitTo(priceDecimals)}} |
||||
|
 </span> |
||||
|
<span><span class="text-secondary"> |
||||
|
{{ $t("common.filled-amount") }}</span>:{{ rec.trade_amount|omitTo(qtyDecimals)}} |
||||
|
 </span> |
||||
|
<span><span class="text-secondary"> |
||||
|
{{ $t("common.filled-total") }}</span>:{{ rec.trade_money|omitTo(priceDecimals)}} |
||||
|
 </span> |
||||
|
<span><span class="text-secondary"> |
||||
|
{{ $t("common.fee") }}</span>:{{ rec.trade_fee|omitTo(priceDecimals)}} |
||||
|
 </span> |
||||
|
<span v-if="rec.total_profit>=0"><span class="text-secondary"> |
||||
|
{{ $t("common.d23") }}</span>:{{rec.total_profit}} |
||||
|
 </span> |
||||
|
</div> |
||||
|
</template> |
||||
|
<div class="text-center text-secondary" v-else> |
||||
|
Loading... |
||||
|
</div> |
||||
|
</td> |
||||
|
</tr> |
||||
|
</template> |
||||
|
</tbody> |
||||
|
</table> |
||||
|
<span class="no-data" v-else> |
||||
|
<i class="icon ion-md-document"></i> |
||||
|
{{ $t("common.notData") }} |
||||
|
</span> |
||||
|
<div class="p-2"> |
||||
|
<el-pagination layout="prev, pager, next" :page-size="ordersHistory.per_page" |
||||
|
@current-change="changePagination" :total="ordersHistory.total"> |
||||
|
</el-pagination> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
import Order from "@/api/order"; |
||||
|
import math from "@/utils/class/math.js"; |
||||
|
|
||||
|
export default { |
||||
|
props: [ |
||||
|
"ordersOpen", |
||||
|
"ordersHistory", |
||||
|
"holdPositionList", |
||||
|
"conditionOrders", |
||||
|
"priceDecimals", |
||||
|
"qtyDecimals", |
||||
|
"isLogin", |
||||
|
"pair" |
||||
|
], |
||||
|
|
||||
|
data() { |
||||
|
return { |
||||
|
currentTab: "stockholdPosition", |
||||
|
activeItems: [] |
||||
|
}; |
||||
|
}, |
||||
|
methods: { |
||||
|
omitTo: math.omitTo, |
||||
|
toggle(name) { |
||||
|
this.currentTab = name; |
||||
|
// 更新父组件 |
||||
|
this.$emit("change", name); |
||||
|
}, |
||||
|
|
||||
|
update() { |
||||
|
this.$emit("update"); |
||||
|
}, |
||||
|
|
||||
|
// 撤销当前订单 |
||||
|
delOrder(item, idx) { |
||||
|
let data = { |
||||
|
entrust_id: item.id, |
||||
|
entrust_type: item.entrust_type, |
||||
|
symbol: item.symbol |
||||
|
}; |
||||
|
this.$confirm(this.$t("order.ifCancel", { |
||||
|
confirmButtonText: this.$t('common.confirmBtn'), |
||||
|
cancelButtonText: this.$t('common.cancelBtn'), |
||||
|
})) |
||||
|
.then(res => { |
||||
|
Order.stockcancelEntrust(data) |
||||
|
.then(res => { |
||||
|
this.$message.success(this.$t("order.cancelSuccess")); |
||||
|
this.update(); |
||||
|
}) |
||||
|
.catch(() => {}); |
||||
|
}) |
||||
|
.catch(err => {}); |
||||
|
}, |
||||
|
|
||||
|
handleChange(item) { |
||||
|
this.$set(item, "show", !item.show); |
||||
|
if (item.children) return; |
||||
|
if (this.isLogin) { |
||||
|
Order.getstockEntrustTradeRecord({ |
||||
|
entrust_type: item.entrust_type, |
||||
|
entrust_id: item.id |
||||
|
}) |
||||
|
.then(data => { |
||||
|
this.$set(item, "children", data); |
||||
|
}) |
||||
|
.catch(err => {}); |
||||
|
} |
||||
|
|
||||
|
}, |
||||
|
changePagination(idx) { |
||||
|
// console.log(idx); |
||||
|
this.$emit("Pagination", idx); |
||||
|
}, |
||||
|
changePagination1(idx) { |
||||
|
// console.log(idx); |
||||
|
this.$emit("Pagination1", idx); |
||||
|
} |
||||
|
}, |
||||
|
created() { |
||||
|
// console.log(this.ordersHistory); |
||||
|
} |
||||
|
}; |
||||
|
</script> |
||||
|
|
||||
|
<style scoped> |
||||
|
.market-order{ |
||||
|
border: 1px solid #404040; |
||||
|
} |
||||
|
</style> |
||||
|
<style lang="scss"> |
||||
|
.exchange-history { |
||||
|
.nav { |
||||
|
background: #121212; |
||||
|
} |
||||
|
|
||||
|
.nav-link.active { |
||||
|
color: #007bff; |
||||
|
background: transparent; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.order-tbody { |
||||
|
display: table-row-group !important; |
||||
|
|
||||
|
tr { |
||||
|
float: none; |
||||
|
} |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,260 @@ |
|||||
|
<template> |
||||
|
<div class="col-md-3"> |
||||
|
<div class="market-pairs"> |
||||
|
|
||||
|
<!-- 搜索框区域 --> |
||||
|
<div class="input-group"> |
||||
|
<div class="input-group-prepend"> |
||||
|
<span class="input-group-text" id="inputGroup-sizing-sm"> |
||||
|
<i class="icon ion-md-search"></i> |
||||
|
</span> |
||||
|
</div> |
||||
|
<input type="text" class="form-control" v-model="keyword" :placeholder="$t('exchange.search')" aria-describedby="inputGroup-sizing-sm"> |
||||
|
</div> |
||||
|
|
||||
|
<!-- 币种列表 --> |
||||
|
<ul class="nav nav-pills" role="tablist" ref="navList"> |
||||
|
|
||||
|
<li class="nav-item" v-for="(coin, index) in markets" :key="index"> |
||||
|
<a :class="[`nav-link`, {active:currentCoinIdx == index}]" href @click.prevent="currentCoinIdx = index"> |
||||
|
<!-- 查看收藏交易对 --> |
||||
|
<template v-if="coin.coin_name == 'fav'"> |
||||
|
<i class="icon ion-md-star"></i> |
||||
|
</template> |
||||
|
<template v-else> |
||||
|
{{ coin.coin_name }} |
||||
|
</template> |
||||
|
</a> |
||||
|
</li> |
||||
|
|
||||
|
</ul> |
||||
|
|
||||
|
<!-- 币种行情信息,不同的交易对价值 --> |
||||
|
<div class="tab-content"> |
||||
|
|
||||
|
<div v-for="(coin, index) in markets" :key="index"> |
||||
|
<table class="table" v-if="currentCoinIdx == index"> |
||||
|
<thead> |
||||
|
<tr style="display:block"> |
||||
|
<th class="w-33">{{ $t("exchange.pair") }}</th> |
||||
|
<th class="w-33 text-right">{{ $t("exchange.last-price") }}</th> |
||||
|
<th class="w-33 text-right">{{ $t("exchange.change") }}</th> |
||||
|
</tr> |
||||
|
</thead> |
||||
|
|
||||
|
<tbody> |
||||
|
<tr style="display:block" :class="{highlight : item.pair_id == marketId}" @click="$emit('update:symbol', item.symbol)" v-for="(item, key) in coin.marketInfoList" :key="key" v-show="isShow(item)"> |
||||
|
<td class="w-33" style="white-space:nowrap"> |
||||
|
<i class="icon ion-md-star h6" :class="{ active: isCoolect(item) }" @click.self="handleFav(item)"></i> |
||||
|
{{ coin.coin_name == 'fav' ? item.pair_name : item.coin_name + '/' + coin.coin_name}} |
||||
|
</td> |
||||
|
<td class="w-33 text-right"> |
||||
|
{{ coin.coin_name == 'fav' ? item.close : item.price}} |
||||
|
</td> |
||||
|
<!-- <td class="w-33 text-right" :class="item.increaseStr.startsWith('-') ? 'red' : 'green'"> --> |
||||
|
<td class="w-33 text-right" :class="increaseStrColor(item)"> |
||||
|
{{ item.increaseStr }} |
||||
|
</td> |
||||
|
</tr> |
||||
|
</tbody> |
||||
|
</table> |
||||
|
</div> |
||||
|
|
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
import Market from "@/api/market"; |
||||
|
import Home from "@/api/home"; |
||||
|
import { symbolCircle } from "d3"; |
||||
|
export default { |
||||
|
|
||||
|
props: { |
||||
|
marketList: { |
||||
|
type: Array, |
||||
|
|
||||
|
// 初始化填充页面排版的数据 |
||||
|
default: Array(5).fill({ |
||||
|
coin_name: "-", |
||||
|
marketInfoList: Array(10).fill({ |
||||
|
coin_name: "-", |
||||
|
price: "-", |
||||
|
increace: 0, |
||||
|
increaseStr: "+0.00%", |
||||
|
}), |
||||
|
}) |
||||
|
}, |
||||
|
|
||||
|
isLogin: { |
||||
|
type: Boolean, |
||||
|
default: false, |
||||
|
}, |
||||
|
|
||||
|
marketId: { |
||||
|
type: Number, |
||||
|
default: null, |
||||
|
}, |
||||
|
|
||||
|
firstEnter: true, |
||||
|
}, |
||||
|
|
||||
|
data() { |
||||
|
return { |
||||
|
keyword: '', // 搜索关键字 |
||||
|
current: "fav", |
||||
|
// 个人收藏的交易对信息 |
||||
|
favList: { |
||||
|
coinName: "fav", |
||||
|
marketInfoList: Array(10).fill({ |
||||
|
pair: "-", |
||||
|
price: "-", |
||||
|
increace: 0, |
||||
|
increaseStr: "+0.00%", |
||||
|
}), |
||||
|
}, |
||||
|
|
||||
|
// 收藏交易对的数据结构 |
||||
|
favList: { |
||||
|
coin_name: "fav", |
||||
|
image: require("@/assets/img/waiting.png"), |
||||
|
marketInfoList: [], |
||||
|
}, |
||||
|
|
||||
|
currentCoinIdx: 0, // 当前展示的币种 |
||||
|
|
||||
|
cacheMarketList : [], |
||||
|
collect:[] |
||||
|
} |
||||
|
|
||||
|
}, |
||||
|
|
||||
|
computed: { |
||||
|
|
||||
|
markets() { |
||||
|
// 将行情列表和收藏交易对整理一起 方便渲染 |
||||
|
return [...this.cacheMarketList, this.favList]; |
||||
|
}, |
||||
|
|
||||
|
}, |
||||
|
|
||||
|
watch : { |
||||
|
marketList (list) { |
||||
|
if (list.length) this.cacheMarketList = list; |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
methods: { |
||||
|
|
||||
|
/* |
||||
|
* 询问用户是否登录 |
||||
|
* 如果已经登录 返回true |
||||
|
* 如果没有登录 询问用户是否登录进行操作 |
||||
|
*/ |
||||
|
inquiryLogin() { |
||||
|
if (!this.isLogin) { |
||||
|
this.$confirm(this.$t('nav.login'), this.$t('nav.tips'), { |
||||
|
confirmButtonText: this.$t('home.Login'), |
||||
|
cancelButtonText: this.$t('home.Cancel'), |
||||
|
type: "info", |
||||
|
}) |
||||
|
.then(() => { |
||||
|
location.href = "/login"; |
||||
|
}) |
||||
|
.catch(() => {}); |
||||
|
return false; |
||||
|
} else { |
||||
|
return true; |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
// 搜索关键字 |
||||
|
isShow(symbol) { |
||||
|
|
||||
|
const reg = new RegExp(this.keyword, "gi"); |
||||
|
if (!this.keyword) return true; |
||||
|
else { |
||||
|
let name = symbol.pair_name || symbol.coin_name; |
||||
|
return name.search(reg) >= 0; |
||||
|
} |
||||
|
// return !this.keyword || symbol.coinName.concat(symbol.pair).search(reg) >= 0; |
||||
|
|
||||
|
}, |
||||
|
// 是否为自选 |
||||
|
isCoolect(i) { |
||||
|
// console.log(this.markets[this.currentCoinIdx].marketInfoList) |
||||
|
return this.favList.marketInfoList.map((item) => item.pair_name).includes(i.pair_name); |
||||
|
}, |
||||
|
// 添加收藏的方法 |
||||
|
handleFav(item) { |
||||
|
let data = { |
||||
|
pair_name: item.pair_name, |
||||
|
}; |
||||
|
Home.option(data) |
||||
|
.then((res) => { |
||||
|
this.getCollect(); |
||||
|
if (res) { |
||||
|
this.$message.success(this.$t("home.add")); |
||||
|
} else { |
||||
|
this.$message.success(this.$t("home.cancel")); |
||||
|
} |
||||
|
}) |
||||
|
.catch((err) => {}); |
||||
|
}, |
||||
|
getCollect() { |
||||
|
Home.getCollect() |
||||
|
.then((res) => { |
||||
|
this.favList.marketInfoList = res||[]; |
||||
|
}) |
||||
|
.catch((err) => {}); |
||||
|
}, |
||||
|
increaseStrColor(item){ |
||||
|
if (item && item.increaseStr && item.increaseStr.startsWith('-')) { |
||||
|
return 'red' |
||||
|
} else { |
||||
|
return 'green' |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
created() { |
||||
|
|
||||
|
}, |
||||
|
|
||||
|
mounted() { |
||||
|
// 初始化市场行情 覆盖初始化的[] |
||||
|
Market.getstockMarketList().then(data => { |
||||
|
this.cacheMarketList = data; |
||||
|
}).catch(err => {}); |
||||
|
|
||||
|
// console.log(this.isLogin) |
||||
|
// 如果已登陆 则写入收藏交易对 |
||||
|
if (this.isLogin) { |
||||
|
this.getCollect() |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss"> |
||||
|
.highlight { |
||||
|
background: #f6f8f9; |
||||
|
background: #F8F8FF; |
||||
|
|
||||
|
td:first-child { |
||||
|
color: #007bff !important; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.w-33 { |
||||
|
display: inline-block !important; |
||||
|
vertical-align: top !important; |
||||
|
width: 32% !important; |
||||
|
} |
||||
|
.active{ |
||||
|
color: #326AEB!important; |
||||
|
} |
||||
|
</style> |
||||
Loading…
Reference in new issue