li.shaoyi 3 tahun lalu
induk
melakukan
ed7e099e18

+ 1 - 1
public/config/appconfig.json

@@ -1,4 +1,4 @@
 {
   "version": "3.0.0",
-  "apiUrl": "http://47.104.141.54:38280/cfg?key=mtp_20"
+  "apiUrl": "http://192.168.31.203:8080/cfg?key=test_203"
 }

+ 10 - 3
src/business/account/index.ts

@@ -5,6 +5,7 @@ import { sessionCache } from '@/store'
 import { initBaseData } from '@/business/common'
 import { login, queryLoginId } from '@/services/api/account'
 import { v4 } from 'uuid'
+import eventBus from '@/services/bus'
 
 export function useAccount() {
     const route = useRoute(),
@@ -12,8 +13,8 @@ export function useAccount() {
         loading = ref(false);
 
     const account = reactive<Proto.LoginReq>({
-        LoginID: '2177700025',
-        LoginPWD: 'd99999999',
+        LoginID: '1000',
+        LoginPWD: '123456',
         GUID: v4(),
         LoginType: 0,
         ClientType: 4,
@@ -21,7 +22,7 @@ export function useAccount() {
         DeviceID: ''
     })
 
-    // 户登录
+    // 户登录
     const userLogin = (callback?: (msg?: string) => void) => {
         loading.value = true;
         return queryLoginId({
@@ -63,9 +64,15 @@ export function useAccount() {
         })
     }
 
+    // 用户登出
+    const userlogout = () => {
+        eventBus.$emit('logoutNotify');
+    }
+
     return {
         loading,
         account,
         userLogin,
+        userlogout,
     }
 }

+ 6 - 220
src/business/common/index.ts

@@ -1,190 +1,10 @@
 import { useRoute } from 'vue-router'
-import moment from 'moment'
 import eventBus from '@/services/bus'
 import { queryGoodsList } from '@/services/api/goods'
-import { quoteServerRequest } from '@/services/socket/quote'
 import { globalState, sessionCache, localCache } from '@/store'
 import socket from '@/services/socket'
 
 /**
- * 全局消息订阅
- */
-function globalSubscribeMessage() {
-    // 监听退出登录
-    eventBus.$on('logout', () => {
-        socket.closeQuoteServer();
-        socket.closeTradeServer();
-    });
-
-    // 监听行情推送
-    eventBus.$on('subscribeQuote', (res) => {
-        const tmpList = <Proto.GoodsQuote[]>res;
-
-        tmpList.forEach((item) => {
-            const quoteList = globalState.getRef('quoteList');
-            const quote = quoteList.value.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) {
-                // 数据更新
-                let key: keyof Proto.GoodsQuote;
-                for (key in item) {
-                    // 只更新有值的属性
-                    if (Reflect.has(quote, key)) {
-                        type QuoteKey = keyof Ermcp.QuoteDay;
-                        type QuoteValue = Ermcp.QuoteDay[QuoteKey];
-                        (<QuoteValue>quote[<QuoteKey>key]) = <QuoteValue>(<unknown>item[key]);
-                    }
-                }
-
-                // 处理最高最低价
-                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 + ' 缺少盘面信息')
-                quoteList.value.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: ''
-                });
-            }
-        })
-    })
-}
-
-/**
  * 初始化业务数据
  * @param callback 
  */
@@ -200,7 +20,12 @@ export async function initBaseData(callback?: () => void) {
 
     await Promise.all([getGoodsList]);
 
-    globalSubscribeMessage();
+    // 接收用户登出通知
+    eventBus.$on('logoutNotify', () => {
+        socket.closeQuoteServer();
+        socket.closeTradeServer();
+    })
+
     callback && callback();
 }
 
@@ -234,43 +59,4 @@ export function getAccountAuth(filtered: string[] = [], reverse = false) {
     }
 
     return result;
-}
-
-/**
- * 行情服务订阅
- */
-export function useSubscribe() {
-    // 添加订阅
-    const addSubscribe = () => {
-        quoteServerRequest({
-            data: [
-                {
-                    "exchangeCode": 250,
-                    "goodsCode": "CFN003",
-                    "subState": 0
-                },
-                {
-                    "exchangeCode": 250,
-                    "goodsCode": "CFN002",
-                    "subState": 0
-                },
-                {
-                    "exchangeCode": 250,
-                    "goodsCode": "CFN001",
-                    "subState": 0
-                }
-            ],
-            success: (res) => {
-                if (res.length) {
-                    console.log('行情订阅成功', res)
-                } else {
-                    console.log('行情订阅失败')
-                }
-            }
-        })
-    }
-
-    return {
-        addSubscribe
-    }
 }

+ 253 - 9
src/business/quote/index.ts

@@ -1,17 +1,261 @@
-import { computed } from 'vue'
+import { v4 } from 'uuid'
+import { quoteServerRequest } from '@/services/socket/quote'
 import { globalState } from '@/store'
+import moment from 'moment'
+import eventBus from '@/services/bus'
+import socket from '@/services/socket'
 
-export function useQuote() {
-    const quoteList = globalState.getRef('quoteList');
+export default new (class {
+    /** 订阅列表 */
+    private subscribeMap = new Map<string, string[]>();
 
-    const getQuote = (goodscode: string) => {
-        const quote = quoteList.value.findIndex((e) => e.goodscode.toUpperCase() === goodscode.toUpperCase());
-        if (quote) {
+    constructor() {
+        // 接收行情服务断线重连成功通知
+        eventBus.$on('quoteServerReconnectNotify', () => {
+            this.startSubscribe();
+        })
 
+        // 接收行情推送通知
+        eventBus.$on('quotePushNotify', (res) => {
+            const tmpList = <Proto.GoodsQuote[]>res;
+
+            tmpList.forEach((item) => {
+                const quoteList = globalState.getRef('quoteList');
+                const quote = quoteList.value.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) {
+                    // 数据更新
+                    let key: keyof Proto.GoodsQuote;
+                    for (key in item) {
+                        // 只更新有值的属性
+                        if (Reflect.has(quote, key)) {
+                            type QuoteKey = keyof Ermcp.QuoteDay;
+                            type QuoteValue = Ermcp.QuoteDay[QuoteKey];
+                            (<QuoteValue>quote[<QuoteKey>key]) = <QuoteValue>(<unknown>item[key]);
+                        }
+                    }
+
+                    // 处理最高最低价
+                    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 + ' 缺少盘面信息')
+                    quoteList.value.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: ''
+                    })
+                }
+            })
+        })
+    }
+
+    /**
+     * 开始订阅
+     */
+    startSubscribe() {
+        const subscribeData: Proto.GoodsQuoteReq[] = [];
+
+        this.subscribeMap.forEach((value) => {
+            const item = value.map((code) => ({
+                goodsCode: code,
+                exchangeCode: 250,
+                subState: 0
+            }))
+            subscribeData.push(...item);
+        })
+
+        if (subscribeData.length) {
+            console.log('开始行情订阅', subscribeData)
+            quoteServerRequest({
+                data: subscribeData,
+                success: (res) => {
+                    if (res.length) {
+                        console.log('行情订阅成功', res)
+                    } else {
+                        console.error('行情订阅失败')
+                    }
+                },
+                fail: (err) => {
+                    console.error('行情订阅失败', err)
+                }
+            })
+        } else {
+            // 没有订阅商品的时候,断开连接
+            socket.closeQuoteServer();
         }
     }
 
-    return {
-        getQuote
+    /**
+     * 添加订阅
+     * @param goodsCodes 
+     * @param key 
+     * @returns 
+     */
+    addSubscribe(goodsCodes: string[], key?: string) {
+        const uuid = key ?? v4();
+        const value = this.subscribeMap.get(uuid) ?? [];
+
+        // 对相同 key 订阅的商品进行合并处理
+        this.subscribeMap.set(uuid, [...value, ...goodsCodes]);
+        this.startSubscribe();
+
+        return {
+            uuid,
+            stop: () => {
+                console.log('删除订阅', uuid);
+                this.subscribeMap.delete(uuid);
+                this.startSubscribe();
+            },
+        }
+    }
+
+    /**
+     * 删除订阅
+     * @param keys 
+     */
+    removeSubscribe(...keys: string[]) {
+        if (keys.length) {
+            console.log('删除订阅', keys);
+            keys.forEach((key) => {
+                this.subscribeMap.delete(key);
+            })
+        } else {
+            this.subscribeMap.clear();
+        }
+        this.startSubscribe();
     }
-}
+})

+ 3 - 0
src/constants/enum/funcode.ts

@@ -9,6 +9,9 @@ export enum FunCode {
     LoginReq = 65537, // 用户登录请求
     LoginRsp = 65538, // 用户登录应答
 
+    // 交易通知
+    MoneyChangedNotify = 131076, // 资金变化通知
+
     // 行情内容
     QuoteBeat = 0x12, // 心跳
     QuoteSubscribeReq = 0x20, // 实时行情订阅请求

+ 1 - 1
src/mock/account.ts

@@ -5,7 +5,7 @@ const getLoginId = {
         code: 200,
         message: 'success',
         total: 0,
-        data: '2177700025'
+        data: '110000000001'
     }
 }
 

+ 5 - 0
src/packages/mobile/router/index.ts

@@ -6,6 +6,11 @@ import Page from '@mobile/components/layouts/page/index.vue'
 
 const routes: Array<RouteRecordRaw> = [
   {
+    path: '/:pathMatch(.*)*',
+    name: 'error',
+    component: () => import('../views/error/404.vue')
+  },
+  {
     path: '/boot',
     name: 'boot',
     component: () => import('../views/boot/index.vue')

+ 3 - 0
src/packages/mobile/views/error/404.vue

@@ -0,0 +1,3 @@
+<template>
+    <div>404</div>
+</template>

+ 12 - 7
src/packages/pc/views/market/quote/index.vue

@@ -2,8 +2,9 @@
   <app-view class="market-quote">
     <app-filter @search="search" />
     <!-- 表格数据 -->
-    <app-table :columns="columns" :row-key="rowKey" :expand-row-keys="expands" :data="tableList" @row-click="rowClickExpand" @row-contextmenu="rowContextmenu">
-      <template #expand="{row}">
+    <app-table :columns="columns" :row-key="rowKey" :expand-row-keys="expands" :data="tableList"
+      @row-click="rowClickExpand" @row-contextmenu="rowContextmenu">
+      <template #expand="{ row }">
         <app-button-group :data="handleButton(row)" @click="openComponent" />
       </template>
     </app-table>
@@ -17,9 +18,9 @@
 </template>
 
 <script lang="ts" setup>
-import { defineAsyncComponent } from 'vue';
+import { defineAsyncComponent, onBeforeUnmount } from 'vue';
 import { queryGoodsList } from '@/services/api/goods';
-import { getAccountAuth, useSubscribe } from '@/business/common'
+import { getAccountAuth } from '@/business/common'
 import { useComponent } from '@/hooks/component'
 import { useTable } from '@pc/components/base/table'
 import AppTable from '@pc/components/base/table/index.vue'
@@ -27,6 +28,7 @@ import AppContextmenu from '@pc/components/base/contextmenu/index.vue'
 import AppButtonGroup from '@pc/components/modules/button-group/index.vue'
 import AppFilter from './components/filter/index.vue'
 import socket from '@/services/socket'
+import quote from '@/business/quote'
 
 const components = {
   trade: defineAsyncComponent(() => import('@pc/components/modules/trade/index.vue')),
@@ -69,14 +71,17 @@ const handleButton = (item?: Ermcp.Goods) => {
   }
 }
 
-const { addSubscribe } = useSubscribe()
-addSubscribe()
+const subscribe = quote.addSubscribe(['pp2205', 'pp2206', 'b2205', 'b2206']);
 
 queryGoodsList({
   success: (res) => {
     tableList.value = res.data;
   }
-});
+})
+
+onBeforeUnmount(() => {
+  subscribe.stop();
+})
 </script>
 
 <style lang="less">

+ 4 - 2
src/services/bus/interface.ts

@@ -2,8 +2,10 @@
  * 事件key
  */
 export enum EventKey {
-    subscribeQuote,
-    logout,
+    quotePushNotify, // 行情推送通知
+    quoteServerReconnectNotify, // 行情服务重连成功通知
+    logoutNotify, // 用户登出通知
+    MoneyChangedNotify, // 资金变动通知
 }
 
 /**

+ 28 - 2
src/services/socket/index.ts

@@ -1,7 +1,9 @@
 import { MTP2WebSocket } from '@/utils/websocket'
 import { SendMessage } from '@/utils/websocket/interface'
 import { Package40, Package50 } from '@/utils/websocket/package'
+import { timerInterceptor } from '@/utils/timer'
 import { globalState } from '@/store'
+import { FunCode } from '@/constants/enum/funcode'
 import { parseReceivePush } from './quote/build/decode'
 import eventBus from '@/services/bus'
 
@@ -15,12 +17,36 @@ export default new (class {
     private readonly tradeServer = new MTP2WebSocket(Package50);
 
     constructor() {
-        // 行情推送
         this.quoteServer.onPush = (p) => {
             const { mainClassNumber, content } = p;
             if (mainClassNumber === 65 && content) {
                 const result = parseReceivePush(content);
-                eventBus.$emit('subscribeQuote', result);
+                // 通知上层 行情推送
+                eventBus.$emit('quotePushNotify', result);
+            }
+        }
+
+        this.quoteServer.onReconnect = () => {
+            // 通知上层 重新订阅商品
+            eventBus.$emit('quoteServerReconnectNotify');
+        }
+
+        this.tradeServer.onPush = ({ funCode }) => {
+            const delay = 2000; // 延迟推送消息,防止短时间内重复请求
+
+            switch (funCode) {
+                case FunCode.MoneyChangedNotify: {
+                    timerInterceptor.debounce(() => {
+                        // 通知上层 资金变动
+                        eventBus.$emit('MoneyChangedNotify');
+                    }, delay, funCode.toString())
+                    break;
+                }
+                default: {
+                    if (funCode) {
+                        console.warn('接收到未定义的通知', funCode);
+                    }
+                }
             }
         }
     }

+ 4 - 1
src/utils/websocket/index.ts

@@ -40,6 +40,8 @@ export class MTP2WebSocket<T extends Package40 | Package50>{
     onError?: (e: Event) => void;
     /** 接收到推送类报文的回调 */
     onPush?: (data: T) => void;
+    /** 重连状态发生改变时的回调 */
+    onReconnect?: (socket: MTP2WebSocket<T>) => void;
 
     /** 当前连接状态 */
     connState: keyof typeof ConnectionState = 'Unconnected';
@@ -190,9 +192,10 @@ export class MTP2WebSocket<T extends Package40 | Package50>{
             this.reconnectTimer = window.setTimeout(() => {
                 this.onReady = undefined;
                 this.connect().then(() => {
-                    // 重连成功
+                    console.log(this.Package.name, this.host, '重连成功,可开始进行业务操作');
                     this.reconnectCount = 0;
                     this.reconnectInterval = this.defaultReconnectInterval;
+                    this.onReconnect && this.onReconnect(this);
                 }).catch(() => {
                     if (this.reconnectCount) {
                         this.reconnectInterval += this.defaultReconnectInterval; // 重连间隔时间每次递增5秒