7 changed files with 750 additions and 165 deletions
File diff suppressed because one or more lines are too long
@ -0,0 +1,148 @@ |
|||
<template> |
|||
<custom-base-table |
|||
:data="data" |
|||
:columns="columns" |
|||
thead-classes="text-primary" |
|||
> |
|||
<template slot="LogType" slot-scope="item"> |
|||
{{ typeRender(item.row.item.LogType) }} |
|||
</template> |
|||
</custom-base-table> |
|||
</template> |
|||
|
|||
<script> |
|||
import Bus from "../../common/bus"; |
|||
import CustomBaseTable from "../../components/CustomBaseTable"; |
|||
import moment from "moment"; |
|||
export default { |
|||
props: { |
|||
RobotId: { type: String, default: "60521323-28C3-AC14-0076-48B075584510" } |
|||
}, |
|||
components: { CustomBaseTable }, |
|||
data() { |
|||
return { |
|||
columns: [ |
|||
{ name: "RobotId", prop: "RobotId" }, |
|||
{ name: "内容", prop: "Content" }, |
|||
{ |
|||
name: "日志类型", |
|||
prop: "LogType", |
|||
|
|||
customSlot: "LogType" |
|||
}, |
|||
{ |
|||
name: "订单Id", |
|||
prop: "SpotGoodsOrderId" |
|||
}, |
|||
{ name: "创建时间", prop: "CreateTime" } |
|||
], |
|||
data: [], |
|||
noMoreData: false, |
|||
endTime: null, |
|||
scrollInstance: null, |
|||
nullPlusTime: 0 |
|||
}; |
|||
}, |
|||
created() { |
|||
let endTime = moment(); |
|||
this.endTime = endTime; |
|||
this.getLatestLog(endTime); |
|||
}, |
|||
|
|||
mounted() { |
|||
Bus.$on("tradeLog", data => { |
|||
console.log(data, "received from ws Bus"); |
|||
this.data.unshift(data); |
|||
}); |
|||
this.initScroller(); |
|||
}, |
|||
|
|||
destroyed() { |
|||
if (this.scrollInstance) |
|||
this.scrollInstance.removeEventListener("scroll", this.scrollerListener); |
|||
}, |
|||
methods: { |
|||
initScroller() { |
|||
let target = document.getElementById("tradeLog"); |
|||
this.scrollInstance = target; |
|||
this.scrollInstance.addEventListener( |
|||
"scroll", |
|||
this.scrollerListener, |
|||
false |
|||
); |
|||
}, |
|||
|
|||
getPreday() {}, |
|||
|
|||
scrollerListener() { |
|||
// console.log( |
|||
// this.scrollInstance.scrollTop, |
|||
// this.scrollInstance.scrollHeight, |
|||
// this.scrollInstance.clientHeight |
|||
// ); |
|||
if ( |
|||
this.scrollInstance.scrollTop + this.scrollInstance.clientHeight == |
|||
this.scrollInstance.scrollHeight |
|||
) { |
|||
if (!this.spinning && !this.noMoreData) this.getLatestLog(this.endTime); |
|||
} |
|||
}, |
|||
|
|||
typeRender(logType) { |
|||
switch (logType) { |
|||
case 0: |
|||
return "买入"; |
|||
case 1: |
|||
return "卖出"; |
|||
case 2: |
|||
return "做多"; |
|||
case 3: |
|||
return "做空"; |
|||
case 4: |
|||
return "大趋势看多"; |
|||
case 5: |
|||
return "大趋势看空"; |
|||
case 10: |
|||
return "自动卖出"; |
|||
} |
|||
}, |
|||
getLatestLog(endTime) { |
|||
this.spinning = true; |
|||
let _endTime = endTime.format("YYYY-MM-DD HH:mm:ss"); |
|||
|
|||
this.$http |
|||
.get( |
|||
`/Api/ExecutionLog/GetList?robotId=${this.RobotId}&endTime=${_endTime}` |
|||
) |
|||
.then(res => { |
|||
this.spinning = false; |
|||
if (res.Code == 200) { |
|||
if (res.Data.length > 0) { |
|||
if (this.data.length > 0) { |
|||
res.Data.forEach(item => this.data.push(item)); |
|||
this.endTime = moment( |
|||
this.data[this.data.length - 1].CreateTime |
|||
); |
|||
} else { |
|||
this.data = res.Data; |
|||
} |
|||
} else { |
|||
this.noMoreData = true; |
|||
this.sMessage("danger", "已经没有更多日志了"); |
|||
} |
|||
} |
|||
}); |
|||
}, |
|||
// 封装showNotification |
|||
sMessage(type, message) { |
|||
this.$notify({ |
|||
type: type, |
|||
message, |
|||
timeout: 1800 |
|||
}); |
|||
} |
|||
} |
|||
}; |
|||
</script> |
|||
|
|||
<style scoped></style> |
@ -0,0 +1,350 @@ |
|||
<template> |
|||
<card> |
|||
<el-tabs v-model="activeName"> |
|||
<el-tab-pane label="历史订单" name="first"> |
|||
<custom-base-table |
|||
:data="historyOrders" |
|||
:columns="OrderColumns.filter(item => !item.hidden)" |
|||
thead-classes="text-primary" |
|||
></custom-base-table> |
|||
<el-pagination |
|||
small |
|||
:hide-on-single-page="true" |
|||
layout="prev, pager, next" |
|||
:total="historyOrdersPagination.total" |
|||
:page-size="historyOrdersPagination.pageSize" |
|||
:current-page="historyOrdersPagination.current" |
|||
> |
|||
</el-pagination> |
|||
</el-tab-pane> |
|||
<el-tab-pane label="持仓订单" name="second"> |
|||
<custom-base-table |
|||
:data="nowOrders" |
|||
:columns="OrderColumns" |
|||
thead-classes="text-primary" |
|||
></custom-base-table> |
|||
</el-tab-pane> |
|||
</el-tabs> |
|||
|
|||
<card> |
|||
<h5 slot="header" class="title">账号配置信息</h5> |
|||
<div class="row"> |
|||
<div class="col-md-3"> |
|||
<base-input v-model="basic.CoinCount" label="持币数量" disabled> |
|||
</base-input> |
|||
</div> |
|||
<div class="col-md-3"> |
|||
<base-input |
|||
v-model="basic.TotalPurchasePrice" |
|||
label="持仓总价" |
|||
disabled |
|||
> |
|||
</base-input> |
|||
</div> |
|||
<div class="col-md-3"> |
|||
<base-input |
|||
v-model="basic.AvgPurchasePrice" |
|||
label="持仓均价" |
|||
disabled |
|||
> |
|||
</base-input> |
|||
</div> |
|||
<div class="col-md-3"> |
|||
<base-input |
|||
v-model="basic.TotalPurchasePriceRatio" |
|||
label="持仓占比(%)" |
|||
disabled |
|||
> |
|||
</base-input> |
|||
</div> |
|||
<div class="col-md-3"> |
|||
<base-input v-model="basic.FloatingPL" label="浮动盈亏(%)" disabled> |
|||
</base-input> |
|||
</div> |
|||
<div class="col-md-3"> |
|||
<base-input |
|||
v-model="basic.TotalPurchasePriceProfit" |
|||
label="浮动持仓利润(已预扣手续费)" |
|||
disabled |
|||
> |
|||
</base-input> |
|||
</div> |
|||
<div class="col-md-3"> |
|||
<base-input |
|||
v-model="basic.TotalProfit" |
|||
label="总利润(已预扣手续费)" |
|||
disabled |
|||
> |
|||
</base-input> |
|||
</div> |
|||
<div class="col-md-3"> |
|||
<base-input v-model="basic.NewestPrice" label="最新成交价" disabled> |
|||
</base-input> |
|||
</div> |
|||
</div> |
|||
</card> |
|||
</card> |
|||
</template> |
|||
<script> |
|||
import { OrderColumns } from "../../pages/prePages/js/columns"; |
|||
import CustomBaseTable from "../../components/CustomBaseTable"; |
|||
import Bus from "../../common/bus"; |
|||
|
|||
import { |
|||
sendSock, |
|||
initWebSocket, |
|||
closeWebSocket |
|||
} from "../../utils/plugin/socket"; |
|||
|
|||
const S_PING = 100; |
|||
const R_PONG = 101; |
|||
const SUBSCRIBE = 102; |
|||
const ACCOUNT_INFO = 103; |
|||
const ORDER_PUBLISH = 104; |
|||
const TRADE_LOG = 105; |
|||
|
|||
export default { |
|||
components: { CustomBaseTable }, |
|||
props: { |
|||
RobotId: { type: String, default: "60521323-28C3-AC14-0076-48B075584510" } |
|||
}, |
|||
data() { |
|||
return { |
|||
activeName: "first", |
|||
OrderColumns, |
|||
historyOrders: [], |
|||
nowOrders: [], |
|||
basic: {}, |
|||
historyOrdersPagination: { current: 1, pageSize: 15 }, |
|||
pingInterval: null |
|||
}; |
|||
}, |
|||
|
|||
created() { |
|||
this.initOrders(); //初始化两个订单列表 |
|||
}, |
|||
|
|||
mounted() { |
|||
console.log("connecting"); |
|||
this.initWs(); //初始化ws连接 |
|||
}, |
|||
|
|||
beforeDestroy() { |
|||
closeWebSocket(); |
|||
localStorage.clear(); |
|||
clearInterval(this.pingInterval); |
|||
}, |
|||
|
|||
methods: { |
|||
initOrders() { |
|||
this.initHistoryOrders(); |
|||
this.initNowOrders(); |
|||
}, |
|||
initHistoryOrders() { |
|||
let pageIndex = this.historyOrdersPagination.current; |
|||
let pageSize = this.historyOrdersPagination.pageSize; |
|||
this.$http |
|||
.get( |
|||
`/Api/Order/GetHistorySpotGoodsOrder?pageIndex=${pageIndex}&pageSize=${pageSize}&robotId=${this.RobotId}` |
|||
) |
|||
.then(res => { |
|||
if (res.Code == 200) { |
|||
this.historyOrders = res.Data.List; |
|||
const pager = { ...this.historyOrdersPagination }; |
|||
pager.total = res.Data.Count; |
|||
this.historyOrdersPagination = pager; |
|||
} |
|||
}); |
|||
}, |
|||
|
|||
//触发分页 |
|||
historyOrdersChange(pagination) { |
|||
this.historyOrdersPagination = pagination; |
|||
this.initHistoryOrders(); |
|||
}, |
|||
|
|||
initNowOrders() { |
|||
this.$http |
|||
.get(`/Api/Order/GetRuningSpotGoodsOrder?robotId=${this.RobotId}`) |
|||
.then(res => { |
|||
if (res.Code == 200) { |
|||
this.nowOrders = res.Data; |
|||
} |
|||
}); |
|||
}, |
|||
|
|||
initWs() { |
|||
let that = this; |
|||
initWebSocket("ws://54.249.164.224").then( |
|||
rs => { |
|||
//订阅事件 |
|||
sendSock( |
|||
{ |
|||
Notify: SUBSCRIBE, |
|||
RobotId: this.RobotId |
|||
}, |
|||
that.wsCb |
|||
); |
|||
//ping包检测连接 |
|||
that.pingIntervalKeeper(); |
|||
}, |
|||
rj => { |
|||
that.$message.error("连接websocket失败,正在重连"); |
|||
that.initWs(); |
|||
} |
|||
); |
|||
}, |
|||
|
|||
wsCb(data) { |
|||
console.log("ws received", data); |
|||
|
|||
if (data && data.Notify == ACCOUNT_INFO) { |
|||
this.dealAccountInfo(data); |
|||
} else if (data && data.Notify == ORDER_PUBLISH) { |
|||
this.dealOrder(data); |
|||
} else if (data && data.Notify == R_PONG) { |
|||
this.dealPong(data); |
|||
} else if (data && data.Notify == TRADE_LOG) { |
|||
Bus.$emit("tradeLog", data); |
|||
} |
|||
}, |
|||
|
|||
pingPkg() { |
|||
console.log("心跳包检测发送"); |
|||
let timeStamp = Date.now(); |
|||
let that = this; |
|||
sendSock( |
|||
{ |
|||
Notify: S_PING, |
|||
TimeStamp: timeStamp |
|||
}, |
|||
that.wsCb |
|||
); |
|||
localStorage.setItem("pingTimeStamp", timeStamp); |
|||
if (!localStorage.getItem("missPkg")) { |
|||
localStorage.setItem("missPkg", 1); |
|||
} else { |
|||
let missPkgCount = parseInt(localStorage.getItem("missPkg")) + 1; |
|||
localStorage.setItem("missPkg", missPkgCount); |
|||
console.log("丢包次数增加1", missPkgCount); |
|||
if (missPkgCount > 3) { |
|||
/** 达到丢包上限 |
|||
* 1.停止ping包interval |
|||
* 2.关闭ws |
|||
* 3.重新获取订单列表 |
|||
*/ |
|||
console.log("达到丢包次数", missPkgCount); |
|||
clearInterval(this.pingInterval); |
|||
localStorage.clear(); |
|||
closeWebSocket(); |
|||
this.initOrders(); |
|||
this.initWs(); |
|||
} |
|||
} |
|||
}, |
|||
|
|||
//心跳包ping包定时发送 |
|||
pingIntervalKeeper() { |
|||
let that = this; |
|||
that.pingPkg(); |
|||
this.pingInterval = setInterval(() => { |
|||
that.pingPkg(); |
|||
}, 30000); |
|||
}, |
|||
|
|||
//心跳包pong包检测 |
|||
dealPong(data) { |
|||
//收到pong包后与本地得timeStamp匹配到之后丢包次数默认-1 |
|||
let timeStamp = localStorage.getItem("pingTimeStamp"); |
|||
let missPkgCount = parseInt(localStorage.getItem("missPkg")); |
|||
if (data.TimeStamp == timeStamp) { |
|||
missPkgCount--; |
|||
console.log("丢包次数减少1", missPkgCount); |
|||
localStorage.setItem("missPkg", missPkgCount); |
|||
} |
|||
}, |
|||
|
|||
//账号信息推送处理 |
|||
dealAccountInfo(data) { |
|||
this.basic = { ...this.basic, ...data }; |
|||
if ( |
|||
this.nowOrders.length > 0 && |
|||
data.NewestPrice && |
|||
data.NewestPrice != 0 |
|||
) { |
|||
this.nowOrders.forEach(item => { |
|||
let totalSalePrice = data.NewestPrice * item.PurchaseCoinCount; //销售总价 |
|||
let saleFee = totalSalePrice * 0.02; //销售手续费 |
|||
let Profit = |
|||
totalSalePrice - |
|||
item.TotalPurchasePrice - |
|||
saleFee - |
|||
item.PurchaseFee; |
|||
item.Profit = Profit.toFixed(5); //算出利润 |
|||
item.UnstableProfit = ( |
|||
(data.NewestPrice / item.PurchasePrice - 1) * |
|||
100 |
|||
).toFixed(5); //算出浮动盈亏 |
|||
// console.log(item.UnstableProfit, "看看数据"); |
|||
}); |
|||
} |
|||
}, |
|||
|
|||
//订单推送处理 |
|||
dealOrder(data) { |
|||
//4|| 6 |
|||
let targetIndex = -1; |
|||
for (let i = 0; i < this.nowOrders.length; i++) { |
|||
if (data.Id == this.nowOrders[i].Id) { |
|||
targetIndex = i; |
|||
break; |
|||
} |
|||
} |
|||
if (targetIndex == -1) { |
|||
this.nowOrders.push(data); |
|||
} else { |
|||
this.nowOrders[targetIndex] = { |
|||
...this.nowOrders[targetIndex], |
|||
...data |
|||
}; |
|||
if (data.Status == 4 || data.Status == 6) { |
|||
this.nowOrders.splice(targetIndex, 1); |
|||
if (this.historyOrdersPagination.current == 1) |
|||
this.initHistoryOrders(); |
|||
} |
|||
} |
|||
}, |
|||
statusRender(status) { |
|||
//已创建=0,部分购买=1,已购买=2,部分购买被撤销=3,购买被撤销=4,部分卖出=5,已卖出=6,部分卖出已撤销=7,卖出已撤销=8 |
|||
switch (status) { |
|||
case 0: |
|||
return "已创建"; |
|||
case 1: |
|||
return "部分购买"; |
|||
case 2: |
|||
return "已购买"; |
|||
case 3: |
|||
return "部分购买被撤销"; |
|||
case 4: |
|||
return "购买被撤销"; |
|||
case 5: |
|||
return "部分卖出"; |
|||
case 6: |
|||
return "已卖出"; |
|||
case 7: |
|||
return "部分卖出已撤销"; |
|||
case 8: |
|||
return "卖出已撤销"; |
|||
} |
|||
} |
|||
} |
|||
}; |
|||
</script> |
|||
<style> |
|||
.el-pagination button:disabled { |
|||
background-color: transparent; |
|||
} |
|||
.el-pager li { |
|||
background-color: transparent; |
|||
} |
|||
</style> |
Loading…
Reference in new issue