index.ts 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. import { ref, computed, watch } from 'vue'
  2. import { timerInterceptor } from '@/utils/timer'
  3. import { queryTSData } from '@/services/api/quote'
  4. import { useFuturesStore } from '@/stores'
  5. import { useDataset } from './dataset'
  6. import { useOptions } from './options'
  7. import moment from 'moment'
  8. export function useTimelineChart(goodscode: string) {
  9. const futuresStore = useFuturesStore()
  10. const { dataset, handleData, clearData, calcIndicator } = useDataset()
  11. const { options, initOptions, updateOptions } = useOptions(dataset)
  12. const loading = ref(false)
  13. const isEmpty = ref(false)
  14. const dataIndex = ref(-1) // 当前数据索引值
  15. const quote = futuresStore.getQuoteInfo(goodscode) // 实时行情
  16. // 当前选中的数据项
  17. const selectedItem = computed(() => {
  18. const { close, ma5 } = dataset.timeline.source
  19. return {
  20. close: close[dataIndex.value] ?? '--',
  21. ma5: ma5[dataIndex.value] ?? '--'
  22. }
  23. })
  24. /**
  25. * 初始化数据
  26. */
  27. const initData = () => {
  28. clearData()
  29. dataIndex.value = -1
  30. isEmpty.value = true
  31. loading.value = true
  32. // 获取历史行情
  33. queryTSData({
  34. data: {
  35. goodsCode: goodscode
  36. }
  37. }).then((res) => {
  38. const { historyDatas } = res.data
  39. if (historyDatas.length) {
  40. dataIndex.value = historyDatas.length - 1
  41. isEmpty.value = false
  42. handleData(res.data)
  43. }
  44. }).finally(() => {
  45. loading.value = false
  46. })
  47. }
  48. /**
  49. * 更新图表数据
  50. */
  51. const updateChart = () => {
  52. if (quote.value) {
  53. const { last, lasttime } = quote.value
  54. const { close, ma5 } = dataset.timeline.source
  55. const lastIndex = close.length - 1 // 历史数据最后索引位置
  56. const cycleMilliseconds = 60 * 1000 // 一分钟毫秒数
  57. const oldTime = lastIndex === -1 ? moment(lasttime) : moment(dataset.rawDate[lastIndex]) // 历史行情最后时间
  58. const diffTime = moment(lasttime).valueOf() - oldTime.valueOf() // 计算时间差
  59. if (diffTime > cycleMilliseconds * 2) {
  60. // 时间间隔超过两个周期,重新请求历史数据,待优化
  61. timerInterceptor.debounce(() => {
  62. queryTSData({
  63. data: {
  64. goodsCode: goodscode
  65. }
  66. }).then((res) => {
  67. const { historyDatas } = res.data
  68. if (historyDatas.length) {
  69. dataIndex.value = historyDatas.length - 1
  70. clearData()
  71. handleData(res.data, updateOptions)
  72. }
  73. })
  74. }, 1000, 'updateChart')
  75. } else {
  76. // 判断时间差是否大于周期时间
  77. if (lastIndex === -1 || diffTime > cycleMilliseconds) {
  78. oldTime.add(cycleMilliseconds, 'ms')
  79. const lastDate = oldTime.format('YYYY-MM-DD HH:mm:ss')
  80. // 新增分时数据
  81. dataset.rawDate.push(lastDate)
  82. close.push(last)
  83. ma5.push('-')
  84. } else {
  85. close[lastIndex] = last // 更新最后一条记录的收盘价
  86. }
  87. // 更新各种指标
  88. calcIndicator(lastIndex === -1 ? 0 : lastIndex)
  89. updateOptions()
  90. }
  91. }
  92. }
  93. // 监听行情推送
  94. watch(() => quote.value, () => {
  95. if (!loading.value && !isEmpty.value) {
  96. updateChart()
  97. }
  98. })
  99. initData()
  100. return {
  101. loading,
  102. isEmpty,
  103. dataIndex,
  104. options,
  105. selectedItem,
  106. initData,
  107. initOptions,
  108. }
  109. }