li.shaoyi 2 anni fa
parent
commit
f18b8a5c92
66 ha cambiato i file con 323 aggiunte e 163 eliminazioni
  1. 4 4
      src/hooks/echarts/candlestick/index.ts
  2. 1 1
      src/hooks/echarts/candlestick/options.ts
  3. 2 3
      src/hooks/echarts/smoothedline/index.ts
  4. 4 4
      src/hooks/echarts/timeline/index.ts
  5. 1 1
      src/hooks/echarts/timeline/options.ts
  6. 1 1
      src/packages/gstj/components/modules/quote/forex/index.vue
  7. 1 1
      src/packages/gstj/components/modules/quote/price/index.vue
  8. 2 2
      src/packages/gstj/components/modules/quote/tik/index.vue
  9. 1 1
      src/packages/gstj/views/goods/detail/Index.vue
  10. 1 1
      src/packages/gstj/views/goods/detail/components/listing/Index.vue
  11. 1 1
      src/packages/gstj/views/goods/list/Index.vue
  12. 1 1
      src/packages/gstj/views/goods/trade/components/delisting/index.vue
  13. 1 1
      src/packages/gstj/views/goods/trade/index.vue
  14. 1 1
      src/packages/gstj/views/order/position/components/goods/close/Index.vue
  15. 1 1
      src/packages/gstj/views/order/position/components/goods/delivery/Index.vue
  16. 1 1
      src/packages/mobile/components/modules/quote/forex/index.vue
  17. 1 1
      src/packages/mobile/components/modules/quote/price/index.vue
  18. 2 2
      src/packages/mobile/components/modules/quote/tik/index.vue
  19. 1 1
      src/packages/mobile/views/goods/detail/Index.vue
  20. 1 1
      src/packages/mobile/views/goods/detail/components/listing/Index.vue
  21. 1 1
      src/packages/mobile/views/goods/list/Index.vue
  22. 1 1
      src/packages/mobile/views/goods/trade/components/delisting/index.vue
  23. 3 2
      src/packages/mobile/views/goods/trade/index.vue
  24. 1 1
      src/packages/mobile/views/order/position/components/goods/close/Index.vue
  25. 1 1
      src/packages/mobile/views/order/position/components/goods/delivery/Index.vue
  26. 1 1
      src/packages/mobile/views/order/position/components/swap/close/Index.vue
  27. 1 1
      src/packages/mobile/views/order/position/components/swap/list/Index.vue
  28. 4 3
      src/packages/mobile/views/order/position/components/transfer/listing/Index.vue
  29. 1 1
      src/packages/mobile/views/pricing/detail/Index.vue
  30. 1 1
      src/packages/mobile/views/pricing/list/Index.vue
  31. 1 1
      src/packages/mobile/views/swap/list/Index.vue
  32. 2 2
      src/packages/mobile/views/transfer/detail/Index.vue
  33. 2 2
      src/packages/mobile/views/transfer/detail2/index.vue
  34. 1 1
      src/packages/pc/components/modules/listing/index.vue
  35. 1 1
      src/packages/pc/components/modules/quote/forex/index.vue
  36. 4 2
      src/packages/pc/components/modules/quote/price/index.vue
  37. 9 7
      src/packages/pc/components/modules/quote/tik/index.vue
  38. 3 1
      src/packages/pc/views/auth/login/index.less
  39. 18 13
      src/packages/pc/views/auth/login/index.vue
  40. 2 2
      src/packages/pc/views/footer/goods/position/components/delivery/index.vue
  41. 1 1
      src/packages/pc/views/footer/goods/position/components/transfer/index.vue
  42. 5 23
      src/packages/pc/views/footer/goods/position/index.vue
  43. 1 1
      src/packages/pc/views/market/trade/goods/detail/components/order/delisting/index.vue
  44. 1 1
      src/packages/pc/views/market/trade/goods/detail/components/order/index.vue
  45. 1 1
      src/packages/pc/views/market/trade/goods/detail/index.vue
  46. 1 1
      src/packages/pc/views/market/trade/goods/index.vue
  47. 1 1
      src/packages/qxst/components/modules/quote/forex/index.vue
  48. 1 1
      src/packages/qxst/components/modules/quote/price/index.vue
  49. 1 1
      src/packages/qxst/components/modules/quote/tik/index.vue
  50. 1 1
      src/packages/qxst/views/goods/detail/Index.vue
  51. 1 1
      src/packages/qxst/views/goods/detail/components/listing/Index.vue
  52. 1 1
      src/packages/qxst/views/goods/list/Index.vue
  53. 1 1
      src/packages/qxst/views/goods/trade/components/delisting/index.vue
  54. 1 1
      src/packages/qxst/views/goods/trade/index.vue
  55. 1 1
      src/packages/qxst/views/order/position/components/goods/close/Index.vue
  56. 1 1
      src/packages/qxst/views/order/position/components/goods/delivery/Index.vue
  57. 1 1
      src/packages/sbyj/components/modules/quote/forex/index.vue
  58. 1 1
      src/packages/sbyj/components/modules/quote/price/index.vue
  59. 1 1
      src/packages/sbyj/components/modules/quote/tik/index.vue
  60. 1 1
      src/packages/sbyj/views/market/detail/index.vue
  61. 1 1
      src/packages/sbyj/views/order/list/components/close-holder/index.vue
  62. 1 1
      src/services/websocket/build/index.ts
  63. 140 0
      src/services/websocket/newQuote.ts
  64. 39 31
      src/services/websocket/quote.ts
  65. 19 9
      src/stores/modules/futures.ts
  66. 12 4
      src/stores/modules/position.ts

+ 4 - 4
src/hooks/echarts/candlestick/index.ts

@@ -116,8 +116,8 @@ export function useCandlestickChart(goodscode: string) {
      * 更新图表数据
      */
     const updateChart = () => {
-        if (quote.value) {
-            const { last, lasttime } = quote.value;
+        const { last, lasttime } = quote.value;
+        if (last) {
             const { candlestick, macd, vol, kdj, cci } = dataset;
             const lastIndex = candlestick.source.length - 1; // 历史数据最后索引位置
             const cycleMilliseconds = getCycleMilliseconds();
@@ -211,8 +211,8 @@ export function useCandlestickChart(goodscode: string) {
     }
 
     // 监听行情推送
-    watch(() => quote.value, (q) => {
-        if (q?.last && !loading.value && !isEmpty.value) {
+    watch(() => quote.value, () => {
+        if (!loading.value && !isEmpty.value) {
             updateChart();
         }
     })

+ 1 - 1
src/hooks/echarts/candlestick/options.ts

@@ -388,7 +388,7 @@ export function useOptions(dataset: EchartsDataset) {
                 source: cci.source,
             },
         }
-    }, 100)
+    }, 50)
 
     // 监听主题变化
     watch(appTheme, () => {

+ 2 - 3
src/hooks/echarts/smoothedline/index.ts

@@ -56,9 +56,8 @@ export function useSmoothedLineChart(goodscode: string) {
     }
 
     // 监听行情推送
-    watch(() => quote.value, (q) => {
-        if (q?.last && !loading.value && quote.value) {
-            const { last, lasttime } = quote.value
+    watch(() => quote.value, ({ last, lasttime }) => {
+        if (!loading.value && last) {
             const { date, price } = dataset.line.source
             date.push(formatDate(lasttime, 'HH:mm:ss'))
             price.push(last)

+ 4 - 4
src/hooks/echarts/timeline/index.ts

@@ -55,8 +55,8 @@ export function useTimelineChart(goodscode: string) {
      * 更新图表数据
      */
     const updateChart = () => {
-        if (quote.value) {
-            const { last, lasttime } = quote.value
+        const { last, lasttime } = quote.value
+        if (last) {
             const { close, ma5 } = dataset.timeline.source
             const lastIndex = close.length - 1 // 历史数据最后索引位置
             const cycleMilliseconds = 60 * 1000 // 一分钟毫秒数
@@ -102,8 +102,8 @@ export function useTimelineChart(goodscode: string) {
     }
 
     // 监听行情推送
-    watch(() => quote.value, (q) => {
-        if (q?.last && !loading.value && !isEmpty.value) {
+    watch(() => quote.value, () => {
+        if (!loading.value && !isEmpty.value) {
             updateChart()
         }
     })

+ 1 - 1
src/hooks/echarts/timeline/options.ts

@@ -243,7 +243,7 @@ export function useOptions(dataset: EchartsDataset) {
                 },
             ],
         }
-    }, 100)
+    }, 50)
 
     // 监听主题变化
     watch(appTheme, () => {

+ 1 - 1
src/packages/gstj/components/modules/quote/forex/index.vue

@@ -56,7 +56,7 @@ const emit = defineEmits<{ (event: string, ...args: unknown[]): void }>()
 const { router } = useNavigation()
 const attrs = useAttrs()
 const futuresStore = useFuturesStore()
-const quote = computed(() => futuresStore.getQuoteInfo(props.goodsCode).value)
+const quote = computed(() => futuresStore.getQuoteDayInfo(props.goodsCode).value)
 const active = shallowRef('')
 
 const buyList = computed(() => {

+ 1 - 1
src/packages/gstj/components/modules/quote/price/index.vue

@@ -89,7 +89,7 @@ const props = defineProps({
 
 const futuresStore = useFuturesStore()
 const subscribe = quoteSocket.createSubscribe()
-const quote = futuresStore.getQuoteInfo(props.goodsCode)
+const quote = futuresStore.getQuoteDayInfo(props.goodsCode)
 const showMore = shallowRef(false)
 
 onMounted(() => subscribe.start(props.goodsCode))

+ 2 - 2
src/packages/gstj/components/modules/quote/tik/index.vue

@@ -28,7 +28,7 @@ const props = defineProps({
 })
 
 const futuresStore = useFuturesStore()
-const quote = futuresStore.getQuoteInfo(props.goodsCode)
+const quote = futuresStore.getQuoteDayInfo(props.goodsCode)
 const dataList = ref<Model.HistoryTikDatasRsp[]>([])
 
 const columns: Model.TableColumn[] = [
@@ -64,7 +64,7 @@ useRequest(queryMarketRun, {
 })
 
 watch(() => quote.value, (q) => {
-    if (q?.last) {
+    if (q?.last && q.lastvolume) {
         const list = dataList.value
         if (list.length > 9) {
             // 移除列表最后一条记录

+ 1 - 1
src/packages/gstj/views/goods/detail/Index.vue

@@ -41,7 +41,7 @@ const { positionList } = usePosition(50)
 const { getQueryStringToNumber } = useNavigation()
 const futuresStore = useFuturesStore()
 const goodsid = getQueryStringToNumber('goodsid')
-const quote = futuresStore.getQuoteInfo(goodsid)
+const quote = futuresStore.getQuoteDayInfo(goodsid)
 const buildType = shallowRef<EBuildType>() // 挂牌类型
 
 const goodsCode = computed(() => quote.value?.goodscode ?? '')

+ 1 - 1
src/packages/gstj/views/goods/detail/components/listing/Index.vue

@@ -87,7 +87,7 @@ const { getOrderQty } = usePosition(50)
 const { formData, formSubmit } = useOrder()
 const accountStore = useAccountStore()
 const futuresStore = useFuturesStore()
-const quote = futuresStore.getQuoteInfo(props.goodsCode)
+const quote = futuresStore.getQuoteDayInfo(props.goodsCode)
 const formRef = shallowRef<FormInstance>()
 const showModal = shallowRef(true)
 const refresh = shallowRef(true) // 是否刷新父组件数据

+ 1 - 1
src/packages/gstj/views/goods/list/Index.vue

@@ -91,7 +91,7 @@ const { dataList } = useRequest(queryQuoteGoodsList, {
 
 const tableList = computed(() => {
     return dataList.value.map((item) => {
-        const quote = futuresStore.getQuoteInfo(item.goodscode)
+        const quote = futuresStore.getQuoteDayInfo(item.goodscode)
         const { goodsname, bid, bidColor, bidvolume, ask, askColor, askvolume, limitdown, limitup, lastColor, openedColor, lowestColor, highestColor, last, presettle, rise, change, amplitude, highest, lowest, opened } = quote.value ?? {}
         return {
             ...item,

+ 1 - 1
src/packages/gstj/views/goods/trade/components/delisting/index.vue

@@ -97,7 +97,7 @@ const futuresStore = useFuturesStore()
 const { getOrderQty } = usePosition(50)
 const { formData, formSubmit } = useOrder()
 
-const quote = futuresStore.getQuoteInfo(props.selectedRow.goodsid)
+const quote = futuresStore.getQuoteDayInfo(props.selectedRow.goodsid)
 const formRef = shallowRef<FormInstance>()
 const showModal = shallowRef(true)
 const refresh = shallowRef(false) // 是否刷新父组件数据

+ 1 - 1
src/packages/gstj/views/goods/trade/index.vue

@@ -52,7 +52,7 @@ const goodsid = getQueryStringToNumber('goodsid')
 const buyorsell = getQueryStringToNumber('buyorsell')
 const loginStore = useLoginStore()
 const futuresStore = useFuturesStore()
-const quote = futuresStore.getQuoteInfo(goodsid)
+const quote = futuresStore.getQuoteDayInfo(goodsid)
 
 const tabIndex = shallowRef(buyorsell)
 const selectedRow = shallowRef<Model.WrTradeOrderDetailRsp>()

+ 1 - 1
src/packages/gstj/views/order/position/components/goods/close/Index.vue

@@ -64,7 +64,7 @@ const props = defineProps({
 })
 
 const futuresStore = useFuturesStore()
-const quote = futuresStore.getQuoteInfo(props.selectedRow.goodscode)
+const quote = futuresStore.getQuoteDayInfo(props.selectedRow.goodscode)
 const showModal = shallowRef(true)
 // 是否刷新父组件数据
 const refresh = shallowRef(false)

+ 1 - 1
src/packages/gstj/views/order/position/components/goods/delivery/Index.vue

@@ -64,7 +64,7 @@ const showModal = shallowRef(true)
 const refresh = shallowRef(false)
 const { formSubmit, formData } = useOfflineDelivery()
 const futuresStore = useFuturesStore()
-const quote = futuresStore.getQuoteInfo(props.selectedRow.goodscode)
+const quote = futuresStore.getQuoteDayInfo(props.selectedRow.goodscode)
 
 /// 计算参考损益
 const closepl = computed(() => {

+ 1 - 1
src/packages/mobile/components/modules/quote/forex/index.vue

@@ -56,7 +56,7 @@ const emit = defineEmits<{ (event: string, ...args: unknown[]): void }>()
 const { router } = useNavigation()
 const attrs = useAttrs()
 const futuresStore = useFuturesStore()
-const quote = computed(() => futuresStore.getQuoteInfo(props.goodsCode).value)
+const quote = computed(() => futuresStore.getQuoteDayInfo(props.goodsCode).value)
 const active = shallowRef('')
 
 const buyList = computed(() => {

+ 1 - 1
src/packages/mobile/components/modules/quote/price/index.vue

@@ -89,7 +89,7 @@ const props = defineProps({
 
 const futuresStore = useFuturesStore()
 const subscribe = quoteSocket.createSubscribe()
-const quote = futuresStore.getQuoteInfo(props.goodsCode)
+const quote = futuresStore.getQuoteDayInfo(props.goodsCode)
 const showMore = shallowRef(false)
 
 onMounted(() => subscribe.start(props.goodsCode))

+ 2 - 2
src/packages/mobile/components/modules/quote/tik/index.vue

@@ -28,7 +28,7 @@ const props = defineProps({
 })
 
 const futuresStore = useFuturesStore()
-const quote = futuresStore.getQuoteInfo(props.goodsCode)
+const quote = futuresStore.getQuoteDayInfo(props.goodsCode)
 const dataList = ref<Model.HistoryTikDatasRsp[]>([])
 
 const columns: Model.TableColumn[] = [
@@ -64,7 +64,7 @@ useRequest(queryMarketRun, {
 })
 
 watch(() => quote.value, (q) => {
-    if (q?.last) {
+    if (q?.last && q.lastvolume) {
         const list = dataList.value
         if (list.length > 9) {
             // 移除列表最后一条记录

+ 1 - 1
src/packages/mobile/views/goods/detail/Index.vue

@@ -41,7 +41,7 @@ const { positionList } = usePosition(50)
 const { getQueryStringToNumber } = useNavigation()
 const futuresStore = useFuturesStore()
 const goodsid = getQueryStringToNumber('goodsid')
-const quote = futuresStore.getQuoteInfo(goodsid)
+const quote = futuresStore.getQuoteDayInfo(goodsid)
 const buildType = shallowRef<EBuildType>() // 挂牌类型
 
 const goodsCode = computed(() => quote.value?.goodscode ?? '')

+ 1 - 1
src/packages/mobile/views/goods/detail/components/listing/Index.vue

@@ -87,7 +87,7 @@ const { getOrderQty } = usePosition(50)
 const { formData, formSubmit } = useOrder()
 const accountStore = useAccountStore()
 const futuresStore = useFuturesStore()
-const quote = futuresStore.getQuoteInfo(props.goodsCode)
+const quote = futuresStore.getQuoteDayInfo(props.goodsCode)
 const formRef = shallowRef<FormInstance>()
 const showModal = shallowRef(true)
 const refresh = shallowRef(true) // 是否刷新父组件数据

+ 1 - 1
src/packages/mobile/views/goods/list/Index.vue

@@ -91,7 +91,7 @@ const { dataList } = useRequest(queryQuoteGoodsList, {
 
 const tableList = computed(() => {
     return dataList.value.map((item) => {
-        const quote = futuresStore.getQuoteInfo(item.goodscode)
+        const quote = futuresStore.getQuoteDayInfo(item.goodscode)
         const { goodsname, bid, bidColor, bidvolume, ask, askColor, askvolume, limitdown, limitup, lastColor, openedColor, lowestColor, highestColor, last, presettle, rise, change, amplitude, highest, lowest, opened } = quote.value ?? {}
         return {
             ...item,

+ 1 - 1
src/packages/mobile/views/goods/trade/components/delisting/index.vue

@@ -97,7 +97,7 @@ const futuresStore = useFuturesStore()
 const { getOrderQty } = usePosition(50)
 const { formData, formSubmit } = useOrder()
 
-const quote = futuresStore.getQuoteInfo(props.selectedRow.goodsid)
+const quote = futuresStore.getQuoteDayInfo(props.selectedRow.goodsid)
 const formRef = shallowRef<FormInstance>()
 const showModal = shallowRef(true)
 const refresh = shallowRef(false) // 是否刷新父组件数据

+ 3 - 2
src/packages/mobile/views/goods/trade/index.vue

@@ -19,7 +19,8 @@
                         <span class="text-small">{{ row.username }}</span>
                     </template>
                     <template #operate="{ row, index }">
-                        <Button size="small" type="primary" v-if="index === 0" round @click="onDelisting(row)" style="width: 1rem;">
+                        <Button size="small" type="primary" v-if="index === 0" round @click="onDelisting(row)"
+                            style="width: 1rem;">
                             {{ tabIndex === BuyOrSell.Buy ? '卖出' : '买入' }}
                         </Button>
                     </template>
@@ -52,7 +53,7 @@ const goodsid = getQueryStringToNumber('goodsid')
 const buyorsell = getQueryStringToNumber('buyorsell')
 const loginStore = useLoginStore()
 const futuresStore = useFuturesStore()
-const quote = futuresStore.getQuoteInfo(goodsid)
+const quote = futuresStore.getQuoteDayInfo(goodsid)
 
 const tabIndex = shallowRef(buyorsell)
 const selectedRow = shallowRef<Model.WrTradeOrderDetailRsp>()

+ 1 - 1
src/packages/mobile/views/order/position/components/goods/close/Index.vue

@@ -64,7 +64,7 @@ const props = defineProps({
 })
 
 const futuresStore = useFuturesStore()
-const quote = futuresStore.getQuoteInfo(props.selectedRow.goodscode)
+const quote = futuresStore.getQuoteDayInfo(props.selectedRow.goodscode)
 const showModal = shallowRef(true)
 // 是否刷新父组件数据
 const refresh = shallowRef(false)

+ 1 - 1
src/packages/mobile/views/order/position/components/goods/delivery/Index.vue

@@ -64,7 +64,7 @@ const showModal = shallowRef(true)
 const refresh = shallowRef(false)
 const { formSubmit, formData } = useOfflineDelivery()
 const futuresStore = useFuturesStore()
-const quote = futuresStore.getQuoteInfo(props.selectedRow.goodscode)
+const quote = futuresStore.getQuoteDayInfo(props.selectedRow.goodscode)
 
 /// 计算参考损益
 const closepl = computed(() => {

+ 1 - 1
src/packages/mobile/views/order/position/components/swap/close/Index.vue

@@ -118,7 +118,7 @@ const { loading, pageIndex, pageCount, run } = useRequest(queryTradeHolderDetail
 })
 
 const lastPrice = computed(() => {
-    const quote = futuresStore.getQuoteInfo(props.selectedRow.refgoodscode)
+    const quote = futuresStore.getQuoteDayInfo(props.selectedRow.refgoodscode)
     const { last } = quote.value ?? {}
     return last
 })

+ 1 - 1
src/packages/mobile/views/order/position/components/swap/list/Index.vue

@@ -79,7 +79,7 @@ const last = (goodsCode: string) => {
 }
 
 const lastColor = (goodsCode: string) => {
-    return futuresStore.getQuoteInfo(goodsCode).value?.lastColor
+    return futuresStore.getQuoteDayInfo(goodsCode).value?.lastColor
 }
 
 const { componentRef, componentId, openComponent, closeComponent } = useComponent(() => {

+ 4 - 3
src/packages/mobile/views/order/position/components/transfer/listing/Index.vue

@@ -35,7 +35,8 @@
                     <Field name="OrderPrice" :rules="formRules.OrderPrice" label="转让价">
                         <template #input>
                             <Stepper v-model="formData.OrderPrice" theme="round" :min="quote?.limitdown"
-                                :max="quote?.limitup" :step="Math.pow(10, -selectedRow.decimalplace)" :decimal-length="selectedRow.decimalplace" :auto-fixed="false" button-size="22" />
+                                :max="quote?.limitup" :step="Math.pow(10, -selectedRow.decimalplace)"
+                                :decimal-length="selectedRow.decimalplace" :auto-fixed="false" button-size="22" />
                         </template>
                     </Field>
                     <Field name="OrderQty" :rules="formRules.OrderQty" label="转让数量">
@@ -74,11 +75,11 @@ const props = defineProps({
 })
 
 const { formData, formSubmit } = useOrder()
-const { getQuoteInfo } = useFuturesStore()
+const { getQuoteDayInfo } = useFuturesStore()
 const formRef = shallowRef<FormInstance>()
 const refresh = shallowRef(false) // 是否刷新父组件数据
 const showModal = shallowRef(true)
-const quote = getQuoteInfo(props.selectedRow.goodscode)
+const quote = getQuoteDayInfo(props.selectedRow.goodscode)
 
 // 表单验证规则
 const formRules: { [key in keyof Proto.OrderReq]?: FieldRule[] } = {

+ 1 - 1
src/packages/mobile/views/pricing/detail/Index.vue

@@ -169,7 +169,7 @@ const marketPrice = computed(() => {
 const goodscode = getQueryString('goodscode')
 const buyOrSell = getQueryStringToNumber('buyOrSell')
 const buildType = getQueryStringToNumber('buildType')
-const quote = futuresStore.getQuoteInfo(goodscode)
+const quote = futuresStore.getQuoteDayInfo(goodscode)
 const subscribe = quoteSocket.createSubscribe()
 const sl = shallowRef(false) // 止损
 const sp = shallowRef(false) // 止盈

+ 1 - 1
src/packages/mobile/views/pricing/list/Index.vue

@@ -70,7 +70,7 @@ const { dataList } = useRequest(queryQuoteGoodsList, {
 
 const tableList = computed(() => {
     return dataList.value.map((item) => {
-        const quote = futuresStore.getQuoteInfo(item.goodscode)
+        const quote = futuresStore.getQuoteDayInfo(item.goodscode)
         const { lastColor, openedColor, lowestColor, highestColor, last, presettle, rise, change, amplitude, highest, lowest, opened, ask, bid, bidColor, askColor } = quote.value ?? {}
         return {
             ...item,

+ 1 - 1
src/packages/mobile/views/swap/list/Index.vue

@@ -65,7 +65,7 @@ const { dataList } = useRequest(queryQuoteGoodsList, {
 
 const tableList = computed(() => {
     return dataList.value.map((item) => {
-        const quote = futuresStore.getQuoteInfo(item.refgoodscode)
+        const quote = futuresStore.getQuoteDayInfo(item.refgoodscode)
         const { goodsname, lastColor, openedColor, lowestColor, highestColor, last, presettle, rise, change, amplitude, highest, lowest, opened } = quote.value ?? {}
         return {
             ...item,

+ 2 - 2
src/packages/mobile/views/transfer/detail/Index.vue

@@ -76,9 +76,9 @@ const componentMap = new Map<string, unknown>([
 ])
 
 const { getQueryStringToNumber } = useNavigation()
-const { getQuoteInfo } = useFuturesStore()
+const { getQuoteDayInfo } = useFuturesStore()
 const goodsid = getQueryStringToNumber('goodsid')
-const quote = getQuoteInfo(goodsid)
+const quote = getQuoteDayInfo(goodsid)
 
 const { componentRef, componentId, openComponent, closeComponent } = useComponent(() => {
     getPresaleDefault()

+ 2 - 2
src/packages/mobile/views/transfer/detail2/index.vue

@@ -74,9 +74,9 @@ const componentMap = new Map<string, unknown>([
 ])
 
 const { router, getQueryStringToNumber } = useNavigation()
-const { getQuoteInfo } = useFuturesStore()
+const { getQuoteDayInfo } = useFuturesStore()
 const goodsid = getQueryStringToNumber('goodsid')
-const quote = getQuoteInfo(goodsid)
+const quote = getQuoteDayInfo(goodsid)
 const goodsCode = computed(() => quote.value?.goodscode ?? '')
 
 const { componentRef, componentId, openComponent, closeComponent } = useComponent(() => {

+ 1 - 1
src/packages/pc/components/modules/listing/index.vue

@@ -78,7 +78,7 @@ const qtyStepList = [1, 10, 100] // 数量步长列表
 const qtyStep = shallowRef(qtyStepList[0]) // 数量步长
 
 // 商品盘面
-const quote = computed(() => futuresStore.getQuoteInfo(goodsStore.goodsCode).value)
+const quote = computed(() => futuresStore.getQuoteDayInfo(goodsStore.goodsCode).value)
 
 // 价格步长
 const priceStep = computed(() => {

+ 1 - 1
src/packages/pc/components/modules/quote/forex/index.vue

@@ -36,7 +36,7 @@ const props = defineProps({
 const emit = defineEmits<{ (event: string, ...args: unknown[]): void }>()
 const attrs = useAttrs()
 const futuresStore = useFuturesStore()
-const quote = computed(() => futuresStore.getQuoteInfo(props.goodsCode).value)
+const quote = computed(() => futuresStore.getQuoteDayInfo(props.goodsCode).value)
 const active = shallowRef('')
 
 const buyList = computed(() => {

+ 4 - 2
src/packages/pc/components/modules/quote/price/index.vue

@@ -71,10 +71,12 @@ const props = defineProps({
 
 const futuresStore = useFuturesStore()
 const subscribe = quoteSocket.createSubscribe()
-const quote = futuresStore.getQuoteInfo(props.goodsCode)
+const quote = futuresStore.getQuoteDayInfo(props.goodsCode)
 
 onMounted(() => subscribe.start(props.goodsCode))
 onUnmounted(() => subscribe.stop())
 </script>
 
-<style lang="less">@import './index.less';</style>
+<style lang="less">
+@import './index.less';
+</style>

+ 9 - 7
src/packages/pc/components/modules/quote/tik/index.vue

@@ -4,11 +4,11 @@
             <h4>成交明细</h4>
             <!-- <span>更多</span> -->
         </div>
-        <div class="app-quote-tik__body" v-if="quote">
+        <div class="app-quote-tik__body" v-if="quoteDay">
             <ul>
                 <li v-for="(item, index) in dataList" :key="index">
                     <span>{{ formatDate(item.TS, 'HH:mm:ss') }}</span>
-                    <span :class="handlePriceColor(item.PE, quote.presettle)">{{ handleNumberValue(item.PE) }}</span>
+                    <span :class="handlePriceColor(item.PE, quoteDay.presettle)">{{ handleNumberValue(item.PE) }}</span>
                     <span>{{ handleNumberValue(item.Vol) }}</span>
                 </li>
             </ul>
@@ -31,6 +31,7 @@ const props = defineProps({
 })
 
 const futuresStore = useFuturesStore()
+const quoteDay = futuresStore.getQuoteDayInfo(props.goodsCode)
 const quote = futuresStore.getQuoteInfo(props.goodsCode)
 const dataList = ref<Model.HistoryTikDatasRsp[]>([])
 
@@ -47,7 +48,7 @@ const { run: getHistoryTikDatas } = useRequest(queryHistoryTikDatas, {
 
 useRequest(queryMarketRun, {
     params: {
-        marketID: quote.value?.marketid
+        marketID: quoteDay.value?.marketid
     },
     onSuccess: (res) => {
         const market = res.data[0]
@@ -61,7 +62,8 @@ useRequest(queryMarketRun, {
 })
 
 watch(() => quote.value, (q) => {
-    if (q?.last) {
+    const { last = 0, lasttime = '', lastvolume = 0 } = q
+    if (last && lastvolume) {
         const list = dataList.value
         if (list.length > 9) {
             // 移除列表最后一条记录
@@ -75,12 +77,12 @@ watch(() => quote.value, (q) => {
             Bid: 0,
             HI: 0,
             HV: 0,
-            PE: q.last,
+            PE: last,
             TDR: 0,
             TK: 0,
-            TS: q.lasttime,
+            TS: lasttime,
             TT: 0,
-            Vol: q.lastvolume,
+            Vol: lastvolume,
         })
     }
 })

+ 3 - 1
src/packages/pc/views/auth/login/index.less

@@ -1,7 +1,9 @@
 .user-login {
     .text-link {
+        display: flex;
+        justify-content: space-between;
+        width: 100%;
         color: #666;
         cursor: pointer;
-        margin-left: auto;
     }
 }

+ 18 - 13
src/packages/pc/views/auth/login/index.vue

@@ -1,11 +1,11 @@
 <template>
-  <sign-layout class="user-login" :title="islogin ? '登录' : '重置密码'"  v-loading="rloading">
+  <sign-layout class="user-login" :title="islogin ? '登录' : '重置密码'">
     <el-form ref="formRef" :model="formData" :rules="formRules" v-if="islogin">
       <el-form-item prop="userName">
         <el-input placeholder="用户名/账号/手机号" v-model="formData.userName">
-          <template #append>
+          <!-- <template #append>
             <el-checkbox v-model="remember"></el-checkbox>
-          </template>
+          </template> -->
         </el-input>
       </el-form-item>
       <el-form-item prop="password">
@@ -13,8 +13,10 @@
         </el-input>
       </el-form-item>
       <el-form-item>
-        <span class="text-link" @click="click">立即注册</span>
-        <span class="text-link" @click="islogin = false">忘记密码?</span>
+        <div class="text-link">
+          <span @click="click">立即注册</span>
+          <span @click="islogin = false">忘记密码?</span>
+        </div>
       </el-form-item>
       <el-form-item>
         <el-button class="submit" type="primary" :loading="loading" @click="formSubmit">
@@ -24,12 +26,15 @@
       </el-form-item>
     </el-form>
     <Forget @close="islogin = true" v-else></Forget>
-    <el-dialog v-model="isRegister" title="立即注册" width="30%" >
-      <span>手机扫描二维码进行注册</span>
-      <app-qrcode class="app-register-code__qrcode" :text="qrContent" :logo="require('../../../assets/logo.svg')" />
+    <el-dialog class="register" v-model="isRegister" title="扫码注册" :width="360" center align-center>
+      <div v-loading="rloading" v-if="rloading"></div>
+      <div style="text-align: center;" v-else>
+        <app-qrcode class="app-register-code__qrcode" :width="240" :text="qrContent"
+          :logo="require('../../../assets/logo.svg')" />
+      </div>
       <template #footer>
         <span class="dialog-footer">
-          <el-button @click="isRegister = false">取消</el-button>
+          <el-button @click="isRegister = false">关闭</el-button>
         </span>
       </template>
     </el-dialog>
@@ -39,7 +44,7 @@
 <script lang="ts" setup>
 import { shallowRef } from 'vue'
 import { useRoute, useRouter } from 'vue-router'
-import { ElMessage, ElDialog } from 'element-plus'
+import { ElMessage } from 'element-plus'
 import type { FormInstance, FormRules } from 'element-plus'
 import { ClientType } from '@/constants/client'
 import { useLogin } from '@/business/login'
@@ -49,7 +54,7 @@ import SignLayout from '../components/layout/index.vue'
 import Forget from "../forget/index.vue"
 import AppQrcode from '@/components/base/qrcode/index.vue'
 
-const { formData, remember, userLogin } = useLogin()
+const { formData, userLogin } = useLogin()
 const route = useRoute()
 const router = useRouter()
 const menuStore = useMenuStore()
@@ -70,13 +75,13 @@ const formRules: FormRules = {
 }
 
 const click = () => {
+  isRegister.value = true
   rloading.value = true
   service.onReady().then((res) => {
     qrContent.value = res.mobileOpenUrl
-    isRegister.value = true
   }).finally(() => {
     rloading.value = false
-  }) 
+  })
 }
 
 const formSubmit = () => {

+ 2 - 2
src/packages/pc/views/footer/goods/position/components/delivery/index.vue

@@ -65,7 +65,7 @@ const show = ref(true)
 const refresh = ref(false)
 const formRef = ref<FormInstance>()
 const futuresStore = useFuturesStore()
-const quote = futuresStore.getQuoteInfo(props.selectedRow.goodscode)
+const quote = futuresStore.getQuoteDayInfo(props.selectedRow.goodscode)
 
 /// 计算参考损益
 const closepl = computed(() => {
@@ -113,7 +113,7 @@ const onSubmit = () => {
             })
         }
     })
-    
+
 }
 
 </script>

+ 1 - 1
src/packages/pc/views/footer/goods/position/components/transfer/index.vue

@@ -69,7 +69,7 @@ const props = defineProps({
 })
 
 const futuresStore = useFuturesStore()
-const quote = futuresStore.getQuoteInfo(props.selectedRow.goodscode)
+const quote = futuresStore.getQuoteDayInfo(props.selectedRow.goodscode)
 // 损益
 const closepl = computed(() => {
     const { last = 0 } = quote.value ?? {}

+ 5 - 23
src/packages/pc/views/footer/goods/position/index.vue

@@ -8,13 +8,13 @@
         </template>
         <!-- 最新价 -->
         <template #lastprice="{ row }">
-            <span :class="lastColor(row)">
-                {{ lastprice(row) }}
+            <span :class="row.lastColor">
+                {{ handleNumberValue(row.last) }}
             </span>
         </template>
         <!-- 浮动盈亏-->
         <template #closepl="{ row }">
-            <span :class="handlePriceColor(closepl(row), 0.0)">{{ closepl(row).toFixed(2) }}</span>
+            <span :class="row.closeplColor">{{ row.closepl.toFixed(2) }}</span>
         </template>
         <!-- 展开行 -->
         <template #expand="{ row }">
@@ -32,38 +32,20 @@
 
 <script lang="ts" setup>
 import { shallowRef, defineAsyncComponent } from 'vue'
-import { getBuyOrSellName, BuyOrSell } from '@/constants/order'
+import { getBuyOrSellName } from '@/constants/order'
 import { useComponent } from '@/hooks/component'
 import { useComposeTable } from '@pc/components/base/table'
-import { useFuturesStore } from '@/stores'
 import { usePosition } from '@/business/position'
 import AppTable from '@pc/components/base/table/index.vue'
-import { handlePriceColor } from '@/filters'
+import { handleNumberValue } from '@/filters'
 
 const componentMap = new Map<string, unknown>([
     ['delivery', defineAsyncComponent(() => import('./components/delivery/index.vue'))],
     ['transfer', defineAsyncComponent(() => import('./components/transfer/index.vue'))],
 ])
 
-const futuresStore = useFuturesStore()
 const { positionList, loading } = usePosition(50)
 
-const lastprice = (item: Model.TradePositionRsp) => {
-    const { last = 0 } = futuresStore.getQuoteInfo(item.goodscode).value ?? {}
-    return last
-}
-
-const lastColor = (item: Model.TradePositionRsp) => {
-    return futuresStore.getQuoteInfo(item.goodscode).value?.lastColor
-}
-
-/// 计算参考损益
-const closepl = (item: Model.TradePositionRsp) => {
-    const { last = 0 } = futuresStore.getQuoteInfo(item.goodscode).value ?? {}
-    const { curpositionqty, curholderamount, agreeunit, buyorsell } = item
-    return (last * curpositionqty * agreeunit - curholderamount) * (buyorsell === BuyOrSell.Buy ? 1 : -1)
-}
-
 const { componentRef, componentId, openComponent, closeComponent } = useComponent()
 
 const { rowKey, expandKeys, selectedRow, rowClick } = useComposeTable<Model.TradePositionRsp>({ rowKey: 'pkid' })

+ 1 - 1
src/packages/pc/views/market/trade/goods/detail/components/order/delisting/index.vue

@@ -71,7 +71,7 @@ const qtyStepList = [1, 5, 10, 20, 30, 50] // 数量步长列表
 const qtyStep = shallowRef(qtyStepList[0]) // 数量步长
 
 // 商品盘面
-const quote = futuresStore.getQuoteInfo(props.selectedRow.goodsid)
+const quote = futuresStore.getQuoteDayInfo(props.selectedRow.goodsid)
 
 // 买方向持仓数量
 const buyQty = computed(() => getOrderQty(BuyOrSell.Buy, props.selectedRow.goodsid))

+ 1 - 1
src/packages/pc/views/market/trade/goods/detail/components/order/index.vue

@@ -49,7 +49,7 @@ const componentMap = new Map<string, unknown>([
 
 const loginStore = useLoginStore()
 const futuresStore = useFuturesStore()
-const quote = futuresStore.getQuoteInfo(props.goodsId)
+const quote = futuresStore.getQuoteDayInfo(props.goodsId)
 
 const { rowKey, expandKeys, selectedRow, rowClick } = useComposeTable<Model.WrTradeOrderDetailRsp>({ rowKey: 'orderid' })
 const { componentRef, componentId, openComponent, closeComponent } = useComponent()

+ 1 - 1
src/packages/pc/views/market/trade/goods/detail/index.vue

@@ -44,7 +44,7 @@ const props = defineProps({
 
 const emit = defineEmits(['closed'])
 const futuresStore = useFuturesStore()
-const quote = futuresStore.getQuoteInfo(props.goodsId)
+const quote = futuresStore.getQuoteDayInfo(props.goodsId)
 const active = shallowRef(true)
 
 const goodsCode = computed(() => quote.value?.goodscode ?? '')

+ 1 - 1
src/packages/pc/views/market/trade/goods/index.vue

@@ -64,7 +64,7 @@ const { componentRef, componentId, openComponent, closeComponent } = useComponen
 
 const tableList = computed(() => {
     return quoteGoodsList.value.map((item) => {
-        const quote = futuresStore.getQuoteInfo(item.goodscode)
+        const quote = futuresStore.getQuoteDayInfo(item.goodscode)
         const { bid, bidColor, bidvolume, ask, askColor, askvolume, goodunitid, agreeunit, limitdown, limitup, lastColor, openedColor, lowestColor, highestColor, last, presettle, rise, change, amplitude, highest, lowest, opened, decimalplace } = quote.value ?? {}
         return {
             ...item,

+ 1 - 1
src/packages/qxst/components/modules/quote/forex/index.vue

@@ -56,7 +56,7 @@ const emit = defineEmits<{ (event: string, ...args: unknown[]): void }>()
 const { router } = useNavigation()
 const attrs = useAttrs()
 const futuresStore = useFuturesStore()
-const quote = computed(() => futuresStore.getQuoteInfo(props.goodsCode).value)
+const quote = computed(() => futuresStore.getQuoteDayInfo(props.goodsCode).value)
 const active = shallowRef('')
 
 const buyList = computed(() => {

+ 1 - 1
src/packages/qxst/components/modules/quote/price/index.vue

@@ -89,7 +89,7 @@ const props = defineProps({
 
 const futuresStore = useFuturesStore()
 const subscribe = quoteSocket.createSubscribe()
-const quote = futuresStore.getQuoteInfo(props.goodsCode)
+const quote = futuresStore.getQuoteDayInfo(props.goodsCode)
 const showMore = shallowRef(false)
 
 onMounted(() => subscribe.start(props.goodsCode))

+ 1 - 1
src/packages/qxst/components/modules/quote/tik/index.vue

@@ -28,7 +28,7 @@ const props = defineProps({
 })
 
 const futuresStore = useFuturesStore()
-const quote = futuresStore.getQuoteInfo(props.goodsCode)
+const quote = futuresStore.getQuoteDayInfo(props.goodsCode)
 const dataList = ref<Model.HistoryTikDatasRsp[]>([])
 
 const columns: Model.TableColumn[] = [

+ 1 - 1
src/packages/qxst/views/goods/detail/Index.vue

@@ -41,7 +41,7 @@ const { positionList } = usePosition(50)
 const { getQueryStringToNumber } = useNavigation()
 const futuresStore = useFuturesStore()
 const goodsid = getQueryStringToNumber('goodsid')
-const quote = futuresStore.getQuoteInfo(goodsid)
+const quote = futuresStore.getQuoteDayInfo(goodsid)
 const buildType = shallowRef<EBuildType>() // 挂牌类型
 
 const goodsCode = computed(() => quote.value?.goodscode ?? '')

+ 1 - 1
src/packages/qxst/views/goods/detail/components/listing/Index.vue

@@ -87,7 +87,7 @@ const { getOrderQty } = usePosition(50)
 const { formData, formSubmit } = useOrder()
 const accountStore = useAccountStore()
 const futuresStore = useFuturesStore()
-const quote = futuresStore.getQuoteInfo(props.goodsCode)
+const quote = futuresStore.getQuoteDayInfo(props.goodsCode)
 const formRef = shallowRef<FormInstance>()
 const showModal = shallowRef(true)
 const refresh = shallowRef(true) // 是否刷新父组件数据

+ 1 - 1
src/packages/qxst/views/goods/list/Index.vue

@@ -91,7 +91,7 @@ const { dataList } = useRequest(queryQuoteGoodsList, {
 
 const tableList = computed(() => {
     return dataList.value.map((item) => {
-        const quote = futuresStore.getQuoteInfo(item.goodscode)
+        const quote = futuresStore.getQuoteDayInfo(item.goodscode)
         const { goodsname, bid, bidColor, bidvolume, ask, askColor, askvolume, limitdown, limitup, lastColor, openedColor, lowestColor, highestColor, last, presettle, rise, change, amplitude, highest, lowest, opened } = quote.value ?? {}
         return {
             ...item,

+ 1 - 1
src/packages/qxst/views/goods/trade/components/delisting/index.vue

@@ -97,7 +97,7 @@ const futuresStore = useFuturesStore()
 const { getOrderQty } = usePosition(50)
 const { formData, formSubmit } = useOrder()
 
-const quote = futuresStore.getQuoteInfo(props.selectedRow.goodsid)
+const quote = futuresStore.getQuoteDayInfo(props.selectedRow.goodsid)
 const formRef = shallowRef<FormInstance>()
 const showModal = shallowRef(true)
 const refresh = shallowRef(false) // 是否刷新父组件数据

+ 1 - 1
src/packages/qxst/views/goods/trade/index.vue

@@ -52,7 +52,7 @@ const goodsid = getQueryStringToNumber('goodsid')
 const buyorsell = getQueryStringToNumber('buyorsell')
 const loginStore = useLoginStore()
 const futuresStore = useFuturesStore()
-const quote = futuresStore.getQuoteInfo(goodsid)
+const quote = futuresStore.getQuoteDayInfo(goodsid)
 
 const tabIndex = shallowRef(buyorsell)
 const selectedRow = shallowRef<Model.WrTradeOrderDetailRsp>()

+ 1 - 1
src/packages/qxst/views/order/position/components/goods/close/Index.vue

@@ -64,7 +64,7 @@ const props = defineProps({
 })
 
 const futuresStore = useFuturesStore()
-const quote = futuresStore.getQuoteInfo(props.selectedRow.goodscode)
+const quote = futuresStore.getQuoteDayInfo(props.selectedRow.goodscode)
 const showModal = shallowRef(true)
 // 是否刷新父组件数据
 const refresh = shallowRef(false)

+ 1 - 1
src/packages/qxst/views/order/position/components/goods/delivery/Index.vue

@@ -64,7 +64,7 @@ const showModal = shallowRef(true)
 const refresh = shallowRef(false)
 const { formSubmit, formData } = useOfflineDelivery()
 const futuresStore = useFuturesStore()
-const quote = futuresStore.getQuoteInfo(props.selectedRow.goodscode)
+const quote = futuresStore.getQuoteDayInfo(props.selectedRow.goodscode)
 
 /// 计算参考损益
 const closepl = computed(() => {

+ 1 - 1
src/packages/sbyj/components/modules/quote/forex/index.vue

@@ -90,7 +90,7 @@ const props = defineProps({
 const emit = defineEmits(['sellclick', 'buyclick'])
 const { router } = useNavigation()
 const futuresStore = useFuturesStore()
-const quote = futuresStore.getQuoteInfo(props.goodsCode)
+const quote = futuresStore.getQuoteDayInfo(props.goodsCode)
 
 const onBuyClick = (index: number) => {
     emit('buyclick', index)

+ 1 - 1
src/packages/sbyj/components/modules/quote/price/index.vue

@@ -89,7 +89,7 @@ const props = defineProps({
 
 const futuresStore = useFuturesStore()
 const subscribe = quoteSocket.createSubscribe()
-const quote = futuresStore.getQuoteInfo(props.goodsCode)
+const quote = futuresStore.getQuoteDayInfo(props.goodsCode)
 const showMore = shallowRef(false)
 
 onMounted(() => subscribe.start(props.goodsCode))

+ 1 - 1
src/packages/sbyj/components/modules/quote/tik/index.vue

@@ -28,7 +28,7 @@ const props = defineProps({
 })
 
 const futuresStore = useFuturesStore()
-const quote = futuresStore.getQuoteInfo(props.goodsCode)
+const quote = futuresStore.getQuoteDayInfo(props.goodsCode)
 const dataList = ref<Model.HistoryTikDatasRsp[]>([])
 
 const columns: Model.TableColumn[] = [

+ 1 - 1
src/packages/sbyj/views/market/detail/index.vue

@@ -130,7 +130,7 @@ const { getQueryString } = useNavigation()
 const { formData, formSubmit } = useOrder()
 const futuresStore = useFuturesStore()
 const goodscode = getQueryString('goodscode')
-const quote = futuresStore.getQuoteInfo(goodscode)
+const quote = futuresStore.getQuoteDayInfo(goodscode)
 const qtyStep = shallowRef(1) // 数量步长
 const error = shallowRef(false)
 const subscribe = quoteSocket.createSubscribe()

+ 1 - 1
src/packages/sbyj/views/order/list/components/close-holder/index.vue

@@ -55,7 +55,7 @@ const props = defineProps({
 })
 
 const futuresStore = useFuturesStore()
-const quote = futuresStore.getQuoteInfo(props.selectedRow.goodsCode)
+const quote = futuresStore.getQuoteDayInfo(props.selectedRow.goodsCode)
 const { formData, formSubmit } = useOrder()
 const formRef = shallowRef<FormInstance>()
 const showModal = shallowRef(true)

+ 1 - 1
src/services/websocket/build/index.ts

@@ -78,7 +78,7 @@ export class MTP2WebSocket<T extends Package40 | Package50>{
                 this.uuid = uuid;
 
                 try {
-                    this.ws = new WebSocket(this.host, this.protocols);
+                    this.ws = this.protocols ? new WebSocket(this.host, this.protocols) : new WebSocket(this.host);
                     // 连接成功
                     this.ws.onopen = () => {
                         console.log(this.host, '连接成功');

+ 140 - 0
src/services/websocket/newQuote.ts

@@ -0,0 +1,140 @@
+import { v4 } from 'uuid'
+import { useLoginStore } from '@/stores'
+import service from '@/services'
+import eventBus from '@/services/bus'
+import { quoteSubscribe } from '@/services/api/quote'
+import { MTP2WebSocket } from './build'
+import { Package40 } from './package'
+import { parseReceivePush } from './package/package40/decode'
+
+export default new (class {
+    private loginStore = useLoginStore()
+
+    /** 行情链路 */
+    private socket = new MTP2WebSocket(Package40)
+
+    /** 行情订阅集合 */
+    private subscribeMap = new Map<string, string[]>()
+
+    constructor() {
+        this.socket.onOpen = () => {
+            this.subscribe()
+        }
+
+        this.socket.onReconnect = () => {
+            // 重新订阅商品
+            this.subscribe()
+        }
+
+        this.socket.onPush = (p) => {
+            const { mainClassNumber, content } = p
+            if (mainClassNumber === 65 && content) {
+                const result = parseReceivePush(content)
+                // 通知上层 行情推送
+                eventBus.$emit('QuotePushNotify', result)
+            }
+        }
+    }
+
+    async connect() {
+        const res = await service.onReady()
+        await this.socket.connect(res.quoteWS, this.loginStore.token)
+    }
+
+    /**
+     * 开始行情订阅
+     */
+    private subscribe = () => {
+        const quoteGoodses: Model.QuoteSubscribeReq['quoteGoodses'] = []
+
+        this.subscribeMap.forEach((list) => {
+            list.forEach((code) => {
+                if (!quoteGoodses.some((e) => e.goodsCode === code)) {
+                    quoteGoodses.push({
+                        exchangeId: 250,
+                        goodsCode: code,
+                    })
+                }
+            })
+        })
+
+        if (quoteGoodses.length) {
+            console.log('开始行情订阅', quoteGoodses)
+            this.connect().then(() => {
+                quoteSubscribe({
+                    data: {
+                        quoteGoodses
+                    }
+                }).then((res) => {
+                    console.log('行情订阅成功', res)
+                }).catch((err) => {
+                    console.error('行情订阅失败', err)
+                })
+            })
+        }
+    }
+
+    /**
+     * 创建行情订阅
+     * @param goodsCodes 
+     * @param key 
+     * @returns 
+     */
+    createSubscribe = (key?: string) => {
+        const loginStore = useLoginStore()
+        const uuid = key ?? v4()
+        const values = this.subscribeMap.get(uuid) ?? []
+
+        const start = (...goodsCodes: string[]) => {
+            if (loginStore.token) {
+                goodsCodes.forEach((code) => {
+                    if (code && !values.includes(code)) {
+                        values.push(code)
+                    }
+                })
+                this.subscribeMap.set(uuid, values)
+                this.subscribe()
+            }
+        }
+
+        return {
+            uuid,
+            start,
+            stop: () => {
+                const flag = this.subscribeMap.delete(uuid)
+                if (flag) {
+                    console.log('删除订阅', uuid)
+                }
+                if (loginStore.token) {
+                    this.subscribe()
+                }
+                return flag
+            },
+        }
+    }
+
+    /**
+     * 删除行情订阅
+     * @param keys 
+     */
+    removeSubscribe = (...keys: string[]) => {
+        if (keys.length) {
+            keys.forEach((key) => {
+                if (this.subscribeMap.delete(key)) {
+                    console.log('删除订阅', key)
+                }
+            })
+        } else {
+            console.log('取消订阅')
+            this.subscribeMap.clear()
+        }
+        this.subscribe()
+    }
+
+    /**
+     * 关闭行情链路
+     */
+    close() {
+        this.socket?.close()
+    }
+})

+ 39 - 31
src/services/websocket/quote.ts

@@ -1,15 +1,14 @@
 import { v4 } from 'uuid'
-import { useLoginStore } from '@/stores'
+import { FunCode } from '@/constants/funcode'
 import service from '@/services'
 import eventBus from '@/services/bus'
-import { quoteSubscribe } from '@/services/api/quote'
 import { MTP2WebSocket } from './build'
 import { Package40 } from './package'
-import { parseReceivePush } from './package/package40/decode'
+import { parseReceivePush, parseSubscribeRsp } from './package/package40/decode'
+import { subscribeListToByteArrary } from './package/package40/encode'
+import Long from 'long'
 
 export default new (class {
-    private loginStore = useLoginStore()
-
     /** 行情链路 */
     private socket = new MTP2WebSocket(Package40)
 
@@ -38,37 +37,51 @@ export default new (class {
 
     async connect() {
         const res = await service.onReady()
-        await this.socket.connect(res.quoteWS, this.loginStore.token)
+        await this.socket.connect(res.quoteUrl)
     }
 
     /**
      * 开始行情订阅
      */
     private subscribe = () => {
-        const quoteGoodses: Model.QuoteSubscribeReq['quoteGoodses'] = []
+        const goodsList: Proto.QuoteReq[] = []
 
         this.subscribeMap.forEach((list) => {
             list.forEach((code) => {
-                if (!quoteGoodses.some((e) => e.goodsCode === code)) {
-                    quoteGoodses.push({
-                        exchangeId: 250,
+                if (!goodsList.some((e) => e.goodsCode === code)) {
+                    goodsList.push({
+                        exchangeCode: 250,
                         goodsCode: code,
+                        subState: 0,
                     })
                 }
             })
         })
 
-        if (quoteGoodses.length) {
-            console.log('开始行情订阅', quoteGoodses)
+        if (goodsList.length) {
+            console.log('开始行情订阅', goodsList)
             this.connect().then(() => {
-                quoteSubscribe({
+                const content = subscribeListToByteArrary(goodsList, '2_TOKEN_NEKOT_', Long.fromNumber(2))
+
+                this.socket.send({
                     data: {
-                        quoteGoodses
+                        rspCode: FunCode.QuoteSubscribeRsp,
+                        payload: new Package40(FunCode.QuoteSubscribeReq, content)
+                    },
+                    success: (raw) => {
+                        if (raw.content) {
+                            parseSubscribeRsp(raw.content).then((res) => {
+                                console.log('行情订阅成功', res)
+                            }).catch(() => {
+                                console.error('报文解析失败', raw)
+                            })
+                        } else {
+                            console.error('数据异常')
+                        }
+                    },
+                    fail: (err) => {
+                        console.error('行情订阅失败', err)
                     }
-                }).then((res) => {
-                    console.log('行情订阅成功', res)
-                }).catch((err) => {
-                    console.error('行情订阅失败', err)
                 })
             })
         }
@@ -81,20 +94,17 @@ export default new (class {
      * @returns 
      */
     createSubscribe = (key?: string) => {
-        const loginStore = useLoginStore()
         const uuid = key ?? v4()
         const values = this.subscribeMap.get(uuid) ?? []
 
         const start = (...goodsCodes: string[]) => {
-            if (loginStore.token) {
-                goodsCodes.forEach((code) => {
-                    if (code && !values.includes(code)) {
-                        values.push(code)
-                    }
-                })
-                this.subscribeMap.set(uuid, values)
-                this.subscribe()
-            }
+            goodsCodes.forEach((code) => {
+                if (code && !values.includes(code)) {
+                    values.push(code)
+                }
+            })
+            this.subscribeMap.set(uuid, values)
+            this.subscribe()
         }
 
         return {
@@ -105,9 +115,7 @@ export default new (class {
                 if (flag) {
                     console.log('删除订阅', uuid)
                 }
-                if (loginStore.token) {
-                    this.subscribe()
-                }
+                this.subscribe()
                 return flag
             },
         }

+ 19 - 9
src/stores/modules/futures.ts

@@ -182,14 +182,27 @@ export const useFuturesStore = defineStore(() => {
     }
 
     // 通过 goodscode 获取实时行情信息
-    const getQuoteInfo = (code?: string | number) => {
+    const getQuoteInfo = (goodsCode: string) => {
+        return computed(() => {
+            const quote = state.quotes.find((e) => e.goodscode === goodsCode)
+            const lasttime = (quote?.date && quote.time) ? moment(quote.date + quote.time, 'YYYYMMDDHHmmss').format('YYYY-MM-DD HH:mm:ss') : ''
+
+            return {
+                ...quote,
+                lasttime
+            }
+        })
+    }
+
+    // 通过 goodscode 获取实时盘面信息
+    const getQuoteDayInfo = (code?: string | number) => {
         return computed(() => quoteList.value.find((e) => e.goodscode === code || e.goodsid === code))
     }
 
     // 通过 goodscode 获取实时行情报价
     const getQuotePrice = (code?: string | number) => {
         return computed(() => {
-            const quote = getQuoteInfo(code)
+            const quote = getQuoteDayInfo(code)
             return quote.value?.last ?? 0
         })
     }
@@ -206,8 +219,8 @@ export const useFuturesStore = defineStore(() => {
         return quote?.marketid ?? 0
     }
 
-    // 处理行情数据
-    const handleQuote = timerInterceptor.setThrottle(() => {
+    // 更新盘面数据
+    const updateQuoteDay = 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())
@@ -388,21 +401,18 @@ export const useFuturesStore = defineStore(() => {
                 state.quotes.push(item)
             }
         })
-        handleQuote()
+        updateQuoteDay()
     })
 
-    // 接收委托单成交通知
-    const orderDealedNtf = eventBus.$on('OrderDealedNtf', () => getGoodsList())
-
     return {
         ...toRefs(state),
         quoteList,
         getGoodsList,
+        getQuoteDayInfo,
         getQuoteInfo,
         getQuotePrice,
         getGoodsName,
         getGoodsMarket,
         quotePushNotify,
-        orderDealedNtf,
     }
 })

+ 12 - 4
src/stores/modules/position.ts

@@ -1,4 +1,5 @@
 import { reactive, computed, toRefs } from 'vue'
+import { handlePriceColor } from '@/filters'
 import { BuyOrSell } from '@/constants/order'
 import { queryTradePosition } from '@/services/api/order'
 import { useFuturesStore } from './futures'
@@ -29,18 +30,25 @@ export const usePositionStore = defineStore(() => {
     // 持仓汇总计算列表
     const orderPositionComputedList = computed(() => {
         const result: (Model.TradePositionRsp & {
-            closepl: number; // 参考损益
+            last: number; // 最新价
+            lastColor: string; // 最新价颜色
+            closepl: number; // 浮动盈亏
+            closeplColor: string; // 浮动盈亏颜色
         })[] = []
 
         state.orderPositionList.forEach((item) => {
-            const lastPrice = futuresStore.getQuotePrice(item.goodscode)
+            const quote = futuresStore.getQuoteDayInfo(item.goodscode)
+            const { last = 0, lastColor = '' } = quote.value ?? {}
 
-            // 计算参考损益
-            const closepl = (lastPrice.value * item.curpositionqty * item.agreeunit - item.curholderamount) * (item.buyorsell === BuyOrSell.Buy ? 1 : -1)
+            // 计算浮动盈亏
+            const closepl = (last * item.curpositionqty * item.agreeunit - item.curholderamount) * (item.buyorsell === BuyOrSell.Buy ? 1 : -1)
 
             result.push({
                 ...item,
+                last,
+                lastColor,
                 closepl,
+                closeplColor: handlePriceColor(closepl, 0),
             })
         })