父组件代码:
<template>
<view class="hq-detail-wrapper">
<!-- 分时图导航栏 -->
<view left-icon="back" :codeName="shortname" :code="code"
:bgColor="isLeave != 1 ? Color(0,tooltipData[3]) : Color(0,symbol.pc)"
:navTransparentFixedBackgrpundColor="isLeave != 1 ? Color(0,tooltipData[3]) : Color(0,symbol.pc)"
transparentFixedFontColor="#fff" :fontColor="'#fff'" :navFontColor="'#fff'" :pageParams="2" class="hq-nav"
v-if="navIndex == 0">
<template slot="left">
<view @click="clickLeft" class="iconfont icon-zuofanhui nBack" style="margin-left: 15rpx;"></view>
</template>
<template slot="right">
<view class="search_icon">
<u-icon name="search" size="28" color="#fff"></u-icon>
</view>
</template>
</view>
<view class="hq-page-content">
<!-- 分时图涨跌,涨跌幅等显示框 -->
<view class="detail-top-box"
:style="{backgroundColor: isLeave != 1 ? Color(0,tooltipData[3]) : Color(0,symbol.pc)}"
v-if="navIndex == 0">
<view class="detail-price">
{{ isLeave != 1 ? tooltipData[1] == null || tooltipData[1] == '' || tooltipData[1] == '0.00' ? '--' : toDecimal(tooltipData[1],getTickDecLen(symbol), true) : (symbol.cp == null || symbol.cp == '' || symbol.cp == '0.00' ? '--' : toDecimal(symbol.cp,getTickDecLen(symbol), true)) }}
</view>
<view class="detail-zdf">
<view class="detail-zd">
<text
v-if="isLeave != 1">{{ tooltipData[3] > 0 ? "+" : ""}}{{tooltipData[3] == null || tooltipData[3] == '' ? '--' : toDecimal(tooltipData[3],2, true)}}</text>
<text
v-else>{{ symbol.pc > 0 ? "+" : ""}}{{symbol.pc == null || symbol.pc == '' ? '--' : toDecimal(symbol.pc,2, true)}}</text>
</view>
<view class="detail-zf">
<text>{{ isLeave != 1 ? tooltipData[2] == null || toRatio(tooltipData[2]) == '' ? '--' : tooltipData[2]+'%' : (symbol.cr == null || symbol.cr == '' ?'--':toRatio(symbol.cr)+'%') }}</text>
</view>
<view class="line"></view>
<view class="detail-zc">
<text>{{ isLeave != 1 ? tooltipData[0] ? tooltipData[0] : '-- : --' : (symbol.utc != '00:00' ? symbol.utc : '-- : --') }}</text>
</view>
</view>
</view>
<view class="detail-top xflex">
<view class="detail-top-right xflex-1 xflex xflex-j-s">
<view class="right-item xflex xflex-col xflex-j-s">
<view class="right-item-1 xflex">
<view class="item-label">
今开
</view>
<view class="item-text" :style="{color: Color(symbol.pp, symbol.op)}">
{{toDecimal(symbol.op,digit, true)}}
</view>
</view>
<view class="right-item-1 xflex" v-if="curIndex == 4">
<view class="item-label">
现量
</view>
<view class="item-text">
{{formatNumUnit(symbol.cq, 1)}}
</view>
</view>
<view class="right-item-1 xflex" v-if="curIndex == 6">
<view class="item-label">
总额
</view>
<view class="item-text">
{{formatNumUnit(symbol.tm, 1)}}
</view>
</view>
<view class="right-item-1 xflex" v-if="curIndex < 4||curIndex == 5">
<view class="item-label">
换手
</view>
<view class="item-text">
<text>{{symbol.tr == null?'--':(toRatio(symbol.tr)+'%') }}</text>
</view>
</view>
<view class="right-item-1 xflex" v-if="curIndex == 3">
<view class="item-label">
净值
</view>
<view class="item-text">
{{symbol.nav==null?'--':formatNumUnit(symbol.nav, 3)}}
</view>
</view>
<view class="right-item-1 xflex" v-else-if="curIndex == 4">
<view class="item-label">
总额
</view>
<view class="item-text">
{{formatNumUnit(symbol.tm, 1)}}
</view>
</view>
<view class="right-item-1 xflex" v-else-if="curIndex == 6">
<view class="item-label">
涨家
</view>
<view class="item-text" :style="{color: symbol.un?'#c00':''}">
{{toDecimal(symbol.un,0)}}
</view>
</view>
<view class="right-item-1 xflex" v-else>
<view class="item-label">
总值
</view>
<view class="item-text">
{{symbol.tmv==null?'--':formatNumUnit(symbol.tmv, 1)}}
</view>
</view>
</view>
<view class="right-item xflex xflex-col xflex-j-s">
<view class="right-item-1 xflex">
<view class="item-label">
最高
</view>
<view class="item-text" :style="{color: Color(symbol.pp, symbol.hp)}">
{{toDecimal(symbol.hp,digit, true)}}
</view>
</view>
<view class="right-item-1 xflex" v-if="curIndex != 6">
<view class="item-label">
总手
</view>
<view class="item-text">{{symbol.tq?formatNumUnit(symbol.tq.toFixed(),1):'--'}}</view>
</view>
<view class="right-item-1 xflex" v-if="curIndex == 6">
<view class="item-label">
总手
</view>
<view class="item-text">{{formatNumUnit(symbol.tq,1)}}</view>
</view>
<view class="right-item-1 xflex" v-if="curIndex == 3">
<view class="item-label">
溢价
</view>
<view class="item-text" :style="{color: Color(0,symbol.pre)}">
{{toDecimal(symbol.pre,3)}}
</view>
</view>
<view class="right-item-1 xflex" v-else-if="curIndex == 4">
<view class="item-label">
外盘
</view>
<view class="item-text">
{{symbol.bv==null?'--':formatNumUnit(parseInt(symbol.bv), 1)}}
</view>
</view>
<view class="right-item-1 xflex" v-else-if="curIndex == 6">
<view class="item-label">
跌家
</view>
<view class="item-text" :style="{color: symbol.dn?'#20b120':''}">
{{toDecimal(symbol.dn,0)}}
</view>
</view>
<view class="right-item-1 xflex" v-else>
<view class="item-label">
流值
</view>
<view class="item-text">
{{symbol.cmv==null?'--':formatNumUnit(symbol.cmv,1)}}
</view>
</view>
</view>
<view class="right-item xflex xflex-col xflex-j-s">
<view class="right-item-1 xflex">
<view class="item-label">
最低
</view>
<view class="item-text" :style="{color: Color(symbol.pp, symbol.lp)}">
{{toDecimal(symbol.lp,digit, true)}}
</view>
</view>
<view class="right-item-1 xflex" v-if="curIndex == 6">
<view class="item-label">
均价
</view>
<view class="item-text" :style="{color: Color(symbol.pp, symbol.ap)}">
{{toDecimal(symbol.ap,digit, true)}}
</view>
</view>
<view class="right-item-1 xflex" v-else>
<view class="item-label">
委比
</view>
<view class="item-text" :style="{color: Color(0,symbol.or)}">
{{symbol.or == null ? '--':toDecimal(symbol.or * 100, 2, true)+'%'}} <text></text>
</view>
</view>
<view class="right-item-1 xflex" v-if="curIndex == 3 ">
<view class="item-label">
溢价率
</view>
<view class="item-text" :style="{color: Color(0,symbol.prer)}">
<text>{{toDecimal(symbol.prer*100,2, true)}}% </text>
</view>
</view>
<view class="right-item-1 xflex" v-else-if="curIndex == 4 ">
<view class="item-label">
内盘
</view>
<view class="item-text">
{{symbol.sv==null?'--':formatNumUnit(parseInt(symbol.sv), 1)}}
</view>
</view>
<view class="right-item-1 xflex" v-else-if="curIndex == 6">
<view class="item-label">
平家
</view>
<view class="item-text">
{{toDecimal(symbol.fn,0)}}
</view>
</view>
<view class="right-item-1 xflex" v-else>
<view class="item-label">
市盈率
</view>
<view class="item-text">
<text>{{toDecimal(symbol.pe1,2, true)}} </text>
</view>
</view>
</view>
</view>
</view>
<view class="content-wrapper">
<view class="main-content">
<chartMin :mdata="mdata" :code="code" :shortname="shortname" :maket="maket"
:haswd="haswd" :preclose="symbol.pp" :curIndex="curIndex" :isLeave="isLeave"
@getTooltipData="getTooltipData" />
</view>
</view>
<view class="foot-wrapper">
<view class="comfirm xflex xflex-j-a">
<view class="add">
<view v-if="!selectId" @tap.stop="addSelfData" class="text-but">
<i class="iconfont icon-tianjiazixuan"></i>
<view>加自选</view>
</view>
<view v-if="selectId" @tap.stop="deleteSelfData" class="text-but2">
<i class="iconfont icon-quxiaozixuan"></i>
<view>删自选</view>
</view>
</view>
<view class="sell">
<view class="sell-but" @click="hqSale">卖出</view>
</view>
<view class="buy">
<view class="buy-but" @click="hqBuy">买入</view>
</view>
</view>
</view>
</view>
<!-- 加载loading动画,用于socket完整链接 -->
<view class="mask mask-show" v-if="loadingShow">
<u-loading-icon></u-loading-icon>
<view class="title">加载中...</view>
</view>
</view>
</template>
<script>
import common from "@/common/index";
import chartMin from './components/chartMin.vue';
import {
allSelfSecurity,
addSelfSecurity,
deleteSelfSecurity
} from "@/api/optional.js"; // 后端接口
import {
turnColor,
getQueryString
} from './u.js';
import {
IsEndMatch,
getMatchAndExercise
} from "@/api/practice.js"; // 后端接口
import {
signalrsOn,
signalrInvoke
} from '@/util/signalR.js'; // 行情订阅与取消订阅接口
import {
trigger
} from '@/util/callback';
export default {
components: {
chartMin
},
data() {
return {
bgColor: '#57B967',
curIndex: 0,
shortname: '',
code: '',
maket: '',
securityType: '',
plateId: '',
selectId: '',
navList: [{
label: '分时'
},
{
label: '日K'
},
{
label: '周K'
},
{
label: '月K'
},
],
navType: [
'L1MinQuotation', 'DayKlineQuotation', 'WeekKlineQuotation', 'MonthKlineQuotation'
],
navIndex: 0,
mlist: {},
mdata: {},
removeDuplication: {},
symbol: {
cp: null,
cg: null,
cr: null,
op: null,
hp: null,
lp: null,
tr: '',
tq: null,
tm: null,
or: null,
tm: null,
cmv: null,
pe1: null,
pp: null, // 昨收
pre: null, // 溢价
prer: null, // 溢价率
nav: null, // 净值
cq: null, //现量
bv: null, //外盘
sv: null, //内盘
tr: null, // 换手
or: null, // 委比
pc: null, // 涨跌
utc: '', // 时间
},
tq: 0,
op: 0,
haswd: true, // 是否显示五档行情
sbData: [],
selectList: [],
sbList: [],
partType: '', // 成分股类型
loadingShow: false, // 阻止频繁链接断开socket
lockTime: null,
isIos: sessionStorage.getItem('isIOS'),
preNavIndex: 0, // 日K切换上一个记录,用于取消订阅
tradingTimeList: [], // 买卖时间数组
scrollTopPage: 0,
tooltipData: [], // 分时图数据
isLeave: 1, // 分时图是否离开点击(1:是 0:否)
isKLineLeave: 1, // K线图是否离开点击(1:是 0:否)
topNum: 590,
tradePageTypeData:true,//正常股票显示,该大赛包含港股通,显示
}
},
// 实时获取滚动条的位置
onPageScroll(res) {
this.scrollTopPage = res.scrollTop
},
onReachBottom() {
if(this.securityType == 'S0101') {
this.$refs.sharesInfo.loadFund()
}
},
methods: {
// 小数位数
getTickDecLen(item) {
return common.getTickDecLen(this.securityType, item.mk);
},
// 获取分时图涨跌,涨跌幅,时间,现价数据
getTooltipData(value) {
this.tooltipData = value
this.isLeave = value[4]
},
// 行情订阅
SubscribeOn() {
signalrsOn('SubscribeReturn', (item) => {
if (item.quotationtype) {
if (item.quotationtype === 'L1MinQuotation' && item.tranparam == 10) {
if (this.securityType == 'S0104') {
setTimeout(() => {
this.initMdata(item.data)
}, 200)
} else {
this.initMdata(item.data)
}
this.isLeave = 1
this.symbol.cp = item.data[item.data.length - 1].cp // 现价
this.symbol.pc = item.data[item.data.length - 1].pc // 涨跌
this.symbol.cr = item.data[item.data.length - 1].cr // 涨跌幅
this.symbol.utc = this.formatDate(new Date(item.data[item.data.length - 1].utc),
'hh:mm') // 时间
trigger('TickQuotationInfoList', this.mdata)
} else if (item.quotationtype === 'TickQuotationInfo' && this.maket != 'PIDX') {
if (`${this.code}.${this.maket}` != `${item.data.sm}.${item.data.mk}`) {
return;
}
this.symbol.cp = item.data.cp
this.symbol.cg = item.data.cg
this.symbol.cr = item.data.cr
this.symbol.op = item.data.op
this.symbol.hp = item.data.hp
this.symbol.lp = item.data.lp
this.symbol.tr = item.data.tr
this.symbol.tq = item.data.tq
this.symbol.or = item.data.or
this.symbol.tm = item.data.tm
this.symbol.cmv = item.data.cmv
this.symbol.pe1 = item.data.pe1
this.symbol.pp = item.data.pp
this.symbol.sid = item.data.sid
this.symbol.sm = item.data.sm
this.symbol.mk = item.data.mk
this.symbol.sn = item.data.sn
this.symbol.tmv = item.data.tmv
this.symbol.pre = item.data.pre
this.symbol.prer = item.data.prer
this.symbol.nav = this.toDecimal(item.data.nav, 3)
this.symbol.cq = item.data.cq
this.symbol.bv = item.data.bv
this.symbol.sv = item.data.sv
this.symbol.ap = item.data.ap // 均价
trigger('getPp', this.symbol.pp)
} else if (item.quotationtype === 'FiveGearQuoteInfo') {
if (item.data.buylevels && item.data.buylevels.length > 0) {
item.data.buylevels.forEach(r => {
r.volume = Math.round(r.volume)
r.price = this.toDecimal(Number(r.price), this.digit)
})
}
if (item.data.selllevels && item.data.selllevels.length > 0) {
item.data.selllevels.forEach(r => {
r.volume = Math.round(r.volume)
r.price = this.toDecimal(Number(r.price), this.digit)
})
}
trigger('FiveGearQuoteInfo', item)
} else if (item && item.quotationtype == 'TickQuotationcs') {
let res = item
if (res && res.data) {
let {
data
} = res.data
this.sbData[this.tranparam] = []
if (data && data.length && data.length <= 10) {
data.forEach((item) => {
item.selectId = ""
let index = this.sbData[this.tranparam].findIndex((sb) => {
return sb.sid == item.sid
})
if (index > -1) {
if (JSON.stringify(i) != JSON.stringify(this.sbData[this
.tranparam][index])) {
this.$set(this.sbData[this.tranparam], index, i);
}
} else {
this.sbData[this.tranparam].push(item)
}
})
let list = this.sbData[this.tranparam]
if (this.selectList.length) {
for (let i = 0; i < list.length; i++) {
let id = list[i].sm + "." + list[i].mk;
list[i].selectId = "";
for (let j = 0; j < this.selectList.length; j++) {
let code = this.selectList[j].commodityCode + "." + this
.selectList[j].market;
if (code == id) {
list[i].selectId = this.selectList[j].id || '';
break;
}
}
}
}
this.sbList = list
if (this.sbList.length) {
let [{
tid
}] = this.sbList
this.partType = tid
}
}
}
} else if (item.quotationtype === 'PlateIndexQuotationInfo' && this.maket == 'PIDX') {
if (`${this.code}.${this.maket}` != `${item.data.sm}.${item.data.mk}`) {
return;
}
this.symbol = item.data
this.symbol.cp = item.data.lp
this.symbol.cg = item.data.c
this.symbol.cr = item.data.cr
this.symbol.op = item.data.op
this.symbol.hp = item.data.hp
this.symbol.lp = item.data.lowprice
this.symbol.tr = item.data.tr
this.symbol.tq = item.data.tv
this.symbol.or = item.data.or
this.symbol.tm = item.data.ta
this.symbol.cmv = item.data.cmv
this.symbol.pe1 = item.data.pe1
this.symbol.pp = item.data.pp
this.symbol.sid = item.data.sid
this.symbol.sm = item.data.sm
this.symbol.mk = item.data.mk
this.symbol.sn = item.data.sn
this.symbol.tmv = item.data.tmv
this.symbol.pre = item.data.pre
this.symbol.prer = item.data.prer
this.symbol.nav = this.toDecimal(item.data.nav, 3)
this.symbol.cq = item.data.cq
this.symbol.bv = item.data.bv
this.symbol.sv = item.data.sv
trigger('getPp', this.symbol.pp)
}
}
})
},
unSubscribe() {
signalrInvoke('Quotation2', 'UnSubscribe', {
QuotationType: 'FiveGearQuoteInfo'
})
signalrInvoke('Quotation', 'UnSubscribe', {
QuotationType: 'TickQuotationInfo'
})
for (var i in this.navType) {
signalrInvoke('Quotation', 'UnSubscribe', {
QuotationType: this.navType[i]
})
}
// 指数的 成分股列表订阅
let urls = getQueryString(window.location.href);
if (urls.securityType == 'S0104') {
signalrInvoke('Quotation', 'UnSubscribe', {
QuotationType: 'TickQuotationcs',
})
signalrInvoke('Quotation', 'UnSubscribe', {
QuotationType: 'PlateIndexQuotationInfo'
})
}
this.mlist = {}
this.mdata = {}
this.tq = 0
},
unSubscribe1(index) {
this.tq = 0
if (this.securityType != 'S0104') {
setTimeout(() => {
signalrInvoke('Quotation', 'UnSubscribe', {
QuotationType: this.navType[this.preNavIndex]
})
this.preNavIndex = index
}, 50)
} else {
signalrInvoke('Quotation', 'UnSubscribe', {
QuotationType: this.navType[this.preNavIndex]
})
this.preNavIndex = index
}
},
Color(str1, str2) {
return turnColor(str1, str2)
},
// 验证是否能进行买卖
checkAbled() {
// 日内转大赛非选证券
let matchInfo = sessionStorage.getItem("raceInfo") || {};
let matchUseCodesList = matchInfo.matchUseCodes || [];
let codes = matchUseCodesList.map(item => {
return item.securityID
})
if (matchInfo.matchType == 4 && !codes.includes(this.code)) {
uni.showToast({
title: `非当前日内回转赛指定证券!`,
icon: "none",
})
return false
} else {
return true
}
},
// 未选中大赛默认选取练习场
setPracticeInfo(res) {
let practiceInfo = res.data[0]
const {
matchID,
msTraderID,
traderID
} = practiceInfo
// 1 练习场
sessionStorage.setItem("raceId", matchID);
sessionStorage.setItem("userId", msTraderID);
sessionStorage.setItem("mnTraderId", traderID);
sessionStorage.setItem("raceInfo", practiceInfo);
},
// 判断大赛是否结束
async checkIsEndMatch() {
let raceInfo = sessionStorage.getItem("raceInfo") || {};
if (Object.keys(raceInfo).length == 0) {
let pres = await getMatchAndExercise();
this.setPracticeInfo(pres)
} else {
// 组合不做大赛结束判断
if (raceInfo.endTime) {
const params = {
matchId: raceInfo.matchID || 1,
};
// 大赛结束
let res = await IsEndMatch(params)
if (res.isOK) {
if (res.data && res.data.isStaticEnd) {
let pres = await getMatchAndExercise();
this.setPracticeInfo(pres)
}
}
}
}
},
async hqBuy() {
if (!this.checkAbled()) return
// 获取当前大赛状态,判断
let searchArr = sessionStorage.getItem('searchArr');
let stObj = searchArr.find(i => {
return i.a == this.symbol.sm
}) || {}
let securityType = stObj.e
let info = {
securityID: this.symbol.sm,
symbol: this.symbol.sm,
securityType: securityType,
market: this.symbol.mk,
shortName: this.symbol.sn
}
if(this.maket=='HKEX'){//港股通过无快捷买卖弹框,直接跳转下单页面
this.$store.commit("setTradePageType","HKT") //general正常大赛操作,HKT是港股通操作
uni.redirectTo({
url: '/pages/mnsc/buyHKT?info=' + JSON.stringify(info) + '&isNaverEndMatch=1'
});
return
}
},
async hqSale() {
if (!this.checkAbled()) return
// 获取当前大赛状态,判断
let searchArr = sessionStorage.getItem('searchArr');
let stObj = searchArr.find(i => {
return i.a == this.symbol.sm
}) || {}
let securityType = stObj.e
let info = {
securityID: this.symbol.sm,
symbol: this.symbol.sm,
securityType: securityType,
market: this.symbol.mk,
shortName: this.symbol.sn
}
if(this.maket=='HKEX'){//港股通过无快捷买卖弹框,直接跳转下单页面
this.$store.commit("setTradePageType","HKT") //general正常大赛操作,HKT是港股通操作
uni.redirectTo({
url: '/pages/mnsc/saleHKT?info=' + JSON.stringify(info) + '&isNaverEndMatch=1'
});
return
}
},
// 初始化分时图数据
initMdata(data) {
// 筛选无效数据不做绘图
data = data.filter(item => {
return !!item.cp
})
if (data && data.length > 0) {
data.forEach(item => {
const temp = {
utc: this.formatDate(new Date(item.utc), 'HHmm'),
cp: this.toDecimal(item.cp, this.digit), // 收价
avg: this.toDecimal(item.avg, this.digit), // 均价
tv: this.toDecimal(item.tv, 0), // 总量
ta: item.ta || '--', // 总额
cr: this.toDecimal(this.numMul(item.cr, 100), 3), // 涨幅
pp: this.toDecimal(item.pp, this.digit),
utc1: this.formatDate(new Date(item.utc), 'HH:mm'),
utc2: item.utc,
pc: this.toDecimal(item.pc, this.digit), // 涨跌
}
this.$set(this.mlist, this.formatDate(new Date(item.utc), 'HHmm'), temp)
})
}
let lstData = []
for (const i in this.mlist) {
try {
let listItem = [
this.mlist[i].utc,
this.toDecimal(+this.mlist[i].cp, this.digit),
this.toDecimal(+this.mlist[i].avg, this.digit),
this.mlist[i].tv,
this.mlist[i].ta,
this.mlist[i].cr,
this.toDecimal(+this.mlist[i].pp, this.digit),
this.mlist[i].utc1,
this.mlist[i].utc2,
this.mlist[i].pc,
]
lstData.push(listItem)
} catch (e) {
console.log(e)
}
}
lstData.sort((a, b) => a[0] - b[0])
this.mdata = {
data: lstData,
yestclose: this.mlist[0] && this.mlist[0].pp ? this.mlist[0].pp : this.toDecimal(this.symbol.pp,
this.digit)
}
},
compareNum(a, b) {
if (a >= b) {
return true
} else {
return false
}
},
combomList(arr1, arr2) {
arr2.forEach((item1, j) => {
let flag = arr1.findIndex(r => r[0] === item1[0])
if (flag < 0) {
this.$set(arr1, arr1.length, item1)
} else {
this.$set(arr1, flag, item1)
}
})
return arr1
},
// xx率乘100
toRatio(num) {
if (num == null) {
return 0.00
}
return this.toDecimal(this.numMul(num, 100))
},
/**
* 精确乘
* @param arg1
* @param arg2
* @returns {number}
*/
numMul(arg1, arg2) {
var r1 = arg1 + "";
var r2 = arg2 + "";
var r3 = 0;
var r4 = 0;
try {
r3 = r1.split(".")[1].length;
} catch (err) {
r3 = 0;
}
try {
r4 = r2.split(".")[1].length;
} catch (err) {
r4 = 0;
}
return (
(Number(r1.replace(".", "")) * Number(r2.replace(".", ""))) /
Math.pow(10, r4 + r3)
);
},
// 格式化日期
formatDate(date, format) {
var v = "";
if (typeof date === "string" || typeof date !== "object") {
return;
}
var year = date.getFullYear();
var month = date.getMonth() + 1;
var day = date.getDate();
var hour = date.getHours();
var minute = date.getMinutes();
var second = date.getSeconds();
var weekDay = date.getDay();
var ms = date.getMilliseconds();
var weekDayString = "";
if (weekDay === 1) {
weekDayString = "星期一";
} else if (weekDay === 2) {
weekDayString = "星期二";
} else if (weekDay === 3) {
weekDayString = "星期三";
} else if (weekDay === 4) {
weekDayString = "星期四";
} else if (weekDay === 5) {
weekDayString = "星期五";
} else if (weekDay === 6) {
weekDayString = "星期六";
} else if (weekDay === 0) {
weekDayString = "星期日";
}
v = format;
// Year
v = v.replace(/yyyy/g, year);
v = v.replace(/YYYY/g, year);
v = v.replace(/yy/g, (year + "").substring(2, 4));
v = v.replace(/YY/g, (year + "").substring(2, 4));
// Month
var monthStr = "0" + month;
v = v.replace(/MM/g, monthStr.substring(monthStr.length - 2));
// Day
var dayStr = "0" + day;
v = v.replace(/dd/g, dayStr.substring(dayStr.length - 2));
// hour
var hourStr = "0" + hour;
v = v.replace(/HH/g, hourStr.substring(hourStr.length - 2));
v = v.replace(/hh/g, hourStr.substring(hourStr.length - 2));
// minute
var minuteStr = "0" + minute;
v = v.replace(/mm/g, minuteStr.substring(minuteStr.length - 2));
// Millisecond
v = v.replace(/sss/g, ms);
v = v.replace(/SSS/g, ms);
// second
var secondStr = "0" + second;
v = v.replace(/ss/g, secondStr.substring(secondStr.length - 2));
v = v.replace(/SS/g, secondStr.substring(secondStr.length - 2));
// weekDay
v = v.replace(/E/g, weekDayString);
return v;
},
async allSelfSecurity() {
let res = await allSelfSecurity();
if (res.isOK) {
if (res.data && res.data.length) {
this.selectList = res.data;
let result = res.data.filter((dd) => `${dd.commodityCode}.${dd.market}` ==
`${this.code}.${this.maket}`)
if (result && result.length) {
this.selectId = result[0]['id'] || ''
} else {
this.selectId = ""
}
} else {
this.selectId = ""
}
}
},
// 添加自选代码
async addSelfData() {
let res = await addSelfSecurity({
market: this.maket,
securityType: this.securityType,
shortName: this.shortname,
plateID: this.plateId,
commodityCode: this.code
})
if (res.isOK) {
this.selectId = res.data || ''
uni.showToast({
title: `添加成功`,
icon: "none",
})
allSelfSecurity()
} else {
uni.showToast({
title: res.msg,
icon: "none",
})
}
},
// 删除自选代码
async deleteSelfData() {
let res = await deleteSelfSecurity({
id: this.selectId,
});
if (res.isOK) {
this.selectId = ""
uni.showToast({
title: `删除成功`,
icon: "none",
});
this.allSelfSecurity()
} else {
uni.showToast({
title: `删除失败`,
icon: "none",
});
}
},
// 指数成分股列表加入自选
setSbList(index, val) {
this.$set(this.sbList[index], "selectId", val)
this.allSelfSecurity()
},
//去除自选
deleteSelect(index) {
this.$set(this.sbList[index], "selectId", '')
this.allSelfSecurity()
}
},
computed: {
title() {
return this.shortname + '(' + this.code + ')'
},
digit() {
//判断是不是深圳债券
if (Number(this.curIndex) == 6 || (+this.curIndex) < 3 || Number(this.curIndex) == 5) {
return 2
} else {
return 3
}
},
divol() {
if (this.curIndex == 4 && this.maket == 'SZSE') {
return 10
} else {
return 1
}
},
},
onLoad(options) {
uni.showLoading({
title: '加载中',
mask: true
});
// 接收买卖时间点
if (options.tradingTimeList) {
this.tradingTimeList = JSON.parse(options.tradingTimeList)
}
this.shortname = options.shortname
this.code = options.code
this.maket = options.maket
this.plateId = options.plateId
// ['沪深A股', '科创板', '创业板', '基金', '债券', '北交所', '指数']
this.curIndex = options.curIndex // 从股、债、基、指模块进入详情
this.securityType = options.securityType // 进入详情呈现的类型股、债、基、指
this.selectId = options.selectId || ''
this.haswd = !(options.curIndex == 6) // 指数板块没五档行情
// BK开头的衍生指数,展示分时;
if (this.code.indexOf('BK') > -1) {
this.navList = [{
label: '分时'
}]
}
let timeout = +options.fromQuery ? 20 : (this.securityType == 'S0104' ? 20 : 0)
setTimeout(() => {
// 五档行情
signalrInvoke('Quotation2', 'Subscribe', {
QuotationType: 'FiveGearQuoteInfo',
SearchParamData: {
Symbols: `${this.code}.${this.maket}`
}
})
// 股债基指头部信息
signalrInvoke('Quotation', 'Subscribe', {
QuotationType: 'TickQuotationInfo',
SearchParamData: {
Symbols: `${this.code}.${this.maket}`
}
})
// 日周月K数
signalrInvoke('Quotation', 'Subscribe', {
QuotationType: this.navType[0],
SearchParamData: [{
Symbol: `${this.code}.${this.maket}`
}],
Limit: 1000,
tranparam: 10
})
// 指数的 成分股列表订阅
let urls = getQueryString(window.location.href);
if (urls.securityType == 'S0104') {
// 指数地域板块
signalrInvoke('Quotation', 'Subscribe', {
QuotationType: 'PlateIndexQuotationInfo',
SearchParamData: {
Symbols: `${this.code}.${this.maket}`
}
})
// 指数成分股
signalrInvoke('Quotation', 'Subscribe', {
QuotationType: "TickQuotationcs",
SearchParamData: {
PageIndex: 1,
PageSize: 10,
OrderBy: 'cr', // 根据所选的排序字段
Sortord: 1,
PlateId: this.plateId,
IndustryId: null,
SecurityId: 0,
},
tranparam: 0
})
}
}, timeout)
this.SubscribeOn()
this.allSelfSecurity()
},
onHide() {
this.unSubscribe() // 取消订阅
},
onShow() {
// 回显时候刷新自选
this.SubscribeOn()
this.allSelfSecurity()
// 五档行情
setTimeout(() => {
signalrInvoke('Quotation2', 'Subscribe', {
QuotationType: 'FiveGearQuoteInfo',
SearchParamData: {
Symbols: `${this.code}.${this.maket}`
}
})
// 股债基指头部信息
signalrInvoke('Quotation', 'Subscribe', {
QuotationType: 'TickQuotationInfo',
SearchParamData: {
Symbols: `${this.code}.${this.maket}`
}
})
// 指数的 成分股列表订阅
let urls = getQueryString(window.location.href);
if (urls.securityType == 'S0104') {
// 指数地域板块
signalrInvoke('Quotation', 'Subscribe', {
QuotationType: 'PlateIndexQuotationInfo',
SearchParamData: {
Symbols: `${this.code}.${this.maket}`
}
})
// 指数成分股
signalrInvoke('Quotation', 'Subscribe', {
QuotationType: "TickQuotationcs",
SearchParamData: {
PageIndex: 1,
PageSize: 10,
OrderBy: 'cr', // 根据所选的排序字段
Sortord: 1,
PlateId: this.plateId,
IndustryId: null,
SecurityId: 0,
},
tranparam: 0
})
}
}, 50)
setTimeout(() => {
uni.hideLoading();
}, 1000)
if(this.maket=='HKEX'){//默认的练习场没有港股通
this.tradePageTypeData = false
}
let matchInfo = sessionStorage.getItem("raceInfo") || {};
if(matchInfo&&matchInfo.hasOwnProperty("tradePageType")){
this.tradePageTypeData = matchInfo.tradePageType//当前大赛是否有港股通
}
}
}
</script>
<style lang="scss" scoped>
@import '@/static/css/mixin.scss';
@import '@/static/css/hq.scss';
page {
background-color: #f4f5f6;
.hq-detail-wrapper {
.foot-wrapper {
height: auto;
background-color: #F9F9FA;
border-top: 1px solid #EDEDED;
.xflex-j-a {
justify-content: space-around
}
.add {
font-weight: 500;
font-size: 24rpx;
padding: 24rpx 0;
.iconfont {
font-size: 30rpx;
}
.text-but {
color: #333333;
font-weight: 400;
font-family: Microsoft YaHei;
}
.text-but2 {
color: #E93A40;
font-weight: 400;
font-family: Microsoft YaHei;
}
}
}
.search_icon {
margin-right: 14rpx;
padding-bottom: 5rpx;
}
.ai {
flex: 1;
font-weight: 500;
font-size: 24rpx;
margin: 24rpx 0;
.iconfont {
font-size: 30rpx;
}
.text-but {
color: #333333;
font-weight: 400;
font-family: Microsoft YaHei;
}
}
.ai-border-left {
border-left: 1px solid #EDEDED;
}
.item-label {
white-space: nowrap;
}
}
.xflex {
// position: sticky;
top: 0;
}
.mask {
position: fixed;
z-index: 9999999999;
top: 0;
left: 50%;
transform: translateX(-50%);
bottom: 0;
height: 100vh;
width: 100vw;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
flex-wrap: wrap;
}
.mask.mask-show {
background: rgba(255, 255, 255, 0.8);
}
.title {
color: #666;
font-size: 28rpx;
margin-top: 20rpx;
}
.scroll-top {
width: 82rpx;
height: 82rpx;
border-radius: 50%;
opacity: 1;
transition: opacity .5s;
-webkit-transition: opacity .5s;
bottom: 60rpx;
}
.show-img {
opacity: 0;
}
}
</style>
chartMin组件代码:
<template>
<view class="min-wrapper xflex ">
<view class="chart-min xflex-1">
<view id="m-line" class="m-line" ref="mline"></view>
</view>
<view class="hq-wrapper" v-if="haswd">
<hq :code="code" :shortname="shortname" :maket="maket"></hq>
</view>
</view>
</template>
<script>
var bgColor = "#ffffff"; //背景
var upColor = "#E93A40"; //涨颜色
var downColor = "#57B967"; //跌颜色
import hq from './wdhq.vue';
import * as echarts from '@/common/echarts/echarts.min.js'
import { fetchEmptyQuoteList } from "@/api/hq.js" // 后端接口
import {
on
} from '../../../util/callback';
/**
* 计算价格涨跌幅百分比
* @param {Object} price 现价
* @param {Object} yclose 昨收价
*/
function ratioCalculate(price, yclose) {
return ((price - yclose) / yclose * 100).toFixed(2);
}
import dateFormat from '@/utils/dateFormat'
export default {
components: {
hq
},
props: ['mdata', 'code', 'shortname', 'maket', 'curIndex', 'haswd', 'isLeave'],
data() {
return {
preclose: 0,
mdata1: [],
leftMax: 0,
leftMin: 0,
rightMax: 0,
rightMin: 0,
mChart: null,
timeArr: [], // 根据品种取横轴坐标
isLeave1: this.isLeave
}
},
computed: {
digit() {
// && this.maket == 'SZSE'
let isSZSE = this.curIndex == 4
if (Number(this.curIndex) == 3 || isSZSE) {
return 3
} else {
return 2
}
},
divol() {
if (this.curIndex != 4) {
return 100
} else if (this.curIndex == 4 && this.maket == 'SZSE') {
return 10
} else {
return 1
}
}
},
watch: {
mdata: {
handler: function(newVal, oldVal) {
if (newVal) {
this.mdata1 = JSON.parse(JSON.stringify(newVal))
this.drawLine()
}
},
deep: true
}
},
methods: {
/**
* 15:20 时:分 格式时间增加num分钟
* @param {Object} time 起始时间
* @param {Object} num
*/
addTimeStr(time, num) {
var hour = time.split(':')[0];
var mins = Number(time.split(':')[1]);
var mins_un = parseInt((mins + num) / 60);
var hour_un = parseInt((Number(hour) + mins_un) / 24);
if (mins_un > 0) {
if (hour_un > 0) {
var tmpVal = ((Number(hour) + mins_un) % 24) + "";
hour = tmpVal.length > 1 ? tmpVal : '0' + tmpVal; //判断是否是一位
} else {
var tmpVal = Number(hour) + mins_un + "";
hour = tmpVal.length > 1 ? tmpVal : '0' + tmpVal;
}
var tmpMinsVal = ((mins + num) % 60) + "";
mins = tmpMinsVal.length > 1 ? tmpMinsVal : 0 + tmpMinsVal; //分钟数为 取余60的数
} else {
var tmpMinsVal = mins + num + "";
mins = tmpMinsVal.length > 1 ? tmpMinsVal : '0' + tmpMinsVal; //不大于整除60
}
return hour + ":" + mins;
},
//获取增加指定分钟数的 数组 如 09:30增加2分钟 结果为 ['09:31','09:32']
getNextTime(startTime, endTIme, offset, resultArr) {
var result = this.addTimeStr(startTime, offset);
resultArr.push(result);
if (result == endTIme) {
return resultArr;
} else {
return this.getNextTime(result, endTIme, offset, resultArr);
}
},
/**
* 不同类型的股票的交易时间会不同
* @param {Object} type hs=沪深 us=美股 hk=港股
*/
time_arr(type, time) {
return this.timeArr
},
// 重组分时数据
get_m_data(m_data, type) {
var priceArr = new Array();
var avgPrice = new Array();
var vol = new Array();
var pcArr = new Array()
var times = new Array();
var changeRatio = new Array()
if (m_data.data && m_data.data.length > 0) {
m_data.data.forEach((v) => {
priceArr.push(Number(v[1]));
avgPrice.push(Number(v[2]));
vol.push(Number(v[3]));
changeRatio.push(Number(v[5]))
pcArr.push(Number(v[9]))
if(v[7] != '00:00') {
times.push(v[7])
}
})
}
var _time = this.time_arr(type, m_data.data[m_data.data.length - 1][8]);
for (var t in _time) {
if (!times.includes(_time[t])) {
times.push(_time[t])
}
}
let obj = {
priceArr: priceArr,
avgPrice: avgPrice,
vol: vol,
times: times,
pcArr: pcArr,
changeRatio: changeRatio,
yestclose: Number(m_data.yestclose)
}
this.getMaxMin(obj)
return obj
},
getMaxMin(obj) {
var avgMax;
var avgMin;
var priceMax;
var priceMin = 0;
avgMax = this.getMax(obj.avgPrice);
avgMin = this.getMin(obj.avgPrice);
priceMax = this.getMax(obj.priceArr);
priceMin = this.getMin(obj.priceArr);
const middleLineVal = obj.yestclose;
if ((middleLineVal - priceMax) * -1 > (middleLineVal - priceMin)) {
priceMin = (middleLineVal - ((middleLineVal - priceMax) * -1));
} else {
priceMax = (middleLineVal + (middleLineVal - priceMin));
}
this.leftMax = avgMax > priceMax ? avgMax:priceMax
this.leftMin = avgMin > priceMin ? priceMin : avgMin
this.leftInterval = (this.leftMax - this.leftMin) / 2
this.rightMax = this.getMax(obj.changeRatio)
this.rightMin = this.getMin(obj.changeRatio)
const middleLineVal1 = 0;
const max1 = this.rightMax - middleLineVal1
const min1 = middleLineVal1 - this.rightMin
const absMax1 = Math.max(Math.abs(max1), Math.abs(min1));
if (absMax1 == 0) {
this.rightMax = middleLineVal1 * 1.05
this.rightMin = middleLineVal1 * 0.95
} else {
this.rightMax = middleLineVal1 + absMax1
this.rightMin = middleLineVal1 - absMax1
}
this.rightInterval = Number(
this.toDecimal(
(this.rightMax - this.rightMin) / 2,
3,
true
)
);
},
getMax(arr) {
const maxList = arr.filter((item) => item !== "-" && item != 0);
let Max = 0;
if (maxList.length > 0) {
const max0 = maxList[0];
Max = max0;
maxList.forEach((item) => {
if (Number(item) > Number(Max)) {
Max = Number(item);
}
});
}
return Number(Max);
},
getMin(arr) {
const minList = arr.filter((item) => item !== "-" && item != 0);
let Min = 0;
if (minList.length > 0) {
const min0 = minList[0];
Min = min0;
minList.forEach((item) => {
if (Number(item) < Number(Min)) {
Min = Number(item);
}
});
}
return Number(Min);
},
initData() {
this.mdata1 = JSON.parse(JSON.stringify(this.mdata))
},
async getTimeArr() {
let res = await fetchEmptyQuoteList({symbol: this.code, exchangeCode: this.maket})
let timeArr = res.data.map(item => {
return dateFormat(new Date(item), "hh:mm")
}) || []
return timeArr
},
/**
* 生成分时option
* @param {Object} m_data 分时数据
* @param {Object} type 股票类型 us-美股 hs-沪深 hk-港股
*/
initMOption(m_data, type) {
var m_datas = this.get_m_data(m_data, type);
var _this = this;
return {
tooltip: { //弹框指示器
position: [5, '10%'],
hideDelay: 10000,
formatter: function(params, ticket, callback) {
var i = params[0].dataIndex;
var cpriceColor;
var avgPriceColor;
var radioColor;
if (params[0].seriesType !== "line" || params[0].axisDim == "y") {
return ""
}
// 现价
if (m_datas.priceArr[i] > m_data.yestclose) {
cpriceColor = 'style="color:#ff4242"';
} else if(m_datas.priceArr[i] == m_data.yestclose) {
cpriceColor = 'style="color:#fff"';
} else {
cpriceColor = 'style="color:#26bf66"';
}
// 均价
if (m_datas.avgPrice[i] > m_data.yestclose) {
avgPriceColor = 'style="color:#ff4242"';
} else if(m_datas.avgPrice[i] == m_data.yestclose) {
avgPriceColor = 'style="color:#fff"';
} else {
avgPriceColor = 'style="color:#26bf66"';
}
// 涨幅
if (m_datas.changeRatio[i] > 0) {
radioColor = 'style="color:#ff4242"';
} else if(m_datas.changeRatio[i] == 0) {
radioColor = 'style="color:#fff"';
} else {
radioColor = 'style="color:#26bf66"';
}
var html = '<view>时间 <text> ' + params[0].axisValue + '</text></view><br/>' +
'<view class="commColor" style="width:100px;"><view>现价 <text ' + cpriceColor +' >' +
_this.toDecimal(m_datas.priceArr[i], _this.digit) + '</text></view><br/>';
html += '<view>均价 <text ' + avgPriceColor + ' >' + _this.toDecimal(m_datas.avgPrice[i], _this.digit) + '</text></view><br/>';
html += '<view>涨幅 <text ' + radioColor + ' >' + m_datas.changeRatio[i] + '%</text></view><br/>';
html += '<view>现手 <text style="color:#fff" >' + _this.formatNumUnit(m_datas.vol[i]) +
'</text></view></view>'
_this.isLeave1 = 0
_this.$emit('getTooltipData', [params[0].axisValue, _this.toDecimal(m_datas.priceArr[i], _this.digit), m_datas.changeRatio[i], m_datas.pcArr[i], _this.isLeave1])
return html;
}
},
color: ['#2f569e', '#F39142'],
legend: { //图例控件,点击图例控制哪些系列不显示
icon: 'rect',
type: 'scroll',
itemWidth: 14,
itemHeight: 2,
left: 0,
top: '-1%',
data: ['现价', '均价', '现手'],
textStyle: {
fontSize: 12,
color: '#999999'
}
},
axisPointer: {
show: true,
link: {
xAxisIndex: [0, 2]
}
},
grid: [{
id: 'gd1',
left: '4%',
right: '4%',
height: '62.5%', //主K线的高度,
top: '7%'
},
{
id: 'gd2',
left: '4%',
right: '4%',
height: '62.5%', //主K线的高度,
top: '7%'
}, {
id: 'gd3',
left: '4%',
right: '4%',
top: '75%',
height: '19%' //交易量图的高度
}
],
xAxis: [ //==== x轴
{ //主图
gridIndex: 0,
data: m_datas.times,
show: false,
splitLine: {
show: false,
},
axisLine: {
lineStyle: {
color: 'red',
width: 1, //这里是为了突出显示加上的
}
},
axisPointer: {
label: {
show: false
}
}
},
{
show: false,
gridIndex: 1,
data: m_datas.times,
splitLine: {
show: false,
},
axisTick: {
show: false
},
axisPointer: {
label: {
show: false
}
}
}, { //交易量图
// splitNumber: 2,
type: 'category',
gridIndex: 2,
data: m_datas.times,
axisLabel: { //label文字设置
color: '#9b9da9',
fontSize: 8,
interval: 59,
textAlign: 'center'
}
}
],
yAxis: [ //y轴
{
gridIndex: 0,
scale: true,
splitNumber: 3,
axisLabel: { //label文字设置
inside: true, //label文字朝内对齐
// fontWeight:'bold',
fontSize: 10,
color: function(val) {
if (val == m_data.yestclose) {
return '#aaa'
}
return val > m_data.yestclose ? upColor : downColor;
},
formatter: function(val) {
return _this.toDecimal(val, _this.digit)
}
},
z: 4,
splitLine: { //分割线设置
show: false,
lineStyle: {
color: '#181a23' // #E5E5E5
}
},
axisLine: {
lineStyle: {
color: 'transparent',
width: 0, //这里是为了突出显示加上的
}
},
axisPointer: {
show: true,
label: {
show: false
}
},
min: _this.leftMin,
max: _this.leftMax,
interval: _this.leftInterval,
}, {
scale: true,
gridIndex: 1,
splitNumber: 3,
position: 'right',
z: 4,
axisLabel: { //label文字设置
interval: true,
color: function(val) {
if (val == 0) {
return '#aaa'
}
return val > 0 ? upColor : downColor;
},
inside: true, //label文字朝内对齐
fontSize: 10,
formatter: function(val) {
return _this.toDecimal(val, 2, true) + '%'
},
},
splitLine: { //分割线设置
show: false,
lineStyle: {
color: '#181a23'
}
},
axisPointer: {
show: true,
label: {
show: false
}
},
axisLine: {
lineStyle: {
color: 'transparent',
width: 0, //这里是为了突出显示加上的
}
},
min: _this.rightMin,
max: _this.rightMax,
interval: _this.rightInterval
}, { //交易图
gridIndex: 2,
z: 4,
splitNumber: 3,
axisLine: {
onZero: false
},
axisTick: {
show: false
},
splitLine: {
show: false
},
axisLabel: { //label文字设置
color: '#c7c7c7',
inside: true, //label文字朝内对齐
fontSize: 8,
formatter: function(value) {
return _this.formatNumUnit(value);
},
},
}
],
dataZoom: [
],
animation:false,//禁止动画效果
backgroundColor: bgColor,
blendMode: 'source-over',
series: [{
name: '现价',
type: 'line',
data: m_datas.priceArr,
smooth: true,
symbol: "none", //中时有小圆点
lineStyle: {
normal: {
opacity: 0.8,
color: '#2f569e',
width: 1
}
},
areaStyle: {
normal: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
offset: 0,
color: 'rgba(246, 246, 255, 1)'
}, {
offset: 0.8,
color: 'rgba(246, 246, 255, 0.5)'
}], false),
shadowColor: 'rgba(0, 0, 0, 0.1)',
shadowBlur: 10
}
},
markLine: {
silent: true,
symbol: ["none", "none"],
label: {
normal: {
show: false,
color: '#fff'
}
},
lineStyle: {
color: "#2f569e",
opacity: 0.5,
type: "dot",
},
data: [{
name: "Y 轴值为 yAxis 的水平线",
yAxis: _this.toDecimal(m_datas.yestclose, _this.digit),
}, ],
},
},
{
name: '均价',
type: 'line',
data: m_datas.avgPrice,
smooth: true,
symbol: "none",
lineStyle: { //标线的样式
normal: {
opacity: 0.8,
color: '#F39142',
width: 1
}
}
},
{
type: 'line',
data: m_datas.priceArr,
smooth: true,
symbol: "none",
gridIndex: 1,
xAxisIndex: 1,
yAxisIndex: 1,
lineStyle: { //标线的样式
normal: {
width: 0
}
}
},
{
name: '现手',
type: 'bar',
gridIndex: 2,
xAxisIndex: 2,
yAxisIndex: 2,
data: m_datas.vol,
barWidth: '60%',
itemStyle: {
normal: {
color: function(params) {
let colorList = ''
if (params.dataIndex == 0) {
if (m_datas.priceArr[0] >= m_datas.yestclose) {
colorList = upColor
} else {
colorList = downColor
}
} else {
if (m_datas.priceArr[params.dataIndex] >= m_datas.priceArr[params.dataIndex - 1]) {
colorList = upColor;
} else {
colorList = downColor;
}
}
return colorList
},
}
}
}
]
};
},
aboutMaxAbs(arr,closeVal,digit) {
let absArr = []
arr.forEach(el => {
absArr.push(Math.abs(el - closeVal))
})
let max = Math.max(...absArr)
let maxVal = max + closeVal;
let minVal = closeVal -max;
return [maxVal.toFixed(digit),minVal.toFixed(digit)];
},
drawLine() {
if (this.mChart != null && this.mChart != "" && this.mChart != undefined) {
this.mChart.dispose();
}
let chartDom = document.getElementById('m-line')
if (chartDom) {
this.mChart = echarts.init(chartDom);
let options = {}
if (this.mdata1.data && this.mdata1.data.length > 0) {
options = this.initMOption(this.mdata1, 'hs')
}
if (this.mChart) {
this.mChart.setOption(options);
}
}
}
},
async created() {
on('getPp', (r) => {
this.preclose = r
})
this.timeArr = await this.getTimeArr()
this.initData()
},
mounted() {
this.leftMax = 0;
this.leftMin = 0;
setTimeout(() => {
this.drawLine()
}, 1000)
},
beforeDestroy() {
let chartDom = document.getElementById('m-line')
if (this.mChart != null && this.mChart != "" && this.mChart != undefined) {
this.mChart.dispose();
}
}
}
</script>
<style lang="scss" scoped>
.xflex {
-webkit-display: flex;
-khtml-display: flex;
-moz-display: flex;
-ms-display: flex;
display: flex;
}
.xflex-1 {
-webkit-flex: 1;
-khtml-flex: 1;
-moz-flex: 1;
-ms-flex: 1;
flex: 1;
}
.border1 {
border: 1px solid red;
}
.xflex-a-c {
-webkit-align-items: center;
-khtml-align-items: center;
-moz-align-items: center;
-ms-align-items: center;
align-items: center;
}
.xflex-j-s {
-webkit-justify-content: space-between;
-khtml-justify-content: space-between;
-moz-justify-content: space-between;
-ms-justify-content: space-between;
justify-content: space-between;
}
.xflex-j-c {
-webkit-justify-content: center;
-khtml-justify-content: center;
-moz-justify-content: center;
-ms-justify-content: center;
justify-content: center;
}
.xflex-col {
-webkit-flex-direction: column;
-khtml-flex-direction: column;
-moz-flex-direction: column;
-ms-flex-direction: column;
flex-direction: column;
}
.t-a-c {
text-align: center;
}
.color-up {
color: #CC0000;
}
.color-down {
color: #20B120;
}
.min-wrapper {
height: 100%;
.hq-wrapper {
width: 250rpx;
}
.chart-min {
margin-top: 12rpx;
.m-line {
// border: 1px solid blue;
height: 100%;
width: 100%;
}
}
}
</style>
wdhq五档行情组件代码:
<template>
<view class="min-wrapper xflex ">
<view class="chart-min xflex-1">
<view id="m-line" class="m-line" ref="mline"></view>
</view>
<view class="hq-wrapper" v-if="haswd">
<hq :code="code" :shortname="shortname" :maket="maket"></hq>
</view>
</view>
</template>
<script>
var bgColor = "#ffffff"; //背景
var upColor = "#E93A40"; //涨颜色
var downColor = "#57B967"; //跌颜色
import hq from './wdhq.vue';
import * as echarts from '@/common/echarts/echarts.min.js'
import { fetchEmptyQuoteList } from "@/api/hq.js" // 后端接口
import {
on
} from '../../../util/callback';
/**
* 计算价格涨跌幅百分比
* @param {Object} price 现价
* @param {Object} yclose 昨收价
*/
function ratioCalculate(price, yclose) {
return ((price - yclose) / yclose * 100).toFixed(2);
}
import dateFormat from '@/utils/dateFormat'
export default {
components: {
hq
},
props: ['mdata', 'code', 'shortname', 'maket', 'curIndex', 'haswd', 'isLeave'],
data() {
return {
preclose: 0,
mdata1: [],
leftMax: 0,
leftMin: 0,
rightMax: 0,
rightMin: 0,
mChart: null,
timeArr: [], // 根据品种取横轴坐标
isLeave1: this.isLeave
}
},
computed: {
digit() {
// && this.maket == 'SZSE'
let isSZSE = this.curIndex == 4
if (Number(this.curIndex) == 3 || isSZSE) {
return 3
} else {
return 2
}
},
divol() {
if (this.curIndex != 4) {
return 100
} else if (this.curIndex == 4 && this.maket == 'SZSE') {
return 10
} else {
return 1
}
}
},
watch: {
mdata: {
handler: function(newVal, oldVal) {
if (newVal) {
this.mdata1 = JSON.parse(JSON.stringify(newVal))
this.drawLine()
}
},
deep: true
}
},
methods: {
/**
* 15:20 时:分 格式时间增加num分钟
* @param {Object} time 起始时间
* @param {Object} num
*/
addTimeStr(time, num) {
var hour = time.split(':')[0];
var mins = Number(time.split(':')[1]);
var mins_un = parseInt((mins + num) / 60);
var hour_un = parseInt((Number(hour) + mins_un) / 24);
if (mins_un > 0) {
if (hour_un > 0) {
var tmpVal = ((Number(hour) + mins_un) % 24) + "";
hour = tmpVal.length > 1 ? tmpVal : '0' + tmpVal; //判断是否是一位
} else {
var tmpVal = Number(hour) + mins_un + "";
hour = tmpVal.length > 1 ? tmpVal : '0' + tmpVal;
}
var tmpMinsVal = ((mins + num) % 60) + "";
mins = tmpMinsVal.length > 1 ? tmpMinsVal : 0 + tmpMinsVal; //分钟数为 取余60的数
} else {
var tmpMinsVal = mins + num + "";
mins = tmpMinsVal.length > 1 ? tmpMinsVal : '0' + tmpMinsVal; //不大于整除60
}
return hour + ":" + mins;
},
//获取增加指定分钟数的 数组 如 09:30增加2分钟 结果为 ['09:31','09:32']
getNextTime(startTime, endTIme, offset, resultArr) {
var result = this.addTimeStr(startTime, offset);
resultArr.push(result);
if (result == endTIme) {
return resultArr;
} else {
return this.getNextTime(result, endTIme, offset, resultArr);
}
},
/**
* 不同类型的股票的交易时间会不同
* @param {Object} type hs=沪深 us=美股 hk=港股
*/
time_arr(type, time) {
return this.timeArr
},
// 重组分时数据
get_m_data(m_data, type) {
var priceArr = new Array();
var avgPrice = new Array();
var vol = new Array();
var pcArr = new Array()
var times = new Array();
var changeRatio = new Array()
if (m_data.data && m_data.data.length > 0) {
m_data.data.forEach((v) => {
priceArr.push(Number(v[1]));
avgPrice.push(Number(v[2]));
vol.push(Number(v[3]));
changeRatio.push(Number(v[5]))
pcArr.push(Number(v[9]))
if(v[7] != '00:00') {
times.push(v[7])
}
})
}
var _time = this.time_arr(type, m_data.data[m_data.data.length - 1][8]);
for (var t in _time) {
if (!times.includes(_time[t])) {
times.push(_time[t])
}
}
let obj = {
priceArr: priceArr,
avgPrice: avgPrice,
vol: vol,
times: times,
pcArr: pcArr,
changeRatio: changeRatio,
yestclose: Number(m_data.yestclose)
}
this.getMaxMin(obj)
return obj
},
getMaxMin(obj) {
var avgMax;
var avgMin;
var priceMax;
var priceMin = 0;
avgMax = this.getMax(obj.avgPrice);
avgMin = this.getMin(obj.avgPrice);
priceMax = this.getMax(obj.priceArr);
priceMin = this.getMin(obj.priceArr);
const middleLineVal = obj.yestclose;
if ((middleLineVal - priceMax) * -1 > (middleLineVal - priceMin)) {
priceMin = (middleLineVal - ((middleLineVal - priceMax) * -1));
} else {
priceMax = (middleLineVal + (middleLineVal - priceMin));
}
this.leftMax = avgMax > priceMax ? avgMax:priceMax
this.leftMin = avgMin > priceMin ? priceMin : avgMin
this.leftInterval = (this.leftMax - this.leftMin) / 2
this.rightMax = this.getMax(obj.changeRatio)
this.rightMin = this.getMin(obj.changeRatio)
const middleLineVal1 = 0;
const max1 = this.rightMax - middleLineVal1
const min1 = middleLineVal1 - this.rightMin
const absMax1 = Math.max(Math.abs(max1), Math.abs(min1));
if (absMax1 == 0) {
this.rightMax = middleLineVal1 * 1.05
this.rightMin = middleLineVal1 * 0.95
} else {
this.rightMax = middleLineVal1 + absMax1
this.rightMin = middleLineVal1 - absMax1
}
this.rightInterval = Number(
this.toDecimal(
(this.rightMax - this.rightMin) / 2,
3,
true
)
);
},
getMax(arr) {
const maxList = arr.filter((item) => item !== "-" && item != 0);
let Max = 0;
if (maxList.length > 0) {
const max0 = maxList[0];
Max = max0;
maxList.forEach((item) => {
if (Number(item) > Number(Max)) {
Max = Number(item);
}
});
}
return Number(Max);
},
getMin(arr) {
const minList = arr.filter((item) => item !== "-" && item != 0);
let Min = 0;
if (minList.length > 0) {
const min0 = minList[0];
Min = min0;
minList.forEach((item) => {
if (Number(item) < Number(Min)) {
Min = Number(item);
}
});
}
return Number(Min);
},
initData() {
this.mdata1 = JSON.parse(JSON.stringify(this.mdata))
},
async getTimeArr() {
let res = await fetchEmptyQuoteList({symbol: this.code, exchangeCode: this.maket})
let timeArr = res.data.map(item => {
return dateFormat(new Date(item), "hh:mm")
}) || []
return timeArr
},
/**
* 生成分时option
* @param {Object} m_data 分时数据
* @param {Object} type 股票类型 us-美股 hs-沪深 hk-港股
*/
initMOption(m_data, type) {
var m_datas = this.get_m_data(m_data, type);
var _this = this;
return {
tooltip: { //弹框指示器
position: [5, '10%'],
hideDelay: 10000,
formatter: function(params, ticket, callback) {
var i = params[0].dataIndex;
var cpriceColor;
var avgPriceColor;
var radioColor;
if (params[0].seriesType !== "line" || params[0].axisDim == "y") {
return ""
}
// 现价
if (m_datas.priceArr[i] > m_data.yestclose) {
cpriceColor = 'style="color:#ff4242"';
} else if(m_datas.priceArr[i] == m_data.yestclose) {
cpriceColor = 'style="color:#fff"';
} else {
cpriceColor = 'style="color:#26bf66"';
}
// 均价
if (m_datas.avgPrice[i] > m_data.yestclose) {
avgPriceColor = 'style="color:#ff4242"';
} else if(m_datas.avgPrice[i] == m_data.yestclose) {
avgPriceColor = 'style="color:#fff"';
} else {
avgPriceColor = 'style="color:#26bf66"';
}
// 涨幅
if (m_datas.changeRatio[i] > 0) {
radioColor = 'style="color:#ff4242"';
} else if(m_datas.changeRatio[i] == 0) {
radioColor = 'style="color:#fff"';
} else {
radioColor = 'style="color:#26bf66"';
}
var html = '<view>时间 <text> ' + params[0].axisValue + '</text></view><br/>' +
'<view class="commColor" style="width:100px;"><view>现价 <text ' + cpriceColor +' >' +
_this.toDecimal(m_datas.priceArr[i], _this.digit) + '</text></view><br/>';
html += '<view>均价 <text ' + avgPriceColor + ' >' + _this.toDecimal(m_datas.avgPrice[i], _this.digit) + '</text></view><br/>';
html += '<view>涨幅 <text ' + radioColor + ' >' + m_datas.changeRatio[i] + '%</text></view><br/>';
html += '<view>现手 <text style="color:#fff" >' + _this.formatNumUnit(m_datas.vol[i]) +
'</text></view></view>'
_this.isLeave1 = 0
_this.$emit('getTooltipData', [params[0].axisValue, _this.toDecimal(m_datas.priceArr[i], _this.digit), m_datas.changeRatio[i], m_datas.pcArr[i], _this.isLeave1])
return html;
}
},
color: ['#2f569e', '#F39142'],
legend: { //图例控件,点击图例控制哪些系列不显示
icon: 'rect',
type: 'scroll',
itemWidth: 14,
itemHeight: 2,
left: 0,
top: '-1%',
data: ['现价', '均价', '现手'],
textStyle: {
fontSize: 12,
color: '#999999'
}
},
axisPointer: {
show: true,
link: {
xAxisIndex: [0, 2]
}
},
grid: [{
id: 'gd1',
left: '4%',
right: '4%',
height: '62.5%', //主K线的高度,
top: '7%'
},
{
id: 'gd2',
left: '4%',
right: '4%',
height: '62.5%', //主K线的高度,
top: '7%'
}, {
id: 'gd3',
left: '4%',
right: '4%',
top: '75%',
height: '19%' //交易量图的高度
}
],
xAxis: [ //==== x轴
{ //主图
gridIndex: 0,
data: m_datas.times,
show: false,
splitLine: {
show: false,
},
axisLine: {
lineStyle: {
color: 'red',
width: 1, //这里是为了突出显示加上的
}
},
axisPointer: {
label: {
show: false
}
}
},
{
show: false,
gridIndex: 1,
data: m_datas.times,
splitLine: {
show: false,
},
axisTick: {
show: false
},
axisPointer: {
label: {
show: false
}
}
}, { //交易量图
// splitNumber: 2,
type: 'category',
gridIndex: 2,
data: m_datas.times,
axisLabel: { //label文字设置
color: '#9b9da9',
fontSize: 8,
interval: 59,
textAlign: 'center'
}
}
],
yAxis: [ //y轴
{
gridIndex: 0,
scale: true,
splitNumber: 3,
axisLabel: { //label文字设置
inside: true, //label文字朝内对齐
// fontWeight:'bold',
fontSize: 10,
color: function(val) {
if (val == m_data.yestclose) {
return '#aaa'
}
return val > m_data.yestclose ? upColor : downColor;
},
formatter: function(val) {
return _this.toDecimal(val, _this.digit)
}
},
z: 4,
splitLine: { //分割线设置
show: false,
lineStyle: {
color: '#181a23' // #E5E5E5
}
},
axisLine: {
lineStyle: {
color: 'transparent',
width: 0, //这里是为了突出显示加上的
}
},
axisPointer: {
show: true,
label: {
show: false
}
},
min: _this.leftMin,
max: _this.leftMax,
interval: _this.leftInterval,
}, {
scale: true,
gridIndex: 1,
splitNumber: 3,
position: 'right',
z: 4,
axisLabel: { //label文字设置
interval: true,
color: function(val) {
if (val == 0) {
return '#aaa'
}
return val > 0 ? upColor : downColor;
},
inside: true, //label文字朝内对齐
fontSize: 10,
formatter: function(val) {
return _this.toDecimal(val, 2, true) + '%'
},
},
splitLine: { //分割线设置
show: false,
lineStyle: {
color: '#181a23'
}
},
axisPointer: {
show: true,
label: {
show: false
}
},
axisLine: {
lineStyle: {
color: 'transparent',
width: 0, //这里是为了突出显示加上的
}
},
min: _this.rightMin,
max: _this.rightMax,
interval: _this.rightInterval
}, { //交易图
gridIndex: 2,
z: 4,
splitNumber: 3,
axisLine: {
onZero: false
},
axisTick: {
show: false
},
splitLine: {
show: false
},
axisLabel: { //label文字设置
color: '#c7c7c7',
inside: true, //label文字朝内对齐
fontSize: 8,
formatter: function(value) {
return _this.formatNumUnit(value);
},
},
}
],
dataZoom: [
],
animation:false,//禁止动画效果
backgroundColor: bgColor,
blendMode: 'source-over',
series: [{
name: '现价',
type: 'line',
data: m_datas.priceArr,
smooth: true,
symbol: "none", //中时有小圆点
lineStyle: {
normal: {
opacity: 0.8,
color: '#2f569e',
width: 1
}
},
areaStyle: {
normal: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
offset: 0,
color: 'rgba(246, 246, 255, 1)'
}, {
offset: 0.8,
color: 'rgba(246, 246, 255, 0.5)'
}], false),
shadowColor: 'rgba(0, 0, 0, 0.1)',
shadowBlur: 10
}
},
markLine: {
silent: true,
symbol: ["none", "none"],
label: {
normal: {
show: false,
color: '#fff'
}
},
lineStyle: {
color: "#2f569e",
opacity: 0.5,
type: "dot",
},
data: [{
name: "Y 轴值为 yAxis 的水平线",
yAxis: _this.toDecimal(m_datas.yestclose, _this.digit),
}, ],
},
},
{
name: '均价',
type: 'line',
data: m_datas.avgPrice,
smooth: true,
symbol: "none",
lineStyle: { //标线的样式
normal: {
opacity: 0.8,
color: '#F39142',
width: 1
}
}
},
{
type: 'line',
data: m_datas.priceArr,
smooth: true,
symbol: "none",
gridIndex: 1,
xAxisIndex: 1,
yAxisIndex: 1,
lineStyle: { //标线的样式
normal: {
width: 0
}
}
},
{
name: '现手',
type: 'bar',
gridIndex: 2,
xAxisIndex: 2,
yAxisIndex: 2,
data: m_datas.vol,
barWidth: '60%',
itemStyle: {
normal: {
color: function(params) {
let colorList = ''
if (params.dataIndex == 0) {
if (m_datas.priceArr[0] >= m_datas.yestclose) {
colorList = upColor
} else {
colorList = downColor
}
} else {
if (m_datas.priceArr[params.dataIndex] >= m_datas.priceArr[params.dataIndex - 1]) {
colorList = upColor;
} else {
colorList = downColor;
}
}
return colorList
},
}
}
}
]
};
},
aboutMaxAbs(arr,closeVal,digit) {
let absArr = []
arr.forEach(el => {
absArr.push(Math.abs(el - closeVal))
})
let max = Math.max(...absArr)
let maxVal = max + closeVal;
let minVal = closeVal -max;
return [maxVal.toFixed(digit),minVal.toFixed(digit)];
},
drawLine() {
if (this.mChart != null && this.mChart != "" && this.mChart != undefined) {
this.mChart.dispose();
}
let chartDom = document.getElementById('m-line')
if (chartDom) {
this.mChart = echarts.init(chartDom);
let options = {}
if (this.mdata1.data && this.mdata1.data.length > 0) {
options = this.initMOption(this.mdata1, 'hs')
}
if (this.mChart) {
this.mChart.setOption(options);
}
}
}
},
async created() {
on('getPp', (r) => {
this.preclose = r
})
this.timeArr = await this.getTimeArr()
this.initData()
},
mounted() {
this.leftMax = 0;
this.leftMin = 0;
setTimeout(() => {
this.drawLine()
}, 1000)
},
beforeDestroy() {
let chartDom = document.getElementById('m-line')
if (this.mChart != null && this.mChart != "" && this.mChart != undefined) {
this.mChart.dispose();
}
}
}
</script>
<style lang="scss" scoped>
.xflex {
-webkit-display: flex;
-khtml-display: flex;
-moz-display: flex;
-ms-display: flex;
display: flex;
}
.xflex-1 {
-webkit-flex: 1;
-khtml-flex: 1;
-moz-flex: 1;
-ms-flex: 1;
flex: 1;
}
.border1 {
border: 1px solid red;
}
.xflex-a-c {
-webkit-align-items: center;
-khtml-align-items: center;
-moz-align-items: center;
-ms-align-items: center;
align-items: center;
}
.xflex-j-s {
-webkit-justify-content: space-between;
-khtml-justify-content: space-between;
-moz-justify-content: space-between;
-ms-justify-content: space-between;
justify-content: space-between;
}
.xflex-j-c {
-webkit-justify-content: center;
-khtml-justify-content: center;
-moz-justify-content: center;
-ms-justify-content: center;
justify-content: center;
}
.xflex-col {
-webkit-flex-direction: column;
-khtml-flex-direction: column;
-moz-flex-direction: column;
-ms-flex-direction: column;
flex-direction: column;
}
.t-a-c {
text-align: center;
}
.color-up {
color: #CC0000;
}
.color-down {
color: #20B120;
}
.min-wrapper {
height: 100%;
.hq-wrapper {
width: 250rpx;
}
.chart-min {
margin-top: 12rpx;
.m-line {
// border: 1px solid blue;
height: 100%;
width: 100%;
}
}
}
</style>
u.js文件方法:
// 链接参数获取
export function getQueryString(url="") {
let ItemArr = [];
let ItemObj = {};
url
.substring(url.lastIndexOf("?") + 1, url.length)
.split("&")
.map((item) => {
ItemArr.push(item.split("="));
});
ItemArr.map((item) => {
ItemObj[item[0]] = item[1];
});
return ItemObj;
}
/**
* 设置跌涨颜色
* val1: 对比的值 如:preClosePrice昨收价
* val2: 当前显示的值
* */
export function turnColor(val1, val2) {
var num1 = isNaN(Number(val1)) ? 0 : Number(val1)
var num2 = isNaN(Number(val2)) ? 0 : Number(val2)
// 判断是否是-0
if (num1 == 0 && num2 == 0 && (1 / num2 < 0)) {
return '#57B967'
}
if (num1 == 0 && num2 == 0) {
return '#BEC0C7'
}
if (num1 > num2) {
return '#57B967'
} else if (num1 < num2) {
return '#E93A40'
} else {
return '#BEC0C7'
}
}
callback.js文件方法:
var _callbacks = {}
export function on(eventName, callback) {
if (!_callbacks[eventName]) {
_callbacks[eventName] = []
}
_callbacks[eventName].push(callback)
}
export function off(eventName, callback) {
var callbacks = _callbacks[eventName]
if (!callbacks) {
return
}
var index = -1
for (var i = 0; i < callbacks.length; i++) {
if (callbacks[i] === callback) {
index = i
break
}
}
if (index < 0) {
return
}
_callbacks[eventName].splice(index, 1)
}
export function trigger(eventName) {
var callbacks = _callbacks[eventName]
if (!callbacks || !callbacks.length) {
return
}
var args = Array.prototype.slice.call(arguments, 1)
for (var i = 0; i < callbacks.length; i++) {
callbacks[i].apply(this, args)
}
}
var duestate = {}
export function lock(lockname,func){
if(!duestate[lockname]){
duestate[lockname] = true
on("State",()=>{
duestate[lockname] = false
})
return func
}
}
dateFormat文件方法:
/**
* [dateFormat 时间格式化]
* @param {[Number,String]} [timestamp=Date.now()] [需转化的时间戳或一个能格式化的时间字符串]
* @param {[String]} [format='yyyy-M-d'] [需转化的时间格式]
* yyyy年,月(M)、日(d)、小时(h)、分(m)、秒(s)、季度(q),两个字符表示按2位字符输入
* 举例:
* dateFormat(Date.now(), "yyyy-MM-dd hh:mm:ss") ==> 2017-04-25 16:06:06
* dateFormat(Date.now(), "yyyy-M-d h:m:s q") ==> 2017-4-25 16:6:6 2
* @return {[String]} [格式化时间字符串]
*/
export default function dateFormat(timestamp = Date.now(), format = 'yyyy-M-d') {
return getFormatDate(getJsonDate(timestamp), format)
}
// 生成时间对象
export function getJsonDate(timestamp) {
let time = new Date(getCorrectTime(timestamp))
let jsonDate = {
y: time.getFullYear(), //年
M: time.getMonth() + 1, //月
d: time.getDate(), //日
h: time.getHours(), //时
m: time.getMinutes(), //分
s: time.getSeconds(), //秒
q: Math.floor((time.getMonth() + 3) / 3) //季度
}
return jsonDate
}
// 生成格式化时间字符串
export function getFormatDate(jsonDate, format) {
let dateStr = format.replace(/yyyy/g, jsonDate.y)
Object.keys(jsonDate).forEach(e => {
// 时间格式化操作
let double = e.repeat(2)
let num = jsonDate[e]
if (format.includes(double)) {
// 如果需要两位的格式化数据,则转换为两位数
dateStr = dateStr.replace(double, getTwoDigit(num))
} else {
dateStr = dateStr.replace(e, num)
}
})
return dateStr
}
// 数字如果为一位数,前面加0
function getTwoDigit(num) {
return Number(num) < 10
? `0${num}`
: num
}
// 对于传入时间数据的转换
function getCorrectTime(timestamp) {
if (isNaN(timestamp)) {
// ios日期格式兼容处理
timestamp = timestamp.toString().includes('-')
? (timestamp.replace(/-/g, '/')).slice(0,19)
: timestamp
} else {
timestamp = Number(timestamp)
}
return timestamp
}
页面公共文件方法:
// 大数字单位处理(num为比较值 小于num数据不进行处理)
formatNumUnit(value, fixedLen = 2, num = 10000) {
if (value == "--") {
return value;
}
if (value == null) {
return '--'
}
var result = {};
var k = 10000;
var sizes = ["", "万", "亿", "万亿"];
var i;
if (value < num) {
result.value = value;
result.unit = "";
} else {
i = Math.floor(Math.log(value) / Math.log(k));
result.value = this.round(value / Math.pow(k, i), fixedLen);
result.unit = sizes[i];
}
return result.value + result.unit;
},
/**
* 转化数字为几位小数,四舍五入或者截取多于位数
* num [需转化的数字]
* @param {Number} [digit=2] [需保留或截取的位数]
* @param {Boolean} [isRround=true] [true四舍五入,false截取多于小数]
* */
toDecimal(num, n, b) {
if (num === null || num === undefined || isNaN(num) || num === '') {
return "--";
} else if (num == 0) {
return parseFloat(num).toFixed(n);
}
return toDecimal1(num, n, b);
},
/**
* [toDecimal 转化数字为几位小数,四舍五入或者截取多于位数]
* @param {[Number]} num [需转化的数字]
* @param {Number} [digit=2] [需保留或截取的位数]
* @param {Boolean} [isRround=true] [true四舍五入,false截取多于小数]
* @return {[Number, String]} [转换后的结果]
*/
toDecimal1(num, digit = 2, isRround = true) {
if (num === null || num === undefined) {
return ''
}
// 负数处理四舍五入,先转成正数
let sign = ''
if (num < 0) {
sign = '-'
}
num = Math.abs(num).toString()
// 出现了科学计数法
if (num.indexOf('e-') != -1) {
num = noKeXueJiShuFa(num)
}
const numArr = num.split('.')
if (numArr.length > 1) {
// 有小数时的处理
if (numArr[1].length <= digit) {
// 小数位数少于需保留位数的时候
return sign + Number(num).toFixed(digit)
} else {
// 小数位数多于需保留位数的时候
if (isRround) {
// 四舍五入处理
num = numArr[1][digit] >= 5 ? parseInt(noKeXueJiShuFa(num * Math.pow(10, digit))) + 1 : parseInt(noKeXueJiShuFa(num * Math.pow(10, digit)))
return sign + (num / Math.pow(10, digit)).toFixed(digit)
} else {
// 去除多于小数
return sign + `${numArr[0]}.${numArr[1].substring(0, digit)}`
}
}
} else {
// 无小数时的处理
return sign + Number(num).toFixed(digit)
}
}
noKeXueJiShuFa(num) {
if (String(num).indexOf('e-') != -1) {
num = '0' + String(Number(num) + 1).substr(1)
}
return num
}