| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335 |
- import { reactive, computed, toRefs } from 'vue'
- import { timerInterceptor } from '@/utils/timer'
- import { queryErmcpGoods, queryQuoteDay } from '@/services/api/goods'
- import { defineStore } from '../store'
- import { timerTask } from '@/utils/timer'
- import eventBus from '@/services/bus'
- import moment from 'moment'
- /**
- * 期货存储对象
- * @returns
- */
- export const useFuturesStore = defineStore(() => {
- const state = reactive({
- loading: false,
- quotes: <Proto.Quote[]>[], // 行情数据
- goodsList: <Model.GoodsRsp[]>[], // 商品列表
- quoteDayList: <Model.QuoteDayRsp[]>[], // 盘面列表
- })
- // 行情列表
- const quoteList = computed(() => {
- return state.goodsList.reduce((res, cur) => {
- const { goodsid, goodscode, goodsname, goodsgroupid, marketid, decimalplace } = cur
- const quoteDayInfo = state.quoteDayList.find((e) => e.goodscode.toUpperCase() === goodscode.toUpperCase())
- const {
- last = 0,
- bid = 0,
- ask = 0,
- bidvolume = 0,
- askvolume = 0,
- totalvolume = 0,
- lastvolume = 0,
- holdvolume = 0,
- holdincrement = 0,
- presettle = 0,
- totalturnover = 0,
- opened = 0,
- highest = 0,
- lowest = 0,
- lasttime = '',
- } = quoteDayInfo ?? {}
- const rise = last ? last - presettle : 0 // 涨跌额/涨跌: 最新价 - 昨结价
- const change = presettle ? rise / presettle : 0 // 涨跌幅/幅度: (最新价 - 昨结价) / 昨结价
- const amplitude = last ? (highest - lowest) / last : 0 // 振幅: (最高价 - 最低价 ) / 最新价
- // 处理行情价格颜色
- const handleColor = (value: number) => {
- if (value === presettle) {
- return ''
- } else if (value > presettle) {
- return 'g-up-color'
- } else {
- return 'g-down-color'
- }
- }
- const item: Model.Futures = {
- marketid,
- goodsgroupid,
- goodsid,
- goodscode,
- goodsname,
- decimalplace,
- last,
- lasttime,
- rise,
- change,
- amplitude,
- bid,
- ask,
- bidvolume,
- askvolume,
- totalvolume,
- lastvolume,
- holdvolume,
- holdincrement,
- presettle,
- totalturnover,
- opened,
- highest,
- lowest,
- bidColor: handleColor(bid),
- askColor: handleColor(ask),
- lastColor: handleColor(last),
- bidvolumeColor: handleColor(bidvolume),
- askvolumeColor: handleColor(askvolume),
- openedColor: handleColor(opened),
- highestColor: handleColor(highest),
- lowestColor: handleColor(lowest),
- }
- res.push(item)
- return res
- }, [] as Model.Futures[])
- })
- // 获取商品列表
- const getGoodsList = async () => {
- state.loading = true
- try {
- const res = await queryErmcpGoods()
- const codes = res.data.map((e) => e.goodscode)
- state.goodsList = res.data
- // 获取商品盘面信息
- const getQuoteDay = async () => {
- try {
- const res_1 = await queryQuoteDay({
- data: {
- goodsCodes: codes.join(',')
- }
- })
- state.quoteDayList = res_1.data
- } finally {
- // 每5分钟获取一次盘面
- timerTask.setTimeout(() => getQuoteDay(), 5 * 60 * 1000, 'quoteDay')
- }
- }
- if (codes.length) {
- getQuoteDay()
- }
- } finally {
- state.loading = false
- }
- }
- // 通过 goodscode 获取实时行情信息
- const getQuoteInfo = (goodscode: string) => {
- return computed(() => quoteList.value.find((e) => e.goodscode.toUpperCase() === goodscode.toUpperCase()))
- }
- // 通过 goodscode 获取实时行情报价
- const getQuotePrice = (goodscode: string) => {
- return computed(() => {
- const quote = getQuoteInfo(goodscode)
- return quote.value?.last ?? 0
- })
- }
- // 处理行情数据
- const handleQuote = timerInterceptor.setThrottle(() => {
- state.quotes.forEach((item) => {
- const goods = state.goodsList.find((e) => e.goodscode.toUpperCase() === item.goodscode?.toUpperCase())
- const quote: Model.QuoteDayRsp | undefined = state.quoteDayList.find((e) => e.goodscode.toUpperCase() === item.goodscode?.toUpperCase())
- const lasttime = (item.date && item.time) ? moment(item.date + item.time, 'YYYYMMDDHHmmss').format('YYYY-MM-DD HH:mm:ss') : ''
- // 处理报价小数位
- const handleDeimalplace = (value = 0) => {
- const decimal = goods ? Math.pow(10, goods.decimalplace) : 0
- if (decimal) {
- return value / decimal
- }
- return value
- }
- const quoteItem: Model.QuoteDayRsp = {
- ask: handleDeimalplace(item.ask),
- ask2: handleDeimalplace(item.ask2),
- ask3: handleDeimalplace(item.ask3),
- ask4: handleDeimalplace(item.ask4),
- ask5: handleDeimalplace(item.ask5),
- 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: handleDeimalplace(item.askvolume),
- askvolume2: handleDeimalplace(item.askvolume2),
- askvolume3: handleDeimalplace(item.askvolume3),
- askvolume4: handleDeimalplace(item.askvolume4),
- askvolume5: handleDeimalplace(item.askvolume5),
- askvolume6: 0,
- askvolume7: 0,
- askvolume8: 0,
- askvolume9: 0,
- askvolume10: 0,
- averageprice: 0,
- bid: handleDeimalplace(item.bid),
- bid2: handleDeimalplace(item.bid2),
- bid3: handleDeimalplace(item.bid3),
- bid4: handleDeimalplace(item.bid4),
- bid5: handleDeimalplace(item.bid5),
- 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: handleDeimalplace(item.bidvolume),
- bidvolume2: handleDeimalplace(item.bidvolume2),
- bidvolume3: handleDeimalplace(item.bidvolume3),
- bidvolume4: handleDeimalplace(item.bidvolume4),
- bidvolume5: handleDeimalplace(item.bidvolume5),
- bidvolume6: 0,
- bidvolume7: 0,
- bidvolume8: 0,
- bidvolume9: 0,
- bidvolume10: 0,
- calloptionpremiums: handleDeimalplace(item.calloptionpremiums),
- calloptionpremiums2: handleDeimalplace(item.calloptionpremiums2),
- calloptionpremiums3: handleDeimalplace(item.calloptionpremiums3),
- calloptionpremiums4: handleDeimalplace(item.calloptionpremiums4),
- calloptionpremiums5: handleDeimalplace(item.calloptionpremiums5),
- cleartime: 0,
- exchangecode: handleDeimalplace(item.exchangecode),
- exchangedate: handleDeimalplace(item.exchangedate),
- goodscode: item.goodscode ?? '',
- grepmarketprice: 0,
- highest: handleDeimalplace(item.highest),
- holdincrement: 0,
- holdvolume: handleDeimalplace(item.holdvolume),
- iep: 0,
- iev: 0,
- inventory: handleDeimalplace(item.inventory),
- iscleared: 0,
- issettled: 0,
- last: handleDeimalplace(item.last),
- lastlot: 0,
- lasttime,
- Lastturnover: 0,
- lastvolume: handleDeimalplace(item.lastvolume),
- limitdown: handleDeimalplace(item.limitlow),
- limitup: handleDeimalplace(item.limithigh),
- lowest: handleDeimalplace(item.lowest),
- nontotalholdervolume: 0,
- nontotallot: 0,
- nontotalturnover: 0,
- nontotalvolume: 0,
- opened: handleDeimalplace(item.opened),
- opentime: '',
- orderid: 0,
- preclose: handleDeimalplace(item.preclose),
- preholdvolume: handleDeimalplace(item.preholdvolume),
- presettle: handleDeimalplace(item.presettle),
- publictradetype: '',
- putoptionpremiums: handleDeimalplace(item.putoptionpremiums),
- putoptionpremiums2: handleDeimalplace(item.putoptionpremiums2),
- putoptionpremiums3: handleDeimalplace(item.putoptionpremiums3),
- putoptionpremiums4: handleDeimalplace(item.putoptionpremiums4),
- putoptionpremiums5: handleDeimalplace(item.putoptionpremiums5),
- settle: handleDeimalplace(item.settle),
- strikeprice: 0,
- totalaskvolume: 0,
- totalbidvolume: 0,
- totallot: 0,
- totalturnover: handleDeimalplace(item.totalturnover),
- totalvolume: handleDeimalplace(item.totalvolume),
- utclasttime: ''
- }
- if (quote) {
- Object.keys(item).forEach((key) => {
- // 只更新存在的属性
- if (Reflect.has(quote, key)) {
- (<K extends keyof Model.QuoteDayRsp>(prop: K) => {
- quote[prop] = quoteItem[prop]
- })(key as keyof Model.QuoteDayRsp)
- }
- })
- // 处理最高最低价
- if (quote.last) {
- if (quote.last > quote.highest) {
- quote.highest = quote.last
- }
- if (quote.last < quote.lowest) {
- quote.lowest = quote.last
- }
- }
- // 处理最新时间
- if (lasttime) {
- quote.lasttime = lasttime
- }
- } else {
- console.warn('行情推送的商品 ' + item.goodscode + ' 缺少盘面信息')
- state.quoteDayList.push(quoteItem)
- }
- })
- }, 200)
- // 接收行情推送通知
- 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),
- quoteList,
- getGoodsList,
- getQuoteInfo,
- getQuotePrice,
- quotePushNotify,
- }
- })
|