// 图表库实例化后储存的函数 // console.log("加载kline") var widget = null // 进入页面 默认展示的产品 var index_market = 'btcusdt' // 进入页面 默认展示的产品周期 var index_activeCycle = 1 // 价格精度 默认4位小数 var pricescale = 4 var bb_type = 1 var lastminClose = 0 // window.TradingView.onready 确保在html的dom加载完成后在调用 window.TradingView.onready(function() { // chartConfig 在chartConfig.js里面 // 给chartConfig添加展示周期 chartConfig.interval = index_activeCycle // 给chartConfig添加展示产品 chartConfig.symbol = index_market // 禁用加载的动画,直接显示 chartConfig.loading_screen = { backgroundColor: "#080A17", foregroundColor: "#080A17", disableAnimation: true }; // 初始化 TradingView widget = new window.TradingView.widget(chartConfig) widget && widget.onChartReady && widget.onChartReady(function() { // 强制设置图表类型为K线图 widget.chart().setChartType(1) // 这是k线图 展示的 7日均线和30日均线。 widget.chart().createStudy('Moving Average', false, false, [7], null, { 'Plot.linewidth': 2, 'Plot.color': '#2ba7d6' }) widget.chart().createStudy('Moving Average', false, false, [30], null, { 'Plot.linewidth': 2, 'Plot.color': '#de9f66' }) // 立即获取K线数据 if (bb_type == 2) { app.getHistory() } else { app.getLast() app.getDay() } }) }) let baseUrl = 'https://jyshd.pp1008.top/'; // 请求封装 function http2(url, data, method) { return new Promise((resolve, reject) => { axios({ headers: { "Content-Type": "application/x-www-form-urlencoded" }, method: method, url: baseUrl + url, data: Qs.stringify(data) }) .then(res => { if (res.status == 200) { resolve(res.data) } else { reject() } }) .catch(err => { alertError('请求超时') }) }) } // 弹窗 function alertError(title) { try { plus.nativeUI.toast(title, { style: 'inline', verticalAlign: 'top' }); } catch (e) {} } var app = new Vue({ el: '#app', data: { symbol: "", newData: { close: 0 }, title: "", tab: 1, newDay: { high: 0, low: 0 }, depth: "", coinInfo: "", period: "1min", lost: "", width: "", id: "", zhezhaoceng: 1, changeflag: true, once: true }, created() { }, mounted() { this.getLanguage() this.getCionInfo() Event.on('changeflag', data => { // console.log('分钟线数据',data) this.changeflag = data }) Event.on('zhezhaoceng', data => { // console.log('分钟线数据',data) this.zhezhaoceng = data }) // 拿到实时数据 在这里画 Event.on('newData', data => { // console.log('分钟线数据',data) this.newData = data }) Event.on('newDay', data => { // console.log('一天的数据',data) this.newDay = data }) Event.on('depth', data => { // console.log('深度',data) this.depth = data }) Event.on('reconnect', data => { // console.log('reconnect',data) console.log(data) // 如果socket断了重连 需要重新请求aptusdt的历史数据 if (bb_type == "2") { // console.log('进入币币模式') // this.changeflag = false // setTimeout( ()=> { // this.getHistory(data) // }, 500) } }) }, destroyed: function() {}, methods: { overlay() { var e1 = document.getElementById('modal-overlay'); e1.style.visibility = (e1.style.visibility == "visible") ? "hidden" : "visible"; }, getCionInfo() { http2('api/Contract/get_curr_con', { symbol: this.symbol }, "POST").then(res => { console.log('币种信息', res) if (res.code == 1) { pricescale = res.data.price_jd // 更新价格精度后重新加载图表 if (widget && widget.chart) { widget.chart().applyOverrides({ "pricescale": Math.pow(10, pricescale) }); } } }) }, getLast() { var that = this http2('api/market/get_apt_kline', { period: that.period, symbol: that.symbol }, "POST").then(res => { if (res.code == 1) { if (Array.isArray(res.data) && res.data.length > 0) { Event.emit('realTime', res.data[0]) Event.emit('newData', res.data[0]) Event.emit('data', res.data) } } }) }, getDay() { http2('api/market/get_apt_kline', { period: "1day", symbol: this.symbol }, "POST").then(res => { console.log('获取一天最高最低', res.data) if (res.code == 1) { if (Array.isArray(res.data) && res.data.length > 0) { Event.emit('newDay', res.data[0]) } } }) }, getLanguage() { var args = window.location.href.split('?'); if (args[0] == window.location.href) { return ""; }; var arr = args[1].split('&'); var obj = {}; for (var i = 0; i < arr.length; i++) { var arg = arr[i].split('='); obj[arg[0]] = arg[1]; } // console.log(obj) this.symbol = obj.symbol bb_type = obj.bb_type console.log(this.symbol) console.log('bb_type', bb_type) this.title = obj.title index_market = obj.symbol // 如果是aptusdt币种,进页面先接口请求历史数据 if (bb_type == "2") { console.log('进入币币模式') this.changeflag = false this.getHistory() } else { console.log('进入线上模式') // 确保在线模式也获取初始数据 this.getLast() this.getDay() } }, change(e) { if (!this.changeflag) return // 1 为平均K线; 3 为面积图 index_activeCycle = e this.tab = e if (e == 1) { this.period = "1min" } else if (e == 5) { this.period = "5min" } else if (e == 15) { this.period = "15min" } else if (e == 30) { this.period = "30min" } else if (e == 60) { this.period = "60min" } else if (e == '1D') { this.period = "1day" } this.changeflag = false if (bb_type == 2) { widget.chart().setChartType(e == '0' ? 3 : 1) widget.chart().setResolution(e) this.getHistory(this.period) } else { widget.chart().setChartType(e == '0' ? 3 : 1) widget.chart().setResolution(e) // 切换周期后主动获取一次数据 setTimeout(() => { this.getLast() }, 500) } }, getHistory(e) { var that = this var period = this.period if (e) { console.log("分钟线", e) period = e } http2('api/market/get_apt_kline', { period: period, symbol: this.symbol }, "POST").then(res => { console.log('历史数据请求', res) if (res.code == 1) { // 确保数据是有效的数组 if (Array.isArray(res.data) && res.data.length > 0) { // 格式化数据 const formattedData = res.data.map(item => ({ ...item, open: Number(item.open || 0), high: Number(item.high || 0), low: Number(item.low || 0), close: Number(item.close || 0), vol: Number(item.vol || 0), id: Number(item.id || Math.floor(Date.now() / 1000)) })); Event.emit('data', formattedData) if (period == '1min') { lastminClose = formattedData[formattedData.length - 1].close } this.once = false Event.emit('zhezhaoceng', 2) Event.emit('changeflag', true) } else { Event.emit('data', []) } } }).catch(err => { console.error("获取历史数据失败:", err); // 出错时也要发出信号,避免界面卡住 Event.emit('zhezhaoceng', 2) Event.emit('changeflag', true) }) }, } })