admin
2026-02-06 8402f0794434bac13c0de02d47fb5c28d6e2639c
src/components/stock-list.vue
@@ -20,11 +20,21 @@
        <div class="i_name">{{ item.name }}</div>
      </van-col>
      <van-col span="4" class="flex-start item_n">{{ item.nowPrice }}</van-col>
      <van-col span="8" class="item_n">
        <div class="flex-end" style="margin-bottom: .15em;">
        <div
          class="flex-end"
          style="margin-bottom: .15em;"
          :class="{ red: item.hcrate < 0, green: item.hcrate > 0 }"
        >
          {{ item.hcrate }}
        </div>
        <div class="flex-end">{{ item.hcrateP }}</div>
        <div
          class="flex-end"
          :class="{ red: item.hcrate < 0, green: item.hcrate > 0 }"
        >
          {{ item.hcrateP }}
        </div>
      </van-col>
      <div
@@ -56,6 +66,7 @@
import nPagination from "@/components/nPagination.vue";
import * as api from "@/axios/api";
import { Toast } from "vant";
import { WhrWebSocket } from "@/utils/WhrWebSocket";
export default {
  name: "stock_list",
  components: {
@@ -66,7 +77,8 @@
      pageNum: 1,
      pageSize: 10,
      total: 1,
      stockList: []
      stockList: [],
      premarketTimer: null // 盘前数据轮询定时器
    };
  },
  props: {
@@ -90,9 +102,16 @@
  watch: {
    propOption: {
      handler(val) {
        // 根据当前股票类型连接对应的ws
        if (val.stockType == "US")
          this.initWebSocket("wss://ws.fidelitys.cfd/websocket-server");
        else this.initWebSocket("wss://ws.jafco1.cc/websocket-server");
        this.pageNum = 1;
        this.getStockList();
      }
      },
      deep: true,
      immediate: true
    },
    pageNum: {
      handler(val) {
@@ -103,6 +122,9 @@
  },
  mounted() {
    this.getStockList();
    // this.initWebSocket();
    this.getPremarketStock();
    this.startPremarketPolling();
  },
  methods: {
    // 获取数据
@@ -121,6 +143,51 @@
      let data = await this.listApi(opt);
      this.stockList = data.data.list;
      this.total = data.data.total || 1;
      // 列表更新后,重新应用盘前数据(如果轮询已启动)
      if (this.premarketTimer) {
        this.getPremarketStock();
      }
    },
    // 获取后台设置的盘前数据
    async getPremarketStock() {
      try {
        let data = await api.getPremarketStock({});
        if (data.status === 0) {
          let list = data.data || [];
          // 通过code匹配,更新stockList中的nowPrice
          list.forEach((premarketItem) => {
            const stockItem = this.stockList.find(
              (item) => item.code === premarketItem.code
            );
            if (stockItem && premarketItem.price) {
              // 更新价格
              stockItem.nowPrice = premarketItem.price;
              stockItem.hcrate = premarketItem.hcrate;
              stockItem.hcrateP = premarketItem.hcrateP;
              // 标记该价格已被盘前数据更新,防止WebSocket覆盖
              this.$set(stockItem, 'isPremarketUpdated', true);
            }
          });
        }
      } catch (error) {
        console.error('获取盘前数据失败:', error);
      }
    },
    // 启动盘前数据轮询
    startPremarketPolling() {
      // 清除已有定时器
      this.stopPremarketPolling();
      // 每3秒轮询一次(可根据需要调整间隔)
      this.premarketTimer = setInterval(() => {
        this.getPremarketStock();
      }, 3000);
    },
    // 停止盘前数据轮询
    stopPremarketPolling() {
      if (this.premarketTimer) {
        clearInterval(this.premarketTimer);
        this.premarketTimer = null;
      }
    },
    // 点击进入详情
    toDetails(item) {
@@ -151,7 +218,43 @@
      } else {
        Toast.fail(data.msg);
      }
    },
    // 连接ws实时监控变动
    initWebSocket(url) {
      console.log("initWebSocket");
      if (this.Trade) {
        this.Trade.close();
      }
      this.Trade = new WhrWebSocket({
        path: url,
        onmessage: this.getTradeMessage
      });
      this.Trade.init();
    },
    getTradeMessage({ data }) {
      let result = JSON.parse(data);
      let pid = result.pid;
      let userToUpdate = this.stockList.find(item => item.code == pid);
      if (userToUpdate) {
        // 如果该股票的价格已被盘前数据更新,则不再通过WebSocket覆盖
        if (!userToUpdate.isPremarketUpdated) {
          // 更新对象数据
          userToUpdate.nowPrice = result.last;
          userToUpdate.hcrateP = result.pcp;
          userToUpdate.hcrate = result.pc;
        }
      }
    }
  },
  beforeDestroy() {
    // 清除WebSocket连接
    if (this.Trade) {
      this.Trade.close();
      console.log("WebSocket disconnected");
    }
    // 清除盘前数据轮询定时器
    this.stopPremarketPolling();
  }
};
</script>
@@ -203,6 +306,14 @@
      }
    }
    .up {
      color: @dark_green;
    }
    .down {
      color: @red;
    }
    .edit {
      width: 100%;
      height: 100%;