import { reactive, toRefs, shallowRef } from 'vue' import { ChartCycleType } from '@/constants/chart' import { queryHistoryDatas } from '@/services/api/quote' import { NetworkFilterData, NetworkFilterCallback } from './types' import moment from 'moment' export function useDataset(goodsCode: string, cycleType = ChartCycleType.Minutes) { // 缓存全量数据 const cache = shallowRef([]) const state = reactive({ loading: false, symbol: '000000.et', cycleType }) // K线图网路协议 const networkProtocol = { historyData: 'KLineChartContainer::RequestHistoryData', // 分钟全量数据下载 historyMinuteData: 'KLineChartContainer::ReqeustHistoryMinuteData' // 日线全量数据下载 } const networkFilter = (data: NetworkFilterData, callback: NetworkFilterCallback) => { data.PreventDefault = true switch (data.Name) { case networkProtocol.historyData: case networkProtocol.historyMinuteData: state.symbol = data.Request.Data.symbol getHistoryData(data.Name, data, callback) break default: callback({ symbol: state.symbol, data: [] }) } } // 获取历史行情 const getHistoryData = (protocol: string, data: NetworkFilterData, callback: NetworkFilterCallback) => { queryHistoryDatas({ data: { cycleType: state.cycleType, goodsCode, count: 1440, } }).then((res) => { cache.value = res.data.sort((a, b) => moment(a.ts).valueOf() - moment(b.ts).valueOf()) }).finally(() => { if (cache.value.length) { callback({ symbol: state.symbol, data: handleChartData(protocol, cache.value) }) } else { data.Self.EnableSplashScreen({ Title: '暂无数据', Draw: true, }) } }) } // 处理图表数据 const handleChartData = (protocol: string, data: Model.HistoryDatasRsp[]) => { return data.map((e, i) => { const date = Number(moment(e.ts).format('YYYYMMDD')) const time = Number(moment(e.ts).format('HHmm')) const preclose = data[i - 1] // 上一个收盘价 const close = preclose ? preclose.c : e.c switch (protocol) { // https://blog.csdn.net/jones2000/article/details/100557649 case networkProtocol.historyData: return [ date, // 日期 close, // 前收盘 e.o || null, // 开盘价 e.h || null, // 最高 e.l || null, // 最低 e.c, // 收盘 e.tv, // 成交量 e.tt || null, // 成交金额 e.hv || null // 持仓量 ] // https://blog.csdn.net/jones2000/article/details/100557649 case networkProtocol.historyMinuteData: return [ date, // 日期 close, // 前收盘 e.o || null, // 开盘价 e.h || null, // 最高 e.l || null, // 最低 e.c, // 收盘 e.tv, // 成交量 e.tt || null, // 成交金额 time, // 时间 e.hv || null // 持仓量 ] default: return [] } }) } // 获取周期毫秒数 const getCycleMilliseconds = () => { const milliseconds = 60 * 1000; // 一分钟毫秒数 switch (state.cycleType) { case ChartCycleType.Minutes5: { return milliseconds * 5; } case ChartCycleType.Minutes30: { return milliseconds * 30; } case ChartCycleType.Minutes60: { return milliseconds * 60; } case ChartCycleType.Hours2: { return milliseconds * 2 * 60; } case ChartCycleType.Hours4: { return milliseconds * 4 * 60; } case ChartCycleType.Day: { return milliseconds * 24 * 60; } case ChartCycleType.Week: { return milliseconds * 24 * 60 * 7; } case ChartCycleType.Month: { return milliseconds * 24 * 60 * 30; } default: { return milliseconds; } } } // 更新最新数据 const updateLastData = (q: Partial) => { const { last, lasttime } = q if (last && lasttime) { const lastIndex = cache.value.length - 1 // 历史数据最后索引位置 const cycleMilliseconds = getCycleMilliseconds() const oldTime = lastIndex === -1 ? moment(lasttime) : moment(cache.value[lastIndex].ts) // 历史行情最后时间 const diffTime = moment(lasttime).valueOf() - oldTime.valueOf() // 计算时间差 // 判断时间差是否大于周期时间 if (lastIndex === -1 || diffTime > cycleMilliseconds) { cache.value.push({ o: last, h: last, l: last, c: last, tv: q.lastvolume ?? 0, tt: q.Lastturnover ?? 0, hv: q.holdvolume ?? 0, s: q.settle ?? 0, ts: lasttime, f: false }) } else { // 更新列表中最后一条记录的数据 const record = cache.value[lastIndex] if (record.l > last) { record.l = last // 更新最低价 } if (record.h < last) { record.h = last // 更新最高价 } record.c = last // 更新收盘价 record.tv = q.lastvolume ?? record.tv record.tt = q.Lastturnover ?? record.tt record.hv = q.holdvolume ?? record.hv record.s = q.settle ?? record.s } const lastValue = cache.value.slice(-1) if (state.cycleType === ChartCycleType.Day) { return handleChartData(networkProtocol.historyData, lastValue) } return handleChartData(networkProtocol.historyMinuteData, lastValue) } return [] } return { ...toRefs(state), networkFilter, updateLastData } }