import { reactive, computed, toRefs } from 'vue' import { timerInterceptor } from '@/utils/timer' import { queryGoodsList } from '@/services/api/goods' import { defineStore } from '../store' import eventBus from '@/services/bus' import moment from 'moment' /** * 期货存储对象 */ export const useFuturesStore = defineStore(() => { const state = reactive({ loading: false, quotes: [], // 行情数据 goodsList: [], // 商品列表 quoteDayList: [], // 盘面列表 }) // 获取商品列表 const getGoodsList = async () => { try { state.loading = true const res = await queryGoodsList() state.goodsList = res.data } finally { state.loading = false } } // 通过 goodscode 获取盘面实时行情 const getQuoteDayInfoByCode = (goodscode: string) => { return computed(() => state.quoteDayList.find((e) => e.goodscode.toUpperCase() === goodscode.toUpperCase())) } // 通过 goodscode 获取商品实时报价 const getGoodsPriceByCode = (goodscode: string) => { return computed(() => { const quote = getQuoteDayInfoByCode(goodscode) return quote.value?.last ?? 0 }) } // 处理行情数据 const handleQuote = timerInterceptor.setThrottle(() => { state.quotes.forEach((item) => { const quote = state.quoteDayList.find((e) => e.goodscode.toUpperCase() === item.goodscode?.toUpperCase()) const last = item.last ?? 0 const lasttime = (item.date && item.time) ? moment(item.date + item.time, 'YYYYMMDDHHmmss').format('YYYY-MM-DD HH:mm:ss') : '' if (quote) { Object.entries(item).forEach(([key, value]) => { // 只更新存在的属性 if (Reflect.has(quote, key)) { Object.defineProperty(quote, key, { value }) } }) // 处理最高最低价 if (last) { if (last > quote.highest) { quote.highest = last } if (last < quote.lowest) { quote.lowest = last } } // 处理最新时间 if (lasttime) { quote.lasttime = lasttime } } else { console.warn('行情推送的商品 ' + item.goodscode + ' 缺少盘面信息') state.quoteDayList.push({ Lastturnover: 0, ask: item.ask ?? 0, ask2: item.ask2 ?? 0, ask3: item.ask3 ?? 0, ask4: item.ask4 ?? 0, ask5: item.ask5 ?? 0, ask6: 0, ask7: 0, ask8: 0, ask9: 0, ask10: 0, askorderid: 0, askorderid2: 0, askorderid3: 0, askorderid4: 0, askorderid5: 0, askordervolume: 0, askordervolume2: 0, askordervolume3: 0, askordervolume4: 0, askordervolume5: 0, askordervolume6: 0, askordervolume7: 0, askordervolume8: 0, askordervolume9: 0, askordervolume10: 0, askqueueinfo: "", askvolume: item.askvolume ?? 0, askvolume2: item.askvolume2 ?? 0, askvolume3: item.askvolume3 ?? 0, askvolume4: item.askvolume4 ?? 0, askvolume5: item.askvolume5 ?? 0, askvolume6: 0, askvolume7: 0, askvolume8: 0, askvolume9: 0, askvolume10: 0, averageprice: 0, bid: item.bid ?? 0, bid2: item.bid2 ?? 0, bid3: item.bid3 ?? 0, bid4: item.bid4 ?? 0, bid5: item.bid5 ?? 0, bid6: 0, bid7: 0, bid8: 0, bid9: 0, bid10: 0, bidorderid: 0, bidorderid2: 0, bidorderid3: 0, bidorderid4: 0, bidorderid5: 0, bidordervolume: 0, bidordervolume2: 0, bidordervolume3: 0, bidordervolume4: 0, bidordervolume5: 0, bidordervolume6: 0, bidordervolume7: 0, bidordervolume8: 0, bidordervolume9: 0, bidordervolume10: 0, bidqueueinfo: "", bidvolume: item.bidvolume ?? 0, bidvolume2: item.bidvolume2 ?? 0, bidvolume3: item.bidvolume3 ?? 0, bidvolume4: item.bidvolume4 ?? 0, bidvolume5: item.bidvolume5 ?? 0, bidvolume6: 0, bidvolume7: 0, bidvolume8: 0, bidvolume9: 0, bidvolume10: 0, calloptionpremiums: item.calloptionpremiums ?? 0, calloptionpremiums2: item.calloptionpremiums2 ?? 0, calloptionpremiums3: item.calloptionpremiums3 ?? 0, calloptionpremiums4: item.calloptionpremiums4 ?? 0, calloptionpremiums5: item.calloptionpremiums5 ?? 0, cleartime: 0, exchangecode: item.exchangecode ?? 0, exchangedate: item.exchangedate ?? 0, goodscode: item.goodscode ?? '', grepmarketprice: 0, highest: item.highest ?? 0, holdincrement: 0, holdvolume: item.holdvolume ?? 0, iep: 0, iev: 0, inventory: item.inventory ?? 0, iscleared: 0, issettled: 0, last, lastlot: 0, lasttime, lastvolume: item.lastvolume ?? 0, limitdown: item.limitlow ?? 0, limitup: item.limithigh ?? 0, lowest: item.lowest ?? 0, nontotalholdervolume: 0, nontotallot: 0, nontotalturnover: 0, nontotalvolume: 0, opened: item.opened ?? 0, opentime: '', orderid: 0, preclose: item.preclose ?? 0, preholdvolume: item.preholdvolume ?? 0, presettle: item.presettle ?? 0, publictradetype: '', putoptionpremiums: item.putoptionpremiums ?? 0, putoptionpremiums2: item.putoptionpremiums2 ?? 0, putoptionpremiums3: item.putoptionpremiums3 ?? 0, putoptionpremiums4: item.putoptionpremiums4 ?? 0, putoptionpremiums5: item.putoptionpremiums5 ?? 0, settle: item.settle ?? 0, strikeprice: 0, totalaskvolume: 0, totalbidvolume: 0, totallot: 0, totalturnover: item.totalturnover ?? 0, totalvolume: item.totalvolume ?? 0, utclasttime: '' }) } }) }, 100) // 接收行情推送通知 const quotePushNotify = eventBus.$on('QuotePushNotify', (res) => { const data = res as Proto.Quote[] data.forEach((item) => { const index = state.quotes.findIndex((e) => e.goodscode === item.goodscode) if (index > -1) { state.quotes[index] = item } else { state.quotes.push(item) } }) handleQuote() }) return { ...toRefs(state), getGoodsList, getQuoteDayInfoByCode, getGoodsPriceByCode, quotePushNotify, } })